[tarantool-patches] [PATCH v4 15/20] refactoring: remove exceptions from user_def_new_from_tuple
Ilya Kosarev
i.kosarev at tarantool.org
Mon Sep 23 18:57:06 MSK 2019
user_def_new_from_tuple is used in on_replace_dd_user &
user_cache_alter_user therefore it has to be cleared from
exceptions. Now it doesn't throw any more. It means we also need
to clear from exceptions it's subsidiary function:
user_def_fill_auth_data. Their usages are updated.
Part of #4247
---
src/box/alter.cc | 68 ++++++++++++++++++++++++++++++++----------------
1 file changed, 46 insertions(+), 22 deletions(-)
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 8840e870c..7de20bc7f 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -2713,7 +2713,7 @@ user_has_data(struct user *user, bool *has_data)
* defined, but for now we only support chap-sha1. Get
* password of chap-sha1 from the _user space.
*/
-void
+int
user_def_fill_auth_data(struct user_def *user, const char *auth_data)
{
uint8_t type = mp_typeof(*auth_data);
@@ -2725,13 +2725,14 @@ user_def_fill_auth_data(struct user_def *user, const char *auth_data)
* table may well be encoded as an msgpack array.
* Treat as no data.
*/
- return;
+ return 0;
}
if (mp_typeof(*auth_data) != MP_MAP) {
/** Prevent users from making silly mistakes */
- tnt_raise(ClientError, ER_CREATE_USER,
+ diag_set(ClientError, ER_CREATE_USER,
user->name, "invalid password format, "
"use box.schema.user.passwd() to reset password");
+ return -1;
}
uint32_t mech_count = mp_decode_map(&auth_data);
for (uint32_t i = 0; i < mech_count; i++) {
@@ -2748,50 +2749,64 @@ user_def_fill_auth_data(struct user_def *user, const char *auth_data)
}
const char *hash2_base64 = mp_decode_str(&auth_data, &len);
if (len != 0 && len != SCRAMBLE_BASE64_SIZE) {
- tnt_raise(ClientError, ER_CREATE_USER,
+ diag_set(ClientError, ER_CREATE_USER,
user->name, "invalid user password");
+ return -1;
}
if (user->uid == GUEST) {
- /** Guest user is permitted to have empty password */
- if (strncmp(hash2_base64, CHAP_SHA1_EMPTY_PASSWORD, len))
- tnt_raise(ClientError, ER_GUEST_USER_PASSWORD);
+ /** Guest user is permitted to have empty password */
+ if (strncmp(hash2_base64, CHAP_SHA1_EMPTY_PASSWORD, len)) {
+ diag_set(ClientError, ER_GUEST_USER_PASSWORD);
+ return -1;
+ }
}
base64_decode(hash2_base64, len, user->hash2,
sizeof(user->hash2));
break;
}
+ return 0;
}
static struct user_def *
user_def_new_from_tuple(struct tuple *tuple)
{
uint32_t name_len;
- const char *name = tuple_field_str_xc(tuple, BOX_USER_FIELD_NAME,
- &name_len);
+ const char *name = tuple_field_str(tuple, BOX_USER_FIELD_NAME,
+ &name_len);
+ if (name == NULL)
+ return NULL;
if (name_len > BOX_NAME_MAX) {
- tnt_raise(ClientError, ER_CREATE_USER,
+ diag_set(ClientError, ER_CREATE_USER,
tt_cstr(name, BOX_INVALID_NAME_MAX),
"user name is too long");
+ return NULL;
}
size_t size = user_def_sizeof(name_len);
/* Use calloc: in case user password is empty, fill it with \0 */
struct user_def *user = (struct user_def *) malloc(size);
- if (user == NULL)
- tnt_raise(OutOfMemory, size, "malloc", "user");
+ if (user == NULL) {
+ diag_set(OutOfMemory, size, "malloc", "user");
+ return NULL;
+ }
auto def_guard = make_scoped_guard([=] { free(user); });
- user->uid = tuple_field_u32_xc(tuple, BOX_USER_FIELD_ID);
- user->owner = tuple_field_u32_xc(tuple, BOX_USER_FIELD_UID);
- const char *user_type =
- tuple_field_cstr_xc(tuple, BOX_USER_FIELD_TYPE);
- user->type= schema_object_type(user_type);
+ if (tuple_field_u32(tuple, BOX_USER_FIELD_ID, &(user->uid)) != 0)
+ return NULL;
+ if (tuple_field_u32(tuple, BOX_USER_FIELD_UID, &(user->owner)) != 0)
+ return NULL;
+ const char *user_type = tuple_field_cstr(tuple, BOX_USER_FIELD_TYPE);
+ if (user_type == NULL)
+ return NULL;
+ user->type = schema_object_type(user_type);
memcpy(user->name, name, name_len);
user->name[name_len] = 0;
if (user->type != SC_ROLE && user->type != SC_USER) {
- tnt_raise(ClientError, ER_CREATE_USER,
+ diag_set(ClientError, ER_CREATE_USER,
user->name, "unknown user type");
+ return NULL;
}
- identifier_check_xc(user->name, name_len);
+ if (identifier_check(user->name, name_len) != 0)
+ return NULL;
/*
* AUTH_DATA field in _user space should contain
* chap-sha1 -> base64_encode(sha1(sha1(password), 0).
@@ -2812,11 +2827,14 @@ user_def_new_from_tuple(struct tuple *tuple)
} else {
is_auth_empty = false;
}
- if (!is_auth_empty && user->type == SC_ROLE)
- tnt_raise(ClientError, ER_CREATE_ROLE, user->name,
+ if (!is_auth_empty && user->type == SC_ROLE) {
+ diag_set(ClientError, ER_CREATE_ROLE, user->name,
"authentication data can not be set for a "\
"role");
- user_def_fill_auth_data(user, auth_data);
+ return NULL;
+ }
+ if (user_def_fill_auth_data(user, auth_data) != 0)
+ return NULL;
}
def_guard.is_active = false;
return user;
@@ -2838,6 +2856,8 @@ user_cache_alter_user(struct trigger *trigger, void * /* event */)
{
struct tuple *tuple = (struct tuple *)trigger->data;
struct user_def *user = user_def_new_from_tuple(tuple);
+ if (user == NULL)
+ return -1;
auto def_guard = make_scoped_guard([=] { free(user); });
/* Can throw if, e.g. too many users. */
try {
@@ -2867,6 +2887,8 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
struct user *old_user = user_by_id(uid);
if (new_tuple != NULL && old_user == NULL) { /* INSERT */
struct user_def *user = user_def_new_from_tuple(new_tuple);
+ if (user == NULL)
+ return -1;
if (access_check_ddl(user->name, user->uid, user->owner, user->type,
PRIV_C) != 0)
return -1;
@@ -2921,6 +2943,8 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
* correct.
*/
struct user_def *user = user_def_new_from_tuple(new_tuple);
+ if (user == NULL)
+ return -1;
if (access_check_ddl(user->name, user->uid, user->uid,
old_user->def->type, PRIV_A) != 0)
return -1;
--
2.17.1
More information about the Tarantool-patches
mailing list