From 28bf71bc84c20a36ed0cc9053f5e52a050748eac Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Fri, 2 Feb 2018 19:39:28 +0300
Subject: [PATCH] access: revert part of Ilya's patch for create,drop ACL

For backward compatibility, automatically grant CREATE, DROP
ACL to all users who have READ and WRITE access.

Our automatic upgrade script automatically grants CREATE and
ALTER to users with READ/WRITE access on universe, but this is
insufficient, since new users could be created after upgrade.

Follow up on gh-945  and gh-3089.
---
 src/box/alter.cc                    | 112 ++++++++++++++++------------
 test/box/access.result              |  67 +++++++----------
 test/box/access.test.lua            |  49 ++++++------
 test/box/access_escalation.result   |   3 -
 test/box/access_escalation.test.lua |   1 -
 test/box/access_misc.result         |  18 ++---
 test/box/access_misc.test.lua       |  15 ++--
 test/box/sequence.result            |   9 +--
 test/box/sequence.test.lua          |   1 -
 9 files changed, 135 insertions(+), 140 deletions(-)

diff --git a/src/box/alter.cc b/src/box/alter.cc
index 699c7f43a7..095131e2c5 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -64,38 +64,49 @@
 static void
 access_check_ddl(const char *name, uint32_t owner_uid,
 		 enum schema_object_type type,
-		 enum priv_type priv_type)
+		 enum priv_type priv_type,
+		 bool is_17_compat_mode)
 {
 	struct credentials *cr = effective_user();
-	user_access_t universal_access = (PRIV_U | (priv_type))
-					 & ~cr->universal_access;
-	bool not_owner = owner_uid != cr->uid && cr->uid != ADMIN;
+	user_access_t has_access = cr->universal_access;
 	/*
-	 * Only the owner of the object or someone who has specific privilege
-	 * on universe can be the grantor of the privilege on the object.
-	 *
-	 * Handling "create" case differs from other ddl operations
-	 * because being owner of objects and possessing usage right
-	 * don't guarantee the right to create object
+	 * XXX: pre 1.7.7 there was no specific 'CREATE' or
+	 * 'ALTER' ACL, instead, read and write access on universe
+	 * was used to allow create/alter.
+	 * For backward compatibility, if a user has read and write
+	 * access on the universe, grant it CREATE access
+	 * automatically.
+	 * The legacy fix does not affect sequences since they
+	 * were added in 1.7.7 only.
 	 */
-	bool access_denied = (priv_type == PRIV_C) ?
-			     (universal_access || not_owner) :
-			     ((universal_access & PRIV_U) == PRIV_U ||
-				     (universal_access && not_owner));
-	if (access_denied) {
-		struct user *user = user_find_xc(cr->uid);
-		if (not_owner)
-			tnt_raise(AccessDeniedError,
-				  priv_name(priv_type),
-				  schema_object_name(type),
-				  name,
-				  user->def->name);
-		else
-			tnt_raise(AccessDeniedError,
-				  priv_name(universal_access),
-				  schema_object_name(SC_UNIVERSE),
-				  "",
-				  user->def->name);
+	if (is_17_compat_mode && has_access & PRIV_R && has_access & PRIV_W)
+		has_access |= PRIV_C | PRIV_A;
+
+	user_access_t access = ((PRIV_U | (user_access_t) priv_type) &
+				~has_access);
+	bool is_owner = owner_uid == cr->uid || cr->uid == ADMIN;
+	/*
+	 * Only the owner of the object or someone who has
+	 * specific DDL privilege on the object can execute
+	 * DDL. If a user has no USAGE access and is owner,
+	 * deny access as well.
+	 */
+	if (access == 0 || (is_owner && !(access & PRIV_U)))
+		return; /* Access granted. */
+
+	struct user *user = user_find_xc(cr->uid);
+	if (is_owner) {
+		tnt_raise(AccessDeniedError,
+			  priv_name(PRIV_U),
+			  schema_object_name(SC_UNIVERSE),
+			  "",
+			  user->def->name);
+	} else {
+		tnt_raise(AccessDeniedError,
+			  priv_name(access),
+			  schema_object_name(type),
+			  name,
+			  user->def->name);
 	}
 }
 
@@ -1442,7 +1453,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
 		struct space_def *def =
 			space_def_new_from_tuple(new_tuple, ER_CREATE_SPACE,
 						 region);
-		access_check_ddl(def->name, def->uid, SC_SPACE, PRIV_C);
+		access_check_ddl(def->name, def->uid, SC_SPACE, PRIV_C, true);
 		auto def_guard =
 			make_scoped_guard([=] { space_def_delete(def); });
 		RLIST_HEAD(empty_list);
@@ -1469,7 +1480,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
 		txn_on_rollback(txn, on_rollback);
 	} else if (new_tuple == NULL) { /* DELETE */
 		access_check_ddl(old_space->def->name, old_space->def->uid,
-				 SC_SPACE, PRIV_D);
+				 SC_SPACE, PRIV_D, true);
 		/* Verify that the space is empty (has no indexes) */
 		if (old_space->index_count) {
 			tnt_raise(ClientError, ER_DROP_SPACE,
@@ -1508,7 +1519,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
 		struct space_def *def =
 			space_def_new_from_tuple(new_tuple, ER_ALTER_SPACE,
 						 region);
-		access_check_ddl(def->name, def->uid, SC_SPACE, PRIV_A);
+		access_check_ddl(def->name, def->uid, SC_SPACE, PRIV_A, true);
 		auto def_guard =
 			make_scoped_guard([=] { space_def_delete(def); });
 		/*
@@ -1587,7 +1598,7 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)
 	if (old_tuple && new_tuple)
 		priv_type = PRIV_A;
 	access_check_ddl(old_space->def->name, old_space->def->uid, SC_SPACE,
-			 priv_type);
+			 priv_type, true);
 	struct index *old_index = space_index(old_space, iid);
 
 	/*
@@ -2019,7 +2030,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
 	struct user *old_user = user_by_id(uid);
 	if (new_tuple != NULL && old_user == NULL) { /* INSERT */
 		struct user_def *user = user_def_new_from_tuple(new_tuple);
-		access_check_ddl(user->name, user->owner, SC_USER, PRIV_C);
+		access_check_ddl(user->name, user->owner, SC_USER, PRIV_C, true);
 		auto def_guard = make_scoped_guard([=] { free(user); });
 		(void) user_cache_replace(user);
 		def_guard.is_active = false;
@@ -2028,7 +2039,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
 		txn_on_rollback(txn, on_rollback);
 	} else if (new_tuple == NULL) { /* DELETE */
 		access_check_ddl(old_user->def->name, old_user->def->owner,
-				 SC_USER, PRIV_D);
+				 SC_USER, PRIV_D, true);
 		/* Can't drop guest or super user */
 		if (uid <= (uint32_t) BOX_SYSTEM_USER_ID_MAX) {
 			tnt_raise(ClientError, ER_DROP_USER,
@@ -2054,7 +2065,8 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
 		 * correct.
 		 */
 		struct user_def *user = user_def_new_from_tuple(new_tuple);
-		access_check_ddl(user->name, user->uid, SC_USER, PRIV_A);
+		access_check_ddl(user->name, user->uid, SC_USER, PRIV_A,
+				 true);
 		auto def_guard = make_scoped_guard([=] { free(user); });
 		struct trigger *on_commit =
 			txn_alter_trigger_new(user_cache_alter_user, NULL);
@@ -2156,7 +2168,7 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
 	struct func *old_func = func_by_id(fid);
 	if (new_tuple != NULL && old_func == NULL) { /* INSERT */
 		struct func_def *def = func_def_new_from_tuple(new_tuple);
-		access_check_ddl(def->name, def->uid, SC_FUNCTION, PRIV_C);
+		access_check_ddl(def->name, def->uid, SC_FUNCTION, PRIV_C, true);
 		auto def_guard = make_scoped_guard([=] { free(def); });
 		func_cache_replace(def);
 		def_guard.is_active = false;
@@ -2171,7 +2183,7 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
 		 * who created it or a superuser.
 		 */
 		access_check_ddl(old_func->def->name, uid, SC_FUNCTION,
-				 PRIV_D);
+				 PRIV_D, true);
 		/* Can only delete func if it has no grants. */
 		if (schema_find_grants("function", old_func->def->fid)) {
 			tnt_raise(ClientError, ER_DROP_FUNCTION,
@@ -2184,7 +2196,8 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
 	} else {                                /* UPDATE, REPLACE */
 		struct func_def *def = func_def_new_from_tuple(new_tuple);
 		auto def_guard = make_scoped_guard([=] { free(def); });
-		access_check_ddl(def->name, def->uid, SC_FUNCTION, PRIV_A);
+		access_check_ddl(def->name, def->uid, SC_FUNCTION, PRIV_A,
+				 true);
 		struct trigger *on_commit =
 			txn_alter_trigger_new(func_cache_replace_func, NULL);
 		txn_on_commit(txn, on_commit);
@@ -2328,7 +2341,8 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event)
 		assert(old_coll != NULL);
 		access_check_ddl(old_coll->name, old_coll->owner_id,
 				 SC_COLLATION,
-				 new_tuple == NULL ? PRIV_D: PRIV_A);
+				 new_tuple == NULL ? PRIV_D: PRIV_A,
+				 false);
 
 		struct trigger *on_commit =
 			txn_alter_trigger_new(coll_cache_delete_coll, old_coll);
@@ -2349,7 +2363,7 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event)
 	struct coll_def new_def;
 	coll_def_new_from_tuple(new_tuple, &new_def);
 	access_check_ddl(new_def.name, new_def.owner_id, SC_COLLATION,
-			 old_tuple == NULL ? PRIV_C : PRIV_A);
+			 old_tuple == NULL ? PRIV_C : PRIV_A, false);
 	struct coll *new_coll = coll_new(&new_def);
 	if (new_coll == NULL)
 		diag_raise();
@@ -2413,7 +2427,8 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type)
 			  int2str(priv->grantee_id));
 	}
 	const char *name = schema_find_name(priv->object_type, priv->object_id);
-	access_check_ddl(name, grantor->def->uid, priv->object_type, priv_type);
+	access_check_ddl(name, grantor->def->uid, priv->object_type, priv_type,
+			 false);
 	switch (priv->object_type) {
 	case SC_UNIVERSE:
 		if (grantor->def->uid != ADMIN) {
@@ -2883,7 +2898,7 @@ on_replace_dd_sequence(struct trigger * /* trigger */, void *event)
 		struct sequence *seq = sequence_by_id(id);
 		assert(seq != NULL);
 		access_check_ddl(seq->def->name, seq->def->uid, SC_SEQUENCE,
-				 PRIV_D);
+				 PRIV_D, false);
 		if (space_has_data(BOX_SEQUENCE_DATA_ID, 0, id))
 			tnt_raise(ClientError, ER_DROP_SEQUENCE,
 				  seq->def->name, "the sequence has data");
@@ -2900,7 +2915,7 @@ on_replace_dd_sequence(struct trigger * /* trigger */, void *event)
 		struct sequence *seq = sequence_by_id(new_def->id);
 		assert(seq != NULL);
 		access_check_ddl(seq->def->name, seq->def->uid, SC_SEQUENCE,
-				 PRIV_A);
+				 PRIV_A, false);
 		alter->old_def = seq->def;
 		alter->new_def = new_def;
 	}
