The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
rlm_test.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: ff3e1336ee384078ce1e3bb49f99e00307df4f91 $
19  * @file rlm_test.c
20  * @brief test module code.
21  *
22  * @copyright 2013 The FreeRADIUS server project
23  * @copyright 2013 your name (email@example.org)
24  */
25 RCSID("$Id: ff3e1336ee384078ce1e3bb49f99e00307df4f91 $")
26 
27 #define LOG_PREFIX mctx->mi->name
28 
29 #include <freeradius-devel/server/base.h>
30 #include <freeradius-devel/server/module_rlm.h>
31 #include <freeradius-devel/server/tmpl.h>
32 #include <freeradius-devel/util/debug.h>
33 #include <freeradius-devel/util/inet.h>
34 #include <freeradius-devel/unlang/xlat_func.h>
35 
36 /*
37  * Define a structure for our module configuration.
38  *
39  * These variables do not need to be in a structure, but it's
40  * a lot cleaner to do so, and a pointer to the structure can
41  * be used as the instance handle.
42  */
43 typedef struct {
46  char const *string;
47  char const **string_m;
48 
49  bool boolean;
50  bool *boolean_m;
51 
54 
57 
60 
62 
65 
68 
70 
72 
75 
76  uint8_t const *octets;
77  uint8_t const **octets_m;
78 
81 
83  /*
84  * clang correctly performs type compatibility checks between
85  * arrays with a specific length, but for pointers to pointers
86  * to arrays of specific length
87  * (which is what FR_TYPE_CONF_CHECK receives) the check doesn't
88  * seem to work.
89  *
90  * So the "multi" variants of ethernet and ifid buffers, must
91  * be a **.
92  */
96 
98  /*
99  * See above...
100  */
102 
103  int32_t int32;
104  int32_t *int32_m;
105 
106  uint64_t uint64;
107  uint64_t *uint64_m;
108 
111 } rlm_test_t;
112 
113 typedef struct {
115  pthread_t value;
117 
118 /*
119  * A mapping of configuration file names to internal variables.
120  */
121 static const conf_parser_t module_config[] = {
122  { FR_CONF_OFFSET("tmpl", rlm_test_t, tmpl), .dflt = "&Tmp-String-0", .quote = T_BARE_WORD },
123  { FR_CONF_OFFSET("tmpl_m", rlm_test_t, tmpl_m), .dflt = "&Tmp-String-0", .quote = T_DOUBLE_QUOTED_STRING },
124 
125  { FR_CONF_OFFSET("string", rlm_test_t, string) },
126  { FR_CONF_OFFSET("string_m", rlm_test_t, string_m) },
127 
128  { FR_CONF_OFFSET("boolean", rlm_test_t, boolean), .dflt = "no" },
129  { FR_CONF_OFFSET("boolean_m", rlm_test_t, boolean_m), .dflt = "no" },
130 
131  { FR_CONF_OFFSET("integer", rlm_test_t, integer), .dflt = "1" },
132  { FR_CONF_OFFSET_FLAGS("integer_m" , CONF_FLAG_MULTI, rlm_test_t, integer_m), .dflt = "2" },
133 
134  { FR_CONF_OFFSET_TYPE_FLAGS("ipv4_addr", FR_TYPE_IPV4_ADDR, 0, rlm_test_t, ipv4_addr), .dflt = "*" },
135  { FR_CONF_OFFSET_TYPE_FLAGS("ipv4_addr_m", FR_TYPE_IPV4_ADDR, CONF_FLAG_MULTI, rlm_test_t, ipv4_addr_m), .dflt = "*" },
136 
137  { FR_CONF_OFFSET_TYPE_FLAGS("ipv4_prefix", FR_TYPE_IPV4_PREFIX, 0, rlm_test_t, ipv4_addr), .dflt = "192.168.0.1/24" },
138  { FR_CONF_OFFSET_TYPE_FLAGS("ipv4_prefix_m", FR_TYPE_IPV4_PREFIX, CONF_FLAG_MULTI, rlm_test_t, ipv4_addr_m), .dflt = "192.168.0.1/24" },
139 
140  { FR_CONF_OFFSET_TYPE_FLAGS("ipv6_addr", FR_TYPE_IPV6_ADDR, 0, rlm_test_t, ipv6_addr), .dflt = "*" },
141  { FR_CONF_OFFSET_TYPE_FLAGS("ipv6_addr_m", FR_TYPE_IPV6_ADDR, CONF_FLAG_MULTI, rlm_test_t, ipv6_addr_m), .dflt = "*" },
142 
143  { FR_CONF_OFFSET_TYPE_FLAGS("ipv6_prefix", FR_TYPE_IPV6_PREFIX, 0, rlm_test_t, ipv6_prefix), .dflt = "::1/128" },
144  { FR_CONF_OFFSET_TYPE_FLAGS("ipv6_prefix_m", FR_TYPE_IPV6_PREFIX, CONF_FLAG_MULTI, rlm_test_t, ipv6_prefix_m), .dflt = "::1/128" },
145 
146  { FR_CONF_OFFSET_TYPE_FLAGS("combo", FR_TYPE_COMBO_IP_ADDR, 0, rlm_test_t, combo_ipaddr), .dflt = "::1/128" },
147  { FR_CONF_OFFSET_TYPE_FLAGS("combo_m", FR_TYPE_COMBO_IP_ADDR, CONF_FLAG_MULTI, rlm_test_t, combo_ipaddr_m), .dflt = "::1/128" },
148 
149  { FR_CONF_OFFSET("date", rlm_test_t, date) },
150  { FR_CONF_OFFSET("date_m", rlm_test_t, date_m) },
151 
152  { FR_CONF_OFFSET("octets", rlm_test_t, octets) },
153  { FR_CONF_OFFSET("octets_m", rlm_test_t, octets_m) },
154 
155  { FR_CONF_OFFSET("bytes", rlm_test_t, byte) },
156  { FR_CONF_OFFSET("bytes_m", rlm_test_t, byte_m) },
157 
158  { FR_CONF_OFFSET("ifid", rlm_test_t, ifid) },
159  { FR_CONF_OFFSET("ifid_m", rlm_test_t, ifid_m) },
160 
161  { FR_CONF_OFFSET("short", rlm_test_t, shortint) },
162  { FR_CONF_OFFSET("short_m", rlm_test_t, shortint_m) },
163 
164  { FR_CONF_OFFSET("ethernet", rlm_test_t, ethernet) },
165  { FR_CONF_OFFSET("ethernet_m", rlm_test_t, ethernet_m) },
166 
167  { FR_CONF_OFFSET("signed", rlm_test_t, int32) },
168  { FR_CONF_OFFSET("signed_m", rlm_test_t, int32_m) },
169 
170  { FR_CONF_OFFSET("uint64", rlm_test_t, uint64) },
171  { FR_CONF_OFFSET("uint64_m", rlm_test_t, uint64_m) },
172 
173  { FR_CONF_OFFSET("time_delta", rlm_test_t, time_delta) },
174  { FR_CONF_OFFSET("time_delta_t", rlm_test_t, time_delta_m) },
175 
177 };
178 
179 static fr_dict_t const *dict_radius;
180 
183  { .out = &dict_radius, .proto = "radius" },
184  { NULL }
185 };
186 
188 
191  { .out = &attr_user_name, .name = "User-Name", .type = FR_TYPE_STRING, .dict = &dict_radius },
192  { NULL }
193 };
194 
195 /*
196  * Find the named user in this modules database. Create the set
197  * of attribute-value pairs to check and reply with for this user
198  * from the database. The authentication code only needs to check
199  * the password, the rest is done here.
200  */
201 static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
202 {
203  rlm_test_thread_t *t = mctx->thread;
204 
205  RINFO("RINFO message");
206  RDEBUG("RDEBUG message");
207  RDEBUG2("RDEBUG2 message");
208 
209  RWARN("RWARN message");
210  RWDEBUG("RWDEBUG message");
211  RWDEBUG("RWDEBUG2 message");
212 
213  /*
214  * Should appear wavy
215  */
216  RERROR("RERROR error message");
217  RINDENT();
218  REDEBUG("RDEBUG error message");
219  REXDENT();
220  REDEBUG2("RDEBUG2 error message");
221  RINDENT();
222  REDEBUG3("RDEBUG3 error message");
223  REXDENT();
224  REDEBUG4("RDEBUG4 error message");
225 
226  if (!fr_cond_assert(t->value == pthread_self())) RETURN_MODULE_FAIL;
227 
229 }
230 
231 /*
232  * Authenticate the user with the given password.
233  */
234 static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
235 {
236  rlm_test_thread_t *t = mctx->thread;
237 
238  if (!fr_cond_assert(t->value == pthread_self())) RETURN_MODULE_FAIL;
239 
241 }
242 
243 /*
244  * Massage the request before recording it or proxying it
245  */
246 static unlang_action_t CC_HINT(nonnull) mod_preacct(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
247 {
248  rlm_test_thread_t *t = mctx->thread;
249 
250  if (!fr_cond_assert(t->value == pthread_self())) RETURN_MODULE_FAIL;
251 
253 }
254 
255 /*
256  * Write accounting information to this modules database.
257  */
258 static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
259 {
260  rlm_test_thread_t *t = mctx->thread;
261 
262  if (!fr_cond_assert(t->value == pthread_self())) RETURN_MODULE_FAIL;
263 
265 }
266 
267 /*
268  * Write accounting information to this modules database.
269  */
270 static unlang_action_t CC_HINT(nonnull) mod_return(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, UNUSED request_t *request)
271 {
273 }
274 
275 static void mod_retry_signal(module_ctx_t const *mctx, request_t *request, fr_signal_t action);
276 
277 /** Continue after marked runnable
278  *
279  */
281 {
282  RDEBUG("Test called main retry handler - that's a failure");
283 
285 }
286 
287 /** Continue after FR_SIGNAL_RETRY
288  *
289  */
291 {
292  RDEBUG("Test retry");
293 
294  return unlang_module_yield(request, mod_retry_resume, mod_retry_signal, 0, NULL);
295 }
296 
297 /** Continue after FR_SIGNAL_TIMEOUT
298  *
299  */
301 {
302  RDEBUG("Test timed out as expected");
303 
305 }
306 
307 static void mod_retry_signal(UNUSED module_ctx_t const *mctx, request_t *request, fr_signal_t action)
308 {
309  switch (action) {
310  case FR_SIGNAL_RETRY:
311  RDEBUG("Test retry");
314  break;
315 
316  case FR_SIGNAL_TIMEOUT:
317  RDEBUG("Test timeout");
320  break;
321 
322  /*
323  * Ignore all other signals.
324  */
325  default:
326  break;
327  }
328 
329 }
330 
331 /*
332  * Test retries
333  */
334 static unlang_action_t CC_HINT(nonnull) mod_retry(UNUSED rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
335 {
336  return unlang_module_yield(request, mod_retry_resume, mod_retry_signal, 0, NULL);
337 }
338 
339 
341  { .required = true, .single = true, .type = FR_TYPE_STRING },
343 };
344 
345 
346 /** Run a trigger (useful for testing)
347  *
348  */
350  UNUSED xlat_ctx_t const *xctx, request_t *request,
351  fr_value_box_list_t *in)
352 {
353  fr_value_box_t *in_head = fr_value_box_list_head(in);
354  fr_value_box_t *vb;
355 
356  MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL));
357  fr_dcursor_append(out, vb);
358 
359  if (trigger_exec(unlang_interpret_get(request), NULL, in_head->vb_strvalue, false, NULL) < 0) {
360  RPEDEBUG("Running trigger failed");
361  vb->vb_bool = false;
362  return XLAT_ACTION_FAIL;
363  }
364 
365  vb->vb_bool = true;
366 
367  return XLAT_ACTION_DONE;
368 }
369 
370 
372  { .required = true, .concat = true, .type = FR_TYPE_STRING },
373  { .variadic = XLAT_ARG_VARIADIC_EMPTY_KEEP, .concat = true, .type = FR_TYPE_STRING },
375 };
376 
377 
378 /** Run a generic xlat (useful for testing)
379  *
380  * This just copies the input to the output.
381  */
383  UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request,
384  fr_value_box_list_t *in)
385 {
386  fr_value_box_t *vb;
387 
389  MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL));
390 
391  if (fr_value_box_copy(vb, vb, vb_p) < 0) {
392  talloc_free(vb);
393  return XLAT_ACTION_FAIL;
394  }
395 
396  fr_dcursor_append(out, vb);
397  }
398 
399  return XLAT_ACTION_DONE;
400 }
401 
402 
404  { .required = false, .concat = true, .type = FR_TYPE_STRING },
406 };
407 
408 
409 /** Always return XLAT_ACTION_FAIL
410  */
412  UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request,
413  UNUSED fr_value_box_list_t *in)
414 {
415  return XLAT_ACTION_FAIL;
416 }
417 
418 
420 {
421  rlm_test_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_test_t);
422  rlm_test_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_test_thread_t);
423 
424  t->inst = inst;
425  t->value = pthread_self();
426  INFO("Performing instantiation for thread %p (ctx %p)", (void *)t->value, t);
427 
428  return 0;
429 }
430 
432 {
433  rlm_test_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_test_thread_t);
434 
435  INFO("Performing detach for thread %p", (void *)t->value);
436 
437  if (!fr_cond_assert(t->value == pthread_self())) return -1;
438 
439  return 0;
440 }
441 
442 /*
443  * Do any per-module bootstrapping that is separate to each
444  * configured instance of the module. e.g. set up connections
445  * to external databases, read configuration files, set up
446  * dictionary entries, etc.
447  *
448  * If configuration information is given in the config section
449  * that must be referenced in later calls, store a handle to it
450  * in *instance otherwise put a null pointer there.
451  */
452 static int mod_bootstrap(module_inst_ctx_t const *mctx)
453 {
454  rlm_test_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_test_t);
455  xlat_t *xlat;
456 
457  /*
458  * Log some messages
459  */
460  INFO("Informational message");
461  WARN("Warning message");
462  ERROR("Error message");
463  DEBUG("Debug message");
464  DEBUG2("Debug2 message");
465  DEBUG3("Debug3 message");
466  DEBUG4("Debug4 message");
467 
468  /*
469  * Output parsed tmpls
470  */
471  if (inst->tmpl) {
472  INFO("%s", inst->tmpl->name);
473  } else {
474  INFO("inst->tmpl is NULL");
475  }
476 
477  if (inst->tmpl_m) {
478  talloc_foreach(inst->tmpl_m, item) INFO("%s", item->name);
479  } else {
480  INFO("inst->tmpl_m is NULL");
481  }
482 
483  if (!(xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "passthrough", test_xlat_passthrough, FR_TYPE_VOID))) return -1;
485 
486  if (!(xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "fail", test_xlat_fail, FR_TYPE_VOID))) return -1;
488 
489  return 0;
490 }
491 
492 static int mod_load(void)
493 {
494  xlat_t *xlat;
495 
496  if (!(xlat = xlat_func_register(NULL, "test_trigger", trigger_test_xlat, FR_TYPE_BOOL))) return -1;
498 
499  return 0;
500 }
501 
502 static void mod_unload(void)
503 {
504  xlat_func_unregister("test_trigger");
505 }
506 
507 /*
508  * The module name should be the only globally exported symbol.
509  * That is, everything else should be 'static'.
510  *
511  * If the module needs to temporarily modify it's instantiation
512  * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
513  * The server will then take care of ensuring that the module
514  * is single-threaded.
515  */
516 extern module_rlm_t rlm_test;
518  .common = {
519  .magic = MODULE_MAGIC_INIT,
520  .name = "test",
521  .flags = MODULE_TYPE_RETRY,
522  .inst_size = sizeof(rlm_test_t),
523  .thread_inst_size = sizeof(rlm_test_thread_t),
524  .config = module_config,
525  .bootstrap = mod_bootstrap,
526  .onload = mod_load,
527  .unload = mod_unload,
528  .thread_instantiate = mod_thread_instantiate,
529  .thread_detach = mod_thread_detach
530  },
531  .method_group = {
532  .bindings = (module_method_binding_t[]){
533  { .section = SECTION_NAME("accounting", CF_IDENT_ANY), .method = mod_accounting },
534  { .section = SECTION_NAME("authenticate", CF_IDENT_ANY), .method = mod_authenticate },
535  { .section = SECTION_NAME("authorize", CF_IDENT_ANY), .method = mod_authorize },
536 
537  { .section = SECTION_NAME("name1_null", NULL), .method = mod_return },
538 
539  { .section = SECTION_NAME("recv", "access-challenge"), .method = mod_return },
540  { .section = SECTION_NAME("recv", "accounting-request"), .method = mod_preacct },
541  { .section = SECTION_NAME("recv", CF_IDENT_ANY), .method = mod_authorize },
542 
543  { .section = SECTION_NAME("retry", NULL), .method = mod_retry },
544  { .section = SECTION_NAME("send", CF_IDENT_ANY), .method = mod_return },
545 
547  }
548  }
549 };
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
#define RCSID(id)
Definition: build.h:446
#define UNUSED
Definition: build.h:313
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:626
#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_MULTI
CONF_PAIR can have multiple copies.
Definition: cf_parse.h:420
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _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:241
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
#define CF_IDENT_ANY
Definition: cf_util.h:78
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition: dcursor.h:405
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:139
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
#define DEBUG(fmt,...)
Definition: dhcpclient.c:39
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:250
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:263
static fr_slen_t in
Definition: dict.h:645
Specifies an attribute which must be present for the module to function.
Definition: dict.h:249
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:262
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:63
Struct to represent an ethernet address.
Definition: inet.h:45
Struct to represent an interface id.
Definition: inet.h:54
IPv4/6 prefix.
Definition: merged_model.c:272
unlang_interpret_t * unlang_interpret_get(request_t *request)
Get the interpreter set for a request.
Definition: interpret.c:1754
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
Definition: interpret.c:1359
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition: log.h:443
#define DEBUG3(_fmt,...)
Definition: log.h:266
#define RWDEBUG(fmt,...)
Definition: log.h:361
#define REDEBUG3(fmt,...)
Definition: log.h:373
#define RWARN(fmt,...)
Definition: log.h:297
#define RERROR(fmt,...)
Definition: log.h:298
#define DEBUG4(_fmt,...)
Definition: log.h:267
#define RINFO(fmt,...)
Definition: log.h:296
#define RPEDEBUG(fmt,...)
Definition: log.h:376
#define REDEBUG2(fmt,...)
Definition: log.h:372
#define REDEBUG4(fmt,...)
Definition: log.h:374
#define RINDENT()
Indent R* messages by one level.
Definition: log.h:430
talloc_free(reap)
static void * item(fr_lst_t const *lst, fr_lst_index_t idx)
Definition: lst.c:122
unsigned short uint16_t
Definition: merged_model.c:31
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
Definition: merged_model.c:86
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
Definition: merged_model.c:89
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
Definition: merged_model.c:88
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
Definition: merged_model.c:87
@ FR_TYPE_VOID
User data.
Definition: merged_model.c:127
@ FR_TYPE_BOOL
A truth value.
Definition: merged_model.c:95
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
Definition: merged_model.c:91
unsigned int uint32_t
Definition: merged_model.c:33
unsigned char uint8_t
Definition: merged_model.c:30
void * thread
Thread specific instance data.
Definition: module_ctx.h:43
void * thread
Thread instance data.
Definition: module_ctx.h:67
module_instance_t const * mi
Instance of the module being instantiated.
Definition: module_ctx.h:64
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 instantiation calls.
Definition: module_ctx.h:50
Temporary structure to hold arguments for thread_instantiation calls.
Definition: module_ctx.h:63
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Definition: module_rlm.c:257
module_t common
Common fields presented by all modules.
Definition: module_rlm.h:39
#define REDEBUG(fmt,...)
Definition: radclient.h:52
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
#define RDEBUG(fmt,...)
Definition: radclient.h:53
#define DEBUG2(fmt,...)
Definition: radclient.h:43
#define WARN(fmt,...)
Definition: radclient.h:47
#define INFO(fmt,...)
Definition: radict.c:54
#define RETURN_MODULE_OK
Definition: rcode.h:57
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
static xlat_arg_parser_t const test_xlat_fail_args[]
Definition: rlm_test.c:403
static int mod_load(void)
Definition: rlm_test.c:492
int32_t int32
Definition: rlm_test.c:103
static unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
Definition: rlm_test.c:234
tmpl_t * tmpl
Definition: rlm_test.c:44
static void mod_retry_signal(module_ctx_t const *mctx, request_t *request, fr_signal_t action)
fr_time_delta_t time_delta
Definition: rlm_test.c:109
fr_ipaddr_t * ipv4_addr_m
Definition: rlm_test.c:63
static xlat_action_t trigger_test_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Run a trigger (useful for testing)
Definition: rlm_test.c:349
fr_ipaddr_t * ipv4_prefix_m
Definition: rlm_test.c:64
fr_ipaddr_t ipv6_addr
Definition: rlm_test.c:58
fr_time_t * date_m
Definition: rlm_test.c:74
fr_ipaddr_t ipaddr
Definition: rlm_test.c:71
fr_ipaddr_t * ipv6_addr_m
Definition: rlm_test.c:66
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
static unlang_action_t mod_retry_resume(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
Continue after marked runnable.
Definition: rlm_test.c:280
fr_ifid_t ifid
Definition: rlm_test.c:82
fr_ipaddr_t * combo_ipaddr_m
Definition: rlm_test.c:69
static unlang_action_t mod_accounting(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
Definition: rlm_test.c:258
fr_ipaddr_t ipv4_addr
Definition: rlm_test.c:55
fr_time_delta_t * time_delta_m
Definition: rlm_test.c:110
fr_ipaddr_t ipv6_prefix
Definition: rlm_test.c:59
static xlat_arg_parser_t const test_xlat_passthrough_args[]
Definition: rlm_test.c:371
uint8_t byte
Definition: rlm_test.c:79
static fr_dict_t const * dict_radius
Definition: rlm_test.c:179
static xlat_arg_parser_t const trigger_test_xlat_args[]
Definition: rlm_test.c:340
fr_ipaddr_t combo_ipaddr
Definition: rlm_test.c:61
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Definition: rlm_test.c:452
static xlat_action_t test_xlat_passthrough(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
Run a generic xlat (useful for testing)
Definition: rlm_test.c:382
uint8_t const * octets
Definition: rlm_test.c:76
static void mod_unload(void)
Definition: rlm_test.c:502
static unlang_action_t mod_return(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, UNUSED request_t *request)
Definition: rlm_test.c:270
fr_ethernet_t ethernet
Definition: rlm_test.c:97
uint32_t integer
Definition: rlm_test.c:52
bool * boolean_m
Definition: rlm_test.c:50
uint8_t * byte_m
Definition: rlm_test.c:80
pthread_t value
Definition: rlm_test.c:115
char const ** string_m
Definition: rlm_test.c:47
fr_dict_autoload_t rlm_test_dict[]
Definition: rlm_test.c:182
tmpl_t ** tmpl_m
Definition: rlm_test.c:45
bool boolean
Definition: rlm_test.c:49
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition: rlm_test.c:201
module_rlm_t rlm_test
Definition: rlm_test.c:517
uint16_t * shortint_m
Definition: rlm_test.c:95
rlm_test_t * inst
Definition: rlm_test.c:114
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Definition: rlm_test.c:419
uint64_t * uint64_m
Definition: rlm_test.c:107
fr_ethernet_t * ethernet_m
Definition: rlm_test.c:101
fr_dict_attr_autoload_t rlm_test_dict_attr[]
Definition: rlm_test.c:190
fr_ifid_t * ifid_m
Definition: rlm_test.c:93
fr_ipaddr_t * ipv6_prefix_m
Definition: rlm_test.c:67
fr_time_t date
Definition: rlm_test.c:73
uint8_t const ** octets_m
Definition: rlm_test.c:77
int32_t * int32_m
Definition: rlm_test.c:104
char const * string
Definition: rlm_test.c:46
static fr_dict_attr_t const * attr_user_name
Definition: rlm_test.c:187
static unlang_action_t mod_retry_resume_retry(UNUSED rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
Continue after FR_SIGNAL_RETRY.
Definition: rlm_test.c:290
static unlang_action_t mod_retry_resume_timeout(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
Continue after FR_SIGNAL_TIMEOUT.
Definition: rlm_test.c:300
uint64_t uint64
Definition: rlm_test.c:106
static const conf_parser_t module_config[]
Definition: rlm_test.c:121
static xlat_action_t test_xlat_fail(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
Always return XLAT_ACTION_FAIL.
Definition: rlm_test.c:411
uint32_t * integer_m
Definition: rlm_test.c:53
fr_ipaddr_t ipv4_prefix
Definition: rlm_test.c:56
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
Definition: rlm_test.c:431
static unlang_action_t mod_retry(UNUSED rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
Definition: rlm_test.c:334
uint16_t shortint
Definition: rlm_test.c:94
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition: section.h:40
@ MODULE_TYPE_RETRY
can handle retries
Definition: module.h:50
void * data
Module's instance data.
Definition: module.h:271
void * boot
Data allocated during the boostrap phase.
Definition: module.h:274
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition: module.h:151
Named methods exported by a module.
Definition: module.h:173
fr_signal_t
Definition: signal.h:48
int unlang_module_set_resume(request_t *request, module_method_t resume)
Change the resume function of a module.
Definition: module.c:403
unlang_action_t unlang_module_yield(request_t *request, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
Definition: module.c:578
RETURN_MODULE_FAIL
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
#define talloc_foreach(_array, _iter)
Iterate over a talloced array of elements.
Definition: talloc.h:75
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
"server local" time.
Definition: time.h:69
@ T_BARE_WORD
Definition: token.h:120
@ T_DOUBLE_QUOTED_STRING
Definition: token.h:121
int trigger_exec(unlang_interpret_t *intp, CONF_SECTION const *cs, char const *name, bool rate_limit, fr_pair_list_t *args)
Execute a trigger - call an executable to process an event.
Definition: trigger.c:233
bool required
Argument must be present, and non-empty.
Definition: xlat.h:145
@ XLAT_ARG_VARIADIC_EMPTY_KEEP
Empty argument groups are left alone, and either passed through as empty groups or null boxes.
Definition: xlat.h:136
#define XLAT_ARG_PARSER_TERMINATOR
Definition: xlat.h:165
xlat_action_t
Definition: xlat.h:35
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition: xlat.h:42
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition: xlat.h:41
Definition for a single argument consumend by an xlat function.
Definition: xlat.h:144
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
Definition: value.c:3689
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
Definition: value.h:608
int nonnull(2, 5))
#define fr_value_box_list_foreach(_list_head, _iter)
Definition: value.h:199
static size_t char ** out
Definition: value.h:984
An xlat calling ctx.
Definition: xlat_ctx.h:49
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition: xlat_func.c:365
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
Definition: xlat_func.c:218
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition: xlat_func.c:518