The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_lua.c
Go to the documentation of this file.
1/*
2 * This program is is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2 if the
4 * License as published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
14 */
15
16/**
17 * $Id: f65d06bfcf8297adb3e158d97fefe2ade77acd77 $
18 * @file rlm_lua.c
19 * @brief Translates requests between the server an a Lua interpreter.
20 *
21 * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
22 *
23 * @copyright 2016 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 * @copyright 2016 The FreeRADIUS Server Project.
25 */
26RCSID("$Id: f65d06bfcf8297adb3e158d97fefe2ade77acd77 $")
27
28#define LOG_PREFIX mctx->mi->name
29
30#include <freeradius-devel/server/base.h>
31#include <freeradius-devel/util/debug.h>
32#include <freeradius-devel/server/module_rlm.h>
33
34#include "lua.h"
35/*
36 * A mapping of configuration file names to internal variables.
37 *
38 * Note that the string is dynamically allocated, so it MUST
39 * be freed. When the configuration file parse re-reads the string,
40 * it free's the old one, and strdup's the new one, placing the pointer
41 * to the strdup'd string into 'config.string'. This gets around
42 * buffer over-flows.
43 */
44static const conf_parser_t module_config[] = {
46 { FR_CONF_OFFSET("func_instantiate", rlm_lua_t, func_instantiate), NULL},
47 { FR_CONF_OFFSET("func_detach", rlm_lua_t, func_detach), NULL},
48 { FR_CONF_OFFSET("func_authorize", rlm_lua_t, func_authorize), NULL},
49 { FR_CONF_OFFSET("func_authenticate", rlm_lua_t, func_authenticate), NULL},
50 { FR_CONF_OFFSET("func_accounting", rlm_lua_t, func_accounting), NULL},
51 { FR_CONF_OFFSET("func_preacct", rlm_lua_t, func_preacct), NULL},
52 { FR_CONF_OFFSET("func_xlat", rlm_lua_t, func_xlat), NULL},
53 { FR_CONF_OFFSET("func_post_auth", rlm_lua_t, func_post_auth), NULL},
54
56};
57
58#define DO_LUA(_s)\
59static unlang_action_t mod_##_s(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request) \
60{\
61 rlm_lua_t const *inst = talloc_get_type_abort_const(mctx->mi->data, rlm_lua_t);\
62 if (!inst->func_##_s) RETURN_MODULE_NOOP;\
63 return fr_lua_run(p_result, mctx, request, inst->func_##_s);\
64}
65
66DO_LUA(authorize)
67DO_LUA(authenticate)
68DO_LUA(preacct)
69DO_LUA(accounting)
70DO_LUA(post_auth)
71
72
73/** Free any thread specific interpreters
74 *
75 */
77{
78 rlm_lua_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_lua_thread_t);
79
80 /*
81 * May be NULL if fr_lua_init failed
82 */
83 if (t->interpreter) lua_close(t->interpreter);
84
85 return 0;
86}
87
88/** Create thread-specific connections and buffers
89 *
90 * @param[in] mctx specific data (where we write the interpreter).
91 * @return
92 * - 0 on success.
93 * - -1 on failure.
94 */
96{
97 rlm_lua_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_lua_thread_t);
98
99 if (fr_lua_init(&t->interpreter, (module_inst_ctx_t const *)mctx) < 0) return -1;
100
101 return 0;
102}
103
104/** Close the global interpreter
105 *
106 */
107static int mod_detach(module_detach_ctx_t const *mctx)
108{
109 rlm_lua_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_lua_t);
110 rlm_rcode_t ret = 0;
111
112 /*
113 * May be NULL if fr_lua_init failed
114 */
115 if (inst->interpreter) {
116 if (inst->func_detach) {
117 fr_lua_run(&ret,
118 MODULE_CTX(mctx->mi,
120 .interpreter = inst->interpreter
121 },
122 NULL, NULL),
123 NULL, inst->func_detach);
124 }
125 lua_close(inst->interpreter);
126 }
127
128 return ret;
129}
130
131static int mod_instantiate(module_inst_ctx_t const *mctx)
132{
133 rlm_lua_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_lua_t);
134 rlm_rcode_t rcode;
135
136 /*
137 * Get an instance global interpreter to use with various things...
138 */
139 if (fr_lua_init(&inst->interpreter, mctx) < 0) return -1;
140 inst->jit = fr_lua_isjit(inst->interpreter);
141 if (!inst->jit) WARN("Using standard Lua interpreter, performance will be suboptimal");
142
143 DEBUG("Using %s interpreter", fr_lua_version(inst->interpreter));
144
145 if (inst->func_instantiate) {
146 fr_lua_run(&rcode,
147 MODULE_CTX(mctx->mi,
149 .interpreter = inst->interpreter
150 },
151 NULL, NULL),
152 NULL, inst->func_instantiate);
153 }
154
155 return 0;
156}
157
158/*
159 * The module name should be the only globally exported symbol.
160 * That is, everything else should be 'static'.
161 *
162 * If the module needs to temporarily modify it's instantiation
163 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
164 * The server will then take care of ensuring that the module
165 * is single-threaded.
166 */
167extern module_rlm_t rlm_lua;
169 .common = {
170 .magic = MODULE_MAGIC_INIT,
171 .name = "lua",
172 .inst_size = sizeof(rlm_lua_t),
173
174 .thread_inst_size = sizeof(rlm_lua_thread_t),
175
176 .config = module_config,
177 .instantiate = mod_instantiate,
178 .thread_instantiate = mod_thread_instantiate,
179
180 .detach = mod_detach,
181 .thread_detach = mod_thread_detach
182 },
183 .method_group = {
184 .bindings = (module_method_binding_t[]){
185 /*
186 * Hack to support old configurations
187 */
188 { .section = SECTION_NAME("accounting", CF_IDENT_ANY), .method = mod_accounting },
189 { .section = SECTION_NAME("authenticate", CF_IDENT_ANY), .method = mod_authenticate },
190 { .section = SECTION_NAME("authorize", CF_IDENT_ANY), .method = mod_authorize },
191
192 { .section = SECTION_NAME("recv", "accounting-request"), .method = mod_preacct },
193 { .section = SECTION_NAME("recv", CF_IDENT_ANY), .method = mod_authorize },
194 { .section = SECTION_NAME("send", CF_IDENT_ANY), .method = mod_post_auth },
196 }
197 }
198};
#define RCSID(id)
Definition build.h:483
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:642
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:268
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:256
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition cf_parse.h:418
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Definition cf_parse.h:424
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:579
#define CF_IDENT_ANY
Definition cf_util.h:78
#define DEBUG(fmt,...)
Definition dhcpclient.c:39
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
unlang_action_t fr_lua_run(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request, char const *funcname)
Definition lua.c:754
char const * fr_lua_version(lua_State *L)
Definition lua.c:605
bool fr_lua_isjit(lua_State *L)
Check whether the Lua interpreter were actually linked to is LuaJIT.
Definition lua.c:591
int fr_lua_init(lua_State **out, module_inst_ctx_t const *mctx)
Initialise a new Lua/LuaJIT interpreter.
Definition lua.c:893
Library function signatures for lua module.
lua_State * interpreter
Thread specific interpreter.
Definition lua.h:63
module_instance_t * mi
Module instance to detach.
Definition module_ctx.h:57
void * thread
Thread instance data.
Definition module_ctx.h:67
#define MODULE_CTX(_mi, _thread, _env_data, _rctx)
Wrapper to create a module_ctx_t as a compound literal.
Definition module_ctx.h:128
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for detach calls.
Definition module_ctx.h:56
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
Temporary structure to hold arguments for thread_instantiation calls.
Definition module_ctx.h:63
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
#define WARN(fmt,...)
Definition radclient.h:47
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
static unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_chap.c:228
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_chap.c:176
static unlang_action_t mod_accounting(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Write accounting data to Couchbase documents.
static unlang_action_t mod_post_auth(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_detail.c:375
module_rlm_t rlm_lua
Definition rlm_lua.c:168
static int mod_detach(module_detach_ctx_t const *mctx)
Close the global interpreter.
Definition rlm_lua.c:107
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Create thread-specific connections and buffers.
Definition rlm_lua.c:95
#define DO_LUA(_s)
Definition rlm_lua.c:58
static const conf_parser_t module_config[]
Definition rlm_lua.c:44
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
Free any thread specific interpreters.
Definition rlm_lua.c:76
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition rlm_lua.c:131
static unlang_action_t mod_preacct(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
Definition rlm_test.c:246
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:40
size_t inst_size
Size of the module's instance data.
Definition module.h:203
void * data
Module's instance data.
Definition module.h:271
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:151
Named methods exported by a module.
Definition module.h:173
eap_aka_sim_process_conf_t * inst