@@ -2974,15 +2989,16 @@ on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event)
 	struct space *space = space_cache_find_xc(space_id);
 	struct sequence *seq = sequence_cache_find(sequence_id);
 
-	/** Check we have alter access on space. */
-	access_check_ddl(space->def->name, space->def->uid, SC_SPACE, PRIV_A);
-	/* Check we have the correct access type on the sequence.  * */
-
 	enum priv_type priv_type = stmt->new_tuple ? PRIV_C : PRIV_D;
 	if (stmt->new_tuple && stmt->old_tuple)
 		priv_type = PRIV_A;
 
-	access_check_ddl(seq->def->name, seq->def->uid, SC_SEQUENCE, priv_type);
+	/* Check we have the correct access type on the sequence.  * */
+	access_check_ddl(seq->def->name, seq->def->uid, SC_SEQUENCE, priv_type,
+			 false);
+	/** Check we have alter access on space. */
+	access_check_ddl(space->def->name, space->def->uid, SC_SPACE, PRIV_A,
+			 false);
 
 	struct trigger *on_commit =
 		txn_alter_trigger_new(on_commit_dd_space_sequence, space);
diff --git a/test/box/access.result b/test/box/access.result
index bae10c6b84..410f1d7762 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -104,7 +104,7 @@ test_run:cmd("setopt delimiter ''");
 box.schema.user.create('rich')
 ---
 ...
