From: Jorge Pereira Date: Thu, 14 Mar 2019 02:20:18 +0000 (-0300) Subject: rlm_lua: Add capability to return X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a7d8eb57645a392b862ef76deeea2f75d284e27;p=thirdparty%2Ffreeradius-server.git rlm_lua: Add capability to return --- diff --git a/src/modules/rlm_lua/example.lua b/src/modules/rlm_lua/example.lua index a0a67d80e17..0bca45cf8d7 100755 --- a/src/modules/rlm_lua/example.lua +++ b/src/modules/rlm_lua/example.lua @@ -14,42 +14,52 @@ end function preacct() print("example.lua/preacct()") + return fr.ok end function accounting() print("example.lua/accounting()") + return fr.ok end function pre_proxy() print("example.lua/pre_proxy()") + return fr.ok end function post_proxy() print("example.lua/post_proxy()") + return fr.ok end function post_auth() print("example.lua/post_auth()") + return fr.ok end function recv_coa() print("example.lua/recv_coa()") + return fr.ok end function send_coa() print("example.lua/send_coa()") + return fr.ok end function detach() print("example.lua/detach()") + return fr.ok end function xlat() print("example.lua/xlat()") + return fr.ok end function authenticate() print("example.lua/authenticate()") + return fr.ok end function authorize() @@ -69,4 +79,6 @@ function authorize() print("example.lua/authorize()") print("Request list contents:") tprint(request, 2) + + return fr.ok end diff --git a/src/modules/rlm_lua/lua.c b/src/modules/rlm_lua/lua.c index 53c339736a3..7cd63dcaddd 100644 --- a/src/modules/rlm_lua/lua.c +++ b/src/modules/rlm_lua/lua.c @@ -466,6 +466,47 @@ static int _lua_list_iterator_init(lua_State *L) return 1; } +/* + * Initialise the table "fr." with all valid return codes. + */ +static int _lua_rcode_table_newindex(UNUSED lua_State *L) +{ + REQUEST *request = rlm_lua_request; + + RWDEBUG("You can't modify the table 'fr.*' (read-only)"); + + return 1; +} + +static int _lua_rcode_table_index(lua_State *L) +{ + char const *key = lua_tostring(L, -1); + int ret; + + ret = fr_str2int(mod_rcode_table, key, -1); + if (ret != -1) { + lua_pushinteger(L, ret); + return 1; + } + + lua_pushfstring(L, "The fr.%s is not found", key); + return -1; +} + +static void rlm_lua_rcode_table_init(lua_State *L, char const *name) +{ + lua_newtable(L); + luaL_newmetatable(L, name); + + lua_pushcfunction(L, _lua_rcode_table_index); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, _lua_rcode_table_newindex); + lua_setfield(L, -2, "__newindex"); + + lua_setmetatable(L, -2); + lua_setglobal(L, name); +} /** Initialise and return a new accessor table * @@ -742,7 +783,7 @@ int do_lua(rlm_lua_thread_t *thread, REQUEST *request, char const *funcname) { fr_cursor_t cursor; lua_State *L = thread->interpreter; - + int ret = RLM_MODULE_OK; rlm_lua_request = request; RDEBUG2("Calling %s() in interpreter %p", funcname, L); @@ -768,12 +809,17 @@ int do_lua(rlm_lua_thread_t *thread, REQUEST *request, char const *funcname) lua_setmetatable(L, -2); lua_setglobal(L, "request"); + /* + * Setup the "fr" global table. with all RLM_MODULE_* values. e.g: "fr.reject", "fr.ok", ... + */ + rlm_lua_rcode_table_init(L, "fr"); + /* * Get the function were going to be calling */ if (rlm_lua_get_field(L, request, funcname) < 0) { error: - return -1; + return RLM_MODULE_FAIL; } if (!lua_isfunction(L, -1)) { @@ -782,11 +828,36 @@ error: goto error; } - if (lua_pcall(L, 0, 0, 0) != 0) { + if (lua_pcall(L, 0, 1, 0) != 0) { char const *msg = lua_tostring(L, -1); REDEBUG("Call to %s failed: %s", funcname, msg ? msg : "unknown error"); goto error; } - return 0; + /* + * functions without return or returning none/nil will be RLM_MODULE_OK + */ + if (!lua_isnoneornil(L, -1)) { + /* + * e.g: return 2, return "2", return fr.handled, fr.fail, ... + */ + if (lua_isnumber(L, -1)) { + ret = lua_tointeger(L, -1); + if (fr_int2str(mod_rcode_table, ret, NULL) != NULL) goto done; + } + + /* + * e.g: return "handled", "ok", "fail", ... + */ + if (lua_isstring(L, -1)) { + ret = fr_str2int(mod_rcode_table, lua_tostring(L, -1), -1); + if (ret != -1) goto done; + } + + REDEBUG("Lua function %s() returned invalid rcode \"%s\"", funcname, lua_tostring(L, -1)); + goto error; + } + +done: + return ret; } diff --git a/src/modules/rlm_lua/rlm_lua.c b/src/modules/rlm_lua/rlm_lua.c index eb5fe6fe5c2..966e82cc3eb 100644 --- a/src/modules/rlm_lua/rlm_lua.c +++ b/src/modules/rlm_lua/rlm_lua.c @@ -70,8 +70,7 @@ static rlm_rcode_t mod_##_s(void *instance, void *thread, REQUEST *request) \ {\ rlm_lua_t const *inst = instance;\ if (!inst->func_##_s) return RLM_MODULE_NOOP;\ - if (do_lua(thread, request, inst->func_##_s) < 0) return RLM_MODULE_FAIL;\ - return RLM_MODULE_OK;\ + return do_lua(thread, request, inst->func_##_s);\ } DO_LUA(authorize)