[PATCH v2 4/4] Add a privilege upgrade script and update tests.

Serge Petrenko sergepetrenko at tarantool.org
Wed Aug 22 16:39:05 MSK 2018


This patch adds a privilege upgrade script, which runs on upgrade to
1.10.2 and automatically grants CREATE,ALTER,DROP on objects and entities
to all users, who have READ and WRITE access on them.
Also all tests are rewritten to grant only necessary privileges, not
privileges to universe.

Closes #3539
---
 src/box/bootstrap.snap                      | Bin 1556 -> 1555 bytes
 src/box/lua/upgrade.lua                     |  23 +++
 test/box-tap/auth.test.lua                  |   5 -
 test/box-tap/session.test.lua               |  15 +-
 test/box/access.result                      |   4 +-
 test/box/access.test.lua                    |   4 +-
 test/box/access_bin.result                  |   4 +-
 test/box/access_bin.test.lua                |   4 +-
 test/box/access_escalation.result           |  18 +-
 test/box/access_escalation.test.lua         |  11 +-
 test/box/access_misc.result                 |   4 +-
 test/box/access_misc.test.lua               |   4 +-
 test/box/call.result                        |   4 +-
 test/box/call.test.lua                      |   4 +-
 test/box/errinj.result                      |  39 +++-
 test/box/errinj.test.lua                    |  25 ++-
 test/box/net.box.result                     | 265 ++++++++++++++++++++++++++--
 test/box/net.box.test.lua                   | 121 +++++++++++--
 test/box/net_msg_max.result                 |  13 +-
 test/box/net_msg_max.test.lua               |   9 +-
 test/box/on_replace.result                  |   2 +-
 test/box/on_replace.test.lua                |   2 +-
 test/box/protocol.result                    |   9 +-
 test/box/protocol.test.lua                  |   5 +-
 test/box/push.result                        |  52 +++++-
 test/box/push.test.lua                      |  27 ++-
 test/box/schema_reload.result               |  32 +++-
 test/box/schema_reload.test.lua             |  16 +-
 test/box/sql.result                         |   9 +-
 test/box/sql.test.lua                       |   5 +-
 test/box/stat_net.result                    |   7 +-
 test/box/stat_net.test.lua                  |   5 +-
 test/engine/params.result                   |   6 -
 test/engine/params.test.lua                 |   2 -
 test/engine/replica_join.result             |   6 -
 test/engine/replica_join.test.lua           |   2 -
 test/replication/autobootstrap.result       |  23 ++-
 test/replication/autobootstrap.test.lua     |  10 +-
 test/replication/catch.result               |   6 -
 test/replication/catch.test.lua             |   2 -
 test/replication/errinj.result              |   3 -
 test/replication/errinj.test.lua            |   1 -
 test/replication/gc.result                  |   6 -
 test/replication/gc.test.lua                |   2 -
 test/replication/join_vclock.result         |   6 -
 test/replication/join_vclock.test.lua       |   2 -
 test/replication/skip_conflict_row.result   |   6 -
 test/replication/skip_conflict_row.test.lua |   2 -
 test/vinyl/replica_quota.result             |   6 -
 test/vinyl/replica_quota.test.lua           |   2 -
 test/wal_off/func_max.result                |  25 +--
 test/wal_off/func_max.test.lua              |  19 +-
 test/xlog/errinj.result                     |   9 +-
 test/xlog/errinj.test.lua                   |   4 +-
 test/xlog/misc.result                       |   9 +-
 test/xlog/misc.test.lua                     |   5 +-
 test/xlog/upgrade.result                    |   4 +-
 57 files changed, 689 insertions(+), 226 deletions(-)

diff --git a/src/box/bootstrap.snap b/src/box/bootstrap.snap
index 44992b050e9d73d69608fb92782d1e965f6cdc51..7f214e019d316a58689d6c0e6f40d27a812b3a5e 100644
GIT binary patch
delta 1430
zcmV;H1!?+}43i9y8-F=5EoU__HZWo|VP<0rNp5p=VQyn(Iv_PQVK-$pWMeHdW at ctB
zG&yB9En#C}W-U1|I5}oHVqr5dIbsS{Lu_wjYdRo%eF_TIx(m9^1(*QN^Y_tyr2qf`
z001bpFZ}>eeJlVbz1K<57I6arUp&AU-y+dqH(0h4*l!hp|9@?Au~44{l+5aDRdrXC
zTZ%99zp_%;Z$4xEWR9K})E4?c8<3Sf)i+QjABdtA)&V7D3d8`p0L=ik5N9#8jj`V~
z*AdT8bJzBq{Q33}9v?35kHb*R9+A2dK;xik80Iw>-~D@=9%H}8)1!m#e3*uv7^Yv@
zd$+1mg??}%0Dsp~GuAO|_wn}nF0T9cKRb5zh}e{Csi{NA3=%46RexgMoV-;ZZslG}
zO<SOHar>^zn~!U$IaGzd?d at QgtzJt_+>)6|eIM#mrD{$!p9-I7WLh()Po)A+tr;4b
zTtm~rK<WB>GR!v_r&1|xqQVox$q<hqQJ&Z^NwJhCT7Qe5<L<hZyN}*kR}5xddos1)
zT57&NiDzAV(mN|k#Yg5OSbDZ<QgAIb$*;YS%t_EYYbk*bhoIx}+%%sZ{qgPD>dOHj
zrAMTa3|vc1GQ{O6`}p&W)RqF*Qj=pHief9wG5yLopTFbp&mGJ+jMlYFf4*;{{=No;
zYchxS9)D0}A)upo>0|y at dbc_nfP2R$hIJ9Nxo`-cpOa$tzEE#4h;J9ywjVm<(R;Qk
z5^yawM+~F+KZ*fedom_wM{FUfb;gxO{L~zq9M+A9$_l{((S7JVbRA?iyXxp_buBfo
ztjDS*MUzscW>7LH4ycp~W!lhViYc8+8m^^gPk$)`he5`fUP`i;3nUAq3M819$FCL&
zEE8BbmY0#sh%{=kR>V?eJxZ!bf+#|*qid<TBBHXMC7R5!IceLWb^kT0QiXiD7YLvJ
zxNELmp5H~hpdLqR&Vy^IDf>8cvVRY#-Z;3HnxxG8sjQW9_pxhmEj3*_+~w{g5Dszn
zHh&=RXMLk31_iASC4*ZX*sW0A3B(znXmmGo0zr_&DSs+mgH<XRC{@O>YPis-Ggvpr
z-pJ@;q+pm{a4twK>WIZk6*}#T%EkRNC&3?EXWR;BXlSTOy}6c}BC37Y<>us%ifgHv
zVriXms}x<2q(7?*ioC;7_n>-D=uqsnyiLOvIohh7aVQgf!#;f0TH;!2f^dPaG3G-X
zoD(?%3>#V}*5ac^935T0$|NcL@~08MGSH5$Jz4u+ldiMU8HXZqEj4Xste{m9<U1yl
z;{$kq<&yA*v9DHNiqhqMhe!F1;~pZGgt-MOgwj)RS*N~MRiBc?OaWVQ>U_2?9S8bT
zXg at BZn0!c%aMF#2emA;jQIk-kZ(s$l(KfJx*J$3@;>G3!)M#v=4e!a~&2=(O8N!-K
z(fpkJCpwmMxU~>Kdu&fj at L~@Ku_5vZdT^kB_JA_e7JERMX_E<O&-So;A6PZ15m3;2
z>$e60!X*?()iJEx_ZSsd48gsp*U-lQ&_Rcij{JZQyl!;Rc8`S at eLrGOFxso0NJs6C
z`M6X|kQVip_*Vcnn-T(xpq5B`;47 at NNm5bfh8*6*Z8-6t=--2ZLXh=^6gnZv*}5!$
zdXSkOG}IB_MstxdAV+a`Bu8K!JeTT!@n-SS)D}ztrgN`IkHZjSSzsg>2OZlXnlm^$
zC(C9)>G$W(au5tT?Tg0~SqBHnDIfv-AXrpHepy)vNntbh6W&FWLB^(Ac(_lU726m0
zT5PurtR*k%L?+ysVKEXDMK2LunUe at Ti0XflY)8qCPz542!%5cW`e at h{o>Ry7;H?5`
kH2dAqNwknw1B3n#t@}v0hILv;5b+g_o+KJv4%HB??ay<dv;Y7A

delta 1431
zcmV;I1!(${43rFz8-F%9EoV7qIb>ruGc#feNp5p=VQyn(Iv_MNF*G<~Fkvk?H8U|S
zG-Eb6En#9ZVl6Q>G-6^mHaRzAIAsb}Lu_wjYdRo%eF_TIx(m9^1(^WO-p7q!r2qf`
z001bpFZ}>eg)9IjJ=jXn7I6XqUp#=+EdLQ|J|L*^AY#R!#(&L~S<f?ekgxrXsIhk{
zMM^S1wf5W-S?24aPUh&f!BR>qR4&hTqO<`TZ%_TqF<&H8N&&+Fxd6=oxe<%xs4HuI
zzs4a`*lStl+U$YlAUZsn%pH#-DTYGqN`SwCdm7d`na;a&-IukV)7jBcb2{y5DW?5Q
z<l)Y$SRfx?2!DWgD_Yx_mUp?Eb(#L%dC!h4hC*(NcPpv`h>Q^_aQ0!On6<gHJl~4v
z-HP4<R+E|UKX*O6ThSm31j}I#rs=GAD=LC299v=hE0v51uT-Gvzm+n*POO!Q1)E{D
zUMCdHll`5WqqwtuDz?@pDmqJGM9Dz}iW3?pDYxnb|9 at oHc*}NY-es6tkil&~H&F|`
zThUoJ at ohgh!_=NsdWhPLouST_6nM9yW`Ev8)MhM9Ehz!dhhXC}%{ZQ%hv^*Z?8|{4
zXDGyu40yMq=7`VK)-fzBVp|G$x1t*VNRqEnto=;HV%j(EJk7y6({TG`-*w)V-+Atb
zeiO&@(0|9W5Wx9-@*3Zr;m(Q%;JtB*X`77cWO$6FU7MsB!p6_BADw0Tbv|CiB at cBr
zB*42BEinzpdr1cSxfv6aL%xn!d;3Ttdh89&jjJYvb%AhwXnAOLXmPOVF4(Fd=-rBX
zHXa}gwL+;-sng6!=7cJpN*i`cF(ea7gLf;sLx0NfVX%Fr7n1Ge!pOp?!U$%@@vMac
z%LJB><wfKo8i`u&4Y63;P7)iE5Q<=}$h#F?302#Uk~eW=ZR&RX at 1CnF7KrD2fdKoC
z_v at F1JP!$fco?xa54>AZTgRd{cMpARjRWsi)U<^?*0plxUA7u{x1zEi^O<+)gGVfK
zoqtc*#kcVye*zDRtk#P4dZkn-(@W-sP2fsQnNTw-(1cGIOrd5{Fi))QbJ1{_VP&|y
zn_Cm31q1b><l<{FVqrxqRxD6 at Rai~tE^0H at bM5T|ZGwV=n%EleRy0(f??1CPds29}
zqA9o9+Xtf9Uz$9%E+ at o1mcM_jXW~b4=TF2uzRXf*@9jI4(3u9qskJ1$ThR})*sQGa
zk;cY^nBhf@$EmUCr_u)J&)JCtg=gGU;+g2PV?Q@@oxdqdZM}V`5#FsRjSLkyOU87L
z36tRicz<06Zy5V(^`$6X-gkJE-#G3eVo8`=ph74;1($W|YgP3rNz4?m6{pT;>(X(c
zKZW+=B8tg}<OnC-Xy|vNdloebHTnit at EUCcD|n6OjV)emPC$*u2HNnREZ$rv)082s
zi4 at Jx$$z3_Ifq*d0kp^Vv;;5qa1a|JkDvz!YJU$XGi|X4l$kb}aQ18uyZ3=rlNtd9
zt+#$_5FlJaaa0|{%6*Sfam5hadwLCR{0|*;DCx)#=)mhn2W|IQc+vMG<^-d?>WOsJ
z?wF5DwFGHVZ;5{eV6!P9un202v<JSzI-4XFWp2pfJ=}&9|B3!R7$^i;Ur3=7lANu}
zqJIaO=|Mvs at oh9083S?@cSmvr*1>bB{ugf+A5Cq+1YkP%iu5=PF_r~Jf^pEX9ilmd
zqjR!s29$n(?koqvkkh_+Jdt&9kemV%zz>2&MdX*2g^(0Bb3fr-G#O-Ux`l`P)LF58
zaj(U8%fMRlqE2MOof#G*F;Vmq(Um!gfIO)F7s+;%><CpLQZt-nZLW`oUEw)(d=K6#
lphmOb4V^>_X*DqD|IoURglkx*bp#P#(dbE{!R6Hut?gN!sVe{g

diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua
index ec3826399..6e8263389 100644
--- a/src/box/lua/upgrade.lua
+++ b/src/box/lua/upgrade.lua
@@ -983,8 +983,31 @@ local function upgrade_priv_to_1_10_2()
     _vpriv.index.object:alter{parts={3, 'string', 4, 'scalar'}}
 end
 
+local function upgrade_users_to_1_10_2()
+    local _priv = box.space[box.schema.PRIV_ID]
+    local _user = box.space[box.schema.USER_ID]
+
+    for _, user in _user:pairs() do
+        if user[0] ~= ADMIN and user[0] ~= SUPER then
+            for _, priv in _priv:pairs(user[0]) do
+                if bit.band(priv[5], box.priv.W) ~= 0 and
+                bit.band(priv[5], box.priv.R) ~= 0 then
+                    local new_privs = bit.bor(box.priv.A, box.priv.D)
+                    -- for universal grants
+                    if priv[3] == 'universe' then
+                        new_privs = bit.bor(new_privs, box.priv.C)
+                    end
+                    _priv:update({priv[2], priv[3], priv[4]},
+                                 {{ "|", 5, new_privs}})
+                end
+            end
+        end
+    end
+end
+
 local function upgrade_to_1_10_2()
     upgrade_priv_to_1_10_2()
+    upgrade_users_to_1_10_2()
 end
 
 local function get_version()
diff --git a/test/box-tap/auth.test.lua b/test/box-tap/auth.test.lua
index 272bd97dc..4e9879408 100755
--- a/test/box-tap/auth.test.lua
+++ b/test/box-tap/auth.test.lua
@@ -20,10 +20,7 @@ test:plan(42)
 local space = box.schema.space.create('tweedledum')
 local index = space:create_index('primary', { type = 'hash' })
 box.schema.user.create('test', {password='pass'})
-box.schema.user.grant('test', 'read,write,execute', 'universe')
 box.schema.user.create('test2', {password=''})
-box.schema.user.grant('test2', 'read,write,execute', 'universe')
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 
 -- check how authentication trigger work
 local msg, counter, succeeded
@@ -163,8 +160,6 @@ test:is(session.sync(), 0, "box.session.sync()")
 
 -- cleanup
 space:drop()
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
-box.schema.user.revoke('test', 'read,write,execute', 'universe')
 box.schema.user.drop('test', { if_exists = true})
 box.schema.user.drop("test2", { if_exists = true})
 
diff --git a/test/box-tap/session.test.lua b/test/box-tap/session.test.lua
index c3c07a67c..857bc643b 100755
--- a/test/box-tap/session.test.lua
+++ b/test/box-tap/session.test.lua
@@ -101,7 +101,8 @@ function audit_disconnect() box.space['tweedledum']:delete{session.id()} end
 test:is(type(session.on_connect(audit_connect)), "function", "type of trigger audit_connect on_connect")
 test:is(type(session.on_disconnect(audit_disconnect)), "function", "type of trigger audit_connect on_disconnect")
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.user.grant('guest', 'read,write', 'space', 'tweedledum')
+box.schema.user.grant('guest', 'execute', 'universe')
 a = net.box.connect(HOST, PORT)
 test:ok(a:eval('return space:get{box.session.id()}[1] == session.id()'), "eval get_id")
 test:ok(a:eval('return session.sync() ~= 0'), "eval sync")
@@ -112,12 +113,12 @@ session.on_connect(nil, audit_connect)
 session.on_disconnect(nil, audit_disconnect)
 test:is(active_connections, 0, "active connections after other triggers")
 
-space:drop()
+space:drop() -- tweedledum
 
 test:is(session.uid(), 1, "uid == 1")
 test:is(session.user(), "admin", "user is admin")
 test:is(session.sync(), 0, "sync constant")
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'universe')
 
 -- audit permission in on_connect/on_disconnect triggers
 box.schema.user.create('tester', { password = 'tester' })
@@ -199,7 +200,10 @@ function f2()
 	sync2 = box.session.sync()
 	cond:signal()
 end
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.func.create('f1')
+box.schema.func.create('f2')
+box.schema.user.grant('guest', 'execute', 'function', 'f1')
+box.schema.user.grant('guest', 'execute', 'function', 'f2')
 conn = net.box.connect(box.cfg.listen)
 test:ok(conn:ping(), 'connect to self')
 _ = fiber.create(function() conn:call('f1') end)
@@ -208,7 +212,8 @@ _ = fiber.create(function() conn:call('f2') end)
 while started ~= 2 do fiber.sleep(0.01) end
 test:isnt(sync1, sync2, 'session.sync() is request local')
 conn:close()
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'function', 'f1')
+box.schema.user.revoke('guest', 'execute', 'function', 'f2')
 
 inspector:cmd('stop server session with cleanup=1')
 session = nil
diff --git a/test/box/access.result b/test/box/access.result
index 4f0607471..2ca8944c6 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -370,7 +370,7 @@ box.schema.user.drop('uniuser')
 box.schema.user.create('grantor')
 ---
 ...
-box.schema.user.grant('grantor', 'read, write, execute', 'universe')
+box.schema.user.grant('grantor', 'read, write, execute, create, alter, drop', 'universe')
 ---
 ...
 session.su('grantor')
@@ -379,7 +379,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, create, alter, drop', 'universe')
 ---
 - error: Grant access to universe '' is denied for user 'grantor'
 ...
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index d3e2aab98..6ebb45c1f 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -167,10 +167,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', 'universe')
+box.schema.user.grant('grantor', 'read, write, execute, create, alter, drop', '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, create, alter, drop', 'universe')
 session.su('grantee')
 -- fails - can't suicide - ask the creator to kill you
 box.schema.user.drop('grantee')
diff --git a/test/box/access_bin.result b/test/box/access_bin.result
index 7b30d11f2..df8ef8dee 100644
--- a/test/box/access_bin.result
+++ b/test/box/access_bin.result
@@ -8,7 +8,7 @@ test_run = env.new()
 -- Access control tests which require a binary protocol
 -- connection to the server
 --
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest','execute','universe')
 ---
 ...
 session = box.session
@@ -30,7 +30,7 @@ c:eval("return session.user()")
 c:close()
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'universe')
 ---
 ...
 -- gh-488 suid functions
diff --git a/test/box/access_bin.test.lua b/test/box/access_bin.test.lua
index 4c7a6d08f..e77d8c0a8 100644
--- a/test/box/access_bin.test.lua
+++ b/test/box/access_bin.test.lua
@@ -4,14 +4,14 @@ test_run = env.new()
 -- Access control tests which require a binary protocol
 -- connection to the server
 --
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest','execute','universe')
 session = box.session
 remote = require('net.box')
 c = remote.connect(box.cfg.listen)
 c:eval("session.su('admin')")
 c:eval("return session.user()")
 c:close()
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'universe')
 
 -- gh-488 suid functions
 --