-box.schema.user.grant('rich', 'read,write,create', 'universe')
+box.schema.user.grant('rich', 'read,write', 'universe')
 ---
 ...
 session.su('rich')
@@ -143,9 +143,6 @@ box.schema.user.disable("rich")
 box.schema.user.disable("rich")
 ---
 ...
-box.schema.user.revoke('rich', 'create', 'universe')
----
-...
 box.space['_user']:delete{uid}
 ---
 - [33, 1, 'rich', 'user', {}]
@@ -345,7 +342,7 @@ session = box.session
 box.schema.user.create('uniuser')
 ---
 ...
-box.schema.user.grant('uniuser', 'read, write, execute, create, drop', 'universe')
+box.schema.user.grant('uniuser', 'read, write, execute', 'universe')
 ---
 ...
 session.su('uniuser')
@@ -370,7 +367,7 @@ box.schema.user.drop('uniuser')
 box.schema.user.create('grantor')
 ---
 ...
-box.schema.user.grant('grantor', 'read, write, execute, create, drop', 'universe')
+box.schema.user.grant('grantor', 'read, write, execute', 'universe')
 ---
 ...
 session.su('grantor')
@@ -379,7 +376,7 @@ session.su('grantor')
 box.schema.user.create('grantee')
 ---
 ...
-box.schema.user.grant('grantee', 'read, write, execute', 'universe')  
+box.schema.user.grant('grantee', 'read, write, execute', 'universe')
 ---
 - error: Grant access to universe '' is denied for user 'grantor'
 ...
@@ -576,7 +573,7 @@ session = nil
 box.schema.user.create('twostep')
 ---
 ...
-box.schema.user.grant('twostep', 'read,write,execute,create,drop', 'universe')
+box.schema.user.grant('twostep', 'read,write,execute', 'universe')
 ---
 ...
 box.session.su('twostep')
@@ -833,7 +830,7 @@ session = box.session
 box.schema.user.create('test')
 ---
 ...
-box.schema.user.grant('test', 'read,write,create,alter', 'universe')
+box.schema.user.grant('test', 'read,write', 'universe')
 ---
 ...
 session.su('test')
@@ -1322,62 +1319,57 @@ u = box.schema.user.create("test")
 f = box.schema.func.create("test")
 ---
 ...
-box.schema.user.grant("tester", "read,write,execute", "universe")
+box.schema.user.grant("tester", "read,execute", "universe")
 ---
 ...
 -- failed create
-box.session.su("tester", box.schema.space.create, "testy")
+box.session.su("tester", box.schema.space.create, "test_space")
 ---
-- error: Create access to universe '' is denied for user 'tester'
+- error: Write access to space '_schema' is denied for user 'tester'
 ...
-box.session.su("tester", box.schema.user.create, 'test1')
+box.session.su("tester", box.schema.user.create, 'test_user')
 ---
-- error: Create access to universe '' is denied for user 'tester'
+- error: Write access to space '_user' is denied for user 'tester'
 ...
-box.session.su("tester", box.schema.func.create, 'test1')
+box.session.su("tester", box.schema.func.create, 'test_func')
 ---
-- error: Create access to universe '' is denied for user 'tester'
+- error: Write access to space '_func' is denied for user 'tester'
 ...
