Search code examples
tarantool

How to grant a user to perform only a certain function in Tarantool


Now the challenge is: there are 2 functions. And there is a user who can only execute one of them. The question is how to do it? If you just write: box.schema.user.grant ('user', 'execute', 'function', 'dima', nil, {if_not_exists = true}) then the user 'user' cannot connect at all. An error message is displayed: Execute access to universe '' is denied for user 'user'. How to provide access correctly?

        box.once("schema", function()
        box.schema.user.create('superuser', {password = '11111111'})
        box.schema.user.create('user', {password = '11111111'})
        box.schema.user.grant('superuser', 'read,write,execute','universe', nil, {if_not_exists = true})
        box.schema.user.grant('user','execute','function','dima',nil, {if_not_exists = true})
        end)
        function reload(proc)
            package.loaded[proc]=nil return require(proc)
                end
        ws = reload('project/init')

Function dima:

local obj={}

function obj.open()
    return 'dima'
end

return obj

Function dima2:

local obj={}

function obj.open()
    return 'dima2'
end

return obj

Init.lua:

obj = {}
  collectgarbage('collect')
  net   = require('net.box')
  fiber = require('fiber')
  uuid  = require('uuid')
  -- modules
  obj.dima  = reload('project/dima')
  obj.dima2 = reload('project/dima2')
return obj

Solution

  • In order to give access to only one function, you can do the following:

    box.cfg({listen=3301})
    
    foo = function() print("bar") end
    
    box.schema.user.create('myuser', {if_not_exists=true, password = 'secret'})
    
    -- setuid is required here so that the function, when called by user with
    -- restricted rights, will have access to everything
    box.schema.func.create('foo', {if_not_exists=true, setuid=true})
    
    box.schema.user.grant('myuser', 'execute', 'function', 
                          'foo', {if_not_exists=true})
    

    Then open a separate tarantool prompt (not tarantoolctl! explanation below) and type this:

    net_box = require('net.box')
    c = net_box.connect('myuser:secret@localhost:3301')
    c:call('foo')
    

    Then you'll see "bar" printed in the first console.

    The reason you see "Execute access to universe '' is denied for user 'user'" is because you try to connect with tarantoolctl, which requires read access to the whole database. It will be fine when called via connectors or net.box.