diff --git a/test/box/access_escalation.result b/test/box/access_escalation.result
index a83f1ee8a..1992ba46d 100644
--- a/test/box/access_escalation.result
+++ b/test/box/access_escalation.result
@@ -84,7 +84,7 @@ box.schema.user.create('underprivileged')
 box.schema.user.grant('underprivileged', 'read,write', 'space', '_func')
 ---
 ...
-box.schema.user.grant('underprivileged', 'create', 'universe')
+box.schema.user.grant('underprivileged', 'create', 'function')
 ---
 ...
 box.session.su('underprivileged')
@@ -99,7 +99,16 @@ box.session.su('admin')
 --
 -- create a deprived function
 --
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.func.create('escalation')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'setuid')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'escalation')
+---
+...
+box.schema.user.grant('guest', 'read', 'space', '_space')
 ---
 ...
 connection = net:connect(os.getenv("LISTEN"))
@@ -119,7 +128,10 @@ fiber.cancel(background)
 box.schema.user.drop('underprivileged')
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.func.drop('escalation')
+---
+...
+box.schema.user.revoke('guest', 'read', 'space', '_space')
 ---
 ...
 connection:close()
diff --git a/test/box/access_escalation.test.lua b/test/box/access_escalation.test.lua
index 29b14c8ea..b333eccf4 100644
--- a/test/box/access_escalation.test.lua
+++ b/test/box/access_escalation.test.lua
@@ -61,7 +61,7 @@ connection:close()
 
 box.schema.user.create('underprivileged')
 box.schema.user.grant('underprivileged', 'read,write', 'space', '_func')
-box.schema.user.grant('underprivileged', 'create', 'universe')
+box.schema.user.grant('underprivileged', 'create', 'function')
 box.session.su('underprivileged')
 box.schema.func.create('setuid', {setuid=true})
 box.session.su('admin')
@@ -69,7 +69,10 @@ box.session.su('admin')
 -- create a deprived function
 --
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.func.create('escalation')
+box.schema.user.grant('guest', 'execute', 'function', 'setuid')
+box.schema.user.grant('guest', 'execute', 'function', 'escalation')
+box.schema.user.grant('guest', 'read', 'space', '_space')
 
 connection = net:connect(os.getenv("LISTEN"))
 
@@ -80,6 +83,6 @@ fiber.cancel(background)
 -- tear down
 
 box.schema.user.drop('underprivileged')
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
-
+box.schema.func.drop('escalation')
+box.schema.user.revoke('guest', 'read', 'space', '_space')
 connection:close()
diff --git a/test/box/access_misc.result b/test/box/access_misc.result
index c1809d69a..af1a82c20 100644
--- a/test/box/access_misc.result
+++ b/test/box/access_misc.result
@@ -208,7 +208,7 @@ s:select()
 box.schema.user.create('uniuser')
 ---
 ...
-box.schema.user.grant('uniuser', 'read, write, execute', 'universe')
+box.schema.user.grant('uniuser', 'read, write, execute, create', 'universe')
 ---
 ...
 session.su('uniuser')
@@ -291,7 +291,7 @@ session.su('admin')
 box.schema.user.create('someuser')
 ---
 ...
-box.schema.user.grant('someuser', 'read, write, execute', 'universe')
+box.schema.user.grant('someuser', 'read, write, execute, create', 'universe')
 ---
 ...
 session.su('someuser')
diff --git a/test/box/access_misc.test.lua b/test/box/access_misc.test.lua
index 35234898d..7783dc131 100644
--- a/test/box/access_misc.test.lua
+++ b/test/box/access_misc.test.lua
@@ -86,7 +86,7 @@ s:select()
 -- and create this user session
 --
 box.schema.user.create('uniuser')
-box.schema.user.grant('uniuser', 'read, write, execute', 'universe')
+box.schema.user.grant('uniuser', 'read, write, execute, create', 'universe')
 session.su('uniuser')
 uid = session.uid()
 --
@@ -123,7 +123,7 @@ box.schema.func.create('uniuser_func')
 
 session.su('admin')
 box.schema.user.create('someuser')
-box.schema.user.grant('someuser', 'read, write, execute', 'universe')
+box.schema.user.grant('someuser', 'read, write, execute, create', 'universe')
 session.su('someuser')
 --
 -- Check drop objects of another user
diff --git a/test/box/call.result b/test/box/call.result
index 40d7ef952..349e5ce40 100644
--- a/test/box/call.result
+++ b/test/box/call.result
@@ -1,4 +1,4 @@
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.user.grant('guest', 'execute', 'universe')
 ---
 ...
 conn = require('net.box').connect(box.cfg.listen)
@@ -748,6 +748,6 @@ conn:close()
 require('msgpack').cfg { encode_sparse_safe = sparse_safe }
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'universe')
 ---
 ...
diff --git a/test/box/call.test.lua b/test/box/call.test.lua
index 0cc3b8fe6..a74aac4d1 100644
--- a/test/box/call.test.lua
+++ b/test/box/call.test.lua
@@ -1,4 +1,4 @@
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.user.grant('guest', 'execute', 'universe')
 
 conn = require('net.box').connect(box.cfg.listen)
 conn:ping()