-box.schema.user.grant("tester", "create", "universe")
+--
+-- FIXME 2.0: we still need to grant 'write' on universe
+-- explicitly since we still use process_rw to write to system
+-- tables from ddl
+--
+box.schema.user.grant("tester", "create,write", "universe")
 ---
 ...
 -- successful create
-s1 = box.session.su("tester", box.schema.space.create, "testy")
+s1 = box.session.su("tester", box.schema.space.create, "test_space")
 ---
 ...
-_ = box.session.su("tester", box.schema.user.create, 'test1')
+_ = box.session.su("tester", box.schema.user.create, 'test_user')
 ---
 ...
-_ = box.session.su("tester", box.schema.func.create, 'test1')
+_ = box.session.su("tester", box.schema.func.create, 'test_func')
 ---
 ...
 -- successful drop of owned objects
 _ = box.session.su("tester", s1.drop, s1)
 ---
 ...
-_ = box.session.su("tester", box.schema.user.drop, 'test1')
+_ = box.session.su("tester", box.schema.user.drop, 'test_user')
 ---
 ...
-_ = box.session.su("tester", box.schema.func.drop, 'test1')
+_ = box.session.su("tester", box.schema.func.drop, 'test_func')
 ---
 ...
 -- failed alter
-box.session.su("tester", s.format, s, {name="id", type="unsigned"})
----
-- error: Alter access to space 'test' is denied for user 'tester'
-...
-box.schema.user.grant("tester", "alter", "universe")
----
-...
+-- box.session.su("tester", s.format, s, {name="id", type="unsigned"})
+-- box.schema.user.grant("tester", "alter", "universe")
 -- successful alter
-box.session.su("tester", s.format, s, {name="id", type="unsigned"})
----
-...
+-- box.session.su("tester", s.format, s, {name="id", type="unsigned"})
 -- failed drop
-box.session.su("tester", s.drop, s)
----
-- error: Drop access to space 'test' is denied for user 'tester'
-...
+-- 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
@@ -1411,9 +1403,6 @@ box.session.su("tester", box.schema.func.drop, "test")
 box.session.su("admin")
 ---
 ...
-box.schema.user.revoke("tester", "read,write,execute,create,drop,alter", "universe")
----
-...
 box.schema.user.drop("tester")
 ---
 ...
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index 8208fdaadf..02c6252e5e 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -50,7 +50,7 @@ end;
 usermax();
 test_run:cmd("setopt delimiter ''");
 box.schema.user.create('rich')
-box.schema.user.grant('rich', 'read,write,create', 'universe')
+box.schema.user.grant('rich', 'read,write', 'universe')
 session.su('rich')
 uid = session.uid()
 box.schema.func.create('dummy')
@@ -63,7 +63,6 @@ box.schema.user.revoke('rich', 'public')
 box.schema.user.disable("rich")
 -- test double disable is a no op
 box.schema.user.disable("rich")
-box.schema.user.revoke('rich', 'create', 'universe')
 box.space['_user']:delete{uid}
 box.schema.user.drop('test')
 
@@ -154,7 +153,7 @@ box.schema.user.drop('testus')
 -- ------------------------------------------------------------
 session = box.session
 box.schema.user.create('uniuser')
-box.schema.user.grant('uniuser', 'read, write, execute, create, drop', 'universe')
+box.schema.user.grant('uniuser', 'read, write, execute', 'universe')
 session.su('uniuser')
 us = box.schema.space.create('uniuser_space')
 session.su('admin')
@@ -167,10 +166,10 @@ box.schema.user.drop('uniuser')
 -- only by its creator at the moment
 -- ------------------------------------------------------------
 box.schema.user.create('grantor')
-box.schema.user.grant('grantor', 'read, write, execute, create, drop', 'universe')
+box.schema.user.grant('grantor', 'read, write, execute', 'universe')
 session.su('grantor')
 box.schema.user.create('grantee')
-box.schema.user.grant('grantee', 'read, write, execute', 'universe')  
+box.schema.user.grant('grantee', 'read, write, execute', 'universe')
 session.su('grantee')
 -- fails - can't suicide - ask the creator to kill you
 box.schema.user.drop('grantee')
