From b4c4a606bfa80c9c1f0712fe0c1be57b5833d801 Mon Sep 17 00:00:00 2001 From: imarkov <imarkov@tarantool.org> Date: Mon, 29 Jan 2018 16:46:59 +0300 Subject: [PATCH] security: Prohibit to drop super role * Create constant SUPER - id of super role * Forward the constant to box.schema * Add checks on drop super role Closes #3084 --- src/box/alter.cc | 2 +- src/box/lua/schema.lua | 2 +- src/box/lua/space.cc | 8 ++++++++ src/box/user_def.h | 1 + test/box/access.result | 44 ++++++++++++++++++++++++++++++++++++++++ test/box/access.test.lua | 11 ++++++++++ 6 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/box/alter.cc b/src/box/alter.cc index c48e89f9e6..46c90c883a 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -2043,7 +2043,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event) access_check_ddl(old_user->def->name, old_user->def->owner, SC_USER, PRIV_D, true); /* Can't drop guest or super user */ - if (uid <= (uint32_t) BOX_SYSTEM_USER_ID_MAX) { + if (uid <= (uint32_t) BOX_SYSTEM_USER_ID_MAX || uid == SUPER) { tnt_raise(ClientError, ER_DROP_USER, old_user->def->name, "the user or the role is a system"); diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 89e27555c6..756134b91e 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -2143,7 +2143,7 @@ box.schema.role.drop = function(name, opts) return end if uid >= box.schema.SYSTEM_USER_ID_MIN and - uid <= box.schema.SYSTEM_USER_ID_MAX then + uid <= box.schema.SYSTEM_USER_ID_MAX or uid == box.schema.SUPER_ROLE_ID then -- gh-1205: box.schema.user.info fails box.error(box.error.DROP_USER, name, "the user or the role is a system") end diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc index e95c5285f7..29a9aca931 100644 --- a/src/box/lua/space.cc +++ b/src/box/lua/space.cc @@ -439,6 +439,14 @@ box_lua_space_init(struct lua_State *L) lua_setfield(L, -2, "SYSTEM_USER_ID_MIN"); lua_pushnumber(L, BOX_SYSTEM_USER_ID_MAX); lua_setfield(L, -2, "SYSTEM_USER_ID_MAX"); + lua_pushnumber(L, ADMIN); + lua_setfield(L, -2, "ADMIN_ID"); + lua_pushnumber(L, GUEST); + lua_setfield(L, -2, "GUEST_ID"); + lua_pushnumber(L, PUBLIC); + lua_setfield(L, -2, "PUBLIC_ROLE_ID"); + lua_pushnumber(L, SUPER); + lua_setfield(L, -2, "SUPER_ROLE_ID"); lua_pushnumber(L, BOX_INDEX_MAX); lua_setfield(L, -2, "INDEX_MAX"); lua_pushnumber(L, BOX_SPACE_MAX); diff --git a/src/box/user_def.h b/src/box/user_def.h index 1104ec634a..8bf31c2fc4 100644 --- a/src/box/user_def.h +++ b/src/box/user_def.h @@ -170,6 +170,7 @@ enum { GUEST = 0, ADMIN = 1, PUBLIC = 2, /* role */ + SUPER = 31, /* role */ BOX_SYSTEM_USER_ID_MAX = PUBLIC }; diff --git a/test/box/access.result b/test/box/access.result index 410f1d7762..0ee17ebff7 100644 --- a/test/box/access.result +++ b/test/box/access.result @@ -747,10 +747,18 @@ box.schema.user.drop('guest') --- - error: 'Failed to drop user or role ''guest'': the user or the role is a system' ... +box.schema.role.drop('guest') +--- +- error: Role 'guest' is not found +... box.space._user.index.name:delete{'guest'} --- - error: 'Failed to drop user or role ''guest'': the user or the role is a system' ... +box.space._user:delete{box.schema.GUEST_ID} +--- +- error: 'Failed to drop user or role ''guest'': the user or the role is a system' +... #box.schema.user.info('guest') > 0 --- - true @@ -759,14 +767,26 @@ box.schema.user.drop('admin') --- - error: 'Failed to drop user or role ''admin'': the user or the role is a system' ... +box.schema.role.drop('admin') +--- +- error: Role 'admin' is not found +... box.space._user.index.name:delete{'admin'} --- - error: 'Failed to drop user or role ''admin'': the user or the role is a system' ... +box.space._user:delete{box.schema.ADMIN_ID} +--- +- error: 'Failed to drop user or role ''admin'': the user or the role is a system' +... #box.schema.user.info('admin') > 0 --- - true ... +box.schema.user.drop('public') +--- +- error: User 'public' is not found +... box.schema.role.drop('public') --- - error: 'Failed to drop user or role ''public'': the user or the role is a system' @@ -775,10 +795,34 @@ box.space._user.index.name:delete{'public'} --- - error: 'Failed to drop user or role ''public'': the user or the role is a system' ... +box.space._user:delete{box.schema.PUBLIC_ROLE_ID} +--- +- error: 'Failed to drop user or role ''public'': the user or the role is a system' +... #box.schema.role.info('public') > 0 --- - true ... +box.schema.role.drop('super') +--- +- error: 'Failed to drop user or role ''super'': the user or the role is a system' +... +box.schema.user.drop('super') +--- +- error: User 'super' is not found +... +box.space._user.index.name:delete{'super'} +--- +- error: 'Failed to drop user or role ''super'': the user or the role is a system' +... +box.space._user:delete{box.schema.SUPER_ROLE_ID} +--- +- error: 'Failed to drop user or role ''super'': the user or the role is a system' +... +#box.schema.role.info('super') > 0 +--- +- true +... -- gh-944 name is too long name = string.rep('a', box.schema.NAME_MAX - 1) --- diff --git a/test/box/access.test.lua b/test/box/access.test.lua index 02c6252e5e..241f254534 100644 --- a/test/box/access.test.lua +++ b/test/box/access.test.lua @@ -298,14 +298,25 @@ box.schema.func.drop('blah', 'blah') box.schema.user.passwd('guest', 'sesame') -- gh-1205 box.schema.user.info fails box.schema.user.drop('guest') +box.schema.role.drop('guest') box.space._user.index.name:delete{'guest'} +box.space._user:delete{box.schema.GUEST_ID} #box.schema.user.info('guest') > 0 box.schema.user.drop('admin') +box.schema.role.drop('admin') box.space._user.index.name:delete{'admin'} +box.space._user:delete{box.schema.ADMIN_ID} #box.schema.user.info('admin') > 0 +box.schema.user.drop('public') box.schema.role.drop('public') box.space._user.index.name:delete{'public'} +box.space._user:delete{box.schema.PUBLIC_ROLE_ID} #box.schema.role.info('public') > 0 +box.schema.role.drop('super') +box.schema.user.drop('super') +box.space._user.index.name:delete{'super'} +box.space._user:delete{box.schema.SUPER_ROLE_ID} +#box.schema.role.info('super') > 0 -- gh-944 name is too long name = string.rep('a', box.schema.NAME_MAX - 1) -- GitLab