@@ -240,4 +240,4 @@ conn:call_16("return_sparse4")
 conn:close()
 require('msgpack').cfg { encode_sparse_safe = sparse_safe }
 
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'universe')
diff --git a/test/box/errinj.result b/test/box/errinj.result
index c7e4ce20b..3b7347bc9 100644
--- a/test/box/errinj.result
+++ b/test/box/errinj.result
@@ -786,7 +786,7 @@ test_run:cmd('setopt delimiter ""');
 - true
 ...
 -- Port_dump can fail.
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.user.grant('guest', 'read', 'space', '_space')
 ---
 ...
 cn = net_box.connect(box.cfg.listen)
@@ -818,7 +818,7 @@ errinj.set('ERRINJ_PORT_DUMP', false)
 cn:close()
 ---
 ...
-box.schema.user.revoke('guest', 'read, write, execute', 'universe')
+box.schema.user.revoke('guest', 'read', 'space', '_space')
 ---
 ...
 run()
@@ -1071,15 +1071,15 @@ s:drop()
 -- gh-3255: iproto can crash and discard responses, if a network
 -- is saturated, and DML yields too long on commit.
 --
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 s = box.schema.space.create('test')
 ---
 ...
 _ = s:create_index('pk')
 ---
 ...
+box.schema.user.grant('guest', 'read,write,alter', 'space', 'test')
+---
+...
 c = net_box.connect(box.cfg.listen)
 ---
 ...
@@ -1110,12 +1110,24 @@ s:drop()
 -- gh-3325: do not cancel already sent requests, when a schema
 -- change is detected.
 --
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
 s = box.schema.create_space('test')
 ---
 ...
 pk = s:create_index('pk')
 ---
 ...
+box.schema.user.grant('guest', 'read,write,alter', 'space', 'test')
+---
+...
+box.schema.user.grant('guest', 'create', 'space')
+---
+...
+box.schema.user.grant('guest', 'write', 'space', '_index')
+---
+...
 s:replace{1, 1}
 ---
 - [1, 1]
@@ -1166,6 +1178,12 @@ cn:close()
 s:drop()
 ---
 ...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
+box.schema.user.revoke('guest', 'create', 'space')
+---
+...
 --
 -- If message memory pool is used up, stop the connection, until
 -- the pool has free memory.
@@ -1191,6 +1209,12 @@ function long_poll_f()
 end;
 ---
 ...
+box.schema.func.create('long_poll_f');
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'long_poll_f');
+---
+...
 test_run:cmd('setopt delimiter ""');
 ---
 - true
@@ -1252,7 +1276,10 @@ while finished ~= 2 do fiber.sleep(0.01) end
 cn:close()
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute','universe')
+box.schema.user.revoke('guest', 'execute', 'function', 'long_poll_f')
+---
+...
+box.schema.func.drop('long_poll_f')
 ---
 ...
 --
diff --git a/test/box/errinj.test.lua b/test/box/errinj.test.lua
index a3ea659aa..1c1149e7d 100644
--- a/test/box/errinj.test.lua
+++ b/test/box/errinj.test.lua
@@ -245,7 +245,7 @@ test_run:cmd('setopt delimiter ""');
 
 -- Port_dump can fail.
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.user.grant('guest', 'read', 'space', '_space')
 
 cn = net_box.connect(box.cfg.listen)
 cn:ping()
@@ -255,7 +255,7 @@ assert(not ok)
 assert(string.match(tostring(ret), 'Failed to allocate'))
 errinj.set('ERRINJ_PORT_DUMP', false)
 cn:close()
-box.schema.user.revoke('guest', 'read, write, execute', 'universe')
+box.schema.user.revoke('guest', 'read', 'space', '_space')
 
 run()
 ch:get()
@@ -350,10 +350,9 @@ s:drop()
 -- is saturated, and DML yields too long on commit.
 --
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 s = box.schema.space.create('test')
 _ = s:create_index('pk')
-
+box.schema.user.grant('guest', 'read,write,alter', 'space', 'test')
 c = net_box.connect(box.cfg.listen)
 
 ch = fiber.channel(200)
@@ -369,8 +368,15 @@ s:drop()
 -- gh-3325: do not cancel already sent requests, when a schema
 -- change is detected.
 --
+
+box.schema.user.grant('guest', 'execute', 'universe')
+
 s = box.schema.create_space('test')
 pk = s:create_index('pk')
+
+box.schema.user.grant('guest', 'read,write,alter', 'space', 'test')
+box.schema.user.grant('guest', 'create', 'space')
+box.schema.user.grant('guest', 'write', 'space', '_index')
 s:replace{1, 1}
 cn = net_box.connect(box.cfg.listen)
 errinj.set("ERRINJ_WAL_DELAY", true)
@@ -388,7 +394,8 @@ while ok == nil do fiber.sleep(0.01) end
 ok, err
 cn:close()
 s:drop()
-
+box.schema.user.revoke('guest', 'execute', 'universe')
+box.schema.user.revoke('guest', 'create', 'space')
 --
 -- If message memory pool is used up, stop the connection, until
 -- the pool has free memory.
@@ -403,6 +410,10 @@ function long_poll_f()
     while not continue do fiber.sleep(0.01) end
     finished = finished + 1
 end;
+
+box.schema.func.create('long_poll_f');
+box.schema.user.grant('guest', 'execute', 'function', 'long_poll_f');
+
 test_run:cmd('setopt delimiter ""');
 cn = net_box.connect(box.cfg.listen)
 function long_poll() cn:call('long_poll_f') end
@@ -428,8 +439,8 @@ errinj.set("ERRINJ_TESTING", false)
 while finished ~= 2 do fiber.sleep(0.01) end
 cn:close()
 
-box.schema.user.revoke('guest', 'read,write,execute','universe')
-
+box.schema.user.revoke('guest', 'execute', 'function', 'long_poll_f')
+box.schema.func.drop('long_poll_f')
 --
 -- gh-3289: drop/truncate leaves the space in inconsistent
 -- state if WAL write fails.
diff --git a/test/box/net.box.result b/test/box/net.box.result
index 37ac54658..bd91f63c2 100644
--- a/test/box/net.box.result
+++ b/test/box/net.box.result
@@ -203,6 +203,9 @@ remote.self:eval('!invalid expression')
 ---
 - error: '[string "return !invalid expression"]:1: unexpected symbol near ''!'''
 ...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
 --
 -- gh-822: net.box.call should roll back local transaction on error
 --
@@ -265,10 +268,10 @@ test_run:cmd("setopt delimiter ''");
 box.space.gh822:drop()
 ---
 ...
-box.schema.user.revoke('guest','execute','universe')
+box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space')
 ---
 ...
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest', 'execute', 'universe')
 ---
 ...
 cn:close()
@@ -496,6 +499,15 @@ cn.space.net_box_test_space:get(354)
 - [354, 1, 2, 4]
 ...
 -- reconnects after errors
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
+box.schema.func.create('test_foo')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'test_foo')
+---
+...
 -- -- 1. no reconnect
 x_fatal(cn)
 ---
@@ -593,6 +605,12 @@ type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end))
 function pause() fiber.sleep(10) return true end
 ---
 ...
+box.schema.func.create('pause')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'pause')
+---
+...
 cn:call('pause')
 ---
 - error: Peer closed
@@ -601,6 +619,9 @@ cn:call('test_foo', {'a', 'b', 'c'})
 ---
 - [[{'a': 1}], [{'b': 2}], 'c']
 ...
+box.schema.func.drop('pause')
+---
+...
 -- call
 remote.self:call('test_foo', {'a', 'b', 'c'})
 ---
@@ -612,6 +633,15 @@ cn:call('test_foo', {'a', 'b', 'c'})
 ---
 - [[{'a': 1}], [{'b': 2}], 'c']
 ...
+box.schema.func.drop('test_foo')
+---
+...
+box.schema.func.create('long_rep')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'long_rep')
+---
+...
 -- long replies
 function long_rep() return { 1,  string.rep('a', 5000) } end
 ---
@@ -641,6 +671,9 @@ res[2] == string.rep('a', 50000)
 ---
 - true
 ...
+box.schema.func.drop('long_rep')
+---
+...
 -- a.b.c.d
 u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E'
 ---
@@ -654,6 +687,15 @@ X.X = X
 function X.fn(x,y) return y or x end
 ---
 ...
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
+cn:close()
+---
+...
+cn = remote.connect(LISTEN.host, LISTEN.service)
+---
+...
 cn:call('X.fn', {u})
 ---
 - 84F7BCFA-079C-46CC-98B4-F0C821BE833E
@@ -666,6 +708,12 @@ cn:call('X.X.X.X:fn', {u})
 ---
 - 84F7BCFA-079C-46CC-98B4-F0C821BE833E
 ...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
+cn:close()
+---
+...
 -- auth
 cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true })
 ---
@@ -685,7 +733,10 @@ cn.state
 box.schema.user.create('netbox', { password  = 'test' })
 ---
 ...
-box.schema.user.grant('netbox', 'read, write, execute', 'universe');
+box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space')
+---
+...
+box.schema.user.grant('netbox', 'execute', 'universe')
 ---
 ...
 cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' })
@@ -1119,6 +1170,15 @@ cn:close()
 cn = remote.connect(LISTEN.host, LISTEN.service)
 ---
 ...
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
+cn:close()
+---
+...
+cn = remote.connect(LISTEN.host, LISTEN.service)
+---
+...
 cn:eval('return true')
 ---
 - true
@@ -1142,6 +1202,9 @@ remote.self.eval('return true')
 ---
 - error: 'Use remote:eval(...) instead of remote.eval(...):'
 ...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
 -- uri as the first argument
 uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service)
 ---
@@ -1186,13 +1249,16 @@ cn:ping()
 cn:close()
 ---
 ...
-box.schema.user.revoke('netbox', 'read, write, execute', 'universe');
----
-...
 box.schema.user.drop('netbox')
 ---
 ...
 -- #594: bad argument #1 to 'setmetatable' (table expected, got number)
+box.schema.func.create('dostring')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'dostring')
+---
+...
 test_run:cmd("setopt delimiter ';'")
 ---
 - true
@@ -1212,6 +1278,9 @@ test_run:cmd("setopt delimiter ''");
 gh594()
 ---
 ...
+box.schema.func.drop('dostring')
+---
+...
 -- #636: Reload schema on demand
 sp = box.schema.space.create('test_old')
 ---
@@ -1223,6 +1292,9 @@ sp:insert{1, 2, 3}
 ---
 - [1, 2, 3]
 ...
+box.schema.user.grant('guest', 'read', 'space', 'test_old')
+---
+...
 con = remote.new(box.cfg.listen)
 ---
 ...
@@ -1248,6 +1320,9 @@ sp:insert{2, 3, 4}
 ---
 - [2, 3, 4]
 ...
+box.schema.user.grant('guest', 'read', 'space', 'test')
+---
+...
 con.space.test == nil
 ---
 - true
@@ -1278,6 +1353,9 @@ file_log:seek(0, 'SEEK_END') ~= 0
 ---
 - true
 ...
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
 test_run:cmd("setopt delimiter ';'")
 ---
 - true
@@ -1299,6 +1377,9 @@ test_run:grep_log("default", "ER_NO_SUCH_PROC")
 ---
 - ER_NO_SUCH_PROC
 ...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
 -- gh-983 selecting a lot of data crashes the server or hangs the
 -- connection
 -- gh-983 test case: iproto connection selecting a lot of data
@@ -1314,6 +1395,9 @@ data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabb
 for i = 0,10000 do box.space.test:insert{i, data1k} end
 ---
 ...
+box.schema.user.grant('guest', 'read', 'space', 'test')
+---
+...
 net = require('net.box')
 ---
 ...
@@ -1339,6 +1423,9 @@ _ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned
 _ = box.space.test:insert{1, 2, "string"}
 ---
 ...
+box.schema.user.grant('guest', 'read,write', 'space', 'test')
+---
+...
 c = net:connect(box.cfg.listen)
 ---
 ...
@@ -1395,6 +1482,9 @@ box.space.test:drop()
 function echo(...) return ... end
 ---
 ...
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
 c = net.connect(box.cfg.listen)
 ---
 ...
@@ -1434,6 +1524,9 @@ c:eval('return echo(...)', 42)
 c:close()
 ---
 ...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
 --
 -- gh-2195 export pure msgpack from net.box
 --
@@ -1443,6 +1536,12 @@ space = box.schema.space.create('test')
 _ = box.space.test:create_index('primary')
 ---
 ...