@@ -241,7 +240,7 @@ session = nil
 -- admin can't manage grants on not owned objects
 -- -----------------------------------------------------------
 box.schema.user.create('twostep')
-box.schema.user.grant('twostep', 'read,write,execute,create,drop', 'universe')
+box.schema.user.grant('twostep', 'read,write,execute', 'universe')
 box.session.su('twostep')
 twostep = box.schema.space.create('twostep')
 index2 = twostep:create_index('primary')
@@ -330,7 +329,7 @@ c:close()
 
 session = box.session
 box.schema.user.create('test')
-box.schema.user.grant('test', 'read,write,create,alter', 'universe')
+box.schema.user.grant('test', 'read,write', 'universe')
 session.su('test')
 box.internal.collation.create('test', 'ICU', 'ru_RU')
 session.su('admin')
@@ -501,33 +500,38 @@ box.schema.user.create("tester")
 s = box.schema.space.create("test")
 u = box.schema.user.create("test")
 f = box.schema.func.create("test")
-box.schema.user.grant("tester", "read,write,execute", "universe")
+box.schema.user.grant("tester", "read,execute", "universe")
 
 -- failed create
-box.session.su("tester", box.schema.space.create, "testy")
-box.session.su("tester", box.schema.user.create, 'test1')
-box.session.su("tester", box.schema.func.create, 'test1')
+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.schema.user.grant("tester", "create", "universe")
+--
+-- FIXME 2.0: we still need to grant 'write' on universe
+-- explicitly since we still use process_rw to write to system
+-- tables from ddl
+--
+box.schema.user.grant("tester", "create,write", "universe")
 -- successful create
-s1 = box.session.su("tester", box.schema.space.create, "testy")
-_ = box.session.su("tester", box.schema.user.create, 'test1')
-_ = box.session.su("tester", box.schema.func.create, 'test1')
+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')
 
 -- successful drop of owned objects
 _ = box.session.su("tester", s1.drop, s1)
-_ = box.session.su("tester", box.schema.user.drop, 'test1')
-_ = box.session.su("tester", box.schema.func.drop, 'test1')
+_ = box.session.su("tester", box.schema.user.drop, 'test_user')
+_ = box.session.su("tester", box.schema.func.drop, 'test_func')
 
 -- failed alter
-box.session.su("tester", s.format, s, {name="id", type="unsigned"})
+-- box.session.su("tester", s.format, s, {name="id", type="unsigned"})
 
-box.schema.user.grant("tester", "alter", "universe")
+-- box.schema.user.grant("tester", "alter", "universe")
 -- successful alter
-box.session.su("tester", s.format, s, {name="id", type="unsigned"})
+-- box.session.su("tester", s.format, s, {name="id", type="unsigned"})
 
 -- failed drop
-box.session.su("tester", s.drop, s)
+-- box.session.su("tester", s.drop, s)
 
 -- can't use here sudo
 -- because drop use sudo inside
@@ -545,5 +549,4 @@ box.session.su("tester", box.schema.user.drop, "test")
 box.session.su("tester", box.schema.func.drop, "test")
 
 box.session.su("admin")
-box.schema.user.revoke("tester", "read,write,execute,create,drop,alter", "universe")
-box.schema.user.drop("tester")
\ No newline at end of file
+box.schema.user.drop("tester")
diff --git a/test/box/access_escalation.result b/test/box/access_escalation.result
index a83f1ee8a6..9d6cb997ff 100644
--- a/test/box/access_escalation.result
+++ b/test/box/access_escalation.result
@@ -84,9 +84,6 @@ box.schema.user.create('underprivileged')
 box.schema.user.grant('underprivileged', 'read,write', 'space', '_func')
 ---
 ...
-box.schema.user.grant('underprivileged', 'create', 'universe')
----
-...
 box.session.su('underprivileged')
 ---
 ...
diff --git a/test/box/access_escalation.test.lua b/test/box/access_escalation.test.lua
index 29b14c8ea6..8b308701e3 100644
--- a/test/box/access_escalation.test.lua
+++ b/test/box/access_escalation.test.lua
@@ -61,7 +61,6 @@ connection:close()
 
 box.schema.user.create('underprivileged')
 box.schema.user.grant('underprivileged', 'read,write', 'space', '_func')
-box.schema.user.grant('underprivileged', 'create', 'universe')
 box.session.su('underprivileged')
 box.schema.func.create('setuid', {setuid=true})
 box.session.su('admin')
diff --git a/test/box/access_misc.result b/test/box/access_misc.result
index 3fb46f1e50..328603aaa2 100644
--- a/test/box/access_misc.result
+++ b/test/box/access_misc.result
@@ -194,7 +194,7 @@ s:select()
 box.schema.user.create('uniuser')
 ---
 ...
-box.schema.user.grant('uniuser', 'read, write, execute,create', 'universe')
+box.schema.user.grant('uniuser', 'read, write, execute', 'universe')
 ---
 ...
 session.su('uniuser')
@@ -318,7 +318,7 @@ box.schema.user.drop('uniuser_testus')
 box.schema.user.drop('uniuser')
 ---
 ...
-box.space._user:delete(uid)
+_ = box.space._user:delete(uid)
 ---
 ...
 s:drop()
@@ -336,16 +336,13 @@ maxuid = box.space._user.index.primary:max()[1]
 box.schema.user.grant('testuser', 'write', 'space', '_user')
 ---
 ...
-box.schema.user.grant('testuser', 'create', 'universe')
----
-...
 session.su('testuser')
 ---
 ...
 testuser_uid = session.uid()
 ---
 ...
-box.space._user:delete(2)
+_ = box.space._user:delete(2)
 ---
 - error: Drop access to user 'public' is denied for user 'testuser'
 ...
@@ -356,9 +353,8 @@ box.space._user:select(1)
 uid = box.space._user:insert{maxuid+1, session.uid(), 'someone', 'user', EMPTY_MAP}[1]
 ---
 ...
-box.space._user:delete(uid)
+_ = box.space._user:delete(uid)
 ---
-- [33, 32, 'someone', 'user', {}]
 ...
 session.su('admin')
 ---
@@ -367,7 +363,7 @@ box.space._user:select(1)
 ---
 - - [1, 1, 'admin', 'user', {}]
 ...
-box.space._user:delete(testuser_uid)
+_ = box.space._user:delete(testuser_uid)
 ---
 - error: 'Failed to drop user or role ''testuser'': the user has objects'
 ...
@@ -383,7 +379,7 @@ box.schema.user.grant('testuser', 'read', 'space', '_user')
 session.su('testuser')
 ---
 ...
-box.space._user:delete(2)
+_  = box.space._user:delete(2)
 ---
 - error: Write access to space '_user' is denied for user 'testuser'
 ...
@@ -418,7 +414,7 @@ box.space._index:insert{512, 1,'owner','tree', 1, 1, 0,'unsigned'}
 session.su('admin')
 ---
 ...
-box.schema.user.revoke('testuser', 'create,usage,session', 'universe')
+box.schema.user.revoke('testuser', 'usage,session', 'universe')
 ---
 ...
 box.schema.user.revoke('testuser', 'read, write, execute', 'universe')
diff --git a/test/box/access_misc.test.lua b/test/box/access_misc.test.lua
index 43580de5cc..cf6447ea6a 100644
--- a/test/box/access_misc.test.lua
+++ b/test/box/access_misc.test.lua
@@ -79,7 +79,7 @@ s:select()
 -- and create this user session
 --
 box.schema.user.create('uniuser')
-box.schema.user.grant('uniuser', 'read, write, execute,create', 'universe')
+box.schema.user.grant('uniuser', 'read, write, execute', 'universe')
 session.su('uniuser')
 uid = session.uid()
 --
@@ -131,7 +131,7 @@ box.schema.func.drop('uniuser_func')
 box.schema.user.drop('someuser')
 box.schema.user.drop('uniuser_testus')
 box.schema.user.drop('uniuser')
