Skip to content
Snippets Groups Projects
Commit 4b88d5fd authored by Vladimir Davydov's avatar Vladimir Davydov Committed by Vladimir Davydov
Browse files

box: allow lua_call priv owners to call registered Lua functions

Currently, the lua_call privilege simply doesn't work for registered
functions. This patch fixes this issue: now, it grants access to any
registered function that is written in Lua unless it's a built-in
function, such as dostring, or a persistent function.

Note, this patch renames access_check_call to access_check_lua_call to
avoid confusion because this function is now global. It also renames
access_check_eval to access_check_lua_eval for consistency.

Closes #9363

NO_DOC=updated doc ticket manually
NO_CHANGELOG=feature has not been released yet
parent 44401529
No related branches found
No related tags found
No related merge requests found
......@@ -160,9 +160,8 @@ box_run_on_call(enum iproto_type type, const char *expr, int expr_len,
trigger_run(&box_on_call, &ctx);
}
/** Checks if the current user may execute any global Lua function. */
static int
access_check_call(const char *name, uint32_t name_len)
int
access_check_lua_call(const char *name, uint32_t name_len)
{
struct credentials *cr = effective_user();
user_access_t access = PRIV_X | PRIV_U;
......@@ -182,7 +181,7 @@ access_check_call(const char *name, uint32_t name_len)
/** Checks if the current user may execute an arbitrary Lua expression. */
static int
access_check_eval(void)
access_check_lua_eval(void)
{
struct credentials *cr = effective_user();
user_access_t access = PRIV_X | PRIV_U;
......@@ -229,7 +228,7 @@ box_process_call(struct call_request *request, struct port *port)
goto cleanup;
}
} else {
if (access_check_call(name, name_len) != 0) {
if (access_check_lua_call(name, name_len) != 0) {
rc = -1;
goto cleanup;
}
......@@ -249,7 +248,7 @@ box_process_eval(struct call_request *request, struct port *port)
{
rmean_collect(rmean_box, IPROTO_EVAL, 1);
/* Check permissions */
if (access_check_eval() != 0)
if (access_check_lua_eval() != 0)
return -1;
struct mp_box_ctx ctx;
if (mp_box_ctx_create(&ctx, NULL, request->tuple_formats) != 0)
......
......@@ -76,6 +76,10 @@ box_process_call(struct call_request *request, struct port *port);
int
box_process_eval(struct call_request *request, struct port *port);
/** Checks if the current user may execute a global Lua function. */
int
access_check_lua_call(const char *name, uint32_t name_len);
#if defined(__cplusplus)
} /* extern "C" */
#endif /* defined(__cplusplus) */
......
......@@ -31,6 +31,7 @@
#include "func.h"
#include "fiber.h"
#include "assoc.h"
#include "call.h"
#include "lua/call.h"
#include "diag.h"
#include "port.h"
......@@ -567,6 +568,10 @@ func_access_check(struct func *func)
if ((func_access & PRIV_U) != 0 ||
(func->def->uid != credentials->uid &&
func_access & ~func->access[credentials->auth_token].effective)) {
if (func->def->language == FUNC_LANGUAGE_LUA &&
func->def->body == NULL)
return access_check_lua_call(func->def->name,
func->def->name_len);
/* Access violation, report error. */
struct user *user = user_find(credentials->uid);
if (user != NULL) {
......
......@@ -133,6 +133,7 @@ g.before_test('test_lua_call_func', function(cg)
language = 'LUA',
body = [[function() return true end]],
})
box.schema.func.create('dostring', {language = 'LUA'})
end)
end)
......@@ -141,19 +142,21 @@ g.after_test('test_lua_call_func', function(cg)
box.schema.func.drop('c_func')
box.schema.func.drop('lua_func')
box.schema.func.drop('stored_lua_func')
box.schema.func.drop('dostring')
end)
end)
-- Checks that execute privilege granted on lua_call does not grant access to
-- Lua functions from _func.
-- Checks that execute privilege granted on lua_call grants access to
-- Lua functions registered in _func except for built-ins and persistent
-- functions.
g.test_lua_call_func = function(cg)
local c = cg.conn
local errfmt = "Execute access to function '%s' is denied for user 'test'"
local func_list = {'c_func', 'lua_func', 'stored_lua_func'}
cg.grant('test', 'execute', 'lua_call')
for _, func in ipairs(func_list) do
for _, func in ipairs({'c_func', 'stored_lua_func', 'dostring'}) do
t.assert_error_msg_equals(errfmt:format(func), c.call, c, func)
end
t.assert(c:call('lua_func'))
end
-- Checks that execute privilege granted on lua_call does not grant access
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment