From 5c3c8ed32c7a9c84a0e86c8453269f0925ce63ed Mon Sep 17 00:00:00 2001 From: Dmitry Rodionov <d.rodionov@picodata.io> Date: Thu, 28 Sep 2023 13:59:26 +0300 Subject: [PATCH] refactor: rename priv_type to box_privilege_type and expose it Rename the members as well. Keep uint16_t in box_check_acess_space as it is for other exported functions NO_DOC=picodata internal patch NO_CHANGELOG=picodata internal patch NO_TEST=picodata internal patch --- src/CMakeLists.txt | 1 + src/box/alter.cc | 75 +++++++++++++++++++++++------------------- src/box/box.cc | 16 ++++----- src/box/box.h | 2 +- src/box/call.c | 16 +++++---- src/box/func.c | 15 +++++---- src/box/index.cc | 2 +- src/box/lua/schema.lua | 66 ++++++++++++++++++------------------- src/box/sequence.c | 11 ++++--- src/box/session.c | 11 ++++--- src/box/session.h | 6 ++-- src/box/space.c | 12 +++---- src/box/space.h | 4 +-- src/box/sql/vdbe.c | 2 +- src/box/sysview.c | 36 +++++++++++--------- src/box/user.cc | 7 ++-- src/box/user_def.c | 2 +- src/box/user_def.h | 52 ++++++++++++++++------------- 18 files changed, 182 insertions(+), 154 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 22e4c11214..1a9226eec0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,6 +232,7 @@ set(api_headers ${PROJECT_SOURCE_DIR}/src/box/error.h ${PROJECT_SOURCE_DIR}/src/box/lua/tuple.h ${PROJECT_SOURCE_DIR}/src/box/user.h + ${PROJECT_SOURCE_DIR}/src/box/user_def.h ${PROJECT_SOURCE_DIR}/src/lib/core/latch.h ${PROJECT_SOURCE_DIR}/src/lib/core/clock.h ${PROJECT_SOURCE_DIR}/src/box/decimal.h diff --git a/src/box/alter.cc b/src/box/alter.cc index ec9de86355..be8ab2f7f5 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -71,13 +71,15 @@ box_schema_version_bump(void) static int access_check_ddl(const char *name, uint32_t object_id, uint32_t owner_uid, - enum schema_object_type type, enum priv_type priv_type) + enum schema_object_type type, + enum box_privilege_type priv_type) { struct credentials *cr = effective_user(); - user_access_t has_access = cr->universal_access; + box_user_access_mask_t has_access = cr->universal_access; - user_access_t access = ((PRIV_U | (user_access_t) priv_type) & - ~has_access); + box_user_access_mask_t access = ( + (BOX_PRIVILEGE_USAGE | (box_user_access_mask_t)priv_type) & + ~has_access); bool is_owner = owner_uid == cr->uid || cr->uid == ADMIN; if (access == 0) return 0; /* Access granted. */ @@ -95,12 +97,12 @@ access_check_ddl(const char *name, uint32_t object_id, uint32_t owner_uid, * the owner of the object, but this should be ignored -- * CREATE privilege is required. */ - if (access == 0 || (is_owner && !(access & (PRIV_U | PRIV_C)))) + if (access == 0 || (is_owner && !(access & (BOX_PRIVILEGE_USAGE | BOX_PRIVILEGE_CREATE)))) return 0; /* Access granted. */ /* * USAGE can be granted only globally. */ - if (!(access & PRIV_U)) { + if (!(access & BOX_PRIVILEGE_USAGE)) { /* Check for privileges on a single object. */ struct access *object = access_find(type, object_id); if (object != NULL) @@ -114,9 +116,9 @@ access_check_ddl(const char *name, uint32_t object_id, uint32_t owner_uid, return -1; const char *object_name; const char *pname; - if (access & PRIV_U) { + if (access & BOX_PRIVILEGE_USAGE) { object_name = schema_object_name(SC_UNIVERSE); - pname = priv_name(PRIV_U); + pname = priv_name(BOX_PRIVILEGE_USAGE); name = ""; } else { object_name = schema_object_name(type); @@ -2086,7 +2088,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) auto def_guard = make_scoped_guard([=] { space_def_delete(def); }); if (access_check_ddl(def->name, def->id, def->uid, SC_SPACE, - PRIV_C) != 0) + BOX_PRIVILEGE_CREATE) != 0) return -1; RLIST_HEAD(empty_list); struct space *space = space_new(def, &empty_list); @@ -2143,7 +2145,8 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) } } else if (new_tuple == NULL) { /* DELETE */ if (access_check_ddl(old_space->def->name, old_space->def->id, - old_space->def->uid, SC_SPACE, PRIV_D) != 0) + old_space->def->uid, SC_SPACE, + BOX_PRIVILEGE_DROP) != 0) return -1; /* Verify that the space is empty (has no indexes) */ if (old_space->index_count) { @@ -2244,7 +2247,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) auto def_guard = make_scoped_guard([=] { space_def_delete(def); }); if (access_check_ddl(def->name, def->id, def->uid, SC_SPACE, - PRIV_A) != 0) + BOX_PRIVILEGE_ALTER) != 0) return -1; if (def->id != space_id(old_space)) { diag_set(ClientError, ER_ALTER_SPACE, @@ -2407,9 +2410,10 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event) "can not add index on a view"); return -1; } - enum priv_type priv_type = new_tuple ? PRIV_C : PRIV_D; + enum box_privilege_type priv_type = ( + new_tuple ? BOX_PRIVILEGE_CREATE : BOX_PRIVILEGE_DROP); if (old_tuple && new_tuple) - priv_type = PRIV_A; + priv_type = BOX_PRIVILEGE_ALTER; if (access_check_ddl(old_space->def->name, old_space->def->id, old_space->def->uid, SC_SPACE, priv_type) != 0) return -1; @@ -2702,7 +2706,7 @@ on_replace_dd_truncate(struct trigger * /* trigger */, void *event) * The check should precede initial recovery check to correctly * handle direct insert into _truncate systable. */ - if (access_check_space(old_space, PRIV_W) != 0) + if (access_check_space(old_space, BOX_PRIVILEGE_WRITE) != 0) return -1; /* @@ -2973,7 +2977,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event) if (user == NULL) return -1; if (access_check_ddl(user->name, user->uid, user->owner, user->type, - PRIV_C) != 0) + BOX_PRIVILEGE_CREATE) != 0) return -1; auto def_guard = make_scoped_guard([=] { user_def_delete(user); @@ -2992,7 +2996,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event) } else if (new_tuple == NULL) { /* DELETE */ if (access_check_ddl(old_user->def->name, old_user->def->uid, old_user->def->owner, old_user->def->type, - PRIV_D) != 0) + BOX_PRIVILEGE_DROP) != 0) return -1; /* Can't drop guest or super user */ if (uid <= (uint32_t) BOX_SYSTEM_USER_ID_MAX || uid == SUPER) { @@ -3031,7 +3035,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event) if (user == NULL) return -1; if (access_check_ddl(user->name, user->uid, user->uid, - old_user->def->type, PRIV_A) != 0) + old_user->def->type, BOX_PRIVILEGE_ALTER) != 0) return -1; auto def_guard = make_scoped_guard([=] { user_def_delete(user); @@ -3331,7 +3335,7 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event) func_def_delete(def); }); if (access_check_ddl(def->name, def->fid, def->uid, SC_FUNCTION, - PRIV_C) != 0) + BOX_PRIVILEGE_CREATE) != 0) return -1; struct trigger *on_rollback = txn_alter_trigger_new(on_create_func_rollback, NULL); @@ -3354,7 +3358,7 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event) * who created it or a superuser. */ if (access_check_ddl(old_func->def->name, fid, uid, SC_FUNCTION, - PRIV_D) != 0) + BOX_PRIVILEGE_DROP) != 0) return -1; /* Can only delete func if it has no grants. */ bool out; @@ -3606,7 +3610,7 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event) assert(old_coll_id != NULL); if (access_check_ddl(old_coll_id->name, old_coll_id->id, old_coll_id->owner_id, SC_COLLATION, - PRIV_D) != 0) + BOX_PRIVILEGE_DROP) != 0) return -1; /* * Set on_commit/on_rollback triggers after @@ -3628,7 +3632,7 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event) if (coll_id_def_new_from_tuple(new_tuple, &new_def) != 0) return -1; if (access_check_ddl(new_def.name, new_def.id, new_def.owner_id, - SC_COLLATION, PRIV_C) != 0) + SC_COLLATION, BOX_PRIVILEGE_CREATE) != 0) return -1; struct coll_id *new_coll_id = coll_id_new(&new_def); if (new_coll_id == NULL) @@ -3716,7 +3720,7 @@ priv_def_create_from_tuple(struct priv_def *priv, struct tuple *tuple) * In the future we must protect grant/revoke with a logical lock. */ static int -priv_def_check(struct priv_def *priv, enum priv_type priv_type) +priv_def_check(struct priv_def *priv, enum box_privilege_type priv_type) { struct user *grantor = user_find(priv->grantor_id); if (grantor == NULL) @@ -3814,7 +3818,8 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type) */ if (role->def->owner != grantor->def->uid && grantor->def->uid != ADMIN && - (role->def->uid != PUBLIC || priv->access != PRIV_X)) { + (role->def->uid != PUBLIC || + priv->access != BOX_PRIVILEGE_EXECUTE)) { diag_set(AccessDeniedError, priv_name(priv_type), schema_object_name(SC_ROLE), name, @@ -3884,7 +3889,8 @@ grant_or_revoke(struct priv_def *priv) * Grant a role to a user only when privilege type is 'execute' * and the role is specified. */ - if (priv->object_type == SC_ROLE && !(priv->access & ~PRIV_X)) { + if (priv->object_type == SC_ROLE && + !(priv->access & ~BOX_PRIVILEGE_EXECUTE)) { struct user *role = user_by_id(priv->object_id); if (role == NULL || role->def->type != SC_ROLE) return 0; @@ -3945,7 +3951,7 @@ on_replace_dd_priv(struct trigger * /* trigger */, void *event) if (new_tuple != NULL && old_tuple == NULL) { /* grant */ if (priv_def_create_from_tuple(&priv, new_tuple) != 0 || - priv_def_check(&priv, PRIV_GRANT) != 0 || + priv_def_check(&priv, BOX_PRIVILEGE_GRANT) != 0 || grant_or_revoke(&priv) != 0) return -1; struct trigger *on_rollback = @@ -3956,7 +3962,7 @@ on_replace_dd_priv(struct trigger * /* trigger */, void *event) } else if (new_tuple == NULL) { /* revoke */ assert(old_tuple); if (priv_def_create_from_tuple(&priv, old_tuple) != 0 || - priv_def_check(&priv, PRIV_REVOKE) != 0) + priv_def_check(&priv, BOX_PRIVILEGE_REVOKE) != 0) return -1; priv.access = 0; if (grant_or_revoke(&priv) != 0) @@ -3968,7 +3974,7 @@ on_replace_dd_priv(struct trigger * /* trigger */, void *event) txn_stmt_on_rollback(stmt, on_rollback); } else { /* modify */ if (priv_def_create_from_tuple(&priv, new_tuple) != 0 || - priv_def_check(&priv, PRIV_GRANT) != 0 || + priv_def_check(&priv, BOX_PRIVILEGE_GRANT) != 0 || grant_or_revoke(&priv) != 0) return -1; struct trigger *on_rollback = @@ -4329,7 +4335,7 @@ on_replace_dd_sequence(struct trigger * /* trigger */, void *event) if (new_def == NULL) return -1; if (access_check_ddl(new_def->name, new_def->id, new_def->uid, - SC_SEQUENCE, PRIV_C) != 0) + SC_SEQUENCE, BOX_PRIVILEGE_CREATE) != 0) return -1; struct trigger *on_rollback = txn_alter_trigger_new(on_create_sequence_rollback, NULL); @@ -4348,7 +4354,7 @@ on_replace_dd_sequence(struct trigger * /* trigger */, void *event) seq = sequence_by_id(id); assert(seq != NULL); if (access_check_ddl(seq->def->name, seq->def->id, seq->def->uid, - SC_SEQUENCE, PRIV_D) != 0) + SC_SEQUENCE, BOX_PRIVILEGE_DROP) != 0) return -1; bool out; if (space_has_data(BOX_SEQUENCE_DATA_ID, 0, id, &out) != 0) @@ -4390,7 +4396,7 @@ on_replace_dd_sequence(struct trigger * /* trigger */, void *event) seq = sequence_by_id(new_def->id); assert(seq != NULL); if (access_check_ddl(seq->def->name, seq->def->id, seq->def->uid, - SC_SEQUENCE, PRIV_A) != 0) + SC_SEQUENCE, BOX_PRIVILEGE_ALTER) != 0) return -1; struct trigger *on_commit = txn_alter_trigger_new(on_alter_sequence_commit, seq->def); @@ -4620,7 +4626,8 @@ on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event) "space \"_space_sequence\"", "update"); return -1; } - enum priv_type priv_type = stmt->new_tuple ? PRIV_C : PRIV_D; + enum box_privilege_type priv_type = stmt->new_tuple ? + BOX_PRIVILEGE_CREATE : BOX_PRIVILEGE_DROP; /* Check we have the correct access type on the sequence. * */ if (is_generated || !stmt->new_tuple) { @@ -4633,15 +4640,15 @@ on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event) * check that it has read and write access. */ if (access_check_ddl(seq->def->name, seq->def->id, seq->def->uid, - SC_SEQUENCE, PRIV_R) != 0) + SC_SEQUENCE, BOX_PRIVILEGE_READ) != 0) return -1; if (access_check_ddl(seq->def->name, seq->def->id, seq->def->uid, - SC_SEQUENCE, PRIV_W) != 0) + SC_SEQUENCE, BOX_PRIVILEGE_WRITE) != 0) return -1; } /** Check we have alter access on space. */ if (access_check_ddl(space->def->name, space->def->id, space->def->uid, - SC_SPACE, PRIV_A) != 0) + SC_SPACE, BOX_PRIVILEGE_ALTER) != 0) return -1; if (stmt->new_tuple != NULL) { /* INSERT, UPDATE */ diff --git a/src/box/box.cc b/src/box/box.cc index 1b0541c88f..e22e664680 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -454,7 +454,7 @@ box_process_rw(struct request *request, struct space *space, return -1; assert(iproto_type_is_dml(request->type)); rmean_collect(rmean_box, request->type, 1); - if (access_check_space(space, PRIV_W) != 0) + if (access_check_space(space, BOX_PRIVILEGE_WRITE) != 0) goto rollback; if (txn_begin_stmt(txn, space, request->type) != 0) goto rollback; @@ -3185,7 +3185,7 @@ box_select(uint32_t space_id, uint32_t index_id, struct space *space = space_cache_find(space_id); if (space == NULL) return -1; - if (access_check_space(space, PRIV_R) != 0) + if (access_check_space(space, BOX_PRIVILEGE_READ) != 0) return -1; struct index *index = index_find(space, index_id); if (index == NULL) @@ -3720,7 +3720,7 @@ box_process_fetch_snapshot(struct iostream *io, tnt_raise(ClientError, ER_LOADING); /* Check permissions */ - access_check_universe_xc(PRIV_R); + access_check_universe_xc(BOX_PRIVILEGE_READ); /* Forbid replication with disabled WAL */ if (wal_mode() == WAL_NONE) { @@ -3761,7 +3761,7 @@ box_process_register(struct iostream *io, const struct xrow_header *header) if (tt_uuid_is_equal(&req.instance_uuid, &INSTANCE_UUID)) tnt_raise(ClientError, ER_CONNECTION_TO_SELF); - access_check_universe_xc(PRIV_R); + access_check_universe_xc(BOX_PRIVILEGE_READ); /* We only get register requests from anonymous instances. */ struct replica *replica = replica_by_uuid(&req.instance_uuid); if (replica && replica->id != REPLICA_ID_NIL) { @@ -3777,7 +3777,7 @@ box_process_register(struct iostream *io, const struct xrow_header *header) /* See box_process_join() */ box_check_writable_xc(); struct space *space = space_cache_find_xc(BOX_CLUSTER_ID); - access_check_space_xc(space, PRIV_W); + access_check_space_xc(space, BOX_PRIVILEGE_WRITE); /* Forbid replication with disabled WAL */ if (wal_mode() == WAL_NONE) { @@ -3897,7 +3897,7 @@ box_process_join(struct iostream *io, const struct xrow_header *header) tnt_raise(ClientError, ER_CONNECTION_TO_SELF); /* Check permissions */ - access_check_universe_xc(PRIV_R); + access_check_universe_xc(BOX_PRIVILEGE_READ); if (replication_anon) { tnt_raise(ClientError, ER_UNSUPPORTED, "Anonymous replica", @@ -3914,7 +3914,7 @@ box_process_join(struct iostream *io, const struct xrow_header *header) if (replica == NULL || replica->id == REPLICA_ID_NIL) { box_check_writable_xc(); struct space *space = space_cache_find_xc(BOX_CLUSTER_ID); - access_check_space_xc(space, PRIV_W); + access_check_space_xc(space, BOX_PRIVILEGE_WRITE); } /* Forbid replication with disabled WAL */ @@ -4027,7 +4027,7 @@ box_process_subscribe(struct iostream *io, const struct xrow_header *header) } /* Check permissions */ - access_check_universe_xc(PRIV_R); + access_check_universe_xc(BOX_PRIVILEGE_READ); /* Check replica uuid */ struct replica *replica = replica_by_uuid(&req.instance_uuid); diff --git a/src/box/box.h b/src/box/box.h index b52a387fb9..eff8aa3ee3 100644 --- a/src/box/box.h +++ b/src/box/box.h @@ -708,7 +708,7 @@ box_user_id_by_name(const char *name, const char *name_end, uint32_t *uid); * with only one permission at a time. * Most relevant access types are read and write. * \param space_id space id - * \param access type of access. See valid options in priv_type enum. + * \param access type of access. See valid options in box_privilege_type enum. * \retval -1 on error (check box_error_last()) * \retval 0 on success */ diff --git a/src/box/call.c b/src/box/call.c index 65312e2406..cfb6079163 100644 --- a/src/box/call.c +++ b/src/box/call.c @@ -122,11 +122,12 @@ int box_module_reload(const char *name) { struct credentials *credentials = effective_user(); - if ((credentials->universal_access & (PRIV_X | PRIV_U)) != - (PRIV_X | PRIV_U)) { + if ((credentials->universal_access & + (BOX_PRIVILEGE_EXECUTE | BOX_PRIVILEGE_USAGE)) != + (BOX_PRIVILEGE_EXECUTE | BOX_PRIVILEGE_USAGE)) { struct user *user = user_find(credentials->uid); if (user != NULL) - diag_set(AccessDeniedError, priv_name(PRIV_U), + diag_set(AccessDeniedError, priv_name(BOX_PRIVILEGE_USAGE), schema_object_name(SC_UNIVERSE), "", user->def->name); return -1; @@ -172,9 +173,10 @@ box_process_call(struct call_request *request, struct port *port) if (func_call_no_access_check(func, &args, port) != 0) return -1; } else { - if (access_check_universe_object(PRIV_X | PRIV_U, - SC_FUNCTION, - tt_cstr(name, name_len)) != 0) + if (access_check_universe_object( + BOX_PRIVILEGE_EXECUTE | BOX_PRIVILEGE_USAGE, + SC_FUNCTION, + tt_cstr(name, name_len)) != 0) return -1; box_run_on_call(IPROTO_CALL, name, name_len, request->args); if (box_lua_call(name, name_len, &args, port) != 0) @@ -188,7 +190,7 @@ box_process_eval(struct call_request *request, struct port *port) { rmean_collect(rmean_box, IPROTO_EVAL, 1); /* Check permissions */ - if (access_check_universe(PRIV_X) != 0) + if (access_check_universe(BOX_PRIVILEGE_EXECUTE) != 0) return -1; struct port args; port_msgpack_create(&args, request->args, diff --git a/src/box/func.c b/src/box/func.c index ae3f89c75f..1ec1eb245d 100644 --- a/src/box/func.c +++ b/src/box/func.c @@ -557,20 +557,23 @@ func_access_check(struct func *func) * checks. No special check for ADMIN user is necessary * since ADMIN has universal access. */ - if ((credentials->universal_access & (PRIV_X | PRIV_U)) == - (PRIV_X | PRIV_U)) + if ((credentials->universal_access & + (BOX_PRIVILEGE_EXECUTE | BOX_PRIVILEGE_USAGE)) == + (BOX_PRIVILEGE_EXECUTE | BOX_PRIVILEGE_USAGE)) return 0; - user_access_t access = PRIV_X | PRIV_U; + box_user_access_mask_t access = + BOX_PRIVILEGE_EXECUTE | BOX_PRIVILEGE_USAGE; /* Check access for all functions. */ access &= ~entity_access_get(SC_FUNCTION)[credentials->auth_token].effective; - user_access_t func_access = access & ~credentials->universal_access; - if ((func_access & PRIV_U) != 0 || + box_user_access_mask_t func_access = + access & ~credentials->universal_access; + if ((func_access & BOX_PRIVILEGE_USAGE) != 0 || (func->def->uid != credentials->uid && func_access & ~func->access[credentials->auth_token].effective)) { /* Access violation, report error. */ struct user *user = user_find(credentials->uid); if (user != NULL) { - diag_set(AccessDeniedError, priv_name(PRIV_X), + diag_set(AccessDeniedError, priv_name(BOX_PRIVILEGE_EXECUTE), schema_object_name(SC_FUNCTION), func->def->name, user->def->name); } diff --git a/src/box/index.cc b/src/box/index.cc index 5b7abaee2f..2f250ed608 100644 --- a/src/box/index.cc +++ b/src/box/index.cc @@ -190,7 +190,7 @@ check_index(uint32_t space_id, uint32_t index_id, *space = space_cache_find(space_id); if (*space == NULL) return -1; - if (access_check_space(*space, PRIV_R) != 0) + if (access_check_space(*space, BOX_PRIVILEGE_READ) != 0) return -1; *index = index_find(*space, index_id); if (*index == NULL) diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 10865b18b2..c853c64720 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -124,44 +124,44 @@ ffi.cdef[[ struct port *port, int64_t iterator, uint64_t offset, uint64_t limit); - enum priv_type { - PRIV_R = 1, - PRIV_W = 2, - PRIV_X = 4, - PRIV_S = 8, - PRIV_U = 16, - PRIV_C = 32, - PRIV_D = 64, - PRIV_A = 128, - PRIV_REFERENCE = 256, - PRIV_TRIGGER = 512, - PRIV_INSERT = 1024, - PRIV_UPDATE = 2048, - PRIV_DELETE = 4096, - PRIV_GRANT = 8192, - PRIV_REVOKE = 16384, - PRIV_ALL = 4294967295 + enum box_privilege_type { + BOX_PRIVILEGE_READ = 1, + BOX_PRIVILEGE_WRITE = 2, + BOX_PRIVILEGE_EXECUTE = 4, + BOX_PRIVILEGE_SESSION = 8, + BOX_PRIVILEGE_USAGE = 16, + BOX_PRIVILEGE_CREATE = 32, + BOX_PRIVILEGE_DROP = 64, + BOX_PRIVILEGE_ALTER = 128, + BOX_PRIVILEGE_REFERENCE = 256, + BOX_PRIVILEGE_TRIGGER = 512, + BOX_PRIVILEGE_INSERT = 1024, + BOX_PRIVILEGE_UPDATE = 2048, + BOX_PRIVILEGE_DELETE = 4096, + BOX_PRIVILEGE_GRANT = 8192, + BOX_PRIVILEGE_REVOKE = 16384, + BOX_PRIVILEGE_ALL = 4294967295 }; ]] box.priv = { - ["R"] = builtin.PRIV_R, - ["W"] = builtin.PRIV_W, - ["X"] = builtin.PRIV_X, - ["S"] = builtin.PRIV_S, - ["U"] = builtin.PRIV_U, - ["C"] = builtin.PRIV_C, - ["D"] = builtin.PRIV_D, - ["A"] = builtin.PRIV_A, - ["REFERENCE"] = builtin.PRIV_REFERENCE, - ["TRIGGER"] = builtin.PRIV_TRIGGER, - ["INSERT"] = builtin.PRIV_INSERT, - ["UPDATE"] = builtin.PRIV_UPDATE, - ["DELETE"] = builtin.PRIV_DELETE, - ["GRANT"]= builtin.PRIV_GRANT, - ["REVOKE"] = builtin.PRIV_REVOKE, - ["ALL"] = builtin.PRIV_ALL + ["R"] = builtin.BOX_PRIVILEGE_READ, + ["W"] = builtin.BOX_PRIVILEGE_WRITE, + ["X"] = builtin.BOX_PRIVILEGE_EXECUTE, + ["S"] = builtin.BOX_PRIVILEGE_SESSION, + ["U"] = builtin.BOX_PRIVILEGE_USAGE, + ["C"] = builtin.BOX_PRIVILEGE_CREATE, + ["D"] = builtin.BOX_PRIVILEGE_DROP, + ["A"] = builtin.BOX_PRIVILEGE_ALTER, + ["REFERENCE"] = builtin.BOX_PRIVILEGE_REFERENCE, + ["TRIGGER"] = builtin.BOX_PRIVILEGE_TRIGGER, + ["INSERT"] = builtin.BOX_PRIVILEGE_INSERT, + ["UPDATE"] = builtin.BOX_PRIVILEGE_UPDATE, + ["DELETE"] = builtin.BOX_PRIVILEGE_DELETE, + ["GRANT"]= builtin.BOX_PRIVILEGE_GRANT, + ["REVOKE"] = builtin.BOX_PRIVILEGE_REVOKE, + ["ALL"] = builtin.BOX_PRIVILEGE_ALL } local function user_or_role_resolve(user) diff --git a/src/box/sequence.c b/src/box/sequence.c index 4c3c05d8f7..55f881eba6 100644 --- a/src/box/sequence.c +++ b/src/box/sequence.c @@ -270,12 +270,13 @@ access_check_sequence(struct sequence *seq) * universal access. */ - user_access_t access = PRIV_U | PRIV_W; - user_access_t sequence_access = access & ~cr->universal_access; + box_user_access_mask_t access = + BOX_PRIVILEGE_USAGE | BOX_PRIVILEGE_WRITE; + box_user_access_mask_t sequence_access = access & ~cr->universal_access; sequence_access &= ~entity_access_get(SC_SEQUENCE)[cr->auth_token].effective; if (sequence_access && /* Check for missing Usage access, ignore owner rights. */ - (sequence_access & PRIV_U || + (sequence_access & BOX_PRIVILEGE_USAGE || /* Check for missing specific access, respect owner rights. */ (seq->def->uid != cr->uid && sequence_access & ~seq->access[cr->auth_token].effective))) { @@ -283,9 +284,9 @@ access_check_sequence(struct sequence *seq) /* Access violation, report error. */ struct user *user = user_find(cr->uid); if (user != NULL) { - if (!(cr->universal_access & PRIV_U)) { + if (!(cr->universal_access & BOX_PRIVILEGE_USAGE)) { diag_set(AccessDeniedError, - priv_name(PRIV_U), + priv_name(BOX_PRIVILEGE_USAGE), schema_object_name(SC_UNIVERSE), "", user->def->name); } else { diff --git a/src/box/session.c b/src/box/session.c index a3e91c714e..fefdc6b198 100644 --- a/src/box/session.c +++ b/src/box/session.c @@ -439,8 +439,9 @@ access_check_session(struct user *user) * Can't use here access_check_universe * as current_user is not assigned yet */ - if (!(universe.access[user->auth_token].effective & PRIV_S)) { - diag_set(AccessDeniedError, priv_name(PRIV_S), + if (!(universe.access[user->auth_token].effective & + BOX_PRIVILEGE_SESSION)) { + diag_set(AccessDeniedError, priv_name(BOX_PRIVILEGE_SESSION), schema_object_name(SC_UNIVERSE), "", user->def->name); return -1; @@ -449,12 +450,12 @@ access_check_session(struct user *user) } int -access_check_universe_object(user_access_t access, +access_check_universe_object(box_user_access_mask_t access, enum schema_object_type object_type, const char *object_name) { struct credentials *credentials = effective_user(); - access |= PRIV_U; + access |= BOX_PRIVILEGE_USAGE; if ((credentials->universal_access & access) ^ access) { /* * Access violation, report error. @@ -483,7 +484,7 @@ access_check_universe_object(user_access_t access, } int -access_check_universe(user_access_t access) +access_check_universe(box_user_access_mask_t access) { return access_check_universe_object(access, SC_UNIVERSE, ""); } diff --git a/src/box/session.h b/src/box/session.h index a522d5b8bc..136528ca12 100644 --- a/src/box/session.h +++ b/src/box/session.h @@ -390,7 +390,7 @@ access_check_session(struct user *user); * the requested access to the universe. */ int -access_check_universe(user_access_t access); +access_check_universe(box_user_access_mask_t access); /** * Same as access_check_universe(), but in case the current user @@ -398,7 +398,7 @@ access_check_universe(user_access_t access); * given object type and name. */ int -access_check_universe_object(user_access_t access, +access_check_universe_object(box_user_access_mask_t access, enum schema_object_type object_type, const char *object_name); @@ -441,7 +441,7 @@ generic_session_sync(struct session *session); #include "diag.h" static inline void -access_check_universe_xc(user_access_t access) +access_check_universe_xc(box_user_access_mask_t access) { if (access_check_universe(access) != 0) diag_raise(); diff --git a/src/box/space.c b/src/box/space.c index 319cb8979b..f34ffed324 100644 --- a/src/box/space.c +++ b/src/box/space.c @@ -55,11 +55,11 @@ #include "wal_ext.h" int -access_check_space(struct space *space, user_access_t access) +access_check_space(struct space *space, box_user_access_mask_t access) { struct credentials *cr = effective_user(); /* Any space access also requires global USAGE privilege. */ - access |= PRIV_U; + access |= BOX_PRIVILEGE_USAGE; /* * If a user has a global permission, clear the respective * privilege from the list of privileges required @@ -67,7 +67,7 @@ access_check_space(struct space *space, user_access_t access) * No special check for ADMIN user is necessary * since ADMIN has universal access. */ - user_access_t space_access = access & ~cr->universal_access; + box_user_access_mask_t space_access = access & ~cr->universal_access; /* * Similarly to global access, subtract entity-level access * (access to all spaces) if it is present. @@ -76,7 +76,7 @@ access_check_space(struct space *space, user_access_t access) if (space_access && /* Check for missing USAGE access, ignore owner rights. */ - (space_access & PRIV_U || + (space_access & BOX_PRIVILEGE_USAGE || /* Check for missing specific access, respect owner rights. */ (space->def->uid != cr->uid && space_access & ~space->access[cr->auth_token].effective))) { @@ -88,9 +88,9 @@ access_check_space(struct space *space, user_access_t access) */ struct user *user = user_find(cr->uid); if (user != NULL) { - if (!(cr->universal_access & PRIV_U)) { + if (!(cr->universal_access & BOX_PRIVILEGE_USAGE)) { diag_set(AccessDeniedError, - priv_name(PRIV_U), + priv_name(BOX_PRIVILEGE_USAGE), schema_object_name(SC_UNIVERSE), "", user->def->name); } else { diff --git a/src/box/space.h b/src/box/space.h index 93b197edac..2741777a2c 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -440,7 +440,7 @@ index_name_by_id(struct space *space, uint32_t id); * @retval -1 on error (check box_error_last()) */ int -access_check_space(struct space *space, user_access_t access); +access_check_space(struct space *space, box_user_access_mask_t access); /** * Execute a DML request on the given space. @@ -645,7 +645,7 @@ space_new_xc(struct space_def *space_def, struct rlist *key_list) } static inline void -access_check_space_xc(struct space *space, user_access_t access) +access_check_space_xc(struct space *space, box_user_access_mask_t access) { if (access_check_space(space, access) != 0) diag_raise(); diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 5d83ea63d2..987ae0c8e7 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -2393,7 +2393,7 @@ case OP_IteratorOpen: { } struct space *space = aMem[pOp->p3].u.p; assert(space != NULL); - if (access_check_space(space, PRIV_R) != 0) + if (access_check_space(space, BOX_PRIVILEGE_READ) != 0) goto abort_due_to_error; struct index *index = space_index(space, pOp->p2); diff --git a/src/box/sysview.c b/src/box/sysview.c index 28a5744cca..bc67bdfa78 100644 --- a/src/box/sysview.c +++ b/src/box/sysview.c @@ -269,7 +269,10 @@ sysview_space_execute_upsert(struct space *space, struct txn *txn, * 7. User is parent for the user/role. */ -const uint32_t PRIV_WRDA = PRIV_W | PRIV_D | PRIV_A | PRIV_R; +const uint32_t PRIV_WRDA = BOX_PRIVILEGE_WRITE | + BOX_PRIVILEGE_DROP | + BOX_PRIVILEGE_ALTER | + BOX_PRIVILEGE_READ; static bool vspace_filter(struct space *source, struct tuple *tuple) @@ -284,7 +287,7 @@ vspace_filter(struct space *source, struct tuple *tuple) /* Allow access for a user with space privileges. */ if (PRIV_WRDA & entity_access_get(SC_SPACE)[cr->auth_token].effective) return true; - if (PRIV_R & source->access[cr->auth_token].effective) + if (BOX_PRIVILEGE_READ & source->access[cr->auth_token].effective) return true; /* read access to _space space */ uint32_t space_id; if (tuple_field_u32(tuple, BOX_SPACE_FIELD_ID, &space_id) != 0) @@ -292,7 +295,8 @@ vspace_filter(struct space *source, struct tuple *tuple) struct space *space = space_cache_find(space_id); if (space == NULL) return false; - user_access_t effective = space->access[cr->auth_token].effective; + box_user_access_mask_t effective = + space->access[cr->auth_token].effective; /* * Allow access for space owners and users with any * privilege for the space. @@ -311,7 +315,7 @@ vuser_filter(struct space *source, struct tuple *tuple) */ if (PRIV_WRDA & cr->universal_access) return true; - if (PRIV_R & source->access[cr->auth_token].effective) + if (BOX_PRIVILEGE_READ & source->access[cr->auth_token].effective) return true; /* read access to _user space */ uint32_t uid; @@ -334,7 +338,7 @@ vpriv_filter(struct space *source, struct tuple *tuple) */ if (PRIV_WRDA & cr->universal_access) return true; - if (PRIV_R & source->access[cr->auth_token].effective) + if (BOX_PRIVILEGE_READ & source->access[cr->auth_token].effective) return true; /* read access to _priv space */ uint32_t grantor_id; @@ -355,13 +359,13 @@ vfunc_filter(struct space *source, struct tuple *tuple) * Allow access for a user with read, write, * drop, alter or execute privileges for universe. */ - if ((PRIV_WRDA | PRIV_X) & cr->universal_access) + if ((PRIV_WRDA | BOX_PRIVILEGE_EXECUTE) & cr->universal_access) return true; /* Allow access for a user with function privileges. */ - if ((PRIV_WRDA | PRIV_X) & + if ((PRIV_WRDA | BOX_PRIVILEGE_EXECUTE) & entity_access_get(SC_FUNCTION)[cr->auth_token].effective) return true; - if (PRIV_R & source->access[cr->auth_token].effective) + if (BOX_PRIVILEGE_READ & source->access[cr->auth_token].effective) return true; /* read access to _func space */ uint32_t name_len; @@ -371,9 +375,10 @@ vfunc_filter(struct space *source, struct tuple *tuple) return false; struct func *func = func_by_name(name, name_len); assert(func != NULL); - user_access_t effective = func->access[cr->auth_token].effective; + box_user_access_mask_t effective = + func->access[cr->auth_token].effective; return func->def->uid == cr->uid || - ((PRIV_WRDA | PRIV_X) & effective); + ((PRIV_WRDA | BOX_PRIVILEGE_EXECUTE) & effective); } static bool @@ -384,13 +389,13 @@ vsequence_filter(struct space *source, struct tuple *tuple) * Allow access for a user with read, write, * drop, alter or execute privileges for universe. */ - if ((PRIV_WRDA | PRIV_X) & cr->universal_access) + if ((PRIV_WRDA | BOX_PRIVILEGE_EXECUTE) & cr->universal_access) return true; /* Allow access for a user with sequence privileges. */ - if ((PRIV_WRDA | PRIV_X) & + if ((PRIV_WRDA | BOX_PRIVILEGE_EXECUTE) & entity_access_get(SC_SEQUENCE)[cr->auth_token].effective) return true; - if (PRIV_R & source->access[cr->auth_token].effective) + if (BOX_PRIVILEGE_READ & source->access[cr->auth_token].effective) return true; /* read access to _sequence space */ uint32_t id; @@ -399,9 +404,10 @@ vsequence_filter(struct space *source, struct tuple *tuple) struct sequence *sequence = sequence_by_id(id); if (sequence == NULL) return false; - user_access_t effective = sequence->access[cr->auth_token].effective; + box_user_access_mask_t effective = + sequence->access[cr->auth_token].effective; return sequence->def->uid == cr->uid || - ((PRIV_WRDA | PRIV_X) & effective); + ((PRIV_WRDA | BOX_PRIVILEGE_EXECUTE) & effective); } static bool diff --git a/src/box/user.cc b/src/box/user.cc index 6af3c328af..3479dcb65c 100644 --- a/src/box/user.cc +++ b/src/box/user.cc @@ -51,7 +51,7 @@ static struct user_map user_map_nil; struct mh_i32ptr_t *user_registry; enum { - USER_ACCESS_FULL = (user_access_t)~0, + USER_ACCESS_FULL = (box_user_access_mask_t)~0, }; /* {{{ user_map */ @@ -366,7 +366,7 @@ user_reload_privs(struct user *user) * Skip role grants, we're only * interested in real objects. */ - if (priv.object_type != SC_ROLE || !(priv.access & PRIV_X)) + if (priv.object_type != SC_ROLE || !(priv.access & BOX_PRIVILEGE_EXECUTE)) if (user_grant_priv(user, &priv) != 0) return -1; if (iterator_next(it, &tuple) != 0) @@ -391,7 +391,8 @@ user_reload_privs(struct user *user) user_set_effective_access(user); user->is_dirty = false; struct credentials *creds; - user_access_t new_access = universe.access[user->auth_token].effective; + box_user_access_mask_t new_access = + universe.access[user->auth_token].effective; rlist_foreach_entry(creds, &user->credentials_list, in_user) creds->universal_access = new_access; return 0; diff --git a/src/box/user_def.c b/src/box/user_def.c index 4f5806e427..a17ddbaf8a 100644 --- a/src/box/user_def.c +++ b/src/box/user_def.c @@ -14,7 +14,7 @@ #include "trivia/util.h" const char * -priv_name(user_access_t access) +priv_name(box_user_access_mask_t access) { static const char *priv_name_strs[] = { "Read", diff --git a/src/box/user_def.h b/src/box/user_def.h index 7acc525b6a..01f2e97549 100644 --- a/src/box/user_def.h +++ b/src/box/user_def.h @@ -18,7 +18,10 @@ extern "C" { struct authenticator; -typedef uint16_t user_access_t; +/** \cond public */ +typedef uint16_t box_user_access_mask_t; +/** \endcond public */ + /** * Effective session user. A cache of user data * and access stored in session and fiber local storage. @@ -32,7 +35,7 @@ struct credentials { * Cached global grants, to avoid an extra look up * when checking global grants. */ - user_access_t universal_access; + box_user_access_mask_t universal_access; /** User id of the authenticated user. */ uint32_t uid; /** @@ -43,41 +46,44 @@ struct credentials { struct rlist in_user; }; -enum priv_type { +/** \cond public */ +enum box_privilege_type { /* SELECT */ - PRIV_R = 1, + BOX_PRIVILEGE_READ = 1, /* INSERT, UPDATE, UPSERT, DELETE, REPLACE */ - PRIV_W = 2, + BOX_PRIVILEGE_WRITE = 2, /* CALL */ - PRIV_X = 4, + BOX_PRIVILEGE_EXECUTE = 4, /* SESSION */ - PRIV_S = 8, + BOX_PRIVILEGE_SESSION = 8, /* USAGE */ - PRIV_U = 16, + BOX_PRIVILEGE_USAGE = 16, /* CREATE */ - PRIV_C = 32, + BOX_PRIVILEGE_CREATE = 32, /* DROP */ - PRIV_D = 64, + BOX_PRIVILEGE_DROP = 64, /* ALTER */ - PRIV_A = 128, + BOX_PRIVILEGE_ALTER = 128, /* REFERENCE - required by ANSI - not implemented */ - PRIV_REFERENCE = 256, + BOX_PRIVILEGE_REFERENCE = 256, /* TRIGGER - required by ANSI - not implemented */ - PRIV_TRIGGER = 512, + BOX_PRIVILEGE_TRIGGER = 512, /* INSERT - required by ANSI - not implemented */ - PRIV_INSERT = 1024, + BOX_PRIVILEGE_INSERT = 1024, /* UPDATE - required by ANSI - not implemented */ - PRIV_UPDATE = 2048, + BOX_PRIVILEGE_UPDATE = 2048, /* DELETE - required by ANSI - not implemented */ - PRIV_DELETE = 4096, + BOX_PRIVILEGE_DELETE = 4096, /* This is never granted, but used internally. */ - PRIV_GRANT = 8192, + BOX_PRIVILEGE_GRANT = 8192, /* Never granted, but used internally. */ - PRIV_REVOKE = 16384, + BOX_PRIVILEGE_REVOKE = 16384, /* all bits */ - PRIV_ALL = ~((user_access_t) 0), + BOX_PRIVILEGE_ALL = ~((box_user_access_mask_t)0), }; +/** \endcond public */ + /** * Definition of a privilege */ @@ -94,14 +100,14 @@ struct priv_def { * What is being granted, has been granted, or is being * revoked. */ - user_access_t access; + box_user_access_mask_t access; /** To maintain a set of effective privileges. */ rb_node(struct priv_def) link; }; /* Privilege name for error messages */ const char * -priv_name(user_access_t access); +priv_name(box_user_access_mask_t access); /** * Encapsulates privileges of a user on an object. @@ -113,14 +119,14 @@ struct access { * Granted access has been given to a user explicitly * via some form of a grant. */ - user_access_t granted; + box_user_access_mask_t granted; /** * Effective access is a sum of granted access and * all privileges inherited by a user on this object * via some role. Since roles may be granted to other * roles, this may include indirect grants. */ - user_access_t effective; + box_user_access_mask_t effective; }; /** -- GitLab