+box.schema.user.grant('guest', 'read,write', 'space', 'test')
+---
+...
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
 c = net.connect(box.cfg.listen)
 ---
 ...
@@ -1678,6 +1777,9 @@ c:close()
 space:drop()
 ---
 ...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
 -- gh-1904 net.box hangs in :close() if a fiber was cancelled
 -- while blocked in :_wait_state() in :_request()
 options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01}
@@ -1695,6 +1797,9 @@ fiber.sleep(0.01)
 f:cancel(); c:close()
 ---
 ...
+box.schema.user.grant('guest', 'read', 'space', '_schema')
+---
+...
 -- check for on_schema_reload callback
 test_run:cmd("setopt delimiter ';'")
 ---
@@ -1747,7 +1852,7 @@ test_run:cmd("setopt delimiter ''");
 ---
 - true
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'read', 'space', '_schema')
 ---
 ...
 -- Tarantool < 1.7.1 compatibility (gh-1533)
@@ -1836,7 +1941,7 @@ space ~= nil
 _ = box.space.test:create_index('primary')
 ---
 ...
-box.schema.user.grant('guest','read,write,execute','space', 'test')
+box.schema.user.grant('guest', 'read', 'space', 'test')
 ---
 ...
 c = net.connect(box.cfg.listen)
@@ -1915,7 +2020,7 @@ c:close()
 --
 -- gh-2642: box.session.type()
 --
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest','execute','universe')
 ---
 ...
 c = net.connect(box.cfg.listen)
@@ -1928,6 +2033,9 @@ c:call("box.session.type")
 c:close()
 ---
 ...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
 --
 -- On_connect/disconnect triggers.
 --
@@ -2007,6 +2115,9 @@ space:drop()
 space = box.schema.space.create('test')
 ---
 ...
+box.schema.user.grant('guest', 'read', 'space', 'test')
+---
+...
 c = net.connect(box.cfg.listen)
 ---
 ...
@@ -2040,16 +2151,28 @@ c.space.test.index.test_index ~= nil
 - true
 ...
 -- cleanup
-box.schema.user.revoke('guest','read,write,execute','universe')
----
-...
 space:drop()
 ---
 ...
 --
 -- gh-946: long polling CALL blocks input
 --
-box.schema.user.grant('guest', 'execute', 'universe')
+box.schema.func.create('fast_call')
+---
+...
+box.schema.func.create('long_call')
+---
+...
+box.schema.func.create('wait_signal')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'fast_call')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'long_call')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'wait_signal')
 ---
 ...
 c = net.connect(box.cfg.listen)
@@ -2166,6 +2289,15 @@ disconnected -- true
 box.session.on_disconnect(nil, on_disconnect)
 ---
 ...
+box.schema.func.drop('long_call')
+---
+...
+box.schema.func.drop('fast_call')
+---
+...
+box.schema.func.drop('wait_signal')
+---
+...
 --
 -- gh-2666: check that netbox.call is not repeated on schema
 -- change.
@@ -2185,6 +2317,12 @@ count = 0
 function create_space(name) count = count + 1 box.schema.create_space(name) return true end
 ---
 ...
+box.schema.func.create('create_space')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'create_space')
+---
+...
 c = net.connect(box.cfg.listen)
 ---
 ...
@@ -2233,6 +2371,9 @@ box.schema.user.revoke('guest', 'create', 'universe')
 c:close()
 ---
 ...
+box.schema.func.drop('create_space')
+---
+...
 --
 -- gh-3164: netbox connection is not closed and garbage collected
 -- ever, if reconnect_after is set.
@@ -2343,7 +2484,7 @@ weak.c
 -- binary or text protocol, and netbox could not be created from
 -- existing socket.
 --
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest', 'execute', 'universe')
 ---
 ...
 urilib = require('uri')
@@ -2382,6 +2523,9 @@ c:call('kek', {300})
 s = box.schema.create_space('test')
 ---
 ...
+box.schema.user.grant('guest', 'read,write', 'space', 'test')
+---
+...
 pk = s:create_index('pk')
 ---
 ...
@@ -2436,7 +2580,7 @@ while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end
 c:close()
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'universe')
 ---
 ...
 c.state
@@ -2452,7 +2596,7 @@ c = nil
 space = box.schema.create_space('test')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.user.grant('guest', 'read', 'space', 'test')
 ---
 ...
 _ = space:create_index('pk')
@@ -2476,6 +2620,15 @@ space:drop()
 space = box.schema.create_space('test')
 ---
 ...
+c:close()
+---
+...
+box.schema.user.grant('guest', 'read', 'space', 'test')
+---
+...
+c = net:connect(box.cfg.listen)
+---
+...
 box.internal.collation.create('test', 'ICU', 'ru-RU')
 ---
 ...
@@ -2514,6 +2667,12 @@ c = nil
 cond = nil
 ---
 ...
+box.schema.func.create('long_function')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'long_function')
+---
+...
 function long_function(...) cond = fiber.cond() cond:wait() return ... end
 ---
 ...
@@ -2621,6 +2780,15 @@ ret
 ---
 - [1, 2, 3]
 ...
+c:close()
+---
+...
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
+c = net:connect(box.cfg.listen)
+---
+...
 future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true})
 ---
 ...
@@ -2641,6 +2809,15 @@ future:wait_result(100)
 ---
 - [1, 2, 3]
 ...
+c:close()
+---
+...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
+c = net:connect(box.cfg.listen)
+---
+...
 --
 -- Ensure the request is garbage collected both if is not used and
 -- if is.
@@ -2748,6 +2925,15 @@ ret
 --
 -- Test space methods.
 --
+c:close()
+---
+...
+box.schema.user.grant('guest', 'read,write', 'space', 'test')
+---
+...
+c = net:connect(box.cfg.listen)
+---
+...
 future = c.space.test:select({1}, {is_async = true})
 ---
 ...
@@ -2854,6 +3040,15 @@ future:wait_result(100)
 ---
 - [5, 6]
 ...
+c:close()
+---
+...
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
+c = net:connect(box.cfg.listen)
+---
+...
 future = c.space.test.index.pk:count({3}, {is_async = true})
 ---
 ...
@@ -2861,6 +3056,15 @@ future:wait_result(100)
 ---
 - 1
 ...
+c:close()
+---
+...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
+c = net:connect(box.cfg.listen)
+---
+...
 future = c.space.test.index.pk:delete({3}, {is_async = true})
 ---
 ...
@@ -3029,12 +3233,30 @@ result
 ---
 - {48: [1, 2, 3]}
 ...
+box.schema.func.drop('long_function')
+---
+...
 --
 -- Test async schema version change.
 --
 function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end
 ---
 ...
+box.schema.func.create('change_schema')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'change_schema')
+---
+...
+box.schema.user.grant('guest', 'write', 'space', '_schema')
+---
+...
+box.schema.user.grant('guest', 'read,write', 'space', '_space')
+---
+...
+box.schema.user.grant('guest', 'create', 'space')
+---
+...
 future1 = c:call('change_schema', {'1'}, {is_async = true})
 ---
 ...
@@ -3071,6 +3293,9 @@ box.space.test2:drop()
 box.space.test3:drop()
 ---
 ...
+box.schema.func.drop('change_schema')
+---
+...
 --
 -- gh-3400: long-poll input discard must not touch event loop of
 -- a closed connection.
@@ -3122,6 +3347,12 @@ test_run:grep_log('default', 'too big packet size in the header') ~= nil
 ---
 - true
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'write', 'space', '_schema')
+---
+...
+box.schema.user.revoke('guest', 'read,write', 'space', '_space')
+---
+...
+box.schema.user.revoke('guest', 'create', 'space')
 ---
 ...
diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua
index 56b656cc5..08fe60fd5 100644
--- a/test/box/net.box.test.lua
+++ b/test/box/net.box.test.lua
@@ -31,7 +31,6 @@ log.info("ping is done")
 
 cn:ping()
 
-
 -- check permissions
 cn:call('unexists_procedure')
 function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end
@@ -73,6 +72,8 @@ remote.self:eval('error("exception")')
 remote.self:eval('box.error(0)')
 remote.self:eval('!invalid expression')
 
+box.schema.user.revoke('guest', 'execute', 'universe')
+
 --
 -- gh-822: net.box.call should roll back local transaction on error
 --
@@ -113,8 +114,9 @@ rollback_on_eval_error();
 test_run:cmd("setopt delimiter ''");
 box.space.gh822:drop()
 
-box.schema.user.revoke('guest','execute','universe')
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space')
+box.schema.user.grant('guest', 'execute', 'universe')
+
 cn:close()
 cn = remote.connect(box.cfg.listen)
 
@@ -189,6 +191,10 @@ cn.space.net_box_test_space:get(354)
 
 -- reconnects after errors
 
+box.schema.user.revoke('guest', 'execute', 'universe')
+box.schema.func.create('test_foo')
+box.schema.user.grant('guest', 'execute', 'function', 'test_foo')
+
 -- -- 1. no reconnect
 x_fatal(cn)
 cn.state
@@ -224,13 +230,19 @@ cn1:close()
 type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end))
 function pause() fiber.sleep(10) return true end
 
+box.schema.func.create('pause')
+box.schema.user.grant('guest', 'execute', 'function', 'pause')
 cn:call('pause')
 cn:call('test_foo', {'a', 'b', 'c'})
-
+box.schema.func.drop('pause')
 
 -- call
 remote.self:call('test_foo', {'a', 'b', 'c'})
 cn:call('test_foo', {'a', 'b', 'c'})
+box.schema.func.drop('test_foo')
+
+box.schema.func.create('long_rep')
+box.schema.user.grant('guest', 'execute', 'function', 'long_rep')
 
 -- long replies
 function long_rep() return { 1,  string.rep('a', 5000) } end
@@ -243,14 +255,21 @@ res = cn:call('long_rep')
 res[1] == 1
 res[2] == string.rep('a', 50000)
 
+box.schema.func.drop('long_rep')
+
 -- a.b.c.d
 u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E'
 X = {}
 X.X = X
 function X.fn(x,y) return y or x end
+box.schema.user.grant('guest', 'execute', 'universe')
+cn:close()
+cn = remote.connect(LISTEN.host, LISTEN.service)
 cn:call('X.fn', {u})
 cn:call('X.X.X.X.X.X.X.fn', {u})
 cn:call('X.X.X.X:fn', {u})
+box.schema.user.revoke('guest', 'execute', 'universe')
+cn:close()
 
 -- auth
 
@@ -259,9 +278,10 @@ cn:is_connected()
 cn.error
 cn.state
 
-box.schema.user.create('netbox', { password  = 'test' })
-box.schema.user.grant('netbox', 'read, write, execute', 'universe');
 
+box.schema.user.create('netbox', { password  = 'test' })
+box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space')
+box.schema.user.grant('netbox', 'execute', 'universe')
 cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' })
 cn.state
 cn.error
@@ -427,6 +447,9 @@ cn:close()
 -- #544 usage for remote[point]method
 cn = remote.connect(LISTEN.host, LISTEN.service)
 
+box.schema.user.grant('guest', 'execute', 'universe')
+cn:close()
+cn = remote.connect(LISTEN.host, LISTEN.service)
 cn:eval('return true')
 cn.eval('return true')
 
@@ -436,7 +459,7 @@ cn:close()
 
 remote.self:eval('return true')
 remote.self.eval('return true')
-
+box.schema.user.revoke('guest', 'execute', 'universe')
 
 -- uri as the first argument
 uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service)
@@ -455,10 +478,11 @@ cn = remote.new(uri, { user = 'netbox', password = 'test' })
 cn:ping()
 cn:close()
 
-box.schema.user.revoke('netbox', 'read, write, execute', 'universe');
 box.schema.user.drop('netbox')
 
 -- #594: bad argument #1 to 'setmetatable' (table expected, got number)
+box.schema.func.create('dostring')
+box.schema.user.grant('guest', 'execute', 'function', 'dostring')
 test_run:cmd("setopt delimiter ';'")
 function gh594()
     local cn = remote.connect(box.cfg.listen)
@@ -468,12 +492,15 @@ function gh594()
 end;
 test_run:cmd("setopt delimiter ''");
 gh594()
+box.schema.func.drop('dostring')
+
 
 -- #636: Reload schema on demand
 sp = box.schema.space.create('test_old')
 _ = sp:create_index('primary')
 sp:insert{1, 2, 3}
 
+box.schema.user.grant('guest', 'read', 'space', 'test_old')
 con = remote.new(box.cfg.listen)
 con:ping()
 con.space.test_old:select{}
