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: e714d2a16ddac36ca07c3c2cd2e331059358fdb4 $
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: e714d2a16ddac36ca07c3c2cd2e331059358fdb4 $")
26 
27 #define LOG_PREFIX mctx->inst->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 {
44  char const *name;
45 
48  char const *string;
49  char const **string_m;
50 
51  bool boolean;
52  bool *boolean_m;
53 
56 
59 
62 
64 
67 
70 
72 
74 
77 
78  uint8_t const *octets;
79  uint8_t const **octets_m;
80 
83 
85  /*
86  * clang correctly performs type compatibility checks between
87  * arrays with a specific length, but for pointers to pointers
88  * to arrays of specific length
89  * (which is what FR_TYPE_CONF_CHECK receives) the check doesn't
90  * seem to work.
91  *
92  * So the "multi" variants of ethernet and ifid buffers, must
93  * be a **.
94  */
98 
100  /*
101  * See above...
102  */
104 
105  int32_t int32;
106  int32_t *int32_m;
107 
108  uint64_t uint64;
109  uint64_t *uint64_m;
110 
113 } rlm_test_t;
114 
115 typedef struct {
117  pthread_t value;
119 
120 /*
121  * A mapping of configuration file names to internal variables.
122  */
123 static const conf_parser_t module_config[] = {
124  { FR_CONF_OFFSET("tmpl", rlm_test_t, tmpl), .dflt = "&Tmp-String-0", .quote = T_BARE_WORD },
125  { FR_CONF_OFFSET("tmpl_m", rlm_test_t, tmpl_m), .dflt = "&Tmp-String-0", .quote = T_DOUBLE_QUOTED_STRING },
126 
127  { FR_CONF_OFFSET("string", rlm_test_t, string) },
128  { FR_CONF_OFFSET("string_m", rlm_test_t, string_m) },
129 
130  { FR_CONF_OFFSET("boolean", rlm_test_t, boolean), .dflt = "no" },
131  { FR_CONF_OFFSET("boolean_m", rlm_test_t, boolean_m), .dflt = "no" },
132 
133  { FR_CONF_OFFSET("integer", rlm_test_t, integer), .dflt = "1" },
134  { FR_CONF_OFFSET_FLAGS("integer_m" , CONF_FLAG_MULTI, rlm_test_t, integer_m), .dflt = "2" },
135 
136  { FR_CONF_OFFSET_TYPE_FLAGS("ipv4_addr", FR_TYPE_IPV4_ADDR, 0, rlm_test_t, ipv4_addr), .dflt = "*" },
137  { FR_CONF_OFFSET_TYPE_FLAGS("ipv4_addr_m", FR_TYPE_IPV4_ADDR, CONF_FLAG_MULTI, rlm_test_t, ipv4_addr_m), .dflt = "*" },
138 
139  { FR_CONF_OFFSET_TYPE_FLAGS("ipv4_prefix", FR_TYPE_IPV4_PREFIX, 0, rlm_test_t, ipv4_addr), .dflt = "192.168.0.1/24" },
140  { 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" },
141 
142  { FR_CONF_OFFSET_TYPE_FLAGS("ipv6_addr", FR_TYPE_IPV6_ADDR, 0, rlm_test_t, ipv6_addr), .dflt = "*" },
143  { FR_CONF_OFFSET_TYPE_FLAGS("ipv6_addr_m", FR_TYPE_IPV6_ADDR, CONF_FLAG_MULTI, rlm_test_t, ipv6_addr_m), .dflt = "*" },
144 
145  { FR_CONF_OFFSET_TYPE_FLAGS("ipv6_prefix", FR_TYPE_IPV6_PREFIX, 0, rlm_test_t, ipv6_prefix), .dflt = "::1/128" },
146  { FR_CONF_OFFSET_TYPE_FLAGS("ipv6_prefix_m", FR_TYPE_IPV6_PREFIX, CONF_FLAG_MULTI, rlm_test_t, ipv6_prefix_m), .dflt = "::1/128" },
147 
148  { FR_CONF_OFFSET_TYPE_FLAGS("combo", FR_TYPE_COMBO_IP_ADDR, 0, rlm_test_t, combo_ipaddr), .dflt = "::1/128" },
149  { FR_CONF_OFFSET_TYPE_FLAGS("combo_m", FR_TYPE_COMBO_IP_ADDR, CONF_FLAG_MULTI, rlm_test_t, combo_ipaddr_m), .dflt = "::1/128" },
150 
151  { FR_CONF_OFFSET("date", rlm_test_t, date) },
152  { FR_CONF_OFFSET("date_m", rlm_test_t, date_m) },
153 
154  { FR_CONF_OFFSET("octets", rlm_test_t, octets) },
155  { FR_CONF_OFFSET("octets_m", rlm_test_t, octets_m) },
156 
157  { FR_CONF_OFFSET("bytes", rlm_test_t, byte) },
158  { FR_CONF_OFFSET("bytes_m", rlm_test_t, byte_m) },
159 
160  { FR_CONF_OFFSET("ifid", rlm_test_t, ifid) },
161  { FR_CONF_OFFSET("ifid_m", rlm_test_t, ifid_m) },
162 
163  { FR_CONF_OFFSET("short", rlm_test_t, shortint) },
164  { FR_CONF_OFFSET("short_m", rlm_test_t, shortint_m) },
165 
166  { FR_CONF_OFFSET("ethernet", rlm_test_t, ethernet) },
167  { FR_CONF_OFFSET("ethernet_m", rlm_test_t, ethernet_m) },
168 
169  { FR_CONF_OFFSET("signed", rlm_test_t, int32) },
170  { FR_CONF_OFFSET("signed_m", rlm_test_t, int32_m) },
171 
172  { FR_CONF_OFFSET("uint64", rlm_test_t, uint64) },
173  { FR_CONF_OFFSET("uint64_m", rlm_test_t, uint64_m) },
174 
175  { FR_CONF_OFFSET("time_delta", rlm_test_t, time_delta) },
176  { FR_CONF_OFFSET("time_delta_t", rlm_test_t, time_delta_m) },
177 
179 };
180 
181 static fr_dict_t const *dict_radius;
182 
185  { .out = &dict_radius, .proto = "radius" },
186  { NULL }
187 };
188 
190 
193  { .out = &attr_user_name, .name = "User-Name", .type = FR_TYPE_STRING, .dict = &dict_radius },
194  { NULL }
195 };
196 
197 /*
198  * Find the named user in this modules database. Create the set
199  * of attribute-value pairs to check and reply with for this user
200  * from the database. The authentication code only needs to check
201  * the password, the rest is done here.
202  */
203 static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
204 {
205  rlm_test_thread_t *t = mctx->thread;
206 
207  RINFO("RINFO message");
208  RDEBUG("RDEBUG message");
209  RDEBUG2("RDEBUG2 message");
210 
211  RWARN("RWARN message");
212  RWDEBUG("RWDEBUG message");
213  RWDEBUG("RWDEBUG2 message");
214 
215  /*
216  * Should appear wavy
217  */
218  RERROR("RERROR error message");
219  RINDENT();
220  REDEBUG("RDEBUG error message");
221  REXDENT();
222  REDEBUG2("RDEBUG2 error message");
223  RINDENT();
224  REDEBUG3("RDEBUG3 error message");
225  REXDENT();
226  REDEBUG4("RDEBUG4 error message");
227 
228  if (!fr_cond_assert(t->value == pthread_self())) RETURN_MODULE_FAIL;
229 
231 }
232 
233 /*
234  * Authenticate the user with the given password.
235  */
236 static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
237 {
238  rlm_test_thread_t *t = mctx->thread;
239 
240  if (!fr_cond_assert(t->value == pthread_self())) RETURN_MODULE_FAIL;
241 
243 }
244 
245 /*
246  * Massage the request before recording it or proxying it
247  */
248 static unlang_action_t CC_HINT(nonnull) mod_preacct(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
249 {
250  rlm_test_thread_t *t = mctx->thread;
251 
252  if (!fr_cond_assert(t->value == pthread_self())) RETURN_MODULE_FAIL;
253 
255 }
256 
257 /*
258  * Write accounting information to this modules database.
259  */
260 static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
261 {
262  rlm_test_thread_t *t = mctx->thread;
263 
264  if (!fr_cond_assert(t->value == pthread_self())) RETURN_MODULE_FAIL;
265 
267 }
268 
269 /*
270  * Write accounting information to this modules database.
271  */
272 static unlang_action_t CC_HINT(nonnull) mod_return(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, UNUSED request_t *request)
273 {
275 }
276 
277 static void mod_retry_signal(module_ctx_t const *mctx, request_t *request, fr_signal_t action);
278 
279 /** Continue after marked runnable
280  *
281  */
283 {
284  RDEBUG("Test called main retry handler - that's a failure");
285 
287 }
288 
289 /** Continue after FR_SIGNAL_RETRY
290  *
291  */
293 {
294  RDEBUG("Test retry");
295 
296  return unlang_module_yield(request, mod_retry_resume, mod_retry_signal, 0, NULL);
297 }
298 
299 /** Continue after FR_SIGNAL_TIMEOUT
300  *
301  */
303 {
304  RDEBUG("Test timed out as expected");
305 
307 }
308 
309 static void mod_retry_signal(UNUSED module_ctx_t const *mctx, request_t *request, fr_signal_t action)
310 {
311  switch (action) {
312  case FR_SIGNAL_RETRY:
313  RDEBUG("Test retry");
316  break;
317 
318  case FR_SIGNAL_TIMEOUT:
319  RDEBUG("Test timeout");
322  break;
323 
324  /*
325  * Ignore all other signals.
326  */
327  default:
328  break;
329  }
330 
331 }
332 
333 /*
334  * Test retries
335  */
336 static unlang_action_t CC_HINT(nonnull) mod_retry(UNUSED rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
337 {
338  return unlang_module_yield(request, mod_retry_resume, mod_retry_signal, 0, NULL);
339 }
340 
341 
343  { .required = true, .single = true, .type = FR_TYPE_STRING },
345 };
346 
347 
348 /** Run a trigger (useful for testing)
349  *
350  */
352  UNUSED xlat_ctx_t const *xctx, request_t *request,
353  fr_value_box_list_t *in)
354 {
355  fr_value_box_t *in_head = fr_value_box_list_head(in);
356  fr_value_box_t *vb;
357 
358  MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL));
359  fr_dcursor_append(out, vb);
360 
361  if (trigger_exec(unlang_interpret_get(request), NULL, in_head->vb_strvalue, false, NULL) < 0) {
362  RPEDEBUG("Running trigger failed");
363  vb->vb_bool = false;
364  return XLAT_ACTION_FAIL;
365  }
366 
367  vb->vb_bool = true;
368 
369  return XLAT_ACTION_DONE;
370 }
371 
372 
374  { .required = true, .concat = true, .type = FR_TYPE_STRING },
375  { .variadic = XLAT_ARG_VARIADIC_EMPTY_KEEP, .concat = true, .type = FR_TYPE_STRING },
377 };
378 
379 
380 /** Run a generic xlat (useful for testing)
381  *
382  * This just copies the input to the output.
383  */
385  UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request,
386  fr_value_box_list_t *in)
387 {
388  fr_value_box_t *vb;
389 
391  MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL));
392 
393  if (fr_value_box_copy(vb, vb, vb_p) < 0) {
394  talloc_free(vb);
395  return XLAT_ACTION_FAIL;
396  }
397 
398  fr_dcursor_append(out, vb);
399  }
400 
401  return XLAT_ACTION_DONE;
402 }
403 
404 
406  { .required = false, .concat = true, .type = FR_TYPE_STRING },
408 };
409 
410 
411 /** Always return XLAT_ACTION_FAIL
412  */
414  UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request,
415  UNUSED fr_value_box_list_t *in)
416 {
417  return XLAT_ACTION_FAIL;
418 }
419 
420 
422 {
423  rlm_test_t *inst = talloc_get_type_abort(mctx->inst->data, rlm_test_t);
424  rlm_test_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_test_thread_t);
425 
426  t->inst = inst;
427  t->value = pthread_self();
428  INFO("Performing instantiation for thread %p (ctx %p)", (void *)t->value, t);
429 
430  return 0;
431 }
432 
434 {
435  rlm_test_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_test_thread_t);
436 
437  INFO("Performing detach for thread %p", (void *)t->value);
438 
439  if (!fr_cond_assert(t->value == pthread_self())) return -1;
440 
441  return 0;
442 }
443 
444 /*
445  * Do any per-module bootstrapping that is separate to each
446  * configured instance of the module. e.g. set up connections
447  * to external databases, read configuration files, set up
448  * dictionary entries, etc.
449  *
450  * If configuration information is given in the config section
451  * that must be referenced in later calls, store a handle to it
452  * in *instance otherwise put a null pointer there.
453  */
454 static int mod_bootstrap(module_inst_ctx_t const *mctx)
455 {
456  rlm_test_t *inst = talloc_get_type_abort(mctx->inst->data, rlm_test_t);
457  xlat_t *xlat;
458 
459  /*
460  * Log some messages
461  */
462  INFO("Informational message");
463  WARN("Warning message");
464  ERROR("Error message");
465  DEBUG("Debug message");
466  DEBUG2("Debug2 message");
467  DEBUG3("Debug3 message");
468  DEBUG4("Debug4 message");
469 
470  /*
471  * Output parsed tmpls
472  */
473  if (inst->tmpl) {
474  INFO("%s", inst->tmpl->name);
475  } else {
476  INFO("inst->tmpl is NULL");
477  }
478 
479  if (inst->tmpl_m) {
480  talloc_foreach(inst->tmpl_m, item) INFO("%s", item->name);
481  } else {
482  INFO("inst->tmpl_m is NULL");
483  }
484 
485  if (!(xlat = xlat_func_register_module(inst, mctx, "passthrough", test_xlat_passthrough, FR_TYPE_VOID))) return -1;
487 
488  if (!(xlat = xlat_func_register_module(inst, mctx, "fail", test_xlat_fail, FR_TYPE_VOID))) return -1;
490 
491  return 0;
492 }
493 
494 static int mod_load(void)
495 {
496  xlat_t *xlat;
497 
498  if (!(xlat = xlat_func_register(NULL, "test_trigger", trigger_test_xlat, FR_TYPE_BOOL))) return -1;
500 
501  return 0;
502 }
503 
504 static void mod_unload(void)
505 {
506  xlat_func_unregister("test_trigger");
507 }
508 
509 /*
510  * The module name should be the only globally exported symbol.
511  * That is, everything else should be 'static'.
512  *
513  * If the module needs to temporarily modify it's instantiation
514  * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
515  * The server will then take care of ensuring that the module
516  * is single-threaded.
517  */
518 extern module_rlm_t rlm_test;
520  .common = {
521  .magic = MODULE_MAGIC_INIT,
522  .name = "test",
524  .inst_size = sizeof(rlm_test_t),
525  .thread_inst_size = sizeof(rlm_test_thread_t),
526  .config = module_config,
527  .bootstrap = mod_bootstrap,
528  .onload = mod_load,
529  .unload = mod_unload,
530  .thread_instantiate = mod_thread_instantiate,
531  .thread_detach = mod_thread_detach
532  },
533  .method_names = (module_method_name_t[]){
534  { .name1 = "authorize", .name2 = CF_IDENT_ANY, .method = mod_authorize },
535 
536  { .name1 = "recv", .name2 = "accounting-request", .method = mod_preacct },
537  { .name1 = "recv", .name2 = CF_IDENT_ANY, .method = mod_authorize },
538  { .name1 = "accounting", .name2 = CF_IDENT_ANY, .method = mod_accounting },
539  { .name1 = "authenticate", .name2 = CF_IDENT_ANY, .method = mod_authenticate },
540 
541  { .name1 = "recv", .name2 = "access-challenge", .method = mod_return },
542  { .name1 = "name1_null", .name2 = NULL, .method = mod_return },
543  { .name1 = "send", .name2 = CF_IDENT_ANY, .method = mod_return },
544  { .name1 = "retry", .name2 = NULL, .method = mod_retry },
545 
547  }
548 };
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:444
#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:137
#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
void *_CONST data
Module instance's parsed configuration.
Definition: dl_module.h:165
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
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:1735
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
Definition: interpret.c:1340
#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
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:52
void * thread
Thread instance data.
Definition: module_ctx.h:62
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:59
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:51
Temporary structure to hold arguments for thread_instantiation calls.
Definition: module_ctx.h:58
Specifies a module method identifier.
Definition: module_method.c:36
module_t common
Common fields presented by all modules.
Definition: module_rlm.h:37
#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:405
static int mod_load(void)
Definition: rlm_test.c:494
int32_t int32
Definition: rlm_test.c:105
static unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
Definition: rlm_test.c:236
tmpl_t * tmpl
Definition: rlm_test.c:46
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:111
fr_ipaddr_t * ipv4_addr_m
Definition: rlm_test.c:65
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:351
fr_ipaddr_t * ipv4_prefix_m
Definition: rlm_test.c:66
fr_ipaddr_t ipv6_addr
Definition: rlm_test.c:60
fr_time_t * date_m
Definition: rlm_test.c:76
fr_ipaddr_t ipaddr
Definition: rlm_test.c:73
fr_ipaddr_t * ipv6_addr_m
Definition: rlm_test.c:68
static unlang_action_t mod_preacct(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
Definition: rlm_test.c:248
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:282
fr_ifid_t ifid
Definition: rlm_test.c:84
fr_ipaddr_t * combo_ipaddr_m
Definition: rlm_test.c:71
static unlang_action_t mod_accounting(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
Definition: rlm_test.c:260
fr_ipaddr_t ipv4_addr
Definition: rlm_test.c:57
fr_time_delta_t * time_delta_m
Definition: rlm_test.c:112
fr_ipaddr_t ipv6_prefix
Definition: rlm_test.c:61
static xlat_arg_parser_t const test_xlat_passthrough_args[]
Definition: rlm_test.c:373
uint8_t byte
Definition: rlm_test.c:81
static fr_dict_t const * dict_radius
Definition: rlm_test.c:181
char const * name
Definition: rlm_test.c:44
static xlat_arg_parser_t const trigger_test_xlat_args[]
Definition: rlm_test.c:342
fr_ipaddr_t combo_ipaddr
Definition: rlm_test.c:63
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Definition: rlm_test.c:454
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:384
uint8_t const * octets
Definition: rlm_test.c:78
static void mod_unload(void)
Definition: rlm_test.c:504
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:272
fr_ethernet_t ethernet
Definition: rlm_test.c:99
uint32_t integer
Definition: rlm_test.c:54
bool * boolean_m
Definition: rlm_test.c:52
uint8_t * byte_m
Definition: rlm_test.c:82
pthread_t value
Definition: rlm_test.c:117
char const ** string_m
Definition: rlm_test.c:49
fr_dict_autoload_t rlm_test_dict[]
Definition: rlm_test.c:184
tmpl_t ** tmpl_m
Definition: rlm_test.c:47
bool boolean
Definition: rlm_test.c:51
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition: rlm_test.c:203
module_rlm_t rlm_test
Definition: rlm_test.c:519
uint16_t * shortint_m
Definition: rlm_test.c:97
rlm_test_t * inst
Definition: rlm_test.c:116
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Definition: rlm_test.c:421
uint64_t * uint64_m
Definition: rlm_test.c:109
fr_ethernet_t * ethernet_m
Definition: rlm_test.c:103
fr_dict_attr_autoload_t rlm_test_dict_attr[]
Definition: rlm_test.c:192
fr_ifid_t * ifid_m
Definition: rlm_test.c:95
fr_ipaddr_t * ipv6_prefix_m
Definition: rlm_test.c:69
fr_time_t date
Definition: rlm_test.c:75
uint8_t const ** octets_m
Definition: rlm_test.c:79
int32_t * int32_m
Definition: rlm_test.c:106
char const * string
Definition: rlm_test.c:48
static fr_dict_attr_t const * attr_user_name
Definition: rlm_test.c:189
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:292
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:302
uint64_t uint64
Definition: rlm_test.c:108
static const conf_parser_t module_config[]
Definition: rlm_test.c:123
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:413
uint32_t * integer_m
Definition: rlm_test.c:55
fr_ipaddr_t ipv4_prefix
Definition: rlm_test.c:58
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
Definition: rlm_test.c:433
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:336
uint16_t shortint
Definition: rlm_test.c:96
@ MODULE_TYPE_RETRY
can handle retries
Definition: module.h:54
@ MODULE_TYPE_THREAD_SAFE
Module is threadsafe.
Definition: module.h:49
#define MODULE_NAME_TERMINATOR
Definition: module.h:135
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:400
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:575
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:280
bool required
Argument must be present, and non-empty.
Definition: xlat.h:146
@ XLAT_ARG_VARIADIC_EMPTY_KEEP
Empty argument groups are left alone, and either passed through as empty groups or null boxes.
Definition: xlat.h:137
#define XLAT_ARG_PARSER_TERMINATOR
Definition: xlat.h:166
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:145
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:42
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition: xlat_func.c:360
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:195
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition: xlat_func.c:531
xlat_t * xlat_func_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function for a module.
Definition: xlat_func.c:274