Skip to content

Commit

Permalink
box: add user_def_new and user_def_delete helpers
Browse files Browse the repository at this point in the history
We will need to store some extra data in the user_def struct to support
different authentication mechanisms. Let's introduce convenient helpers
for allocating and freeing this struct so that we don't have to patch
all the places in the code where it's allocated or freed when we extend
the struct.

While we are at it, switch to grp_alloc, shorted the license text, and
replace include guards with pragma.

Needed for #7986

NO_DOC=refactoring
NO_TEST=refactoring
NO_CHANGELOG=refactoring
  • Loading branch information
locker committed Dec 9, 2022
1 parent f1879a1 commit e3f170d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 105 deletions.
40 changes: 19 additions & 21 deletions src/box/alter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2956,31 +2956,25 @@ user_def_new_from_tuple(struct tuple *tuple)
"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) {
diag_set(OutOfMemory, size, "malloc", "user");
return NULL;
}
auto def_guard = make_scoped_guard([=] { free(user); });
if (tuple_field_u32(tuple, BOX_USER_FIELD_ID, &(user->uid)) != 0)
uint32_t uid;
if (tuple_field_u32(tuple, BOX_USER_FIELD_ID, &uid) != 0)
return NULL;
if (tuple_field_u32(tuple, BOX_USER_FIELD_UID, &(user->owner)) != 0)
uint32_t owner;
if (tuple_field_u32(tuple, BOX_USER_FIELD_UID, &owner) != 0)
return NULL;
const char *user_type = tuple_field_cstr(tuple, BOX_USER_FIELD_TYPE);
if (user_type == NULL)
const char *type_str = tuple_field_cstr(tuple, BOX_USER_FIELD_TYPE);
if (type_str == 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) {
enum schema_object_type type = schema_object_type(type_str);
if (type != SC_ROLE && type != SC_USER) {
diag_set(ClientError, ER_CREATE_USER,
user->name, "unknown user type");
tt_cstr(name, name_len), "unknown user type");
return NULL;
}
if (identifier_check(user->name, name_len) != 0)
if (identifier_check(name, name_len) != 0)
return NULL;
struct user_def *user = user_def_new(uid, owner, type, name, name_len);
auto def_guard = make_scoped_guard([=] { user_def_delete(user); });
/*
* AUTH_DATA field in _user space should contain
* chap-sha1 -> base64_encode(sha1(sha1(password), 0).
Expand Down Expand Up @@ -3032,7 +3026,7 @@ user_cache_alter_user(struct trigger *trigger, void * /* event */)
struct user_def *user = user_def_new_from_tuple(tuple);
if (user == NULL)
return -1;
auto def_guard = make_scoped_guard([=] { free(user); });
auto def_guard = make_scoped_guard([=] { user_def_delete(user); });
/* Can throw if, e.g. too many users. */
try {
user_cache_replace(user);
Expand Down Expand Up @@ -3066,7 +3060,9 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
if (access_check_ddl(user->name, user->uid, user->owner, user->type,
PRIV_C) != 0)
return -1;
auto def_guard = make_scoped_guard([=] { free(user); });
auto def_guard = make_scoped_guard([=] {
user_def_delete(user);
});
try {
(void) user_cache_replace(user);
} catch (Exception *e) {
Expand Down Expand Up @@ -3122,7 +3118,9 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
if (access_check_ddl(user->name, user->uid, user->uid,
old_user->def->type, PRIV_A) != 0)
return -1;
auto def_guard = make_scoped_guard([=] { free(user); });
auto def_guard = make_scoped_guard([=] {
user_def_delete(user);
});
try {
user_cache_replace(user);
} catch (Exception *e) {
Expand Down
29 changes: 9 additions & 20 deletions src/box/user.cc
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ user_destroy(struct user *user)
* all privileges from them first.
*/
region_destroy(&user->pool);
free(user->def);
user_def_delete(user->def);
memset(user, 0, sizeof(*user));
}

Expand Down Expand Up @@ -470,7 +470,7 @@ user_cache_replace(struct user_def *def)
struct mh_i32ptr_node_t node = { def->uid, user };
mh_i32ptr_put(user_registry, &node, NULL, NULL);
} else {
free(user->def);
user_def_delete(user->def);
}
user->def = def;
return user;
Expand Down Expand Up @@ -555,32 +555,21 @@ user_cache_init(void)
* for 'guest' and 'admin' users here, they will be
* updated with snapshot contents during recovery.
*/
size_t name_len = strlen("guest");
size_t sz = user_def_sizeof(name_len);
struct user_def *def = (struct user_def *) calloc(1, sz);
if (def == NULL)
tnt_raise(OutOfMemory, sz, "malloc", "def");
const char *name = "guest";
struct user_def *def = user_def_new(GUEST, ADMIN, SC_USER,
name, strlen(name));
/* Free def in a case of exception. */
auto guest_def_guard = make_scoped_guard([=] { free(def); });
memcpy(def->name, "guest", name_len);
def->owner = ADMIN;
def->type = SC_USER;
auto guest_def_guard = make_scoped_guard([=] { user_def_delete(def); });
struct user *user = user_cache_replace(def);
/* Now the user cache owns the def. */
guest_def_guard.is_active = false;
/* 0 is the auth token and user id by default. */
assert(user->def->uid == GUEST && user->auth_token == GUEST);
(void) user;

name_len = strlen("admin");
sz = user_def_sizeof(name_len);
def = (struct user_def *) calloc(1, sz);
if (def == NULL)
tnt_raise(OutOfMemory, sz, "malloc", "def");
auto admin_def_guard = make_scoped_guard([=] { free(def); });
memcpy(def->name, "admin", name_len);
def->uid = def->owner = ADMIN;
def->type = SC_USER;
name = "admin";
def = user_def_new(ADMIN, ADMIN, SC_USER, name, strlen(name));
auto admin_def_guard = make_scoped_guard([=] { user_def_delete(def); });
user = user_cache_replace(def);
admin_def_guard.is_active = false;
/*
Expand Down
62 changes: 35 additions & 27 deletions src/box/user_def.c
Original file line number Diff line number Diff line change
@@ -1,35 +1,18 @@
/*
* Copyright 2010-2016, Tarantool AUTHORS, please see AUTHORS file.
* SPDX-License-Identifier: BSD-2-Clause
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* Copyright 2010-2022, Tarantool AUTHORS, please see AUTHORS file.
*/
#include "user_def.h"

#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "salad/grp_alloc.h"
#include "trivia/util.h"

const char *CHAP_SHA1_EMPTY_PASSWORD = "vhvewKp0tNyweZQ+cFKAlsyphfg=";

const char *
Expand Down Expand Up @@ -58,3 +41,28 @@ priv_name(user_access_t access)
return "Any";
}