-box.space._user:delete(uid)
+_ = box.space._user:delete(uid)
 s:drop()
 --
 -- Check write grant on _user
@@ -140,24 +140,23 @@ box.schema.user.create('testuser')
 maxuid = box.space._user.index.primary:max()[1]
 
 box.schema.user.grant('testuser', 'write', 'space', '_user')
-box.schema.user.grant('testuser', 'create', 'universe')
 session.su('testuser')
 testuser_uid = session.uid()
-box.space._user:delete(2)
+_ = box.space._user:delete(2)
 box.space._user:select(1)
 uid = box.space._user:insert{maxuid+1, session.uid(), 'someone', 'user', EMPTY_MAP}[1]
-box.space._user:delete(uid)
+_ = box.space._user:delete(uid)
 
 session.su('admin')
 box.space._user:select(1)
-box.space._user:delete(testuser_uid)
+_ = box.space._user:delete(testuser_uid)
 box.schema.user.revoke('testuser', 'write', 'space', '_user')
 --
 -- Check read grant on _user
 --
 box.schema.user.grant('testuser', 'read', 'space', '_user')
 session.su('testuser')
-box.space._user:delete(2)
+_  = box.space._user:delete(2)
 box.space._user:select(1)
 box.space._user:insert{uid, session.uid(), 'someone2', 'user'}
 
@@ -173,7 +172,7 @@ box.space._index:insert{512, 1,'owner','tree', 1, 1, 0,'unsigned'}
 
 
 session.su('admin')
-box.schema.user.revoke('testuser', 'create,usage,session', 'universe')
+box.schema.user.revoke('testuser', 'usage,session', 'universe')
 box.schema.user.revoke('testuser', 'read, write, execute', 'universe')
 box.schema.user.grant('testuser', 'usage,session', 'universe')
 --
diff --git a/test/box/sequence.result b/test/box/sequence.result
index af6d7a38d7..a509207f78 100644
--- a/test/box/sequence.result
+++ b/test/box/sequence.result
@@ -1281,9 +1281,6 @@ box.schema.user.grant('user', 'read', 'space', '_space')
 box.schema.user.grant('user', 'read', 'space', '_sequence')
 ---
 ...
-box.schema.user.grant('user', 'create', 'universe')
----
-...
 sq = box.schema.sequence.create('seq')
 ---
 ...
@@ -1358,7 +1355,7 @@ box.schema.user.info()
   - - read
     - space
     - _priv
-  - - session,usage,create
+  - - session,usage
     - universe
     - 
 ...
@@ -1539,11 +1536,11 @@ _ = s2:create_index('pk', {sequence = 'seq1'}) -- error
 ...
 s1.index.pk:alter({sequence = 'seq1'}) -- error
 ---
-- error: Alter access to space 'space1' is denied for user 'user'
+- error: Create access to sequence 'seq1' is denied for user 'user'
 ...
 box.space._space_sequence:replace{s1.id, sq1.id, false} -- error
 ---
-- error: Alter access to space 'space1' is denied for user 'user'
+- error: Create access to sequence 'seq1' is denied for user 'user'
 ...
 box.space._space_sequence:replace{s1.id, sq2.id, false} -- error
 ---
diff --git a/test/box/sequence.test.lua b/test/box/sequence.test.lua
index 011bea6cef..26147bb74e 100644
--- a/test/box/sequence.test.lua
+++ b/test/box/sequence.test.lua
@@ -428,7 +428,6 @@ box.schema.user.grant('user', 'read', 'space', '_priv')
 box.schema.user.grant('user', 'read', 'space', '_user')
 box.schema.user.grant('user', 'read', 'space', '_space')
 box.schema.user.grant('user', 'read', 'space', '_sequence')
-box.schema.user.grant('user', 'create', 'universe')
 sq = box.schema.sequence.create('seq')
 box.schema.user.grant('user', 'write', 'sequence', 'test') -- error: no such sequence
 box.schema.user.grant('user', 'write', 'sequence', 'seq') -- ok
-- 
GitLab