From: Georgy Kirichenko <georgy@tarantool.org> To: tarantool-patches@freelists.org Cc: Georgy Kirichenko <georgy@tarantool.org> Subject: [tarantool-patches] [PATCH 3/3] Introduce privileges for object groups Date: Fri, 8 Jun 2018 12:06:34 +0300 [thread overview] Message-ID: <c59f7fd4b951ddca90db7ae04da6c75f40b111d4.1528448404.git.georgy@tarantool.org> (raw) In-Reply-To: <cover.1528448404.git.georgy@tarantool.org> In-Reply-To: <cover.1528448404.git.georgy@tarantool.org> Allow define access privileges for all spaces, functions and sequences. Read and write privileges are supported for spaces, execute privilege for sequences. Privilege granting and revoking might be done through old api without object identification: box.schema.user.grant("guest", "read", "space") Prerequisite #945 --- src/box/alter.cc | 18 ++++++--- src/box/call.c | 2 + src/box/lua/schema.lua | 9 +++++ src/box/schema.cc | 8 ++++ src/box/schema.h | 26 +++++++++++++ src/box/sequence.c | 1 + src/box/space.c | 2 + src/box/sysview_index.c | 11 ++++++ src/box/user.cc | 12 ++++++ test/box/access.result | 77 +++++++++++++++++++++++++++++++++++++ test/box/access.test.lua | 29 ++++++++++++++ test/box/lua/identifier.lua | 1 - 12 files changed, 189 insertions(+), 7 deletions(-) diff --git a/src/box/alter.cc b/src/box/alter.cc index 6f6fcb097..48af128f1 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -2523,8 +2523,10 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type) break; case SC_SPACE: { - struct space *space = space_cache_find_xc(priv->object_id); - if (space->def->uid != grantor->def->uid && + struct space *space = NULL; + if (priv->object_id != 0) + space = space_cache_find_xc(priv->object_id); + if ((space == NULL || space->def->uid != grantor->def->uid) && grantor->def->uid != ADMIN) { tnt_raise(AccessDeniedError, priv_name(priv_type), @@ -2535,8 +2537,10 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type) } case SC_FUNCTION: { - struct func *func = func_cache_find(priv->object_id); - if (func->def->uid != grantor->def->uid && + struct func *func = NULL; + if (priv->object_id != 0) + func = func_cache_find(priv->object_id); + if ((func == NULL || func->def->uid != grantor->def->uid) && grantor->def->uid != ADMIN) { tnt_raise(AccessDeniedError, priv_name(priv_type), @@ -2547,8 +2551,10 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type) } case SC_SEQUENCE: { - struct sequence *seq = sequence_cache_find(priv->object_id); - if (seq->def->uid != grantor->def->uid && + struct sequence *seq = NULL; + if (priv->object_id != 0) + seq = sequence_cache_find(priv->object_id); + if ((seq == NULL || seq->def->uid != grantor->def->uid) && grantor->def->uid != ADMIN) { tnt_raise(AccessDeniedError, priv_name(priv_type), diff --git a/src/box/call.c b/src/box/call.c index 6388e1e68..8a43db130 100644 --- a/src/box/call.c +++ b/src/box/call.c @@ -71,6 +71,8 @@ access_check_func(const char *name, uint32_t name_len, struct func **funcp) return 0; } user_access_t access = PRIV_X | PRIV_U; + /* Check access for all functions. */ + access &= ~get_entity_access(SC_FUNCTION)[credentials->auth_token].effective; user_access_t func_access = access & ~credentials->universal_access; if (func == NULL || /* Check for missing Usage access, ignore owner rights. */ diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 4455b5e42..9cf980d11 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -1794,6 +1794,9 @@ local function object_resolve(object_type, object_name) return 0 end if object_type == 'space' then + if object_name == nil or object_name == 0 then + return 0 + end local space = box.space[object_name] if space == nil then box.error(box.error.NO_SUCH_SPACE, object_name) @@ -1801,6 +1804,9 @@ local function object_resolve(object_type, object_name) return space.id end if object_type == 'function' then + if object_name == nil or object_name == 0 then + return 0 + end local _vfunc = box.space[box.schema.VFUNC_ID] local func if type(object_name) == 'string' then @@ -1815,6 +1821,9 @@ local function object_resolve(object_type, object_name) end end if object_type == 'sequence' then + if object_name == nil or object_name == 0 then + return 0 + end local seq = sequence_resolve(object_name) if seq == nil then box.error(box.error.NO_SUCH_SEQUENCE, object_name) diff --git a/src/box/schema.cc b/src/box/schema.cc index 8df4aa73b..32d7791a6 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -69,6 +69,8 @@ struct rlist on_alter_sequence = RLIST_HEAD_INITIALIZER(on_alter_sequence); */ struct latch schema_lock = LATCH_INITIALIZER(schema_lock); +struct entity_access entity_access; + bool space_is_system(struct space *space) { @@ -528,6 +530,8 @@ schema_find_name(enum schema_object_type type, uint32_t object_id) return ""; case SC_SPACE: { + if (object_id == 0) + return "SPACE"; struct space *space = space_by_id(object_id); if (space == NULL) break; @@ -535,6 +539,8 @@ schema_find_name(enum schema_object_type type, uint32_t object_id) } case SC_FUNCTION: { + if (object_id == 0) + return "FUNCTION"; struct func *func = func_by_id(object_id); if (func == NULL) break; @@ -542,6 +548,8 @@ schema_find_name(enum schema_object_type type, uint32_t object_id) } case SC_SEQUENCE: { + if (object_id == 0) + return "SEQUENCE"; struct sequence *seq = sequence_by_id(object_id); if (seq == NULL) break; diff --git a/src/box/schema.h b/src/box/schema.h index 2b87f5f50..d0bb8f200 100644 --- a/src/box/schema.h +++ b/src/box/schema.h @@ -235,4 +235,30 @@ struct on_access_denied_ctx { const char *object_name; }; +/** Global grants to classes of objects. */ +struct entity_access { + struct access space[BOX_USER_MAX]; + struct access function[BOX_USER_MAX]; + struct access sequence[BOX_USER_MAX]; +}; + +/** A single instance of the global entities. */ +extern struct entity_access entity_access; + +static inline +struct access * +get_entity_access(enum schema_object_type type) +{ + switch (type) { + case SC_SPACE: + return entity_access.space; + case SC_FUNCTION: + return entity_access.function; + case SC_SEQUENCE: + return entity_access.sequence; + default: + return NULL; + } +} + #endif /* INCLUDES_TARANTOOL_BOX_SCHEMA_H */ diff --git a/src/box/sequence.c b/src/box/sequence.c index 162147cde..a56271971 100644 --- a/src/box/sequence.c +++ b/src/box/sequence.c @@ -250,6 +250,7 @@ access_check_sequence(struct sequence *seq) user_access_t access = PRIV_U | PRIV_W; user_access_t sequence_access = access & ~cr->universal_access; + sequence_access &= ~get_entity_access(SC_SEQUENCE)[cr->auth_token].effective; if (sequence_access && /* Check for missing Usage access, ignore owner rights. */ (sequence_access & PRIV_U || diff --git a/src/box/space.c b/src/box/space.c index 02a97926e..eae48cdfd 100644 --- a/src/box/space.c +++ b/src/box/space.c @@ -42,6 +42,7 @@ #include "request.h" #include "xrow.h" #include "iproto_constants.h" +#include "schema.h" int access_check_space(struct space *space, user_access_t access) @@ -57,6 +58,7 @@ access_check_space(struct space *space, user_access_t access) * since ADMIN has universal access. */ user_access_t space_access = access & ~cr->universal_access; + space_access &= ~get_entity_access(SC_SPACE)[cr->auth_token].effective; if (space_access && /* Check for missing Usage access, ignore owner rights. */ diff --git a/src/box/sysview_index.c b/src/box/sysview_index.c index f1dfbefe5..b9c837441 100644 --- a/src/box/sysview_index.c +++ b/src/box/sysview_index.c @@ -222,6 +222,9 @@ vspace_filter(struct space *source, struct tuple *tuple) */ if (PRIV_WRDA & cr->universal_access) return true; + /* Allow access for a user with space privileges. */ + if (PRIV_WRDA & get_entity_access(SC_SPACE)[cr->auth_token].effective) + return true; if (PRIV_R & source->access[cr->auth_token].effective) return true; /* read access to _space space */ uint32_t space_id; @@ -295,6 +298,10 @@ vfunc_filter(struct space *source, struct tuple *tuple) */ if ((PRIV_WRDA | PRIV_X) & cr->universal_access) return true; + /* Allow access for a user with function privileges. */ + if ((PRIV_WRDA | PRIV_X) & + get_entity_access(SC_FUNCTION)[cr->auth_token].effective) + return true; if (PRIV_R & source->access[cr->auth_token].effective) return true; /* read access to _func space */ @@ -320,6 +327,10 @@ vsequence_filter(struct space *source, struct tuple *tuple) */ if ((PRIV_WRDA | PRIV_X) & cr->universal_access) return true; + /* Allow access for a user with sequence privileges. */ + if ((PRIV_WRDA | PRIV_X) & + get_entity_access(SC_SEQUENCE)[cr->auth_token].effective) + return true; if (PRIV_R & source->access[cr->auth_token].effective) return true; /* read access to _sequence space */ diff --git a/src/box/user.cc b/src/box/user.cc index 7fa66da8f..fbf06566a 100644 --- a/src/box/user.cc +++ b/src/box/user.cc @@ -209,6 +209,10 @@ access_find(struct priv_def *priv) } case SC_SPACE: { + if (priv->object_id == 0) { + access = entity_access.space; + break; + } struct space *space = space_by_id(priv->object_id); if (space) access = space->access; @@ -216,6 +220,10 @@ access_find(struct priv_def *priv) } case SC_FUNCTION: { + if (priv->object_id == 0) { + access = entity_access.function; + break; + } struct func *func = func_by_id(priv->object_id); if (func) access = func->access; @@ -223,6 +231,10 @@ access_find(struct priv_def *priv) } case SC_SEQUENCE: { + if (priv->object_id == 0) { + access = entity_access.sequence; + break; + } struct sequence *seq = sequence_by_id(priv->object_id); if (seq) access = seq->access; diff --git a/test/box/access.result b/test/box/access.result index 72f91173b..ccd0b737f 100644 --- a/test/box/access.result +++ b/test/box/access.result @@ -1662,3 +1662,80 @@ box.schema.user.grant("guest", "read,write,execute", "role") --- - error: Unsupported role privilege 'read,write,execute' ... +-- Check entities DML +box.schema.user.create("tester", { password = '123' }) +--- +... +s = box.schema.space.create("test") +--- +... +_ = s:create_index("primary", {parts={1, "unsigned"}}) +--- +... +seq = box.schema.sequence.create("test") +--- +... +box.schema.func.create("func") +--- +... +c = (require 'net.box').connect(LISTEN.host, LISTEN.service, {user='tester', password = '123'}) +--- +... +box.session.su("tester", s.select, s) +--- +- error: Read access to space 'test' is denied for user 'tester' +... +box.session.su("tester", seq.set, seq, 1) +--- +- error: Write access to sequence 'test' is denied for user 'tester' +... +c:call("func") +--- +- error: Execute access to function 'func' is denied for user 'tester' +... +box.schema.user.grant("tester", "read", "space") +--- +... +box.schema.user.grant("tester", "write", "sequence") +--- +... +box.schema.user.grant("tester", "execute", "function") +--- +... +box.session.su("tester", s.select, s) +--- +- [] +... +box.session.su("tester", seq.next, seq) +--- +- 1 +... +c:call("func") +--- +... +box.session.su("tester", s.insert, s, {1}) +--- +- error: Write access to space 'test' is denied for user 'tester' +... +box.schema.user.grant("tester", "write", "space") +--- +... +box.session.su("tester", s.insert, s, {1}) +--- +- [1] +... +box.schema.user.drop("tester") +--- +... +s:drop() +--- +... +seq:drop() +--- +... +box.schema.func.drop("func") +--- +... +c:close() +--- +... diff --git a/test/box/access.test.lua b/test/box/access.test.lua index 62691c471..8d90b3813 100644 --- a/test/box/access.test.lua +++ b/test/box/access.test.lua @@ -640,3 +640,32 @@ box.schema.user.grant("guest", "alter", "function") box.schema.user.grant("guest", "execute", "sequence") box.schema.user.grant("guest", "read,execute", "sequence") box.schema.user.grant("guest", "read,write,execute", "role") + +-- Check entities DML +box.schema.user.create("tester", { password = '123' }) +s = box.schema.space.create("test") +_ = s:create_index("primary", {parts={1, "unsigned"}}) +seq = box.schema.sequence.create("test") +box.schema.func.create("func") +c = (require 'net.box').connect(LISTEN.host, LISTEN.service, {user='tester', password = '123'}) + +box.session.su("tester", s.select, s) +box.session.su("tester", seq.set, seq, 1) +c:call("func") +box.schema.user.grant("tester", "read", "space") +box.schema.user.grant("tester", "write", "sequence") +box.schema.user.grant("tester", "execute", "function") +box.session.su("tester", s.select, s) +box.session.su("tester", seq.next, seq) +c:call("func") + +box.session.su("tester", s.insert, s, {1}) +box.schema.user.grant("tester", "write", "space") +box.session.su("tester", s.insert, s, {1}) + +box.schema.user.drop("tester") +s:drop() +seq:drop() +box.schema.func.drop("func") +c:close() + diff --git a/test/box/lua/identifier.lua b/test/box/lua/identifier.lua index c3149bce7..0cfb9e722 100644 --- a/test/box/lua/identifier.lua +++ b/test/box/lua/identifier.lua @@ -36,7 +36,6 @@ invalid_testcases = { function run_test(create_func, cleanup_func) local json = require("json") - print("loosadlalsd") local bad_tests = {} for i, identifier in ipairs(valid_testcases) do local ok, res = pcall(create_func,identifier) -- 2.17.1
next prev parent reply other threads:[~2018-06-08 9:06 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-06-08 9:06 [tarantool-patches] [PATCH 0/3] Object group privileges Georgy Kirichenko 2018-06-08 9:06 ` [tarantool-patches] [PATCH 1/3] box: Add privilleges constants to lua Georgy Kirichenko 2018-06-08 10:31 ` [tarantool-patches] " Vladislav Shpilevoy 2018-06-08 13:20 ` Konstantin Osipov 2018-06-08 9:06 ` [tarantool-patches] [PATCH 2/3] security: add limits on object_type-privilege pair Georgy Kirichenko 2018-06-08 14:01 ` [tarantool-patches] " Konstantin Osipov 2018-06-08 9:06 ` Georgy Kirichenko [this message] 2018-06-08 17:26 ` [tarantool-patches] Re: [PATCH 3/3] Introduce privileges for object groups Konstantin Osipov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=c59f7fd4b951ddca90db7ae04da6c75f40b111d4.1528448404.git.georgy@tarantool.org \ --to=georgy@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH 3/3] Introduce privileges for object groups' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox