Description
Related dev. issue(s): tarantool/tarantool#8803
Parent doc. issue(s): #3666
Product: Tarantool
Since: 3.0
Root document: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_schema/user_grant/
https://www.tarantool.io/en/doc/latest/dev_guide/internals/iproto/requests/#box-protocol-eval
https://www.tarantool.io/en/doc/latest/dev_guide/internals/iproto/requests/#iproto-call
https://www.tarantool.io/en/doc/latest/dev_guide/internals/iproto/sql/
SME: @ locker
Details
In Tarantool 3.0 we introduced the new lua_eval
, lua_call
, and sql
object types for box.schema.user.grant
to control access to code execution over the network protocol (IPROTO).
lua_eval
Granting the 'execute' privilege on lua_eval
permits the user to execute arbitrary Lua code with the IPROTO_EVAL
request.
Example:
box.cfg({listen = 3301})
box.schema.user.create('alice', {password = 'secret'})
conn = require('net.box').connect(box.cfg.listen, {user = 'alice', password = 'secret'})
conn:eval('return true') -- access denied
box.schema.user.grant('alice', 'execute', 'lua_eval')
conn:eval('return true') -- ok
lua_call
Granting the 'execute' privilege on lua_call
permits the user to call any global (accessible via the _G
Lua table) user-defined Lua function with the IPROTO_CALL
request. It does not permit the user to call built-in Lua functions, such as loadstring
or box.session.su
. It permits the user to call any Lua function registered in the _func
system space with box.schema.func.create
except for persistent functions (functions with a body).
Example:
function my_func() end
box.cfg({listen = 3301})
box.schema.user.create('alice', {password = 'secret'})
conn = require('net.box').connect(box.cfg.listen, {user = 'alice', password = 'secret'})
conn:call('my_func') -- access denied
box.schema.user.grant('alice', 'execute', 'lua_call')
conn:call('my_func') -- ok
conn:call('box.session.su', {'admin'}) -- access denied
In the scope of tarantool/tarantool#9360, we also made it possible to specify a function name when granting the lua_call
privilege. If a function name is specified, access will be granted only to the given function, which may be a built-in function, but still not a persistent function. The function doesn't need to be defined at the time privileges are granted.
Example:
function my_func_1() end
function my_func_2() end
box.cfg({listen = 3301})
box.schema.user.create('alice', {password = 'secret'})
conn = require('net.box').connect(box.cfg.listen, {user = 'alice', password = 'secret'})
box.schema.user.grant('alice', 'execute', 'lua_call', 'my_func_1')
conn:call('my_func_1') -- ok
conn:call('my_func_2') -- access denied
box.schema.user.grant('alice', 'execute', 'lua_call', 'box.session.su')
conn:call('box.session.su', {'admin'}) -- ok
sql
Granting the 'execute' privilege on sql
permits the user to execute an arbitrary SQL expression with the IPROTO_PREPARE
and IPROTO_EXECUTE
requests. Without this privilege or the 'execute' privilege granted on universe
, the user is not permitted to execute SQL expressions over IPROTO anymore. Note that before Tarantool 3.0 any user (even guest) could execute SQL expressions over IPROTO. It is possible to revert to the old behavior by toggling the sql_priv
compat option. Please add a description to https://tarantool.io/compat/sql_priv
Example:
box.cfg({listen = 3301})
box.schema.user.create('alice', {password = 'secret'})
conn = require('net.box').connect(box.cfg.listen, {user = 'alice', password = 'secret'})
conn:execute('SELECT 1') -- access denied
box.schema.user.grant('alice', 'execute', 'sql')
conn:execute('SELECT 1') -- ok
Requested by @locker in tarantool/tarantool@ff64d58.