[tarantool-patches] [security 2/3] security: Refactor reads from systems spaces
Ilya Markov
imarkov at tarantool.org
Thu Mar 29 10:37:00 MSK 2018
Replace reads from systems spaces with reads from corresponding
system views.
After this patch some error messages are changed:
* Accessing to objects that are not accessible for current user
raises the error claiming these objects don't exists.
* Attempt to add in transaction such methods as object create, drop
raises an multi-engine transaction error instead of multi-statement
transaction error.
In scope of #3250
---
src/box/lua/schema.lua | 111 +++++++++++++++++++++++----------------
src/box/sysview_index.c | 68 +++++++++++++-----------
test/box/access.result | 75 +++++++++++++++++---------
test/box/access.test.lua | 40 +++++++-------
test/box/access_bin.result | 8 +--
test/box/access_misc.result | 2 +-
test/box/access_sysview.result | 11 ++--
test/box/access_sysview.test.lua | 6 +--
test/box/on_replace.result | 12 ++---
test/box/role.result | 2 +-
test/box/transaction.result | 8 +--
test/engine/iterator.result | 2 +-
test/engine/savepoint.result | 12 ++---
13 files changed, 210 insertions(+), 147 deletions(-)
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 30c6bc6..1d245e3 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -102,12 +102,12 @@ ffi.cdef[[
]]
local function user_or_role_resolve(user)
- local _user = box.space[box.schema.USER_ID]
+ local _vuser = box.space[box.schema.VUSER_ID]
local tuple
if type(user) == 'string' then
- tuple = _user.index.name:get{user}
+ tuple = _vuser.index.name:get{user}
else
- tuple = _user:get{user}
+ tuple = _vuser:get{user}
end
if tuple == nil then
return nil
@@ -116,12 +116,12 @@ local function user_or_role_resolve(user)
end
local function role_resolve(name_or_id)
- local _user = box.space[box.schema.USER_ID]
+ local _vuser = box.space[box.schema.VUSER_ID]
local tuple
if type(name_or_id) == 'string' then
- tuple = _user.index.name:get{name_or_id}
+ tuple = _vuser.index.name:get{name_or_id}
elseif type(name_or_id) ~= 'nil' then
- tuple = _user:get{name_or_id}
+ tuple = _vuser:get{name_or_id}
end
if tuple == nil or tuple[4] ~= 'role' then
return nil
@@ -131,12 +131,12 @@ local function role_resolve(name_or_id)
end
local function user_resolve(name_or_id)
- local _user = box.space[box.schema.USER_ID]
+ local _vuser = box.space[box.schema.VUSER_ID]
local tuple
if type(name_or_id) == 'string' then
- tuple = _user.index.name:get{name_or_id}
+ tuple = _vuser.index.name:get{name_or_id}
elseif type(name_or_id) ~= 'nil' then
- tuple = _user:get{name_or_id}
+ tuple = _vuser:get{name_or_id}
end
if tuple == nil or tuple[4] ~= 'user' then
return nil
@@ -146,12 +146,12 @@ local function user_resolve(name_or_id)
end
local function sequence_resolve(name_or_id)
- local _sequence = box.space[box.schema.SEQUENCE_ID]
+ local _vsequence = box.space[box.schema.VSEQUENCE_ID]
local tuple
if type(name_or_id) == 'string' then
- tuple = _sequence.index.name:get{name_or_id}
+ tuple = _vsequence.index.name:get{name_or_id}
elseif type(name_or_id) ~= 'nil' then
- tuple = _sequence:get{name_or_id}
+ tuple = _vsequence:get{name_or_id}
end
if tuple ~= nil then
return tuple[1], tuple
@@ -162,8 +162,9 @@ end
-- Revoke all privileges associated with the given object.
local function revoke_object_privs(object_type, object_id)
+ local _vpriv = box.space[box.schema.VPRIV_ID]
local _priv = box.space[box.schema.PRIV_ID]
- local privs = _priv.index.object:select{object_type, object_id}
+ local privs = _vpriv.index.object:select{object_type, object_id}
for k, tuple in pairs(privs) do
local uid = tuple[2]
_priv:delete{uid, object_type, object_id}
@@ -429,10 +430,15 @@ end
-- space format - the metadata about space fields
function box.schema.space.format(id, format)
local _space = box.space._space
+ local _vspace = box.space._vspace
check_param(id, 'id', 'number')
if format == nil then
- return _space:get(id)[7]
+ local tuple = _vspace:get(id)
+ if tuple == nil then
+ box.error(box.error.NO_SUCH_SPACE, '#' .. tostring(id))
+ end
+ return tuple[7]
else
check_param(format, 'format', 'table')
format = update_format(format)
@@ -448,6 +454,7 @@ box.schema.space.drop = function(space_id, space_name, opts)
check_param_table(opts, { if_exists = 'boolean' })
local _space = box.space[box.schema.SPACE_ID]
local _index = box.space[box.schema.INDEX_ID]
+ local _vindex = box.space[box.schema.VINDEX_ID]
local _truncate = box.space[box.schema.TRUNCATE_ID]
local _space_sequence = box.space[box.schema.SPACE_SEQUENCE_ID]
local sequence_tuple = _space_sequence:delete{space_id}
@@ -455,7 +462,7 @@ box.schema.space.drop = function(space_id, space_name, opts)
-- Delete automatically generated sequence.
box.schema.sequence.drop(sequence_tuple[2])
end
- local keys = _index:select(space_id)
+ local keys = _vindex:select(space_id)
for i = #keys, 1, -1 do
local v = keys[i]
_index:delete{v[1], v[2]}
@@ -693,7 +700,8 @@ box.schema.index.create = function(space_id, name, options)
options = update_param_table(options, options_defaults)
local _index = box.space[box.schema.INDEX_ID]
- if _index.index.name:get{space_id, name} then
+ local _vindex = box.space[box.schema.VINDEX_ID]
+ if _vindex.index.name:get{space_id, name} then
if options.if_not_exists then
return space.index[name], "not created"
else
@@ -706,7 +714,7 @@ box.schema.index.create = function(space_id, name, options)
iid = options.id
else
-- max
- local tuple = _index.index[0]
+ local tuple = _vindex.index[0]
:select(space_id, { limit = 1, iterator = 'LE' })[1]
if tuple then
local id = tuple[1]
@@ -1368,7 +1376,19 @@ function box.schema.space.bless(space)
-- primary key and returns it back to the user
space_mt.auto_increment = function(space, tuple)
check_space_arg(space, 'auto_increment')
- local max_tuple = check_primary_index(space):max()
+ local euid = box.session.euid()
+ -- HACK: habe to call box.session.su here,
+ -- as checking max requires 'READ' access to space, though auto_increment
+ -- is a 'WRITE' operation
+ local max_tuple
+ if euid ~= 1 then
+ box.session.su("admin")
+ max_tuple = check_primary_index(space):max()
+ box.session.su(euid)
+ else
+ max_tuple = check_primary_index(space):max()
+ end
+
local max = 0
if max_tuple ~= nil then
max = max_tuple[1]
@@ -1686,12 +1706,12 @@ local function object_resolve(object_type, object_name)
return space.id
end
if object_type == 'function' then
- local _func = box.space[box.schema.FUNC_ID]
+ local _vfunc = box.space[box.schema.VFUNC_ID]
local func
if type(object_name) == 'string' then
- func = _func.index.name:get{object_name}
+ func = _vfunc.index.name:get{object_name}
else
- func = _func:get{object_name}
+ func = _vfunc:get{object_name}
end
if func then
return func[1]
@@ -1707,12 +1727,12 @@ local function object_resolve(object_type, object_name)
return seq
end
if object_type == 'role' then
- local _user = box.space[box.schema.USER_ID]
+ local _vuser = box.space[box.schema.VUSER_ID]
local role
if type(object_name) == 'string' then
- role = _user.index.name:get{object_name}
+ role = _vuser.index.name:get{object_name}
else
- role = _user:get{object_name}
+ role = _vuser:get{object_name}
end
if role and role[4] == 'role' then
return role[1]
@@ -1730,13 +1750,13 @@ local function object_name(object_type, object_id)
end
local space
if object_type == 'space' then
- space = box.space._space
+ space = box.space._vspace
elseif object_type == 'sequence' then
space = box.space._sequence
elseif object_type == 'function' then
- space = box.space._func
+ space = box.space._vfunc
elseif object_type == 'role' or object_type == 'user' then
- space = box.space._user
+ space = box.space._vuser
else
box.error(box.error.UNKNOWN_SCHEMA_OBJECT, object_type)
end
@@ -1750,7 +1770,8 @@ box.schema.func.create = function(name, opts)
if_not_exists = 'boolean',
language = 'string'})
local _func = box.space[box.schema.FUNC_ID]
- local func = _func.index.name:get{name}
+ local _vfunc = box.space[box.schema.VFUNC_ID]
+ local func = _vfunc.index.name:get{name}
if func then
if not opts.if_not_exists then
box.error(box.error.FUNCTION_EXISTS, name)
@@ -1767,12 +1788,13 @@ box.schema.func.drop = function(name, opts)
opts = opts or {}
check_param_table(opts, { if_exists = 'boolean' })
local _func = box.space[box.schema.FUNC_ID]
+ local _vfunc = box.space[box.schema.VFUNC_ID]
local fid
local tuple
if type(name) == 'string' then
- tuple = _func.index.name:get{name}
+ tuple = _vfunc.index.name:get{name}
else
- tuple = _func:get{name}
+ tuple = _vfunc:get{name}
end
if tuple then
fid = tuple[1]
@@ -1788,12 +1810,12 @@ box.schema.func.drop = function(name, opts)
end
function box.schema.func.exists(name_or_id)
- local _func = box.space[box.schema.FUNC_ID]
+ local _vfunc = box.space[box.schema.VFUNC_ID]
local tuple = nil
if type(name_or_id) == 'string' then
- tuple = _func.index.name:get{name_or_id}
+ tuple = _vfunc.index.name:get{name_or_id}
elseif type(name_or_id) == 'number' then
- tuple = _func:get{name_or_id}
+ tuple = _vfunc:get{name_or_id}
end
return tuple ~= nil
end
@@ -1948,8 +1970,9 @@ local function grant(uid, name, privilege, object_type,
options.grantor = user_or_role_resolve(options.grantor)
end
local _priv = box.space[box.schema.PRIV_ID]
+ local _vpriv = box.space[box.schema.VPRIV_ID]
-- add the granted privilege to the current set
- local tuple = _priv:get{uid, object_type, oid}
+ local tuple = _vpriv:get{uid, object_type, oid}
local old_privilege
if tuple ~= nil then
old_privilege = tuple[5]
@@ -1984,7 +2007,8 @@ local function revoke(uid, name, privilege, object_type, object_name, options)
options = options or {}
local oid = object_resolve(object_type, object_name)
local _priv = box.space[box.schema.PRIV_ID]
- local tuple = _priv:get{uid, object_type, oid}
+ local _vpriv = box.space[box.schema.VPRIV_ID]
+ local tuple = _vpriv:get{uid, object_type, oid}
-- system privileges of admin and guest can't be revoked
if tuple == nil then
if options.if_exists then
@@ -2013,32 +2037,32 @@ end
local function drop(uid, opts)
-- recursive delete of user data
- local _priv = box.space[box.schema.PRIV_ID]
- local spaces = box.space[box.schema.SPACE_ID].index.owner:select{uid}
+ local _vpriv = box.space[box.schema.VPRIV_ID]
+ local spaces = box.space[box.schema.VSPACE_ID].index.owner:select{uid}
for k, tuple in pairs(spaces) do
box.space[tuple[1]]:drop()
end
- local funcs = box.space[box.schema.FUNC_ID].index.owner:select{uid}
+ local funcs = box.space[box.schema.VFUNC_ID].index.owner:select{uid}
for k, tuple in pairs(funcs) do
box.schema.func.drop(tuple[1])
end
-- if this is a role, revoke this role from whoever it was granted to
- local grants = _priv.index.object:select{'role', uid}
+ local grants = _vpriv.index.object:select{'role', uid}
for k, tuple in pairs(grants) do
revoke(tuple[2], tuple[2], uid)
end
- local sequences = box.space[box.schema.SEQUENCE_ID].index.owner:select{uid}
+ local sequences = box.space[box.schema.VSEQUENCE_ID].index.owner:select{uid}
for k, tuple in pairs(sequences) do
box.schema.sequence.drop(tuple[1])
end
-- xxx: hack, we have to revoke session and usage privileges
-- of a user using a setuid function in absence of create/drop
-- privileges and grant option
- if box.space._user:get{uid}[4] == 'user' then
+ if box.space._vuser:get{uid}[4] == 'user' then
box.session.su('admin', box.schema.user.revoke, uid,
'session,usage', 'universe', nil, {if_exists = true})
end
- local privs = _priv.index.primary:select{uid}
+ local privs = _vpriv.index.primary:select{uid}
for k, tuple in pairs(privs) do
revoke(uid, uid, tuple[5], tuple[3], tuple[4])
end
@@ -2095,8 +2119,7 @@ box.schema.user.drop = function(name, opts)
end
local function info(id)
- local _priv = box.space._priv
- local _user = box.space._priv
+ local _priv = box.space._vpriv
local privs = {}
for _, v in pairs(_priv:select{id}) do
table.insert(
diff --git a/src/box/sysview_index.c b/src/box/sysview_index.c
index bf0442b..c18bad3 100644
--- a/src/box/sysview_index.c
+++ b/src/box/sysview_index.c
@@ -182,23 +182,24 @@ static const struct index_vtab sysview_index_vtab = {
/* .end_build = */ generic_index_end_build,
};
+const uint32_t PRIV_WRDA = PRIV_W | PRIV_D | PRIV_A | PRIV_R;
+
static bool
vspace_filter(struct space *source, struct tuple *tuple)
{
struct credentials *cr = effective_user();
- if (PRIV_R & cr->universal_access)
- return true; /* read access to unverse */
- if (PRIV_R & source->access[cr->auth_token].effective)
- return true; /* read access to original space */
-
+ if (PRIV_WRDA & cr->universal_access)
+ return true;
+ if (source->access[cr->auth_token].effective & PRIV_R)
+ return true;
uint32_t space_id;
if (tuple_field_u32(tuple, BOX_SPACE_FIELD_ID, &space_id) != 0)
return false;
struct space *space = space_cache_find(space_id);
if (space == NULL)
return false;
- uint8_t effective = space->access[cr->auth_token].effective;
- return ((PRIV_R | PRIV_W) & (cr->universal_access | effective) ||
+ uint32_t effective = space->access[cr->auth_token].effective;
+ return ((PRIV_R | PRIV_W | PRIV_D | PRIV_A) & effective ||
space->def->uid == cr->uid);
}
@@ -206,10 +207,11 @@ static bool
vuser_filter(struct space *source, struct tuple *tuple)
{
struct credentials *cr = effective_user();
- if (PRIV_R & cr->universal_access)
- return true; /* read access to unverse */
- if (PRIV_R & source->access[cr->auth_token].effective)
- return true; /* read access to original space */
+ /* If user has global alter, drop privilege she may access all users */
+ if (PRIV_WRDA & cr->universal_access)
+ return true;
+ if (source->access[cr->auth_token].effective & PRIV_R)
+ return true;
uint32_t uid;
if (tuple_field_u32(tuple, BOX_USER_FIELD_ID, &uid) != 0)
@@ -217,17 +219,20 @@ vuser_filter(struct space *source, struct tuple *tuple)
uint32_t owner_id;
if (tuple_field_u32(tuple, BOX_USER_FIELD_UID, &owner_id) != 0)
return false;
- return uid == cr->uid || owner_id == cr->uid;
+ return uid == cr->uid || owner_id == cr->uid || uid == PUBLIC;
}
static bool
vpriv_filter(struct space *source, struct tuple *tuple)
{
struct credentials *cr = effective_user();
- if (PRIV_R & cr->universal_access)
- return true; /* read access to unverse */
- if (PRIV_R & source->access[cr->auth_token].effective)
- return true; /* read access to original space */
+ /* If user has global alter, drop privilege
+ * she may access all privileges
+ */
+ if (PRIV_WRDA & cr->universal_access)
+ return true;
+ if (source->access[cr->auth_token].effective & PRIV_R)
+ return true;
uint32_t grantor_id;
if (tuple_field_u32(tuple, BOX_PRIV_FIELD_ID, &grantor_id) != 0)
@@ -235,15 +240,21 @@ vpriv_filter(struct space *source, struct tuple *tuple)
uint32_t grantee_id;
if (tuple_field_u32(tuple, BOX_PRIV_FIELD_UID, &grantee_id) != 0)
return false;
- return grantor_id == cr->uid || grantee_id == cr->uid;
+ const char *type;
+ uint32_t obj_id;
+ if ((type = tuple_field_cstr(tuple, BOX_PRIV_FIELD_OBJECT_TYPE)) == NULL ||
+ tuple_field_u32(tuple, BOX_PRIV_FIELD_OBJECT_ID, &obj_id) != 0)
+ return false;
+ return grantor_id == cr->uid || grantee_id == cr->uid ||
+ (strncmp(type, "role", 4) == 0 && obj_id == PUBLIC);
}
static bool
vfunc_filter(struct space *source, struct tuple *tuple)
{
struct credentials *cr = effective_user();
- if ((PRIV_R | PRIV_X) & cr->universal_access)
- return true; /* read or execute access to unverse */
+ if ((PRIV_WRDA | PRIV_X) & cr->universal_access)
+ return true;
if (PRIV_R & source->access[cr->auth_token].effective)
return true; /* read access to original space */
@@ -253,18 +264,17 @@ vfunc_filter(struct space *source, struct tuple *tuple)
uint32_t name_len = strlen(name);
struct func *func = func_by_name(name, name_len);
assert(func != NULL);
- uint8_t effective = func->access[cr->auth_token].effective;
- if (func->def->uid == cr->uid || (PRIV_X & effective))
- return true;
- return false;
+ uint32_t effective = func->access[cr->auth_token].effective;
+ return func->def->uid == cr->uid ||
+ ((PRIV_WRDA | PRIV_X) & effective);
}
static bool
vsequence_filter(struct space *source, struct tuple *tuple)
{
struct credentials *cr = effective_user();
- if ((PRIV_R | PRIV_X) & cr->universal_access)
- return true; /* read or execute access to unverse */
+ if (PRIV_WRDA & cr->universal_access)
+ return true;
if (PRIV_R & source->access[cr->auth_token].effective)
return true; /* read access to original space */
@@ -274,13 +284,11 @@ vsequence_filter(struct space *source, struct tuple *tuple)
struct sequence *sequence = sequence_by_id(id);
if (sequence == NULL)
return false;
- uint8_t effective = sequence->access[cr->auth_token].effective;
- if (sequence->def->uid == cr->uid || ((PRIV_W | PRIV_R) & effective))
- return true;
- return false;
+ uint32_t effective = sequence->access[cr->auth_token].effective;
+ return sequence->def->uid == cr->uid ||
+ (PRIV_WRDA & effective);
}
-
struct sysview_index *
sysview_index_new(struct sysview_engine *sysview,
struct index_def *def, const char *space_name)
diff --git a/test/box/access.result b/test/box/access.result
index 191857f..4354b05 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -386,7 +386,8 @@ session.su('grantee')
-- fails - can't suicide - ask the creator to kill you
box.schema.user.drop('grantee')
---
-- error: Read access to space '_user' is denied for user 'grantee'
+- error: 'Failed to drop user or role ''grantee'': the user is active in the current
+ session'
...
session.su('grantor')
---
@@ -471,7 +472,7 @@ session.su('user1')
-- permission denied
box.schema.user.passwd('admin', 'xxx')
---
-- error: Read access to space '_user' is denied for user 'user1'
+- error: User 'admin' is not found
...
session.su('admin')
---
@@ -1048,7 +1049,7 @@ session.su("test1")
...
box.schema.user.disable("test")
---
-- error: Read access to space '_user' is denied for user 'test1'
+- error: User 'test' is not found
...
session.su("admin")
---
@@ -1080,7 +1081,7 @@ session.su("test1")
...
box.schema.user.grant("test", "usage", "universe")
---
-- error: Read access to space '_user' is denied for user 'test1'
+- error: User 'test' is not found
...
session.su('admin')
---
@@ -1173,11 +1174,11 @@ box.schema.space.create('test')
...
box.schema.user.create('test')
---
-- error: Read access to space '_user' is denied for user 'guest'
+- error: Write access to space '_user' is denied for user 'guest'
...
box.schema.func.create('test')
---
-- error: Read access to space '_func' is denied for user 'guest'
+- error: Write access to space '_func' is denied for user 'guest'
...
box.session.su('admin')
---
@@ -1357,28 +1358,37 @@ box.schema.user.create("tester")
s = box.schema.space.create("test")
---
...
+_ = s:create_index("primary")
+---
+...
+seq = box.schema.sequence.create("test")
+---
+...
u = box.schema.user.create("test")
---
...
f = box.schema.func.create("test")
---
...
-box.schema.user.grant("tester", "read,execute", "universe")
+-- failed create
+box.session.su("tester")
---
...
--- failed create
-box.session.su("tester", box.schema.space.create, "test_space")
+box.schema.space.create("test_space")
---
- error: Write access to space '_schema' is denied for user 'tester'
...
-box.session.su("tester", box.schema.user.create, 'test_user')
+box.schema.user.create('test_user')
---
- error: Write access to space '_user' is denied for user 'tester'
...
-box.session.su("tester", box.schema.func.create, 'test_func')
+box.schema.func.create('test_func')
---
- error: Write access to space '_func' is denied for user 'tester'
...
+box.session.su("admin")
+---
+...
--
-- FIXME 2.0: we still need to grant 'write' on universe
-- explicitly since we still use process_rw to write to system
@@ -1387,24 +1397,36 @@ box.session.su("tester", box.schema.func.create, 'test_func')
box.schema.user.grant("tester", "create,write", "universe")
---
...
+box.session.su("tester")
+---
+...
-- successful create
-s1 = box.session.su("tester", box.schema.space.create, "test_space")
+s1 = box.schema.space.create("test_space")
+---
+...
+_ = s1:create_index("primary")
---
...
-_ = box.session.su("tester", box.schema.user.create, 'test_user')
+_ = box.schema.user.create('test_user')
---
...
-_ = box.session.su("tester", box.schema.func.create, 'test_func')
+_ = box.schema.func.create('test_func')
+---
+...
+seq1 = box.schema.sequence.create('test_seq')
---
...
-- successful drop of owned objects
-_ = box.session.su("tester", s1.drop, s1)
+s1:drop()
---
...
-_ = box.session.su("tester", box.schema.user.drop, 'test_user')
+seq1:drop()
+---
+...
+box.schema.user.drop('test_user')
---
...
-_ = box.session.su("tester", box.schema.func.drop, 'test_func')
+box.schema.func.drop('test_func')
---
...
-- failed alter
@@ -1414,22 +1436,24 @@ _ = box.session.su("tester", box.schema.func.drop, 'test_func')
-- box.session.su("tester", s.format, s, {name="id", type="unsigned"})
-- failed drop
-- box.session.su("tester", s.drop, s)
--- can't use here sudo
--- because drop use sudo inside
--- and currently sudo can't be performed nested
-box.session.su("tester")
+s:drop()
---
+- error: Drop access to space 'test' is denied for user 'tester'
+...
+seq:drop()
+---
+- error: Drop access to sequence 'test' is denied for user 'tester'
...
box.schema.user.drop("test")
---
- error: Revoke access to role 'public' is denied for user 'tester'
...
-box.session.su("admin")
+box.schema.func.drop("test")
---
+- error: Drop access to function 'test' is denied for user 'tester'
...
-box.session.su("tester", box.schema.func.drop, "test")
+box.session.su("admin")
---
-- error: Drop access to function 'test' is denied for user 'tester'
...
box.schema.user.grant("tester", "drop", "universe")
---
@@ -1438,6 +1462,9 @@ box.schema.user.grant("tester", "drop", "universe")
box.session.su("tester", s.drop, s)
---
...
+box.session.su("tester", seq.drop, seq)
+---
+...
box.session.su("tester", box.schema.user.drop, "test")
---
...
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index 7e880a0..e3ad687 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -509,14 +509,17 @@ s:drop()
--
box.schema.user.create("tester")
s = box.schema.space.create("test")
+_ = s:create_index("primary")
+seq = box.schema.sequence.create("test")
u = box.schema.user.create("test")
f = box.schema.func.create("test")
-box.schema.user.grant("tester", "read,execute", "universe")
-- failed create
-box.session.su("tester", box.schema.space.create, "test_space")
-box.session.su("tester", box.schema.user.create, 'test_user')
-box.session.su("tester", box.schema.func.create, 'test_func')
+box.session.su("tester")
+box.schema.space.create("test_space")
+box.schema.user.create('test_user')
+box.schema.func.create('test_func')
+box.session.su("admin")
--
-- FIXME 2.0: we still need to grant 'write' on universe
@@ -524,15 +527,19 @@ box.session.su("tester", box.schema.func.create, 'test_func')
-- tables from ddl
--
box.schema.user.grant("tester", "create,write", "universe")
+box.session.su("tester")
-- successful create
-s1 = box.session.su("tester", box.schema.space.create, "test_space")
-_ = box.session.su("tester", box.schema.user.create, 'test_user')
-_ = box.session.su("tester", box.schema.func.create, 'test_func')
+s1 = box.schema.space.create("test_space")
+_ = s1:create_index("primary")
+_ = box.schema.user.create('test_user')
+_ = box.schema.func.create('test_func')
+seq1 = box.schema.sequence.create('test_seq')
-- successful drop of owned objects
-_ = box.session.su("tester", s1.drop, s1)
-_ = box.session.su("tester", box.schema.user.drop, 'test_user')
-_ = box.session.su("tester", box.schema.func.drop, 'test_func')
+s1:drop()
+seq1:drop()
+box.schema.user.drop('test_user')
+box.schema.func.drop('test_func')
-- failed alter
-- box.session.su("tester", s.format, s, {name="id", type="unsigned"})
@@ -543,19 +550,16 @@ _ = box.session.su("tester", box.schema.func.drop, 'test_func')
-- failed drop
-- box.session.su("tester", s.drop, s)
-
--- can't use here sudo
--- because drop use sudo inside
--- and currently sudo can't be performed nested
-box.session.su("tester")
+s:drop()
+seq:drop()
box.schema.user.drop("test")
-box.session.su("admin")
-
-box.session.su("tester", box.schema.func.drop, "test")
+box.schema.func.drop("test")
+box.session.su("admin")
box.schema.user.grant("tester", "drop", "universe")
-- successful drop
box.session.su("tester", s.drop, s)
+box.session.su("tester", seq.drop, seq)
box.session.su("tester", box.schema.user.drop, "test")
box.session.su("tester", box.schema.func.drop, "test")
diff --git a/test/box/access_bin.result b/test/box/access_bin.result
index b81279c..d093c75 100644
--- a/test/box/access_bin.result
+++ b/test/box/access_bin.result
@@ -55,14 +55,14 @@ c = remote.connect(box.cfg.listen)
...
c:call("setuid_func")
---
-- error: Read access to space 'setuid_space' is denied for user 'guest'
+- error: Write access to space 'setuid_space' is denied for user 'guest'
...
session.su('guest')
---
...
setuid_func()
---
-- error: Read access to space 'setuid_space' is denied for user 'guest'
+- error: Write access to space 'setuid_space' is denied for user 'guest'
...
session.su('admin')
---
@@ -85,7 +85,7 @@ session.su('guest')
...
setuid_func()
---
-- error: Read access to space 'setuid_space' is denied for user 'guest'
+- error: Write access to space 'setuid_space' is denied for user 'guest'
...
session.su('admin')
---
@@ -122,7 +122,7 @@ session.su('guest')
...
setuid_func()
---
-- error: Read access to space 'setuid_space' is denied for user 'guest'
+- error: Write access to space 'setuid_space' is denied for user 'guest'
...
session.su('admin')
---
diff --git a/test/box/access_misc.result b/test/box/access_misc.result
index 3a56a4c..abc0be7 100644
--- a/test/box/access_misc.result
+++ b/test/box/access_misc.result
@@ -177,7 +177,7 @@ gs = box.schema.space.create('guest_space')
...
box.schema.func.create('guest_func')
---
-- error: Read access to space '_func' is denied for user 'guest'
+- error: Write access to space '_func' is denied for user 'guest'
...
session.su('admin')
---
diff --git a/test/box/access_sysview.result b/test/box/access_sysview.result
index 340ed21..20efd2b 100644
--- a/test/box/access_sysview.result
+++ b/test/box/access_sysview.result
@@ -266,11 +266,11 @@ box.session.su('guest')
...
#box.space._vuser:select{}
---
-- 1
+- 5
...
#box.space._vpriv:select{}
---
-- 2
+- 15
...
#box.space._vfunc:select{}
---
@@ -343,7 +343,7 @@ box.session.su('guest')
-- _vuser
--
-- a guest user can read information about itself
-t = box.space._vuser:select(); return #t == 1 and t[1][3] == 'guest'
+t = box.space._vuser:select(); for i = 1, #t do if t[i][3] == 'guest' then return true end end return false
---
- true
...
@@ -526,8 +526,9 @@ box.schema.user.grant('guest', 'execute', 'function', 'test')
box.session.su('guest')
---
...
-#box.space._vfunc:select{} = cnt + 1
+#box.space._vfunc:select{} == func_cnt
---
+- true
...
box.session.su('admin')
---
@@ -551,7 +552,7 @@ box.schema.user.grant('guest', 'execute', 'universe')
box.session.su('guest')
---
...
-#box.space._vfunc:select{} == cnt + 1
+#box.space._vfunc:select{} == func_cnt
---
- true
...
diff --git a/test/box/access_sysview.test.lua b/test/box/access_sysview.test.lua
index 7955ffc..4cc5611 100644
--- a/test/box/access_sysview.test.lua
+++ b/test/box/access_sysview.test.lua
@@ -134,7 +134,7 @@ box.session.su('guest')
--
-- a guest user can read information about itself
-t = box.space._vuser:select(); return #t == 1 and t[1][3] == 'guest'
+t = box.space._vuser:select(); for i = 1, #t do if t[i][3] == 'guest' then return true end end return false
-- read access to original space also allow to read a view
box.session.su('admin')
@@ -218,7 +218,7 @@ box.session.su('admin')
box.schema.user.grant('guest', 'execute', 'function', 'test')
box.session.su('guest')
-#box.space._vfunc:select{} = cnt + 1
+#box.space._vfunc:select{} == func_cnt
box.session.su('admin')
box.schema.user.revoke('guest', 'execute', 'function', 'test')
@@ -230,7 +230,7 @@ box.session.su('admin')
box.schema.user.grant('guest', 'execute', 'universe')
box.session.su('guest')
-#box.space._vfunc:select{} == cnt + 1
+#box.space._vfunc:select{} == func_cnt
box.session.su('admin')
box.schema.user.revoke('guest', 'execute', 'universe')
diff --git a/test/box/on_replace.result b/test/box/on_replace.result
index d6158dc..b9e6ded 100644
--- a/test/box/on_replace.result
+++ b/test/box/on_replace.result
@@ -471,42 +471,42 @@ t = s:on_replace(function () s:create_index('sec') end, t)
...
s:replace({2, 3})
---
-- error: Space _index does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
t = s:on_replace(function () box.schema.user.create('newu') end, t)
---
...
s:replace({3, 4})
---
-- error: Space _user does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
t = s:on_replace(function () box.schema.role.create('newr') end, t)
---
...
s:replace({4, 5})
---
-- error: Space _user does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
t = s:on_replace(function () s:drop() end, t)
---
...
s:replace({5, 6})
---
-- error: Space _index does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
t = s:on_replace(function () box.schema.func.create('newf') end, t)
---
...
s:replace({6, 7})
---
-- error: Space _func does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
t = s:on_replace(function () box.schema.user.grant('guest', 'read,write', 'space', 'test_on_repl_ddl') end, t)
---
...
s:replace({7, 8})
---
-- error: Space _priv does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
t = s:on_replace(function () s:rename('newname') end, t)
---
diff --git a/test/box/role.result b/test/box/role.result
index 736ec85..806cea9 100644
--- a/test/box/role.result
+++ b/test/box/role.result
@@ -662,7 +662,7 @@ box.session.su('john')
-- error
box.schema.user.grant('grantee', 'role')
---
-- error: Read access to space '_user' is denied for user 'john'
+- error: User 'grantee' is not found
...
--
box.session.su('admin')
diff --git a/test/box/transaction.result b/test/box/transaction.result
index 2a4b3b2..0f1a8b3 100644
--- a/test/box/transaction.result
+++ b/test/box/transaction.result
@@ -69,21 +69,21 @@ box.rollback();
...
box.begin() box.schema.func.create('test');
---
-- error: Space _func does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
box.rollback();
---
...
box.begin() box.schema.user.create('test');
---
-- error: Space _user does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
box.rollback();
---
...
box.begin() box.schema.user.grant('guest', 'read', 'space', '_priv');
---
-- error: Space _priv does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
box.rollback();
---
@@ -107,7 +107,7 @@ s = box.schema.space.create('test');
...
box.begin() index = s:create_index('primary');
---
-- error: Space _index does not support multi-statement transactions
+- error: A multi-statement transaction can not use multiple storage engines
...
box.rollback();
---
diff --git a/test/engine/iterator.result b/test/engine/iterator.result
index a5fc9d7..00c427d 100644
--- a/test/engine/iterator.result
+++ b/test/engine/iterator.result
@@ -4211,7 +4211,7 @@ s:replace{35}
...
state, value = gen(param,state)
---
-- error: 'builtin/box/schema.lua:983: usage: next(param, state)'
+- error: 'builtin/box/schema.lua:991: usage: next(param, state)'
...
value
---
diff --git a/test/engine/savepoint.result b/test/engine/savepoint.result
index 9d238ec..6e07958 100644
--- a/test/engine/savepoint.result
+++ b/test/engine/savepoint.result
@@ -14,7 +14,7 @@ s1 = box.savepoint()
...
box.rollback_to_savepoint(s1)
---
-- error: 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- error: 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
...
box.begin() s1 = box.savepoint()
---
@@ -323,27 +323,27 @@ test_run:cmd("setopt delimiter ''");
ok1, errmsg1
---
- false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
...
ok2, errmsg2
---
- false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
...
ok3, errmsg3
---
- false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
...
ok4, errmsg4
---
- false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
...
ok5, errmsg5
---
- false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
...
s:select{}
---
--
2.7.4
More information about the Tarantool-patches
mailing list