@@ -483,6 +510,8 @@ sp = box.schema.space.create('test')
 _ = sp:create_index('primary')
 sp:insert{2, 3, 4}
 
+box.schema.user.grant('guest', 'read', 'space', 'test')
+
 con.space.test == nil
 con:reload_schema()
 con.space.test:select{}
@@ -495,6 +524,7 @@ name = string.match(arg[0], "([^,]+)%.lua")
 file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'})
 file_log:seek(0, 'SEEK_END') ~= 0
 
+box.schema.user.grant('guest', 'execute', 'universe')
 test_run:cmd("setopt delimiter ';'")
 
 _ = fiber.create(
@@ -506,6 +536,7 @@ _ = fiber.create(
 );
 test_run:cmd("setopt delimiter ''");
 test_run:grep_log("default", "ER_NO_SUCH_PROC")
+box.schema.user.revoke('guest', 'execute', 'universe')
 
 -- gh-983 selecting a lot of data crashes the server or hangs the
 -- connection
@@ -518,6 +549,7 @@ data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabb
 
 for i = 0,10000 do box.space.test:insert{i, data1k} end
 
+box.schema.user.grant('guest', 'read', 'space', 'test')
 net = require('net.box')
 c = net:connect(box.cfg.listen)
 r = c.space.test:select(nil, {limit=5000})
@@ -528,6 +560,7 @@ _ = box.schema.space.create('test')
 _ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}})
 _ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}})
 _ = box.space.test:insert{1, 2, "string"}
+box.schema.user.grant('guest', 'read,write', 'space', 'test')
 c = net:connect(box.cfg.listen)
 c.space.test:select{}
 c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update
@@ -545,6 +578,7 @@ box.space.test:drop()
 
 -- CALL vs CALL_16 in connect options
 function echo(...) return ... end
+box.schema.user.grant('guest', 'execute', 'universe')
 c = net.connect(box.cfg.listen)
 c:call('echo', {42})
 c:eval('return echo(...)', {42})
@@ -556,6 +590,7 @@ c = net.connect(box.cfg.listen, {call_16 = true})
 c:call('echo', 42)
 c:eval('return echo(...)', 42)
 c:close()
+box.schema.user.revoke('guest', 'execute', 'universe')
 
 --
 -- gh-2195 export pure msgpack from net.box
@@ -563,6 +598,8 @@ c:close()
 
 space = box.schema.space.create('test')
 _ = box.space.test:create_index('primary')
+box.schema.user.grant('guest', 'read,write', 'space', 'test')
+box.schema.user.grant('guest', 'execute', 'universe')
 c = net.connect(box.cfg.listen)
 ibuf = require('buffer').ibuf()
 
@@ -649,6 +686,7 @@ ibuf.rpos == rpos, ibuf.wpos == wpos
 ibuf = nil
 c:close()
 space:drop()
+box.schema.user.revoke('guest', 'execute', 'universe')
 
 -- gh-1904 net.box hangs in :close() if a fiber was cancelled
 -- while blocked in :_wait_state() in :_request()
@@ -658,6 +696,8 @@ f = fiber.create(function() c:call("") end)
 fiber.sleep(0.01)
 f:cancel(); c:close()
 
+box.schema.user.grant('guest', 'read', 'space', '_schema')
+
 -- check for on_schema_reload callback
 test_run:cmd("setopt delimiter ';'")
 do
@@ -699,7 +739,7 @@ do
 end;
 test_run:cmd("setopt delimiter ''");
 
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'read', 'space', '_schema')
 
 -- Tarantool < 1.7.1 compatibility (gh-1533)
 c = net.new(box.cfg.listen)
@@ -745,7 +785,7 @@ test_run:cmd("clear filter")
 space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}})
 space ~= nil
 _ = box.space.test:create_index('primary')
-box.schema.user.grant('guest','read,write,execute','space', 'test')
+box.schema.user.grant('guest', 'read', 'space', 'test')
 
 c = net.connect(box.cfg.listen)
 
@@ -785,10 +825,12 @@ c:close()
 -- gh-2642: box.session.type()
 --
 
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest','execute','universe')
 c = net.connect(box.cfg.listen)
 c:call("box.session.type")
 c:close()
+box.schema.user.revoke('guest', 'execute', 'universe')
+
 
 --
 -- On_connect/disconnect triggers.
@@ -818,6 +860,7 @@ test_run:cmd('stop server connecter')
 --
 space:drop()
 space = box.schema.space.create('test')
+box.schema.user.grant('guest', 'read', 'space', 'test')
 c = net.connect(box.cfg.listen)
 cspace = c.space.test
 space.index.test_index == nil
@@ -829,15 +872,18 @@ cspace.index.test_index ~= nil
 c.space.test.index.test_index ~= nil
 
 -- cleanup
-box.schema.user.revoke('guest','read,write,execute','universe')
 
 space:drop()
 
 --
 -- gh-946: long polling CALL blocks input
 --
-box.schema.user.grant('guest', 'execute', 'universe')
-
+box.schema.func.create('fast_call')
+box.schema.func.create('long_call')
+box.schema.func.create('wait_signal')
+box.schema.user.grant('guest', 'execute', 'function', 'fast_call')
+box.schema.user.grant('guest', 'execute', 'function', 'long_call')
+box.schema.user.grant('guest', 'execute', 'function', 'wait_signal')
 c = net.connect(box.cfg.listen)
 
 N = 100
@@ -894,6 +940,9 @@ disconnected -- true
 
 box.session.on_disconnect(nil, on_disconnect)
 
+box.schema.func.drop('long_call')
+box.schema.func.drop('fast_call')
+box.schema.func.drop('wait_signal')
 --
 -- gh-2666: check that netbox.call is not repeated on schema
 -- change.
@@ -903,6 +952,8 @@ box.schema.user.grant('guest', 'write', 'space', '_schema')
 box.schema.user.grant('guest', 'create', 'universe')
 count = 0
 function create_space(name) count = count + 1 box.schema.create_space(name) return true end
+box.schema.func.create('create_space')
+box.schema.user.grant('guest', 'execute', 'function', 'create_space')
 c = net.connect(box.cfg.listen)
 c:call('create_space', {'test1'})
 count
@@ -917,6 +968,7 @@ box.schema.user.revoke('guest', 'write', 'space', '_space')
 box.schema.user.revoke('guest', 'write', 'space', '_schema')
 box.schema.user.revoke('guest', 'create', 'universe')
 c:close()
+box.schema.func.drop('create_space')
 
 --
 -- gh-3164: netbox connection is not closed and garbage collected
@@ -971,7 +1023,7 @@ weak.c
 -- binary or text protocol, and netbox could not be created from
 -- existing socket.
 --
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest', 'execute', 'universe')
 urilib = require('uri')
 uri = urilib.parse(tostring(box.cfg.listen))
 s, greeting = net.establish_connection(uri.host, uri.service)
@@ -984,6 +1036,7 @@ c:eval('a = 200')
 a
 c:call('kek', {300})
 s = box.schema.create_space('test')
+box.schema.user.grant('guest', 'read,write', 'space', 'test')
 pk = s:create_index('pk')
 c:reload_schema()
 c.space.test:replace{1}
@@ -1008,7 +1061,7 @@ c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = fals
 while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end
 c:close()
 
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'universe')
 c.state
 c = nil
 
@@ -1016,7 +1069,7 @@ c = nil
 -- gh-3256 net.box is_nullable and collation options output
 --
 space = box.schema.create_space('test')
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.user.grant('guest', 'read', 'space', 'test')
 _ = space:create_index('pk')
 _ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}})
 c = net:connect(box.cfg.listen)
@@ -1024,6 +1077,9 @@ c.space.test.index.sk.parts
 space:drop()
 
 space = box.schema.create_space('test')
+c:close()
+box.schema.user.grant('guest', 'read', 'space', 'test')
+c = net:connect(box.cfg.listen)
 box.internal.collation.create('test', 'ICU', 'ru-RU')
 _ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true })
 c:reload_schema()
@@ -1038,6 +1094,8 @@ c = nil
 -- gh-3107: fiber-async netbox.
 --
 cond = nil
+box.schema.func.create('long_function')
+box.schema.user.grant('guest', 'execute', 'function', 'long_function')
 function long_function(...) cond = fiber.cond() cond:wait() return ... end
 function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end
 s = box.schema.create_space('test')
@@ -1075,13 +1133,19 @@ _ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async =
 finalize_long()
 while not ret do fiber.sleep(0.01) end
 ret
-
+c:close()
+box.schema.user.grant('guest', 'execute', 'universe')
+c = net:connect(box.cfg.listen)
 future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true})
 future:result()
 future:wait_result(0.01) -- Must fail on timeout.
 finalize_long()
 future:wait_result(100)
 
+c:close()
+box.schema.user.revoke('guest', 'execute', 'universe')
+c = net:connect(box.cfg.listen)
+
 --
 -- Ensure the request is garbage collected both if is not used and
 -- if is.
@@ -1120,6 +1184,9 @@ ret
 --
 -- Test space methods.
 --
+c:close()
+box.schema.user.grant('guest', 'read,write', 'space', 'test')
+c = net:connect(box.cfg.listen)
 future = c.space.test:select({1}, {is_async = true})
 ret = future:wait_result(100)
 ret
@@ -1153,8 +1220,14 @@ future = c.space.test.index.pk:min({}, {is_async = true})
 future:wait_result(100)
 future = c.space.test.index.pk:max({}, {is_async = true})
 future:wait_result(100)
+c:close()
+box.schema.user.grant('guest', 'execute', 'universe')
+c = net:connect(box.cfg.listen)
 future = c.space.test.index.pk:count({3}, {is_async = true})
 future:wait_result(100)
+c:close()
+box.schema.user.revoke('guest', 'execute', 'universe')
+c = net:connect(box.cfg.listen)
 future = c.space.test.index.pk:delete({3}, {is_async = true})
 future:wait_result(100)
 s:get{3}
@@ -1219,10 +1292,17 @@ future:wait_result(100)
 result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos)
 result
 
+box.schema.func.drop('long_function')
+
 --
 -- Test async schema version change.
 --
 function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end
+box.schema.func.create('change_schema')
+box.schema.user.grant('guest', 'execute', 'function', 'change_schema')
+box.schema.user.grant('guest', 'write', 'space', '_schema')
+box.schema.user.grant('guest', 'read,write', 'space', '_space')
+box.schema.user.grant('guest', 'create', 'space')
 future1 = c:call('change_schema', {'1'}, {is_async = true})
 future2 = c:call('change_schema', {'2'}, {is_async = true})
 future3 = c:call('change_schema', {'3'}, {is_async = true})
@@ -1235,6 +1315,7 @@ s:drop()
 box.space.test1:drop()
 box.space.test2:drop()
 box.space.test3:drop()
+box.schema.func.drop('change_schema')
 
 --
 -- gh-3400: long-poll input discard must not touch event loop of
@@ -1263,4 +1344,6 @@ c._transport.perform_request(nil, nil, 'inject', nil, nil, data)
 c:close()
 test_run:grep_log('default', 'too big packet size in the header') ~= nil
 
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'write', 'space', '_schema')
+box.schema.user.revoke('guest', 'read,write', 'space', '_space')
+box.schema.user.revoke('guest', 'create', 'space')
diff --git a/test/box/net_msg_max.result b/test/box/net_msg_max.result
index ccda2014e..85872b65f 100644
--- a/test/box/net_msg_max.result
+++ b/test/box/net_msg_max.result
@@ -7,7 +7,13 @@ fiber = require('fiber')
 net_box = require('net.box')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.user.grant('guest', 'read', 'space', '_space')
+---
+...
+box.schema.func.create('do_long_f')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'do_long_f')
 ---
 ...
 conn = net_box.connect(box.cfg.listen)
@@ -252,7 +258,10 @@ conn2:close()
 conn:close()
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.func.drop('do_long_f')
+---
+...
+box.schema.user.revoke('guest', 'read', 'space', '_space')
 ---
 ...
 box.cfg{readahead = old_readahead, net_msg_max = limit}
diff --git a/test/box/net_msg_max.test.lua b/test/box/net_msg_max.test.lua
index 13f7050ed..c793b0f1c 100644
--- a/test/box/net_msg_max.test.lua
+++ b/test/box/net_msg_max.test.lua
@@ -3,7 +3,10 @@ test_run = require('test_run').new()
 fiber = require('fiber')
 net_box = require('net.box')
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.user.grant('guest', 'read', 'space', '_space')
+box.schema.func.create('do_long_f')
+box.schema.user.grant('guest', 'execute', 'function', 'do_long_f')
+
 conn = net_box.connect(box.cfg.listen)
 conn2 = net_box.connect(box.cfg.listen)
 active = 0