struct user_def *
user_def_new(uint32_t uid, uint32_t owner, enum schema_object_type type,
const char *name, uint32_t name_len)
{
struct user_def *def;
struct grp_alloc all = grp_alloc_initializer();
grp_alloc_reserve_data(&all, sizeof(*def));
grp_alloc_reserve_str(&all, name_len);
grp_alloc_use(&all, xmalloc(grp_alloc_size(&all)));
def = grp_alloc_create_data(&all, sizeof(*def));
def->uid = uid;
def->owner = owner;
def->type = type;
memset(def->hash2, 0, sizeof(def->hash2));
def->name = grp_alloc_create_str(&all, name, name_len);
assert(grp_alloc_size(&all) == 0);
return def;
}

void
user_def_delete(struct user_def *def)
{
TRASH(def);
free(def);
}
55 changes: 18 additions & 37 deletions src/box/user_def.h
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
#ifndef TARANTOOL_BOX_USER_DEF_H_INCLUDED
#define TARANTOOL_BOX_USER_DEF_H_INCLUDED
/*
* Copyright 2010-2016, Tarantool AUTHORS, please see AUTHORS file.
* SPDX-License-Identifier: BSD-2-Clause
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* Copyright 2010-2022, Tarantool AUTHORS, please see AUTHORS file.
*/
#pragma once

#include <stdint.h>

#include "schema_def.h" /* for SCHEMA_OBJECT_TYPE */
#include "scramble.h" /* for SCRAMBLE_SIZE */
#define RB_COMPACT 1
Expand Down Expand Up @@ -167,14 +144,20 @@ struct user_def {
/** User password - hash2 */
char hash2[SCRAMBLE_SIZE];
/** User name - for error messages and debugging */
char name[0];
char *name;
};

static inline size_t
user_def_sizeof(uint32_t name_len)
{
return sizeof(struct user_def) + name_len + 1;
}
/**
* Allocates and initializes a new user definition.
* This function never fails.
*/
struct user_def *
user_def_new(uint32_t uid, uint32_t owner, enum schema_object_type type,
const char *name, uint32_t name_len);

/** Destroys and frees a user definition. */
void
user_def_delete(struct user_def *def);

/** Predefined user ids. */
enum {
Expand All @@ -189,5 +172,3 @@ enum {
#if defined(__cplusplus)
} /* extern "C" */
#endif /* defined(__cplusplus) */

#endif /* TARANTOOL_BOX_USER_DEF_H_INCLUDED */

0 comments on commit e3f170d

Please sign in to comment.