The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_mruby.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 as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 54e131110274126e951f0ee0f11d7f7ded62a5a9 $
19 * @file rlm_mruby.c
20 * @brief Translates requests between the server an an mruby interpreter.
21 *
22 * @copyright 2016 Herwin Weststrate (freeradius@herwinw.nl)
23 * @copyright 2016 The FreeRADIUS server project
24 */
25RCSID("$Id: 54e131110274126e951f0ee0f11d7f7ded62a5a9 $")
26
27#include <freeradius-devel/server/base.h>
28#include <freeradius-devel/server/module_rlm.h>
29#include <freeradius-devel/util/debug.h>
30
31#include "rlm_mruby.h"
32
33typedef struct {
34 char const *function_name; //!< Name of the function being called
35 char *name1; //!< Section name1 where this is called
36 char *name2; //!< Section name2 where this is called
37 fr_rb_node_t node; //!< Node in tree of function calls.
39
43
44/*
45 * A mapping of configuration file names to internal variables.
46 */
47static const conf_parser_t module_config[] = {
49 { FR_CONF_OFFSET("module", rlm_mruby_t, module_name), .dflt = "FreeRADIUS" },
51};
52
53/** How to compare two Ruby function calls
54 *
55 */
56static int8_t mruby_func_def_cmp(void const *one, void const *two)
57{
58 mruby_func_def_t const *a = one, *b = two;
59 int ret;
60
61 ret = strcmp(a->name1, b->name1);
62 if (ret != 0) return CMP(ret, 0);
63 if (!a->name2 && !b->name2) return 0;
64 if (!a->name2 || !b->name2) return a->name2 ? 1 : -1;
65 ret = strcmp(a->name2, b->name2);
66 return CMP(ret, 0);
67}
68
69static mrb_value mruby_log(mrb_state *mrb, UNUSED mrb_value self)
70{
71 mrb_int level;
72 char *msg = NULL;
73
74 mrb_get_args(mrb, "iz", &level, &msg);
75 fr_log(&default_log, level, __FILE__, __LINE__, "rlm_ruby: %s", msg);
76
77 return mrb_nil_value();
78}
79
80static void mruby_parse_config(mrb_state *mrb, CONF_SECTION *cs, int lvl, mrb_value hash)
81{
82 int indent_section = (lvl + 1) * 4;
83 int indent_item = (lvl + 2) * 4;
84 CONF_ITEM *ci = NULL;
85
86 if (!cs) return;
87
88 DEBUG("%*s%s {", indent_section, " ", cf_section_name1(cs));
89
90 while ((ci = cf_item_next(cs, ci))) {
91 if (cf_item_is_section(ci)) {
92 CONF_SECTION *sub_cs = cf_item_to_section(ci);
93 char const *key = cf_section_name1(sub_cs);
94 mrb_value sub_hash, mrubyKey;
95
96 if (!key) continue;
97
98 mrubyKey = mrb_str_new_cstr(mrb, key);
99
100 if (!mrb_nil_p(mrb_hash_get(mrb, hash, mrubyKey))) {
101 WARN("rlm_mruby: Ignoring duplicate config section '%s'", key);
102 continue;
103 }
104
105 sub_hash = mrb_hash_new(mrb);
106 mrb_hash_set(mrb, hash, mrubyKey, sub_hash);
107
108 mruby_parse_config(mrb, sub_cs, lvl + 1, sub_hash);
109 } else if (cf_item_is_pair(ci)) {
110 CONF_PAIR *cp = cf_item_to_pair(ci);
111 const char *key = cf_pair_attr(cp);
112 const char *value = cf_pair_value(cp);
113 mrb_value mrubyKey, mrubyValue;
114
115 if (!key || !value) continue;
116
117 mrubyKey = mrb_str_new_cstr(mrb, key);
118 mrubyValue = mrb_str_new_cstr(mrb, value);
119
120 if (!mrb_nil_p(mrb_hash_get(mrb, hash, mrubyKey))) {
121 WARN("rlm_mruby: Ignoring duplicate config item '%s'", key);
122 continue;
123 }
124
125 mrb_hash_set(mrb, hash, mrubyKey, mrubyValue);
126
127 DEBUG("%*s%s = %s", indent_item, " ", key, value);
128 }
129 }
130
131 DEBUG("%*s}", indent_section, " ");
132}
133
134/*
135 * Do any per-module initialization that is separate to each
136 * configured instance of the module. e.g. set up connections
137 * to external databases, read configuration files, set up
138 * dictionary entries, etc.
139 */
140static int mod_instantiate(module_inst_ctx_t const *mctx)
141{
142 rlm_mruby_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_mruby_t);
144 mruby_func_def_t *func = NULL;
145 mrb_state *mrb;
146 CONF_SECTION *cs;
147 FILE *f;
148 mrb_value status;
149 char *pair_name;
150 CONF_PAIR *cp;
151 mrb_value func_sym;
152
153 mrb = inst->mrb = mrb_open();
154 if (!mrb) {
155 ERROR("mruby initialization failed");
156 return -1;
157 }
158
159 /* Define the freeradius module */
160 DEBUG("Creating module %s", inst->module_name);
161 inst->mruby_module = mrb_define_module(mrb, inst->module_name);
162 if (!inst->mruby_module) {
163 ERROR("Creating module %s failed", inst->module_name);
164 return -1;
165 }
166
167 /* Define the log method */
168 mrb_define_class_method(mrb, inst->mruby_module, "log", mruby_log, MRB_ARGS_REQ(2));
169
170#define A(x) mrb_define_const(mrb, inst->mruby_module, #x, mrb_fixnum_value(x));
171 /* Define the logging constants */
172 A(L_DBG);
173 A(L_WARN);
174 A(L_INFO);
175 A(L_ERR);
176 A(L_WARN);
177 A(L_DBG_WARN);
178 A(L_DBG_ERR);
181
182 /* Define the return value constants */
193#undef A
194
195 /* Convert a FreeRADIUS config structure into a mruby hash */
196 inst->mrubyconf_hash = mrb_hash_new(mrb);
197 cs = cf_section_find(mctx->mi->conf, "config", NULL);
198 if (cs) mruby_parse_config(mrb, cs, 0, inst->mrubyconf_hash);
199
200 /* Define the Request class */
201 inst->mruby_request = mruby_request_class(mrb, inst->mruby_module);
202
203 inst->mruby_pair_list = mruby_pair_list_class(mrb, inst->mruby_module);
204 inst->mruby_pair = mruby_pair_class(mrb, inst->mruby_module);
205
206 inst->mruby_ptr = mrb_define_class_under(mrb, inst->mruby_module, "Ptr", mrb->object_class);
207 MRB_SET_INSTANCE_TT(inst->mruby_ptr, MRB_TT_DATA);
208
209 DEBUG("Loading file %s...", inst->filename);
210 f = fopen(inst->filename, "r");
211 if (!f) {
212 ERROR("Opening file failed");
213 return -1;
214 }
215
216 status = mrb_load_file(mrb, f);
217 fclose(f);
218 if (mrb_undef_p(status)) {
219 ERROR("Parsing file failed");
220 return -1;
221 }
222
223 if (!inst->funcs_init) fr_rb_inline_init(&inst->funcs, mruby_func_def_t, node, mruby_func_def_cmp, NULL);
224 func = fr_rb_iter_init_inorder(&iter, &inst->funcs);
225 while (func) {
226 /*
227 * Check for func_<name1>_<name2> or func_<name1> config pairs.
228 */
229 if (func->name2) {
230 pair_name = talloc_asprintf(func, "func_%s_%s", func->name1, func->name2);
231 cp = cf_pair_find(mctx->mi->conf, pair_name);
232 talloc_free(pair_name);
233 if (cp) goto found_func;
234 }
235 pair_name = talloc_asprintf(func, "func_%s", func->name1);
236 cp = cf_pair_find(mctx->mi->conf, pair_name);
237 talloc_free(pair_name);
238 found_func:
239 if (cp){
240 func->function_name = cf_pair_value(cp);
241 func_sym = mrb_check_intern_cstr(mrb, func->function_name);
242 if (mrb_nil_p(func_sym)) {
243 cf_log_err(cp, "mruby function %s does not exist", func->function_name);
244 return -1;
245 }
246 /*
247 * If no pair was found, then use <name1>_<name2> or <name1> as the function to call.
248 */
249 } else if (func->name2) {
250 func->function_name = talloc_asprintf(func, "%s_%s", func->name1, func->name2);
251 func_sym = mrb_check_intern_cstr(mrb, func->function_name);
252 if (mrb_nil_p(func_sym)) {
254 goto name1_only;
255 }
256 } else {
257 name1_only:
258 func->function_name = func->name1;
259 func_sym = mrb_check_intern_cstr(mrb, func->function_name);
260 if (mrb_nil_p(func_sym)) {
261 cf_log_err(cp, "mruby function %s does not exist", func->function_name);
262 return -1;
263 }
264 }
265
266 func = fr_rb_iter_next_inorder(&iter);
267 }
268
269 if (mrb_nil_p(mrb_check_intern_cstr(mrb, "instantiate"))) return 0;
270
271 status = mrb_funcall(mrb, mrb_obj_value(inst->mruby_module), "instantiate", 0);
272 if (mrb_undef_p(status)) {
273 ERROR("Running instantiate failed");
274 return -1;
275 }
276
277 return 0;
278}
279
280static unlang_action_t CC_HINT(nonnull) mod_mruby(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
281{
282 rlm_mruby_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_mruby_t);
283 mruby_call_env_t *func = talloc_get_type_abort(mctx->env_data, mruby_call_env_t);
284 mrb_state *mrb = inst->mrb;
285 mrb_value mruby_packet, mruby_result, mruby_request, mruby_reply, mruby_control, mruby_session_state;
286 mrb_value args[5];
287
288 mruby_packet = mrb_obj_new(mrb, inst->mruby_request, 0, NULL);
289 mrb_iv_set(mrb, mruby_packet, mrb_intern_cstr(mrb, "@frconfig"), inst->mrubyconf_hash);
290
291 args[0] = mruby_inst_object(mrb, inst->mruby_ptr, inst);
292 args[1] = mruby_request_object(mrb, inst->mruby_ptr, request);
293 args[2] = mruby_dict_attr_object(mrb, inst->mruby_ptr, fr_dict_root(request->proto_dict));
294 args[3] = mrb_int_value(mrb, 0);
295 args[4] = mruby_value_pair_object(mrb, inst->mruby_ptr, fr_pair_list_parent(&request->request_pairs));
296 mruby_request = mrb_obj_new(mrb, inst->mruby_pair_list, 5, args);
297 mrb_iv_set(mrb, mruby_packet, mrb_intern_cstr(mrb, "@request"), mruby_request);
298
299 args[4] = mruby_value_pair_object(mrb, inst->mruby_ptr, fr_pair_list_parent(&request->reply_pairs));
300 mruby_reply = mrb_obj_new(mrb, inst->mruby_pair_list, 5, args);
301 mrb_iv_set(mrb, mruby_packet, mrb_intern_cstr(mrb, "@reply"), mruby_reply);
302
303 args[4] = mruby_value_pair_object(mrb, inst->mruby_ptr, fr_pair_list_parent(&request->control_pairs));
304 mruby_control = mrb_obj_new(mrb, inst->mruby_pair_list, 5, args);
305 mrb_iv_set(mrb, mruby_packet, mrb_intern_cstr(mrb, "@control"), mruby_control);
306
307 args[4] = mruby_value_pair_object(mrb, inst->mruby_ptr, fr_pair_list_parent(&request->session_state_pairs));
308 mruby_session_state = mrb_obj_new(mrb, inst->mruby_pair_list, 5, args);
309 mrb_iv_set(mrb, mruby_packet, mrb_intern_cstr(mrb, "@session_state"), mruby_session_state);
310
311 RDEBUG2("Calling %s", func->func->function_name);
313DIAG_OFF(class-varargs)
314 mruby_result = mrb_funcall(mrb, mrb_obj_value(inst->mruby_module), func->func->function_name, 1, mruby_packet);
315DIAG_ON(class-varargs)
317
318 /*
319 * The return should be a fixnum, which is converted to rlm_rcode_t
320 */
321 if (mrb_type(mruby_result) == MRB_TT_FIXNUM) RETURN_UNLANG_RCODE((rlm_rcode_t)mrb_int(mrb, mruby_result));
322
323 /* Invalid return type */
324 RERROR("Expected return to be a Fixnum, got %s instead", RSTRING_PTR(mrb_obj_as_string(mrb, mruby_result)));
326}
327
328/*
329 * Only free memory we allocated. The strings allocated via
330 * cf_section_parse() do not need to be freed.
331 */
332static int mod_detach(module_detach_ctx_t const *mctx)
333{
334 rlm_mruby_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_mruby_t);
335
336 mrb_close(inst->mrb);
337
338 return 0;
339}
340
341/*
342 * Restrict automatic Ruby function names to lowercase characters, numbers and underscore
343 * meaning that a module call in `recv Access-Request` will look for `recv_access_request`
344 */
345static void mruby_func_name_safe(char *name) {
346 char *p;
347 size_t i;
348
349 p = name;
350 for (i = 0; i < talloc_array_length(name); i++) {
351 *p = tolower(*p);
352 if (!strchr("abcdefghijklmnopqrstuvwxyz1234567890", *p)) *p = '_';
353 p++;
354 }
355}
356
357static int mruby_func_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *out, UNUSED tmpl_rules_t const *t_rules,
358 UNUSED CONF_ITEM *ci, call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
359{
360 rlm_mruby_t *inst = talloc_get_type_abort(cec->mi->data, rlm_mruby_t);
361 call_env_parsed_t *parsed;
362 mruby_func_def_t *func;
363 void *found;
364
365 if (!inst->funcs_init) {
367 inst->funcs_init = true;
368 }
369
370 MEM(parsed = call_env_parsed_add(ctx, out,
372 .name = "func",
374 .pair = {
375 .parsed = {
376 .offset = rule->pair.offset,
378 }
379 }
380 }));
381
382 MEM(func = talloc_zero(inst, mruby_func_def_t));
383 func->name1 = talloc_strdup(func, cec->asked->name1);
385 if (cec->asked->name2) {
386 func->name2 = talloc_strdup(func, cec->asked->name2);
388 }
389 if (fr_rb_find_or_insert(&found, &inst->funcs, func) < 0) {
390 talloc_free(func);
391 return -1;
392 }
393
394 /*
395 * If the function call is already in the tree, use that entry.
396 */
397 if (found) {
398 talloc_free(func);
399 call_env_parsed_set_data(parsed, found);
400 } else {
401 call_env_parsed_set_data(parsed, func);
402 }
403 return 0;
404}
405
413
414/*
415 * The module name should be the only globally exported symbol.
416 * That is, everything else should be 'static'.
417 *
418 * If the module needs to temporarily modify it's instantiation
419 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
420 * The server will then take care of ensuring that the module
421 * is single-threaded.
422 */
425 .common = {
426 .magic = MODULE_MAGIC_INIT,
427 .name = "mruby",
428 .flags = MODULE_TYPE_THREAD_UNSAFE, /* Not sure */
429 .inst_size = sizeof(rlm_mruby_t),
432 .detach = mod_detach,
433 },
434 .method_group = {
435 .bindings = (module_method_binding_t[]){
436 { .section = SECTION_NAME(CF_IDENT_ANY, CF_IDENT_ANY), .method = mod_mruby, .method_env = &mruby_method_env },
438 }
439 }
440};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
log_entry msg
Definition acutest.h:794
va_list args
Definition acutest.h:770
#define RCSID(id)
Definition build.h:485
#define DIAG_UNKNOWN_PRAGMAS
Definition build.h:458
#define DIAG_ON(_x)
Definition build.h:460
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition build.h:112
#define UNUSED
Definition build.h:317
#define DIAG_OFF(_x)
Definition build.h:459
call_env_parsed_t * call_env_parsed_add(TALLOC_CTX *ctx, call_env_parsed_head_t *head, call_env_parser_t const *rule)
Allocate a new call_env_parsed_t structure and add it to the list of parsed call envs.
Definition call_env.c:667
void call_env_parsed_set_data(call_env_parsed_t *parsed, void const *data)
Assign data to a call_env_parsed_t.
Definition call_env.c:724
#define CALL_ENV_TERMINATOR
Definition call_env.h:236
#define FR_CALL_ENV_METHOD_OUT(_inst)
Helper macro for populating the size/type fields of a call_env_method_t from the output structure typ...
Definition call_env.h:240
call_env_parser_t const * env
Parsing rules for call method env.
Definition call_env.h:247
section_name_t const * asked
The actual name1/name2 that resolved to a module_method_binding_t.
Definition call_env.h:232
@ CALL_ENV_FLAG_PARSE_ONLY
The result of parsing will not be evaluated at runtime.
Definition call_env.h:85
@ CALL_ENV_FLAG_PARSE_MISSING
If this subsection is missing, still parse it.
Definition call_env.h:88
@ CALL_ENV_PARSE_TYPE_VOID
Output of the parsing phase is undefined (a custom structure).
Definition call_env.h:62
module_instance_t const * mi
Module instance that the callenv is registered to.
Definition call_env.h:229
#define FR_CALL_ENV_SUBSECTION_FUNC(_name, _name2, _flags, _func)
Specify a call_env_parser_t which parses a subsection using a callback function.
Definition call_env.h:412
Per method call config.
Definition call_env.h:180
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:658
#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:284
#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:272
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition cf_parse.h:434
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Definition cf_parse.h:440
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:595
Common header for all CONF_* types.
Definition cf_priv.h:49
Configuration AVP similar to a fr_pair_t.
Definition cf_priv.h:70
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
bool cf_item_is_pair(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_PAIR.
Definition cf_util.c:631
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition cf_util.c:1170
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
Definition cf_util.c:1027
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition cf_util.c:683
CONF_PAIR * cf_pair_find(CONF_SECTION const *cs, char const *attr)
Search for a CONF_PAIR with a specific name.
Definition cf_util.c:1438
bool cf_item_is_section(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_SECTION.
Definition cf_util.c:617
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition cf_util.c:663
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition cf_util.c:1593
char const * cf_pair_attr(CONF_PAIR const *pair)
Return the attr of a CONF_PAIR.
Definition cf_util.c:1577
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
#define cf_item_next(_parent, _curr)
Definition cf_util.h:92
#define CF_IDENT_ANY
Definition cf_util.h:78
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
#define DEBUG(fmt,...)
Definition dhcpclient.c:39
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2403
Test enumeration values.
Definition dict_test.h:92
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
#define RERROR(fmt,...)
Definition log.h:298
talloc_free(reap)
fr_log_t default_log
Definition log.c:292
void fr_log(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt,...)
Send a server log message to its destination.
Definition log.c:581
@ L_DBG_WARN_REQ
Less severe warning only displayed when debugging is enabled.
Definition log.h:63
@ L_WARN
Warning.
Definition log.h:57
@ L_ERR
Error message.
Definition log.h:56
@ L_DBG_ERR
Error only displayed when debugging is enabled.
Definition log.h:62
@ L_DBG_ERR_REQ
Less severe error only displayed when debugging is enabled.
Definition log.h:64
@ L_DBG_WARN
Warning only displayed when debugging is enabled.
Definition log.h:61
@ L_INFO
Informational message.
Definition log.h:55
@ L_DBG
Only displayed when debugging is enabled.
Definition log.h:59
void * env_data
Per call environment data.
Definition module_ctx.h:44
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
module_instance_t * mi
Module instance to detach.
Definition module_ctx.h:57
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
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
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
struct RClass * mruby_request_class(mrb_state *mrb, struct RClass *parent)
Definition mruby.c:63
mrb_value mruby_request_object(mrb_state *mrb, struct RClass *klass, request_t *request)
Definition mruby.c:114
mrb_value mruby_value_pair_object(mrb_state *mrb, struct RClass *klass, fr_pair_t *vp)
Definition mruby.c:124
mrb_value mruby_dict_attr_object(mrb_state *mrb, struct RClass *klass, fr_dict_attr_t const *da)
Definition mruby.c:119
struct RClass * mruby_pair_list_class(mrb_state *mrb, struct RClass *parent)
Definition mruby.c:611
struct RClass * mruby_pair_class(mrb_state *mrb, struct RClass *parent)
Definition mruby.c:625
mrb_value mruby_inst_object(mrb_state *mrb, struct RClass *klass, rlm_mruby_t const *inst)
Definition mruby.c:109
fr_pair_t * fr_pair_list_parent(fr_pair_list_t const *list)
Return a pointer to the parent pair which contains this list.
Definition pair.c:960
static const conf_parser_t config[]
Definition base.c:186
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define WARN(fmt,...)
Definition radclient.h:47
void * fr_rb_iter_init_inorder(fr_rb_iter_inorder_t *iter, fr_rb_tree_t *tree)
Initialise an in-order iterator.
Definition rb.c:824
int fr_rb_find_or_insert(void **found, fr_rb_tree_t *tree, void const *data)
Attempt to find current data in the tree, if it does not exist insert it.
Definition rb.c:598
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
Definition rb.c:850
#define fr_rb_inline_init(_tree, _type, _field, _data_cmp, _data_free)
Initialises a red black tree.
Definition rb.h:180
Iterator structure for in-order traversal of an rbtree.
Definition rb.h:321
#define RETURN_UNLANG_RCODE(_rcode)
Definition rcode.h:66
#define RETURN_UNLANG_FAIL
Definition rcode.h:57
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
@ RLM_MODULE_INVALID
The module considers the request invalid.
Definition rcode.h:45
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:43
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:42
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
Definition rcode.h:46
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:41
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:47
@ RLM_MODULE_UPDATED
OK (pairs modified).
Definition rcode.h:49
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:48
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
Definition rcode.h:51
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:44
static int mod_detach(module_detach_ctx_t const *mctx)
Definition rlm_mruby.c:332
mruby_func_def_t * func
Definition rlm_mruby.c:41
char * name1
Section name1 where this is called.
Definition rlm_mruby.c:35
#define A(x)
static void mruby_func_name_safe(char *name)
Definition rlm_mruby.c:345
static int8_t mruby_func_def_cmp(void const *one, void const *two)
How to compare two Ruby function calls.
Definition rlm_mruby.c:56
static unlang_action_t mod_mruby(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_mruby.c:280
char const * function_name
Name of the function being called.
Definition rlm_mruby.c:34
char * name2
Section name2 where this is called.
Definition rlm_mruby.c:36
static const call_env_method_t mruby_method_env
Definition rlm_mruby.c:406
static mrb_value mruby_log(mrb_state *mrb, UNUSED mrb_value self)
Definition rlm_mruby.c:69
fr_rb_node_t node
Node in tree of function calls.
Definition rlm_mruby.c:37
static int mruby_func_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *out, UNUSED tmpl_rules_t const *t_rules, UNUSED CONF_ITEM *ci, call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
Definition rlm_mruby.c:357
static void mruby_parse_config(mrb_state *mrb, CONF_SECTION *cs, int lvl, mrb_value hash)
Definition rlm_mruby.c:80
module_rlm_t rlm_mruby
Definition rlm_mruby.c:424
static const conf_parser_t module_config[]
Definition rlm_mruby.c:47
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition rlm_mruby.c:140
Translates requests between the server an an mruby interpreter.
static unsigned int hash(char const *username, unsigned int tablesize)
Definition rlm_passwd.c:132
static char const * name
static int instantiate(module_inst_ctx_t const *mctx)
Definition rlm_rest.c:1297
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:40
char const * name2
Second section name. Usually a packet type like 'access-request', 'access-accept',...
Definition section.h:46
char const * name1
First section name. Usually a verb like 'recv', 'send', etc...
Definition section.h:45
@ MODULE_TYPE_THREAD_UNSAFE
Module is not threadsafe.
Definition module.h:49
module_flags_t flags
Flags that control how a module starts up and how a module is called.
Definition module.h:236
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:349
void * data
Module's instance data.
Definition module.h:291
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:332
eap_aka_sim_process_conf_t * inst
static int talloc_const_free(void const *ptr)
Free const'd memory.
Definition talloc.h:229
int nonnull(2, 5))
static size_t char ** out
Definition value.h:1020