@@ -79,6 +82,7 @@ wait_finished(run_max)
 --
 -- Test minimal iproto msg count.
 --
+
 box.cfg{net_msg_max = 2}
 conn:ping()
 #conn.space._space:select{} > 0
@@ -136,5 +140,6 @@ wait_finished(110)
 conn2:close()
 conn:close()
 
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.func.drop('do_long_f')
+box.schema.user.revoke('guest', 'read', 'space', '_space')
 box.cfg{readahead = old_readahead, net_msg_max = limit}
diff --git a/test/box/on_replace.result b/test/box/on_replace.result
index f2de06f90..ac5a540c2 100644
--- a/test/box/on_replace.result
+++ b/test/box/on_replace.result
@@ -540,7 +540,7 @@ s:select()
 ---
 - []
 ...
-s:drop()
+s:drop() -- test_on_repl_ddl
 ---
 ...
 --
diff --git a/test/box/on_replace.test.lua b/test/box/on_replace.test.lua
index 802aaaf2a..8a9fd3678 100644
--- a/test/box/on_replace.test.lua
+++ b/test/box/on_replace.test.lua
@@ -202,7 +202,7 @@ s:replace({8, 9})
 t = s:on_replace(function () s.index.pk:rename('newname') end, t)
 s:replace({9, 10})
 s:select()
-s:drop()
+s:drop() -- test_on_repl_ddl
 
 --
 -- gh-3020: sub-statement rollback
diff --git a/test/box/protocol.result b/test/box/protocol.result
index 3e43663b1..e03186cc9 100644
--- a/test/box/protocol.result
+++ b/test/box/protocol.result
@@ -1,6 +1,3 @@
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 --------------------------------------------------------------------------------
 -- Test case for #273: IPROTO_ITERATOR ignored in network protocol
 --------------------------------------------------------------------------------
@@ -10,6 +7,9 @@ space = box.schema.space.create('tweedledum')
 index = space:create_index('primary', { type = 'tree'})
 ---
 ...
+box.schema.user.grant('guest', 'read', 'space', 'tweedledum')
+---
+...
 for i=1,5 do space:insert{i} end
 ---
 ...
@@ -51,6 +51,3 @@ conn:close()
 space:drop()
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
diff --git a/test/box/protocol.test.lua b/test/box/protocol.test.lua
index 5026d585e..805a43721 100644
--- a/test/box/protocol.test.lua
+++ b/test/box/protocol.test.lua
@@ -1,4 +1,3 @@
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 
 --------------------------------------------------------------------------------
 -- Test case for #273: IPROTO_ITERATOR ignored in network protocol
@@ -6,6 +5,9 @@ box.schema.user.grant('guest', 'read,write,execute', 'universe')
 
 space = box.schema.space.create('tweedledum')
 index = space:create_index('primary', { type = 'tree'})
+
+box.schema.user.grant('guest', 'read', 'space', 'tweedledum')
+
 for i=1,5 do space:insert{i} end
 
 LISTEN = require('uri').parse(box.cfg.listen)
@@ -18,4 +20,3 @@ conn.space[space.id]:select(3, { iterator = 'LT' })
 conn:close()
 
 space:drop()
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
diff --git a/test/box/push.result b/test/box/push.result
index 4ec7c546c..af730c1a7 100644
--- a/test/box/push.result
+++ b/test/box/push.result
@@ -42,7 +42,10 @@ test_run:cmd("setopt delimiter ''");
 netbox = require('net.box')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+box.schema.func.create('do_pushes')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'do_pushes')
 ---
 ...
 c = netbox.connect(box.cfg.listen)
@@ -78,6 +81,9 @@ finished = 0
 s = box.schema.create_space('test', {format = {{'field1', 'integer'}}})
 ---
 ...
+box.schema.user.grant('guest', 'write', 'space', 'test')
+---
+...
 pk = s:create_index('pk')
 ---
 ...
@@ -133,6 +139,12 @@ function dml_push_and_dml_f()
 end;
 ---
 ...
+box.schema.func.create('dml_push_and_dml');
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'dml_push_and_dml');
+---
+...
 -- At first check that a pushed message can be ignored in a binary
 -- protocol too.
 c:call('do_pushes', {300});
@@ -149,6 +161,8 @@ end;
 while finished ~= 400 do fiber.sleep(0.1) end;
 ---
 ...
+box.schema.func.drop('dml_push_and_dml')
+
 failed_catchers = {};
 ---
 ...
@@ -196,6 +210,12 @@ function push_null() box.session.push(box.NULL) end
 messages = {}
 ---
 ...
+box.schema.func.create('push_null')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'push_null')
+---
+...
 c:call('push_null', {}, {on_push = table.insert, on_push_ctx = messages})
 ---
 ...
@@ -203,6 +223,9 @@ messages
 ---
 - - null
 ...
+box.schema.func.drop('push_null')
+---
+...
 --
 -- Test binary pushes.
 --
@@ -272,6 +295,12 @@ t = setmetatable({100}, {__serialize = function() error('err in ser') end})
 function do_push() ok, err = box.session.push(t) end
 ---
 ...
+box.schema.func.create('do_push')
+---
+...
+box.schema.user.grant("guest", "execute", "function", "do_push")
+---
+...
 c:call('do_push', {}, {on_push = table.insert, on_push_ctx = messages})
 ---
 ...
@@ -284,6 +313,9 @@ messages
 ---
 - []
 ...
+box.schema.func.drop('do_push')
+---
+...
 --
 -- Test push from a non-call request.
 --
@@ -417,9 +449,18 @@ s:replace{1}
 ---
 - [1]
 ...
+box.schema.user.grant('guest', 'write', 'space', 'test')
+---
+...
 function do_push_and_duplicate() box.session.push(100) s:insert{1} end
 ---
 ...
+box.schema.func.create('do_push_and_duplicate')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'do_push_and_duplicate')
+---
+...
 future = c:call('do_push_and_duplicate', {}, {is_async = true})
 ---
 ...
@@ -447,12 +488,15 @@ keys
 - - 1
   - null
 ...
-s:drop()
+box.schema.func.drop('do_push_and_duplicate')
 ---
 ...
-c:close()
+box.schema.func.drop('do_pushes')
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+s:drop()
+---
+...
+c:close()
 ---
 ...
diff --git a/test/box/push.test.lua b/test/box/push.test.lua
index 36dc9eeb1..0d2bec3fe 100644
--- a/test/box/push.test.lua
+++ b/test/box/push.test.lua
@@ -23,7 +23,9 @@ end;
 test_run:cmd("setopt delimiter ''");
 
 netbox = require('net.box')
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
+
+box.schema.func.create('do_pushes')
+box.schema.user.grant('guest', 'execute', 'function', 'do_pushes')
 
 c = netbox.connect(box.cfg.listen)
 c:ping()
@@ -37,6 +39,7 @@ catchers = {}
 started = 0
 finished = 0
 s = box.schema.create_space('test', {format = {{'field1', 'integer'}}})
+box.schema.user.grant('guest', 'write', 'space', 'test')
 pk = s:create_index('pk')
 c:reload_schema()
 test_run:cmd("setopt delimiter ';'")
@@ -77,6 +80,9 @@ function dml_push_and_dml_f()
     table.insert(catchers, catcher)
     finished = finished + 1
 end;
+box.schema.func.create('dml_push_and_dml');
+box.schema.user.grant('guest', 'execute', 'function', 'dml_push_and_dml');
+
 -- At first check that a pushed message can be ignored in a binary
 -- protocol too.
 c:call('do_pushes', {300});
@@ -87,6 +93,8 @@ for i = 1, 200 do
 end;
 while finished ~= 400 do fiber.sleep(0.1) end;
 
+box.schema.func.drop('dml_push_and_dml')
+
 failed_catchers = {};
 
 for _, c in pairs(catchers) do
@@ -121,9 +129,11 @@ failed_catchers
 --
 function push_null() box.session.push(box.NULL) end
 messages = {}
+box.schema.func.create('push_null')
+box.schema.user.grant('guest', 'execute', 'function', 'push_null')
 c:call('push_null', {}, {on_push = table.insert, on_push_ctx = messages})
 messages
-
+box.schema.func.drop('push_null')
 --
 -- Test binary pushes.
 --
@@ -148,10 +158,12 @@ err = nil
 messages = {}
 t = setmetatable({100}, {__serialize = function() error('err in ser') end})
 function do_push() ok, err = box.session.push(t) end
+box.schema.func.create('do_push')
+box.schema.user.grant("guest", "execute", "function", "do_push")
 c:call('do_push', {}, {on_push = table.insert, on_push_ctx = messages})
 ok, err
 messages
-
+box.schema.func.drop('do_push')
 --
 -- Test push from a non-call request.
 --
@@ -187,7 +199,6 @@ function do_pushes()
     return true
 end;
 test_run:cmd("setopt delimiter ''");
-
 -- Can not combine callback and async mode.
 ok, err = pcall(c.call, c, 'do_pushes', {}, {is_async = true, on_push = function() end})
 ok
@@ -209,7 +220,11 @@ s = box.schema.create_space('test')
 pk = s:create_index('pk')
 s:replace{1}
 
+box.schema.user.grant('guest', 'write', 'space', 'test')
+
 function do_push_and_duplicate() box.session.push(100) s:insert{1} end
+box.schema.func.create('do_push_and_duplicate')
+box.schema.user.grant('guest', 'execute', 'function', 'do_push_and_duplicate')
 future = c:call('do_push_and_duplicate', {}, {is_async = true})
 future:wait_result(1000)
 messages = {}
@@ -218,7 +233,7 @@ for i, message in future:pairs() do table.insert(messages, message) table.insert
 messages
 keys
 
+box.schema.func.drop('do_push_and_duplicate')
+box.schema.func.drop('do_pushes')
 s:drop()
 c:close()
-
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
diff --git a/test/box/schema_reload.result b/test/box/schema_reload.result
index 31f215bc3..c927e4fcf 100644
--- a/test/box/schema_reload.result
+++ b/test/box/schema_reload.result
@@ -1,6 +1,3 @@
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 net_box = require('net.box')
 ---
 ...
@@ -17,6 +14,9 @@ s = box.schema.create_space('test')
 i = s:create_index('primary')
 ---
 ...
+box.schema.user.grant('guest', 'read', 'space', 'test')
+---
+...
 cn = net_box.connect(LISTEN.host, LISTEN.service)
 ---
 ...
@@ -35,6 +35,9 @@ s2 = box.schema.create_space('test2')
 i2 = s2:create_index('primary')
 ---
 ...
+box.schema.user.grant('guest', 'read', 'space', 'test2')
+---
+...
 ----------------------------------
 -- TEST #1 simple reload
 ----------------------------------
@@ -123,6 +126,9 @@ s:drop()
 s2:drop()
 ---
 ...
+cn:close()
+---
+...
 --------------------------------------------------------------------------------
 -- gh-1808: support schema_version in CALL, EVAL and PING
 --------------------------------------------------------------------------------
@@ -177,6 +183,12 @@ bump_schema_version()
 function somefunc() return true end
 ---
 ...
+box.schema.func.create('somefunc')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'somefunc')
+---
+...
 cn:call('somefunc')
 ---
 - true
@@ -209,6 +221,18 @@ cn.schema_version == schema_version + 1
 ---
 - true
 ...
+box.schema.func.drop('somefunc')
+---
+...
+cn:close()
+---
+...
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
+cn = net_box.connect(box.cfg.listen)
+---
+...
 -- eval
 schema_version = cn.schema_version
 ---
@@ -271,6 +295,6 @@ box.internal.schema_version() == schema_version + 1
 if box.space.bump_schema_version ~= nil then box.space.bump_schema_version:drop() end
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'universe')
 ---
 ...
diff --git a/test/box/schema_reload.test.lua b/test/box/schema_reload.test.lua
index 48ccb169c..cdfbfca75 100644
--- a/test/box/schema_reload.test.lua
+++ b/test/box/schema_reload.test.lua
@@ -1,4 +1,3 @@
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 net_box = require('net.box')
 fiber = require('fiber')
 LISTEN = require('uri').parse(box.cfg.listen)
@@ -6,6 +5,7 @@ LISTEN = require('uri').parse(box.cfg.listen)
 -- create first space
 s = box.schema.create_space('test')
 i = s:create_index('primary')
+box.schema.user.grant('guest', 'read', 'space', 'test')
 cn = net_box.connect(LISTEN.host, LISTEN.service)
 
 -- check that schema is correct
@@ -15,6 +15,7 @@ old_schema_version = cn.schema_version
 -- create one more space
 s2 = box.schema.create_space('test2')
 i2 = s2:create_index('primary')
+box.schema.user.grant('guest', 'read', 'space', 'test2')
 
 ----------------------------------
 -- TEST #1 simple reload
@@ -66,6 +67,7 @@ request_fiber:cancel()
 reload_fiber:cancel()
 s:drop()
 s2:drop()
+cn:close()
 
 --------------------------------------------------------------------------------
 -- gh-1808: support schema_version in CALL, EVAL and PING
@@ -95,6 +97,8 @@ cn.schema_version == schema_version + 1
 schema_version = cn.schema_version
 bump_schema_version()
 function somefunc() return true end
+box.schema.func.create('somefunc')
+box.schema.user.grant('guest', 'execute', 'function', 'somefunc')
 cn:call('somefunc')
 wait_new_schema()
 cn.schema_version == schema_version + 1
@@ -107,6 +111,12 @@ cn:call('somefunc')
 wait_new_schema()
 cn.schema_version == schema_version + 1
 
+box.schema.func.drop('somefunc')
+
+cn:close()
+box.schema.user.grant('guest', 'execute', 'universe')
+cn = net_box.connect(box.cfg.listen)
+
 -- eval
 schema_version = cn.schema_version
 bump_schema_version()
@@ -125,6 +135,7 @@ somefunc = nil
 
 cn:close()
 
+
 -- box.internal.schema_version()
 schema_version = box.internal.schema_version()
 schema_version > 0
@@ -132,5 +143,4 @@ bump_schema_version()
 box.internal.schema_version() == schema_version + 1
 
 if box.space.bump_schema_version ~= nil then box.space.bump_schema_version:drop() end
-
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+box.schema.user.revoke('guest', 'execute', 'universe')
diff --git a/test/box/sql.result b/test/box/sql.result
index 11a698850..a6c572f35 100644
--- a/test/box/sql.result
+++ b/test/box/sql.result
@@ -16,7 +16,10 @@ _ = box.schema.space.create('test1', { id = 555 })
 box.schema.user.create('test', { password = 'test' })
 ---
 ...
-box.schema.user.grant('test', 'execute,read,write', 'universe')
+box.schema.user.grant('test', 'read,write,alter', 'space', 'test1')
+---
+...
+box.schema.user.grant('test', 'read,write,alter', 'space', 'test')
 ---
 ...
 conn = net_box.connect('test:test@' .. box.cfg.listen)
@@ -228,10 +231,10 @@ net_box = require('net.box')
 box.schema.user.create('test', { password = 'test' })
 ---
 ...
-box.schema.user.grant('test', 'execute,read,write', 'universe')
+s = box.schema.space.create('tweedledum')
 ---
 ...
-s = box.schema.space.create('tweedledum')
+box.schema.user.grant('test', 'read,write,alter', 'space', 'tweedledum')
 ---
 ...
 index1 = s:create_index('primary', { type = 'tree', parts = { 1, 'string'} })
diff --git a/test/box/sql.test.lua b/test/box/sql.test.lua
index b1ba4168c..0523311ee 100644
--- a/test/box/sql.test.lua
+++ b/test/box/sql.test.lua
@@ -5,7 +5,8 @@ net_box = require('net.box')
 s = box.schema.space.create('test')
 _ = box.schema.space.create('test1', { id = 555 })
 box.schema.user.create('test', { password = 'test' })
-box.schema.user.grant('test', 'execute,read,write', 'universe')
+box.schema.user.grant('test', 'read,write,alter', 'space', 'test1')
+box.schema.user.grant('test', 'read,write,alter', 'space', 'test')
 
 conn = net_box.connect('test:test@' .. box.cfg.listen)
 space = conn.space.test
@@ -92,8 +93,8 @@ net_box = require('net.box')
 
 -- Prepare spaces
 box.schema.user.create('test', { password = 'test' })
-box.schema.user.grant('test', 'execute,read,write', 'universe')
 s = box.schema.space.create('tweedledum')
+box.schema.user.grant('test', 'read,write,alter', 'space', 'tweedledum')
 index1 = s:create_index('primary', { type = 'tree', parts = { 1, 'string'} })
 index2 = s:create_index('secondary', { type = 'tree', unique = false, parts = {2, 'string'}})
 function compare(a,b) return a[1] < b[1] end
diff --git a/test/box/stat_net.result b/test/box/stat_net.result
index fc1379920..b3e3db11f 100644
--- a/test/box/stat_net.result
+++ b/test/box/stat_net.result
@@ -19,7 +19,7 @@ box.stat.net.RECEIVED -- zero
 space = box.schema.space.create('tweedledum')
 ---
 ...
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest', 'read', 'space', 'tweedledum')
 ---
 ...
 index = space:create_index('primary', { type = 'hash' })
@@ -60,12 +60,9 @@ box.stat.net.RECEIVED.total
 ---
 - 0
 ...
-space:drop()
+space:drop() -- tweedledum
 ---
 ...
 cn:close()
 ---
 ...
-box.schema.user.revoke('guest','read,write,execute','universe')
----
-...
diff --git a/test/box/stat_net.test.lua b/test/box/stat_net.test.lua
index 9ddc55789..808bb71e7 100644
--- a/test/box/stat_net.test.lua
+++ b/test/box/stat_net.test.lua
@@ -7,7 +7,7 @@ box.stat.net.SENT -- zero
 box.stat.net.RECEIVED -- zero
 
 space = box.schema.space.create('tweedledum')
-box.schema.user.grant('guest','read,write,execute','universe')
+box.schema.user.grant('guest', 'read', 'space', 'tweedledum')
 index = space:create_index('primary', { type = 'hash' })
 remote = require 'net.box'
 
@@ -26,6 +26,5 @@ box.stat.reset()
 box.stat.net.SENT.total
 box.stat.net.RECEIVED.total
 
-space:drop()
+space:drop() -- tweedledum
 cn:close()
-box.schema.user.revoke('guest','read,write,execute','universe')
diff --git a/test/engine/params.result b/test/engine/params.result
index d5f4b3c82..debb40d40 100644
--- a/test/engine/params.result
+++ b/test/engine/params.result
@@ -8,9 +8,6 @@ inspector = test_run.new()
 engine = inspector:get_cfg('engine')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 s = box.schema.create_space('engine', {engine=engine})
 ---
 ...
@@ -30,6 +27,3 @@ box.space.engine:select{}
 box.space.engine:drop()
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
diff --git a/test/engine/params.test.lua b/test/engine/params.test.lua
index 3272835a1..a7cb499fd 100644
--- a/test/engine/params.test.lua
+++ b/test/engine/params.test.lua
@@ -3,7 +3,6 @@ test_run = require('test_run')
 inspector = test_run.new()
 engine = inspector:get_cfg('engine')
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 s = box.schema.create_space('engine', {engine=engine})
 i = s:create_index('primary')
 
@@ -14,4 +13,3 @@ box.space.engine:select{}
 
 -- cleanup
 box.space.engine:drop()
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
diff --git a/test/engine/replica_join.result b/test/engine/replica_join.result
index 39d857fef..7d6f50a19 100644
--- a/test/engine/replica_join.result
+++ b/test/engine/replica_join.result
@@ -10,9 +10,6 @@ engine = test_run:get_cfg('engine')
 index = test_run:get_cfg('index')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 box.schema.user.grant('guest', 'replication')
 ---
 ...
@@ -535,6 +532,3 @@ box.snapshot()
 box.schema.user.revoke('guest', 'replication')
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
diff --git a/test/engine/replica_join.test.lua b/test/engine/replica_join.test.lua
index 1792281e8..07320137b 100644
--- a/test/engine/replica_join.test.lua
+++ b/test/engine/replica_join.test.lua
@@ -2,7 +2,6 @@ env = require('test_run')
 test_run = env.new()
 engine = test_run:get_cfg('engine')
 index = test_run:get_cfg('index')
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 box.schema.user.grant('guest', 'replication')
 space = box.schema.space.create('test', { id = 99999, engine = engine })
 _ = space:create_index('primary', { type = index})
@@ -137,4 +136,3 @@ space:drop()
 box.snapshot()
 
 box.schema.user.revoke('guest', 'replication')
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
diff --git a/test/replication/autobootstrap.result b/test/replication/autobootstrap.result
index 91badc1f1..7b770a5ea 100644
--- a/test/replication/autobootstrap.result
+++ b/test/replication/autobootstrap.result
@@ -112,7 +112,16 @@ _ = test_run:cmd("switch autobootstrap1")
 u1 = box.schema.user.create('test_u')
 ---
 ...
-box.schema.user.grant('test_u', 'read,write,create', 'universe')
+box.schema.user.grant('test_u', 'create', 'space')
+---
+...
+box.schema.user.grant('test_u', 'read,write', 'space', '_space')
+---
+...
+box.schema.user.grant('test_u', 'write', 'space', '_schema')
+---
+...
+box.schema.user.grant('test_u', 'write', 'space', '_index')
 ---
 ...
 box.session.su('test_u')
@@ -131,6 +140,18 @@ box.space.test_u:select()
 ---
 - - [1, 2, 3, 4]
 ...
+box.schema.user.revoke('test_u', 'write', 'space', '_index')
+---
+...
+box.schema.user.revoke('test_u', 'write', 'space', '_schema')
+---
+...
+box.schema.user.revoke('test_u', 'read,write', 'space', '_space')
+---
+...
+box.schema.user.revoke('test_u', 'create', 'space')
+---
+...
 -- Synchronize
 vclock = test_run:get_vclock('autobootstrap1')
 ---
diff --git a/test/replication/autobootstrap.test.lua b/test/replication/autobootstrap.test.lua
index 752d5f317..3b1397eb5 100644
--- a/test/replication/autobootstrap.test.lua
+++ b/test/replication/autobootstrap.test.lua
@@ -55,13 +55,21 @@ _ = test_run:cmd("switch default")
 
 _ = test_run:cmd("switch autobootstrap1")
 u1 = box.schema.user.create('test_u')
-box.schema.user.grant('test_u', 'read,write,create', 'universe')
+box.schema.user.grant('test_u', 'create', 'space')
+box.schema.user.grant('test_u', 'read,write', 'space', '_space')
+box.schema.user.grant('test_u', 'write', 'space', '_schema')
+box.schema.user.grant('test_u', 'write', 'space', '_index')
 box.session.su('test_u')
 _ = box.schema.space.create('test_u'):create_index('pk')
 box.session.su('admin')
 _ = box.space.test_u:replace({1, 2, 3, 4})
 box.space.test_u:select()
 
+box.schema.user.revoke('test_u', 'write', 'space', '_index')
+box.schema.user.revoke('test_u', 'write', 'space', '_schema')
+box.schema.user.revoke('test_u', 'read,write', 'space', '_space')
+box.schema.user.revoke('test_u', 'create', 'space')
+
 -- Synchronize
 vclock = test_run:get_vclock('autobootstrap1')
 _ = test_run:wait_vclock("autobootstrap2", vclock)
diff --git a/test/replication/catch.result b/test/replication/catch.result
index 0f72e89e2..aebba819f 100644
--- a/test/replication/catch.result
+++ b/test/replication/catch.result
@@ -7,9 +7,6 @@ test_run = env.new()
 engine = test_run:get_cfg('engine')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 net_box = require('net.box')
 ---
 ...
@@ -139,6 +136,3 @@ box.space.test:drop()
 box.schema.user.revoke('guest', 'replication')
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
diff --git a/test/replication/catch.test.lua b/test/replication/catch.test.lua
index 457f910e9..8cc3242f7 100644
--- a/test/replication/catch.test.lua
+++ b/test/replication/catch.test.lua
@@ -2,7 +2,6 @@ env = require('test_run')
 test_run = env.new()
 engine = test_run:get_cfg('engine')
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 
 net_box = require('net.box')
 errinj = box.error.injection
@@ -62,5 +61,4 @@ test_run:cmd("stop server replica")
 test_run:cmd("cleanup server replica")
 box.space.test:drop()
 box.schema.user.revoke('guest', 'replication')
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
 
diff --git a/test/replication/errinj.result b/test/replication/errinj.result
index 3fc432010..ce6add8d4 100644
--- a/test/replication/errinj.result
+++ b/test/replication/errinj.result
@@ -7,9 +7,6 @@ test_run = env.new()
 engine = test_run:get_cfg('engine')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 errinj = box.error.injection
 ---
 ...
diff --git a/test/replication/errinj.test.lua b/test/replication/errinj.test.lua
index 37375f45e..e1e96a0c4 100644
--- a/test/replication/errinj.test.lua
+++ b/test/replication/errinj.test.lua
@@ -1,7 +1,6 @@
 env = require('test_run')
 test_run = env.new()
 engine = test_run:get_cfg('engine')
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 
 errinj = box.error.injection
 
diff --git a/test/replication/gc.result b/test/replication/gc.result
index 3f9db26ce..83d0de293 100644
--- a/test/replication/gc.result
+++ b/test/replication/gc.result
@@ -27,9 +27,6 @@ function wait_gc(n) while #box.info.gc().checkpoints > n do fiber.sleep(0.01) en
 ---
 ...
 -- Grant permissions needed for replication.
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 box.schema.user.grant('guest', 'replication')
 ---
 ...
@@ -463,9 +460,6 @@ box.error.injection.set("ERRINJ_RELAY_REPORT_INTERVAL", 0)
 box.schema.user.revoke('guest', 'replication')
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
 box.cfg{checkpoint_count = default_checkpoint_count}
 ---
 ...
diff --git a/test/replication/gc.test.lua b/test/replication/gc.test.lua
index 96f11f8d4..eed76850c 100644
--- a/test/replication/gc.test.lua
+++ b/test/replication/gc.test.lua
@@ -13,7 +13,6 @@ box.cfg{checkpoint_count = 1}
 function wait_gc(n) while #box.info.gc().checkpoints > n do fiber.sleep(0.01) end end
 
 -- Grant permissions needed for replication.
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 box.schema.user.grant('guest', 'replication')
 
 -- By default, relay thread reports status to tx once a second.
@@ -212,6 +211,5 @@ box.cfg{replication = {}}
 s:drop()
 box.error.injection.set("ERRINJ_RELAY_REPORT_INTERVAL", 0)
 box.schema.user.revoke('guest', 'replication')
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
 
 box.cfg{checkpoint_count = default_checkpoint_count}
diff --git a/test/replication/join_vclock.result b/test/replication/join_vclock.result
index 7c402dbf6..a9781073d 100644
--- a/test/replication/join_vclock.result
+++ b/test/replication/join_vclock.result
@@ -13,9 +13,6 @@ test_run = env.new()
 engine = test_run:get_cfg('engine')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 errinj = box.error.injection
 ---
 ...
@@ -87,9 +84,6 @@ replica_set.drop_all(test_run)
 box.space.test:drop()
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
 box.schema.user.revoke('guest', 'replication')
 ---
 ...
diff --git a/test/replication/join_vclock.test.lua b/test/replication/join_vclock.test.lua
index ac6eab75c..0b60dffc2 100644
--- a/test/replication/join_vclock.test.lua
+++ b/test/replication/join_vclock.test.lua
@@ -3,7 +3,6 @@ env = require('test_run')
 replica_set = require('fast_replica')
 test_run = env.new()
 engine = test_run:get_cfg('engine')
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 
 errinj = box.error.injection
 errinj.set("ERRINJ_RELAY_FINAL_SLEEP", true)
@@ -33,5 +32,4 @@ test_run:cmd("switch default")
 
 replica_set.drop_all(test_run)
 box.space.test:drop()
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
 box.schema.user.revoke('guest', 'replication')
diff --git a/test/replication/skip_conflict_row.result b/test/replication/skip_conflict_row.result
index bf794db5a..29963f56a 100644
--- a/test/replication/skip_conflict_row.result
+++ b/test/replication/skip_conflict_row.result
@@ -7,9 +7,6 @@ test_run = env.new()
 engine = test_run:get_cfg('engine')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 box.schema.user.grant('guest', 'replication')
 ---
 ...
@@ -100,6 +97,3 @@ box.space.test:drop()
 box.schema.user.revoke('guest', 'replication')
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
diff --git a/test/replication/skip_conflict_row.test.lua b/test/replication/skip_conflict_row.test.lua
index 695cce9db..5f7d6ead3 100644
--- a/test/replication/skip_conflict_row.test.lua
+++ b/test/replication/skip_conflict_row.test.lua
@@ -2,7 +2,6 @@ env = require('test_run')
 test_run = env.new()
 engine = test_run:get_cfg('engine')
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 box.schema.user.grant('guest', 'replication')
 
 space = box.schema.space.create('test', {engine = engine});
@@ -34,4 +33,3 @@ test_run:cmd("stop server replica")
 test_run:cmd("cleanup server replica")
 box.space.test:drop()
 box.schema.user.revoke('guest', 'replication')
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
diff --git a/test/vinyl/replica_quota.result b/test/vinyl/replica_quota.result
index 460cc1e61..50e397199 100644
--- a/test/vinyl/replica_quota.result
+++ b/test/vinyl/replica_quota.result
@@ -1,9 +1,6 @@
 test_run = require('test_run').new()
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 box.schema.user.grant('guest', 'replication')
 ---
 ...
@@ -94,6 +91,3 @@ s:drop()
 box.schema.user.revoke('guest', 'replication')
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
diff --git a/test/vinyl/replica_quota.test.lua b/test/vinyl/replica_quota.test.lua
index eade6f2f7..e04abbc22 100644
--- a/test/vinyl/replica_quota.test.lua
+++ b/test/vinyl/replica_quota.test.lua
@@ -1,6 +1,5 @@
 test_run = require('test_run').new()
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 box.schema.user.grant('guest', 'replication')
 
 s = box.schema.space.create('test', { engine = 'vinyl' })
@@ -49,4 +48,3 @@ _ = test_run:cmd("cleanup server replica")
 s:drop()
 
 box.schema.user.revoke('guest', 'replication')
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
diff --git a/test/wal_off/func_max.result b/test/wal_off/func_max.result
index 9211c4310..5a43821b2 100644
--- a/test/wal_off/func_max.result
+++ b/test/wal_off/func_max.result
@@ -36,36 +36,41 @@ function drop_limit_func()
 end;
 ---
 ...
-func_limit();
+test_run:cmd("setopt delimiter ''");
+---
+- true
+...
+func_limit()
 ---
 - error: 'A limit on the total number of functions has been reached: 32000'
 ...
-drop_limit_func();
+drop_limit_func()
 ---
 - error: Function 'func32000' does not exist
 ...
-box.schema.user.create('testuser');
+box.schema.user.create('testuser')
 ---
 ...
-box.schema.user.grant('testuser', 'read, write, execute,create', 'universe');
+box.schema.user.grant('testuser', 'read,write', 'space', '_func')
 ---
 ...
-session.su('testuser');
+box.schema.user.grant('testuser', 'create', 'function')
 ---
 ...
-func_limit();
+session.su('testuser')
+---
+...
+func_limit()
 ---
 - error: 'A limit on the total number of functions has been reached: 32000'
 ...
-drop_limit_func();
+drop_limit_func()
 ---
 - error: Function 'func32000' does not exist
 ...
 session.su('admin')
-box.schema.user.drop('testuser');
 ---
 ...
-test_run:cmd("setopt delimiter ''");
+box.schema.user.drop('testuser')
 ---
-- true
 ...
diff --git a/test/wal_off/func_max.test.lua b/test/wal_off/func_max.test.lua
index 00a095936..47fa6834b 100644
--- a/test/wal_off/func_max.test.lua
+++ b/test/wal_off/func_max.test.lua
@@ -21,13 +21,14 @@ function drop_limit_func()
         i = i + 1
     end
 end;
-func_limit();
-drop_limit_func();
-box.schema.user.create('testuser');
-box.schema.user.grant('testuser', 'read, write, execute,create', 'universe');
-session.su('testuser');
-func_limit();
-drop_limit_func();
-session.su('admin')
-box.schema.user.drop('testuser');
 test_run:cmd("setopt delimiter ''");
+func_limit()
+drop_limit_func()
+box.schema.user.create('testuser')
+box.schema.user.grant('testuser', 'read,write', 'space', '_func')
+box.schema.user.grant('testuser', 'create', 'function')
+session.su('testuser')
+func_limit()
+drop_limit_func()
+session.su('admin')
+box.schema.user.drop('testuser')
diff --git a/test/xlog/errinj.result b/test/xlog/errinj.result
index 262677f1d..6243ac701 100644
--- a/test/xlog/errinj.result
+++ b/test/xlog/errinj.result
@@ -50,15 +50,15 @@ test_run:cmd('restart server default with cleanup=1')
 errinj = box.error.injection
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 test = box.schema.create_space('test')
 ---
 ...
 _ = test:create_index('primary')
 ---
 ...
+box.schema.user.grant('guest', 'write', 'space', 'test')
+---
+...
 for i=1, box.cfg.rows_per_wal do test:insert{i, 'test'} end
 ---
 ...
@@ -85,6 +85,3 @@ test:drop()
 errinj = nil
 ---
 ...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
diff --git a/test/xlog/errinj.test.lua b/test/xlog/errinj.test.lua
index 0ea15123f..7a5a29cb6 100644
--- a/test/xlog/errinj.test.lua
+++ b/test/xlog/errinj.test.lua
@@ -25,10 +25,11 @@ test_run:cmd('restart server default with cleanup=1')
 -- gh-881 iproto request with wal IO error
 errinj = box.error.injection
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
 test = box.schema.create_space('test')
 _ = test:create_index('primary')
 
+box.schema.user.grant('guest', 'write', 'space', 'test')
+
 for i=1, box.cfg.rows_per_wal do test:insert{i, 'test'} end
 c = require('net.box').connect(box.cfg.listen)
 
@@ -40,4 +41,3 @@ errinj.set('ERRINJ_WAL_WRITE', false)
 -- Cleanup
 test:drop()
 errinj = nil
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
diff --git a/test/xlog/misc.result b/test/xlog/misc.result
index fd3362c4c..5df21aede 100644
--- a/test/xlog/misc.result
+++ b/test/xlog/misc.result
@@ -11,12 +11,12 @@ xlog = require('xlog')
 netbox = require('net.box')
 ---
 ...
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
 --
 -- Check that xlogs doesn't contain IPROTO_SYNC
 --
+box.schema.user.grant('guest', 'write', 'space', '_schema')
+---
+...
 conn = netbox.connect(box.cfg.listen)
 ---
 ...
@@ -68,9 +68,6 @@ box.space._schema:delete('test')
 --
 -- Clean up
 --
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
 netbox = nil
 ---
 ...
diff --git a/test/xlog/misc.test.lua b/test/xlog/misc.test.lua
index 6e67b86a9..44adfd942 100644
--- a/test/xlog/misc.test.lua
+++ b/test/xlog/misc.test.lua
@@ -5,12 +5,12 @@ fio = require('fio')
 xlog = require('xlog')
 netbox = require('net.box')
 
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
-
 --
 -- Check that xlogs doesn't contain IPROTO_SYNC
 --
 
+box.schema.user.grant('guest', 'write', 'space', '_schema')
+
 conn = netbox.connect(box.cfg.listen)
 -- insert some row using the binary protocol
 conn.space._schema:insert({'test'})
@@ -31,7 +31,6 @@ box.space._schema:delete('test')
 --
 -- Clean up
 --
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
 netbox = nil
 xlog = nil
 fio = nil
diff --git a/test/xlog/upgrade.result b/test/xlog/upgrade.result
index 76467baf1..b4cf18c71 100644
--- a/test/xlog/upgrade.result
+++ b/test/xlog/upgrade.result
@@ -192,9 +192,9 @@ box.space._priv:select()
   - [1, 4, 'function', 3, 4]
   - [1, 4, 'role', 2, 4]
   - [1, 4, 'role', 5, 4]
-  - [1, 4, 'space', 513, 3]
+  - [1, 4, 'space', 513, 195]
   - [1, 4, 'universe', 0, 24]
-  - [1, 5, 'space', 512, 3]
+  - [1, 5, 'space', 512, 195]
   - [1, 31, 'universe', 0, 4294967295]
 ...
 box.space._vspace ~= nil
-- 
2.15.2 (Apple Git-101.1)




More information about the Tarantool-patches mailing list