The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
module_rlm.c
Go to the documentation of this file.
1 /*
2  * This program 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
5  * (at 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: 1559ecfc620ccfa03ede71b420dbc26701a7f13d $
19  *
20  * @file src/lib/server/module_rlm.c
21  * @brief Defines functions for rlm module (re-)initialisation.
22  *
23  * @copyright 2003,2006,2016 The FreeRADIUS server project
24  * @copyright 2016,2024 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
25  * @copyright 2000 Alan DeKok (aland@freeradius.org)
26  * @copyright 2000 Alan Curry (pacman@world.std.com)
27  */
28 
29 RCSID("$Id: 1559ecfc620ccfa03ede71b420dbc26701a7f13d $")
30 
31 #include <freeradius-devel/server/cf_file.h>
32 #include <freeradius-devel/server/cf_util.h>
33 
34 #include <freeradius-devel/server/global_lib.h>
35 #include <freeradius-devel/server/modpriv.h>
36 #include <freeradius-devel/server/module.h>
37 #include <freeradius-devel/server/module_rlm.h>
38 #include <freeradius-devel/server/pair.h>
39 #include <freeradius-devel/server/section.h>
40 #include <freeradius-devel/server/tmpl.h>
41 #include <freeradius-devel/server/virtual_servers.h>
42 
43 #include <freeradius-devel/util/atexit.h>
44 #include <freeradius-devel/util/debug.h>
45 #include <freeradius-devel/util/dlist.h>
46 #include <freeradius-devel/util/rb.h>
47 #include <freeradius-devel/util/sbuff.h>
48 #include <freeradius-devel/util/strerror.h>
49 #include <freeradius-devel/util/talloc.h>
50 #include <freeradius-devel/util/token.h>
51 #include <freeradius-devel/util/value.h>
52 
53 #include <freeradius-devel/unlang/compile.h>
54 
55 #include <freeradius-devel/unlang/xlat_func.h>
56 #include <freeradius-devel/unlang/xlat_redundant.h>
57 
58 #include <pthread.h>
59 
60 /** Lookup virtual module by name
61  */
63 
64 typedef struct {
65  fr_rb_node_t name_node; //!< Entry in the name tree.
66  char const *name; //!< module name
67  CONF_SECTION *cs; //!< CONF_SECTION where it is defined
68  bool all_same;
70 
71 /** Compare virtual modules by name
72  */
73 static int8_t module_rlm_virtual_name_cmp(void const *one, void const *two)
74 {
75  module_rlm_virtual_t const *a = one;
76  module_rlm_virtual_t const *b = two;
77  int ret;
78 
79  ret = strcmp(a->name, b->name);
80  return CMP(ret, 0);
81 }
82 
83 /** Global module list for all backend modules
84  *
85  */
87 
88 /** Runtime instantiated list
89  *
90  */
92 
93 /** Print information on all loaded modules
94  *
95  */
97 {
99 }
100 
101 /** Initialise a module specific exfile handle
102  *
103  * @see exfile_init
104  *
105  * @param[in] ctx to bind the lifetime of the exfile handle to.
106  * @param[in] module section.
107  * @param[in] max_entries Max file descriptors to cache, and manage locks for.
108  * @param[in] max_idle Maximum time a file descriptor can be idle before it's closed.
109  * @param[in] locking Whether or not to lock the files.
110  * @param[in] trigger_prefix if NULL will be set automatically from the module CONF_SECTION.
111  * @param[in] trigger_args to make available in any triggers executed by the connection pool.
112  * @return
113  * - New connection pool.
114  * - NULL on error.
115  */
117  CONF_SECTION *module,
118  uint32_t max_entries,
119  fr_time_delta_t max_idle,
120  bool locking,
121  char const *trigger_prefix,
122  fr_pair_list_t *trigger_args)
123 {
124  char trigger_prefix_buff[128];
125  exfile_t *handle;
126 
127  if (!trigger_prefix) {
128  snprintf(trigger_prefix_buff, sizeof(trigger_prefix_buff), "modules.%s.file", cf_section_name1(module));
129  trigger_prefix = trigger_prefix_buff;
130  }
131 
132  handle = exfile_init(ctx, max_entries, max_idle, locking);
133  if (!handle) return NULL;
134 
135  exfile_enable_triggers(handle, cf_section_find(module, "file", NULL), trigger_prefix, trigger_args);
136 
137  return handle;
138 }
139 
140 /** Resolve polymorphic item's from a module's #CONF_SECTION to a subsection in another module
141  *
142  * This allows certain module sections to reference module sections in other instances
143  * of the same module and share #CONF_DATA associated with them.
144  *
145  * @verbatim
146  example {
147  data {
148  ...
149  }
150  }
151 
152  example inst {
153  data = example
154  }
155  * @endverbatim
156  *
157  * @param[out] out where to write the pointer to a module's config section. May be NULL on success,
158  * indicating the config item was not found within the module #CONF_SECTION
159  * or the chain of module references was followed and the module at the end of the chain
160  * did not a subsection.
161  * @param[in] module #CONF_SECTION.
162  * @param[in] name of the polymorphic sub-section.
163  * @return
164  * - 0 on success with referenced section.
165  * - 1 on success with local section.
166  * - -1 on failure.
167  */
169 {
170  CONF_PAIR *cp;
171  CONF_SECTION *cs;
172  CONF_DATA const *cd;
173 
174 
175  module_instance_t *mi;
176  char const *inst_name;
177 
178 #define FIND_SIBLING_CF_KEY "find_sibling"
179 
180  *out = NULL;
181 
182  /*
183  * Is a real section (not referencing sibling module).
184  */
185  cs = cf_section_find(module, name, NULL);
186  if (cs) {
187  *out = cs;
188 
189  return 0;
190  }
191 
192  /*
193  * Item omitted completely from module config.
194  */
195  cp = cf_pair_find(module, name);
196  if (!cp) return 0;
197 
199  cf_log_err(cp, "Module reference loop found");
200 
201  return -1;
202  }
203  cd = cf_data_add(module, module, FIND_SIBLING_CF_KEY, false);
204 
205  /*
206  * Item found, resolve it to a module instance.
207  * This triggers module loading, so we don't have
208  * instantiation order issues.
209  */
210  inst_name = cf_pair_value(cp);
211  mi = module_instance_by_name(rlm_modules_static, NULL, inst_name);
212  if (!mi) {
213  cf_log_err(cp, "Unknown module instance \"%s\"", inst_name);
214 
215  return -1;
216  }
217 
218  if (mi->state != MODULE_INSTANCE_INSTANTIATED) {
219  CONF_SECTION *parent = module;
220 
221  /*
222  * Find the root of the config...
223  */
224  do {
225  CONF_SECTION *tmp;
226 
228  if (!tmp) break;
229 
230  parent = tmp;
231  } while (true);
232 
233  if (unlikely(module_instantiate(module_instance_by_name(rlm_modules_static, NULL, inst_name)) < 0)) return -1;
234  }
235 
236  /*
237  * Remove the config data we added for loop
238  * detection.
239  */
240  cf_data_remove_by_data(module, cd);
241 
242  /*
243  * Check the module instances are of the same type.
244  */
245  if (strcmp(cf_section_name1(mi->conf), cf_section_name1(module)) != 0) {
246  cf_log_err(cp, "Referenced module is a rlm_%s instance, must be a rlm_%s instance",
247  cf_section_name1(mi->conf), cf_section_name1(module));
248 
249  return -1;
250  }
251 
252  *out = cf_section_find(mi->conf, name, NULL);
253 
254  return 1;
255 }
256 
257 xlat_t *module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx,
258  char const *name, xlat_func_t func, fr_type_t return_type)
259 {
260  module_instance_t *mi = mctx->mi;
261  module_rlm_instance_t *mri = talloc_get_type_abort(mi->uctx, module_rlm_instance_t);
262  module_rlm_xlat_t *mrx;
263  xlat_t *x;
264  char inst_name[256];
265 
266  fr_assert_msg(name != mctx->mi->name, "`name` must not be the same as the module "
267  "instance name. Pass a NULL `name` arg if this is required");
268 
269  if (!name) {
270  name = mctx->mi->name;
271  } else {
272  if ((size_t)snprintf(inst_name, sizeof(inst_name), "%s.%s", mctx->mi->name, name) >= sizeof(inst_name)) {
273  ERROR("%s: Instance name too long", __FUNCTION__);
274  return NULL;
275  }
276  name = inst_name;
277  }
278 
279  x = xlat_func_register(ctx, name, func, return_type);
280  if (unlikely(x == NULL)) return NULL;
281 
282  xlat_mctx_set(x, mctx);
283 
284  MEM(mrx = talloc(mi, module_rlm_xlat_t));
285  mrx->xlat = x;
286  mrx->mi = mi;
287 
288  fr_dlist_insert_tail(&mri->xlats, mrx);
289 
290  return x;
291 }
292 
293 /** Initialise a module specific connection pool
294  *
295  * @see fr_pool_init
296  *
297  * @param[in] module section.
298  * @param[in] opaque data pointer to pass to callbacks.
299  * @param[in] c Callback to create new connections.
300  * @param[in] a Callback to check the status of connections.
301  * @param[in] log_prefix override, if NULL will be set automatically from the module CONF_SECTION.
302  * @param[in] trigger_prefix if NULL will be set automatically from the module CONF_SECTION.
303  * @param[in] trigger_args to make available in any triggers executed by the connection pool.
304  * @return
305  * - New connection pool.
306  * - NULL on error.
307  */
309  void *opaque,
312  char const *log_prefix,
313  char const *trigger_prefix,
314  fr_pair_list_t *trigger_args)
315 {
316  CONF_SECTION *cs, *mycs;
317  char log_prefix_buff[128];
318  char trigger_prefix_buff[128];
319 
320  fr_pool_t *pool;
321  char const *cs_name1, *cs_name2;
322 
323  int ret;
324 
325 #define parent_name(_x) cf_section_name(cf_item_to_section(cf_parent(_x)))
326 
327  cs_name1 = cf_section_name1(module);
328  cs_name2 = cf_section_name2(module);
329  if (!cs_name2) cs_name2 = cs_name1;
330 
331  if (!trigger_prefix) {
332  snprintf(trigger_prefix_buff, sizeof(trigger_prefix_buff), "modules.%s.pool", cs_name1);
333  trigger_prefix = trigger_prefix_buff;
334  }
335 
336  if (!log_prefix) {
337  snprintf(log_prefix_buff, sizeof(log_prefix_buff), "rlm_%s (%s)", cs_name1, cs_name2);
338  log_prefix = log_prefix_buff;
339  }
340 
341  /*
342  * Get sibling's pool config section
343  */
344  ret = module_rlm_sibling_section_find(&cs, module, "pool");
345  switch (ret) {
346  case -1:
347  return NULL;
348 
349  case 1:
350  DEBUG4("%s: Using pool section from \"%s\"", log_prefix, parent_name(cs));
351  break;
352 
353  case 0:
354  DEBUG4("%s: Using local pool section", log_prefix);
355  break;
356  }
357 
358  /*
359  * Get our pool config section
360  */
361  mycs = cf_section_find(module, "pool", NULL);
362  if (!mycs) {
363  DEBUG4("%s: Adding pool section to config item \"%s\" to store pool references", log_prefix,
364  cf_section_name(module));
365 
366  mycs = cf_section_alloc(module, module, "pool", NULL);
367  }
368 
369  /*
370  * Sibling didn't have a pool config section
371  * Use our own local pool.
372  */
373  if (!cs) {
374  DEBUG4("%s: \"%s.pool\" section not found, using \"%s.pool\"", log_prefix,
375  parent_name(cs), parent_name(mycs));
376  cs = mycs;
377  }
378 
379  /*
380  * If fr_pool_init has already been called
381  * for this config section, reuse the previous instance.
382  *
383  * This allows modules to pass in the config sections
384  * they would like to use the connection pool from.
385  */
386  pool = cf_data_value(cf_data_find(cs, fr_pool_t, NULL));
387  if (!pool) {
388  DEBUG4("%s: No pool reference found for config item \"%s.pool\"", log_prefix, parent_name(cs));
389  pool = fr_pool_init(cs, cs, opaque, c, a, log_prefix);
390  if (!pool) return NULL;
391 
392  fr_pool_enable_triggers(pool, trigger_prefix, trigger_args);
393 
394  if (fr_pool_start(pool) < 0) {
395  ERROR("%s: Starting initial connections failed", log_prefix);
396  return NULL;
397  }
398 
399  DEBUG4("%s: Adding pool reference %p to config item \"%s.pool\"", log_prefix, pool, parent_name(cs));
400  cf_data_add(cs, pool, NULL, false);
401  return pool;
402  }
403  fr_pool_ref(pool);
404 
405  DEBUG4("%s: Found pool reference %p in config item \"%s.pool\"", log_prefix, pool, parent_name(cs));
406 
407  /*
408  * We're reusing pool data add it to our local config
409  * section. This allows other modules to transitively
410  * reuse a pool through this module.
411  */
412  if (mycs != cs) {
413  DEBUG4("%s: Copying pool reference %p from config item \"%s.pool\" to config item \"%s.pool\"",
414  log_prefix, pool, parent_name(cs), parent_name(mycs));
415  cf_data_add(mycs, pool, NULL, false);
416  }
417 
418  return pool;
419 }
420 
421 /** Set the next section type if it's not already set
422  *
423  * @param[in] request The current request.
424  * @param[in] type_da to use. Usually attr_auth_type.
425  * @param[in] enumv Enumeration value of the specified type_da.
426  */
427 bool module_rlm_section_type_set(request_t *request, fr_dict_attr_t const *type_da, fr_dict_enum_value_t const *enumv)
428 {
429  fr_pair_t *vp;
430 
431  switch (pair_update_control(&vp, type_da)) {
432  case 0:
433  fr_value_box_copy(vp, &vp->data, enumv->value);
434  vp->data.enumv = vp->da; /* So we get the correct string alias */
435  RDEBUG2("Setting &control.%pP", vp);
436  return true;
437 
438  case 1:
439  RDEBUG2("&control.%s already set. Not setting to %s", vp->da->name, enumv->name);
440  return false;
441 
442  default:
443  return false;
444  }
445 }
446 
447 /** Iterate over an array of named module methods, looking for matches
448  *
449  * @param[in] mmg A structure containing a terminated array of
450  * module method bindings. pre-sorted using #section_name_cmp
451  * with name2 sublists populated.
452  * @param[in] section name1 of the method being called can be one of the following:
453  * - An itenfier.
454  * - CF_IDENT_ANY if the method is a wildcard.
455  * name2 of the method being called can be one of the following:
456  * - An itenfier.
457  * - NULL to match section names with only a name1.
458  * - CF_IDENT_ANY if the method is a wildcard.
459  * @return
460  * - The module_method_name_t on success.
461  * - NULL on not found.
462  */
463 static CC_HINT(nonnull)
465 {
466  module_method_group_t const *mmg_p = mmg;
467  module_method_binding_t const *p;
468 
469  while (mmg_p) {
470  /*
471  * This could potentially be improved by using a binary search
472  * but given the small number of items, reduced branches and
473  * sequential access just scanning the list, it's probably not
474  * worth it.
475  */
476  for (p = mmg_p->bindings; p->section; p++) {
477  switch (section_name_match(p->section, section)) {
478  case 1: /* match */
479  return p;
480 
481  case -1: /* name1 didn't match, skip to the end of the sub-list */
482  p = fr_dlist_tail(&p->same_name1);
483  break;
484 
485  case 0: /* name1 did match - see if we can find a matching name2 */
486  {
487  fr_dlist_head_t const *same_name1 = &p->same_name1;
488 
489  while ((p = fr_dlist_next(same_name1, p))) {
490  if (section_name2_match(p->section, section)) return p;
491  }
492  p = fr_dlist_tail(same_name1);
493  }
494  break;
495  }
496 #ifdef __clang_analyzer__
497  /* Will never be NULL, worse case, p doesn't change*/
498  if (!p) break;
499 #endif
500  }
501 
502  /*
503  * Failed to match, search the next deepest group in the chain.
504  */
505  mmg_p = mmg_p->next;
506  }
507 
508  return NULL;
509 }
510 
511 /** Dump the available bindings for the module into the strerror stack
512  *
513  * @note Methods from _all_ linked module method groups will be pushed onto the error stack.
514  *
515  * @param[in] mmg module method group to evaluate.
516  */
518 {
519  module_method_group_t const *mmg_p = mmg;
520  module_method_binding_t const *mmb_p;
521  bool first = true;
522 
523  while (mmg_p) {
524  mmb_p = mmg_p->bindings;
525 
526  if (!mmb_p || !mmb_p[0].section) goto next;
527 
528  if (first) {
529  fr_strerror_const_push("Available methods are:");
530  first = false;
531  }
532 
533  for (; mmb_p->section; mmb_p++) {
534  char const *name1 = section_name_str(mmb_p->section->name1);
535  char const *name2 = section_name_str(mmb_p->section->name2);
536 
537  fr_strerror_printf_push(" %s%s%s",
538  name1, name2 ? "." : "", name2 ? name2 : "");
539  }
540  next:
541  mmg_p = mmg_p->next;
542  }
543 
544  if (first) {
545  fr_strerror_const_push("No methods available");
546  }
547 }
548 
549 /** Find an existing module instance and verify it implements the specified method
550  *
551  * Extracts the method from the module name where the format is @verbatim <module>[.<method1>[.<method2>]] @endverbatim
552  * and ensures the module implements the specified method.
553  *
554  * @param[in] ctx to allocate the dynamic module key tmpl from.
555  * @param[out] mmc_out the result from resolving the module method,
556  * plus the key tmpl for dynamic modules.
557  * This is not allocated from the ctx to save the runtime
558  * dereference.
559  * @param[in] vs Virtual server to search for alternative module names in.
560  * @param[in] section Section name containing the module call.
561  * @param[in] name The module method call i.e. module[<key>][.<method>]
562  * @param[in] t_rules for resolving the dynamic module key.
563  * @return
564  * - The module instance on success.
565  * - NULL on not found
566  *
567  * If the module exists but the method doesn't exist, then `method` is set to NULL.
568  */
570  virtual_server_t const *vs, section_name_t const *section, fr_sbuff_t *name,
571  tmpl_rules_t const *t_rules)
572 {
573  fr_sbuff_term_t const *dyn_tt = &FR_SBUFF_TERMS(
574  L(""),
575  L("\t"),
576  L("\n"),
577  L(" "),
578  L("[")
579  );
580 
581  fr_sbuff_term_t const *elem_tt = &FR_SBUFF_TERMS(
582  L(""),
583  L("\t"),
584  L("\n"),
585  L(" "),
586  L(".")
587  );
588 
589  fr_sbuff_t *elem1;
591  module_method_call_t mmc_tmp;
592  module_method_binding_t const *mmb;
593 
594  fr_sbuff_marker_t meth_start;
595 
596  fr_slen_t slen;
597  fr_sbuff_t our_name = FR_SBUFF(name);
598 
599  mmc = mmc_out ? mmc_out : &mmc_tmp;
600  if (mmc_out) memset(mmc_out, 0, sizeof(*mmc_out));
601 
602  /*
603  * Advance until the start of the dynamic selector
604  * (if it exists).
605  */
606  if (fr_sbuff_adv_until(&our_name, SIZE_MAX, dyn_tt, '\0') == 0) {
607  fr_strerror_printf("Invalid module method name");
608  return fr_sbuff_error(&our_name);
609  }
610 
612 
613  /*
614  * If the method string contains a '['
615  *
616  * Search for a dynamic module method, e.g. `elem1[<key>]`.
617  */
618  if (fr_sbuff_is_char(&our_name, '[')) {
619  fr_sbuff_marker_t end, s_end;
620  fr_sbuff_marker(&end, &our_name);
621 
622  slen = tmpl_afrom_substr(ctx, &mmc->key, &our_name, T_BARE_WORD, NULL, t_rules);
623  if (slen < 0) {
624  fr_strerror_const_push("Invalid dynamic module selector expression");
625  talloc_free(mmc);
626  return slen;
627  }
628 
629  if (!fr_sbuff_is_char(&our_name, ']')) {
630  fr_strerror_const_push("Missing terminating ']' for dynamic module selector");
631  error:
632  talloc_free(mmc);
633  return fr_sbuff_error(&our_name);
634  }
635  fr_sbuff_marker(&s_end, &our_name);
636 
637  fr_sbuff_set_to_start(&our_name);
638  slen = fr_sbuff_out_bstrncpy(elem1, &our_name, fr_sbuff_ahead(&end));
639  if (slen < 0) {
640  fr_strerror_const("Module method string too long");
641  goto error;
642  }
643  mmc->mi = module_instance_by_name(rlm_modules_dynamic, NULL, elem1->start);
644  if (!mmc->mi) {
645  fr_strerror_printf("No such dynamic module '%s'", elem1->start);
646  goto error;
647  }
648  mmc->rlm = module_rlm_from_module(mmc->mi->exported);
649 
650  fr_sbuff_set(&our_name, &s_end);
651  fr_sbuff_advance(&our_name, 1); /* Skip the ']' */
652  /*
653  * With elem1.elem2.elem3
654  *
655  * Search for a static module matching one of the following:
656  *
657  * - elem1.elem2.elem3
658  * - elem1.elem2
659  * - elem1
660  */
661  } else {
662  char *p;
663 
664  fr_sbuff_set_to_start(&our_name);
665 
666  slen = fr_sbuff_out_bstrncpy_until(elem1, &our_name, SIZE_MAX, dyn_tt, NULL);
667  if (slen == 0) {
668  fr_strerror_const("Invalid module name");
669  goto error;
670  }
671  if (slen < 0) {
672  fr_strerror_const("Module method string too long");
673  goto error;
674  }
675 
676  /*
677  * Now we have a mutable buffer, we can start chopping
678  * it up to find the module.
679  */
680  for (;;) {
681  mmc->mi = (module_instance_t *)module_rlm_static_by_name(NULL, elem1->start);
682  if (mmc->mi) {
683  mmc->rlm = module_rlm_from_module(mmc->mi->exported);
684  break; /* Done */
685  }
686 
687  p = strrchr(elem1->start, '.');
688  if (!p) break; /* No more '.' */
689  *p = '\0'; /* Chop off the last '.' */
690  }
691 
692  if (!mmc->mi) {
693  fr_strerror_printf("No such module '%pV'", fr_box_strvalue_len(our_name.start, slen));
694  return -1;
695  }
696 
697  fr_sbuff_set_to_start(&our_name);
698  fr_sbuff_advance(&our_name, strlen(elem1->start)); /* Advance past the module name */
699  if (fr_sbuff_is_char(&our_name, '.')) {
700  fr_sbuff_advance(&our_name, 1); /* Static module method, search directly */
701  } else {
702  fr_sbuff_marker(&meth_start, &our_name); /* for the errors... */
703  goto by_section; /* Get the method dynamically from the section*/
704  }
705  }
706 
707  /*
708  * For both cases, the buffer should be pointing
709  * at the start of the method string.
710  */
711  fr_sbuff_marker(&meth_start, &our_name);
712 
713  /*
714  * If a module method was provided, search for it in the named
715  * methods provided by the module.
716  *
717  * The method name should be either:
718  *
719  * - name1
720  * - name1.name2
721  */
722  {
723  section_name_t method;
724  fr_sbuff_t *elem2;
725 
726  fr_sbuff_set_to_start(elem1); /* May have used this already for module lookups */
727 
728  slen = fr_sbuff_out_bstrncpy_until(elem1, &our_name, SIZE_MAX, elem_tt, NULL);
729  if (slen < 0) {
730  fr_strerror_const("Module method string too long");
731  return fr_sbuff_error(&our_name);
732  }
733  if (slen == 0) goto by_section; /* This works for both dynamic and static modules */
734 
736 
737  if (fr_sbuff_is_char(&our_name, '.')) {
738  fr_sbuff_advance(&our_name, 1);
739  if (fr_sbuff_out_bstrncpy_until(elem2, &our_name, SIZE_MAX,
740  elem_tt, NULL) == MODULE_INSTANCE_LEN_MAX) {
741  fr_strerror_const("Module method string too long");
742  goto error;
743  }
744  }
745 
746  method = (section_name_t) {
747  .name1 = elem1->start,
748  .name2 = fr_sbuff_used(elem2) ? elem2->start : NULL
749  };
750 
751  mmb = module_binding_find(&mmc->rlm->method_group, &method);
752  if (!mmb) {
753  fr_strerror_printf("Module \"%s\" does not have method %s%s%s",
754  mmc->mi->name,
755  method.name1,
756  method.name2 ? "." : "",
757  method.name2 ? method.name2 : ""
758  );
759 
761  return fr_sbuff_error(&meth_start);
762  }
763  mmc->mmb = *mmb; /* For locality of reference and fewer derefs */
764  if (mmc_out) section_name_dup(ctx, &mmc->asked, &method);
765 
766  return fr_sbuff_set(name, &our_name);
767  }
768 
769 by_section:
770  /*
771  * First look for the section name in the module's
772  * bindings. If that fails, look for the alt
773  * section names from the virtual server section.
774  *
775  * If that fails, we're done.
776  */
777  mmb = module_binding_find(&mmc->rlm->method_group, section);
778  if (!mmb) {
779  section_name_t const **alt_p = virtual_server_section_methods(vs, section);
780  if (alt_p) {
781  for (; *alt_p; alt_p++) {
782  mmb = module_binding_find(&mmc->rlm->method_group, *alt_p);
783  if (mmb) {
784  if (mmc_out) section_name_dup(ctx, &mmc->asked, *alt_p);
785  break;
786  }
787  }
788  }
789  } else {
790  if (mmc_out) section_name_dup(ctx, &mmc->asked, section);
791  }
792  if (!mmb) {
793  fr_strerror_printf("Module \"%s\" has no method for section %s %s { ... }, i.e. %s%s%s",
794  mmc->mi->name,
795  section->name1,
796  section->name2 ? section->name2 : "",
797  section->name1,
798  section->name2 ? "." : "",
799  section->name2 ? section->name2 : ""
800  );
802 
803  return fr_sbuff_error(&meth_start);
804  }
805  mmc->mmb = *mmb; /* For locality of reference and fewer derefs */
806 
807  return fr_sbuff_set(name, &our_name);
808 }
809 
810 CONF_SECTION *module_rlm_virtual_by_name(char const *asked_name)
811 {
813 
816  .name = asked_name,
817  });
818  if (!inst) return NULL;
819 
820  return inst->cs;
821 }
822 
824 {
826 }
827 
829 {
831 }
832 
833 /** Create a virtual module.
834  *
835  * @param[in] cs that defines the virtual module.
836  * @return
837  * - 0 on success.
838  * - -1 on failure.
839  */
841 {
842  char const *name;
843  bool all_same;
844  CONF_ITEM *sub_ci = NULL;
845  CONF_PAIR *cp;
846  module_instance_t *mi;
848 
849  name = cf_section_name1(cs);
850 
851  /*
852  * Groups, etc. must have a name.
853  */
854  if ((strcmp(name, "group") == 0) ||
855  (strcmp(name, "redundant") == 0) ||
856  (strcmp(name, "redundant-load-balance") == 0) ||
857  (strcmp(name, "load-balance") == 0)) {
858  name = cf_section_name2(cs);
859  if (!name) {
860  cf_log_err(cs, "Keyword module must have a second name");
861  return -1;
862  }
863 
864  /*
865  * name2 was already checked in modules_rlm_bootstrap()
866  */
868  } else {
869  cf_log_err(cs, "Module names cannot be unlang keywords '%s'", name);
870  return -1;
871  }
872 
873  /*
874  * Ensure that the module doesn't exist.
875  */
877  if (mi) {
878  ERROR("Duplicate module \"%s\" in file %s[%d] and file %s[%d]",
879  name,
880  cf_filename(cs),
881  cf_lineno(cs),
882  cf_filename(mi->conf),
883  cf_lineno(mi->conf));
884  return -1;
885  }
886 
887  /*
888  * Don't bother registering redundant xlats for a simple "group".
889  */
890  all_same = (strcmp(cf_section_name1(cs), "group") != 0);
891 
892  {
893  module_t const *last = NULL;
894 
895  /*
896  * Ensure that the modules we reference here exist.
897  */
898  while ((sub_ci = cf_item_next(cs, sub_ci))) {
899  if (cf_item_is_pair(sub_ci)) {
900  cp = cf_item_to_pair(sub_ci);
901  if (cf_pair_value(cp)) {
902  cf_log_err(sub_ci, "Cannot set return codes in a %s block", cf_section_name1(cs));
903  return -1;
904  }
905 
906  mi = module_rlm_static_by_name(NULL, cf_pair_attr(cp));
907  if (!mi) {
908  cf_log_perr(sub_ci, "Failed resolving module reference '%s' in %s block",
909  cf_pair_attr(cp), cf_section_name1(cs));
910  return -1;
911  }
912 
913  if (all_same) {
914  if (!last) {
915  last = mi->exported;
916  } else if (last != mi->exported) {
917  last = NULL;
918  all_same = false;
919  }
920  }
921  } else {
922  all_same = false;
923  }
924 
925  /*
926  * Don't check subsections for now. That check
927  * happens later in the unlang compiler.
928  */
929  } /* loop over things in a virtual module section */
930  }
931 
932  inst = talloc_zero(cs, module_rlm_virtual_t);
933  if (!inst) return -1;
934 
935  inst->cs = cs;
936  MEM(inst->name = talloc_strdup(inst, name));
937  inst->all_same = all_same;
938 
940  talloc_free(inst);
941  return -1;
942  }
943 
944  return 0;
945 }
946 
947 /** Generic conf_parser_t func for loading drivers
948  *
949  */
950 int module_rlm_submodule_parse(TALLOC_CTX *ctx, void *out, void *parent,
951  CONF_ITEM *ci, conf_parser_t const *rule)
952 {
953  conf_parser_t our_rule = *rule;
954 
955  our_rule.uctx = &rlm_modules_static;
956 
957  return module_submodule_parse(ctx, out, parent, ci, &our_rule);
958 }
959 
960 /** Frees thread-specific data for all registered backend modules
961  *
962  */
964 {
966 }
967 
968 /** Allocates thread-specific data for all registered backend modules
969  *
970  * @param[in] ctx To allocate any thread-specific data in.
971  * @param[in] el to register events.
972  * @return
973  * - 0 if all modules were instantiated successfully.
974  * - -1 if a module failed instantiation.
975  */
977 {
979 }
980 
981 /** Performs the instantiation phase for all backend modules
982  *
983  * @return
984  * - 0 if all modules were instantiated successfully.
985  * - -1 if a module failed instantiation.
986  */
988 {
990 }
991 
992 /** Compare the section names of two module_method_binding_t structures
993  */
994 static int8_t binding_name_cmp(void const *one, void const *two)
995 {
996  module_method_binding_t const *a = one;
997  module_method_binding_t const *b = two;
998 
999  return section_name_cmp(a->section, b->section);
1000 }
1001 
1003 {
1004  module_method_binding_t *p, *srt_p;
1005  fr_dlist_head_t bindings;
1006  bool in_order = true;
1007 
1008  /*
1009  * Not all modules export module method bindings
1010  */
1011  if (!group || !group->bindings || group->validated) return 0;
1012 
1013  fr_dlist_init(&bindings, module_method_binding_t, entry);
1014 
1015  for (p = group->bindings; p->section; p++) {
1016  if (!fr_cond_assert_msg(p->section->name1,
1017  "First section identifier can't be NULL")) return -1;
1018  if (!fr_cond_assert_msg(p->section->name1 || p->section->name2,
1019  "Section identifiers can't both be null")) return -1;
1020 
1021  /*
1022  * All the bindings go in a list so we can sort them
1023  * and produce the list in the correct order.
1024  */
1025  fr_dlist_insert_tail(&bindings, p);
1026  }
1027 
1028  fr_dlist_sort(&bindings, binding_name_cmp);
1029 
1030  /*
1031  * Iterate over the sorted list of bindings,
1032  * and the original list, to ensure they're
1033  * in the correct order.
1034  */
1035  for (srt_p = fr_dlist_head(&bindings), p = group->bindings;
1036  srt_p;
1037  srt_p = fr_dlist_next(&bindings, srt_p), p++) {
1038  if (p != srt_p) {
1039  in_order = false;
1040  break;
1041  }
1042  }
1043 
1044  /*
1045  * Rebuild the binding list in the correct order.
1046  */
1047  if (!in_order) {
1048  module_method_binding_t *ordered;
1049 
1050  MEM(ordered = talloc_array(NULL, module_method_binding_t, fr_dlist_num_elements(&bindings)));
1051  for (srt_p = fr_dlist_head(&bindings), p = ordered;
1052  srt_p;
1053  srt_p = fr_dlist_next(&bindings, srt_p), p++) {
1054  *p = *srt_p;
1055  }
1056  memcpy(group->bindings, ordered, fr_dlist_num_elements(&bindings) * sizeof(*ordered));
1057  talloc_free(ordered);
1058  }
1059 
1060  /*
1061  * Build the "skip" list of name1 entries
1062  */
1063  {
1064  module_method_binding_t *last_binding = NULL;
1065 
1066  for (p = group->bindings; p->section; p++) {
1067  if (!last_binding ||
1068  (
1069  (last_binding->section->name1 != p->section->name1) &&
1070  (
1071  (last_binding->section->name1 == CF_IDENT_ANY) ||
1072  (p->section->name1 == CF_IDENT_ANY) ||
1073  (strcmp(last_binding->section->name1, p->section->name1) != 0)
1074  )
1075  )
1076  ) {
1078  last_binding = p;
1079  }
1080  fr_dlist_insert_tail(&last_binding->same_name1, p);
1081  }
1082  }
1083  group->validated = true;
1084 
1085  return module_method_group_validate(group->next);
1086 }
1087 
1089 {
1091 
1093 }
1094 
1095 /** Allocate a rlm module instance
1096  *
1097  * These have extra space allocated to hold the dlist of associated xlats.
1098  *
1099  * @param[in] ml Module list to allocate from.
1100  * @param[in] parent Parent module instance.
1101  * @param[in] type Type of module instance.
1102  * @param[in] mod_name Name of the module.
1103  * @param[in] inst_name Name of the instance.
1104  * @param[in] init_state Initial state of the module instance.
1105  * @return
1106  * - The allocated module instance on success.
1107  * - NULL on failure.
1108  */
1109 static inline CC_HINT(always_inline)
1111  module_instance_t const *parent,
1112  dl_module_type_t type, char const *mod_name, char const *inst_name,
1113  module_instance_state_t init_state)
1114 {
1115  module_instance_t *mi;
1116  module_rlm_instance_t *mri;
1117 
1118  mi = module_instance_alloc(ml, parent, type, mod_name, inst_name, init_state);
1119  if (unlikely(mi == NULL)) return NULL;
1120 
1121  MEM(mri = talloc(mi, module_rlm_instance_t));
1122  module_instance_uctx_set(mi, mri);
1123 
1125 
1126  return mi;
1127 }
1128 
1130 {
1131  char const *name;
1132  char const *inst_name;
1133  module_instance_t *mi = NULL;
1134  CONF_SECTION *actions;
1135 
1136  /*
1137  * name2 can't be a keyword
1138  */
1139  name = cf_section_name2(mod_conf);
1141  invalid_name:
1142  cf_log_err(mod_conf, "Module names cannot be unlang keywords '%s'", name);
1143  return -1;
1144  }
1145 
1146  name = cf_section_name1(mod_conf);
1147 
1148  /*
1149  * For now, ignore name1 which is a keyword.
1150  */
1152  if (!cf_section_name2(mod_conf)) {
1153  cf_log_err(mod_conf, "Missing second name at '%s'", name);
1154  return -1;
1155  }
1156  if (module_rlm_bootstrap_virtual(mod_conf) < 0) return -1;
1157  return 0;
1158  }
1159 
1160  /*
1161  * Skip inline templates, and disallow "template { ... }"
1162  */
1163  if (strcmp(name, "template") == 0) {
1164  if (!cf_section_name2(mod_conf)) goto invalid_name;
1165  return 0;
1166  }
1167 
1168  if (module_instance_name_from_conf(&inst_name, mod_conf) < 0) goto invalid_name;
1169 
1170  mi = module_rlm_instance_alloc(ml, NULL, DL_MODULE_TYPE_MODULE, name, inst_name, 0);
1171  if (unlikely(mi == NULL)) {
1172  cf_log_perr(mod_conf, "Failed loading module");
1173  return -1;
1174  }
1175 
1176  /*
1177  * First time we've loaded the dl module, so we need to
1178  * check the module methods to make sure they're ordered
1179  * correctly, and to add the "skip list" style name2
1180  * entries.
1181  */
1182  if ((mi->module->refs == 1) && (module_method_validate(mi) < 0)) {
1183  talloc_free(mi);
1184  return -1;
1185  }
1186 
1187  if (module_instance_conf_parse(mi, mod_conf) < 0) {
1188  cf_log_perr(mod_conf, "Failed parsing module config");
1189  talloc_free(mi);
1190  return -1;
1191  }
1192 
1193  /*
1194  * Compile the default "actions" subsection, which includes retries.
1195  */
1196  actions = cf_section_find(mod_conf, "actions", NULL);
1197  if (actions && unlang_compile_actions(&mi->actions, actions, (mi->exported->flags & MODULE_TYPE_RETRY) != 0)) {
1198  talloc_free(mi);
1199  return -1;
1200  }
1201 
1202  return 0;
1203 }
1204 
1205 /** Bootstrap modules and virtual modules
1206  *
1207  * Parse the module config sections, and load and call each module's init() function.
1208  *
1209  * @param[in] root of the server configuration.
1210  * @return
1211  * - 0 if all modules were bootstrapped successfully.
1212  * - -1 if a module/virtual module failed to bootstrap.
1213  */
1215 {
1216  CONF_SECTION *cs, *modules, *static_cs, *dynamic_cs;
1219 
1220  /*
1221  * Ensure any libraries the modules depend on are instantiated
1222  */
1224 
1225  /*
1226  * Remember where the modules were stored.
1227  */
1228  modules = cf_section_find(root, "modules", NULL);
1229  if (!modules) {
1230  WARN("Cannot find a \"modules\" section in the configuration file!");
1231  return 0;
1232  }
1233 
1234  static_cs = cf_section_find(modules, "static", NULL);
1235  if (!static_cs) {
1236  static_cs = cf_section_alloc(modules, NULL, "static", NULL);
1237  cf_section_foreach(modules, mod_cs) {
1238  CONF_ITEM *prev;
1239 
1240  /*
1241  * Skip over the dynamic section
1242  */
1243  if ((strcmp(cf_section_name1(mod_cs), "dynamic") == 0) &&
1244  cf_section_name2(mod_cs) == NULL) continue;
1245 
1246  /*
1247  * Move all modules which are not in
1248  * the dynamic section into the static
1249  * section for backwards compatibility.
1250  */
1251  prev = cf_item_remove(modules, mod_cs);
1252  cf_item_add(static_cs, mod_cs);
1253 
1254  /*
1255  * Find the previous item that's a section
1256  */
1257  while (prev && !cf_item_is_section(prev)) prev = cf_item_prev(modules, prev);
1258 
1259  /*
1260  * Resume iterating from that item
1261  */
1262  mod_cs = cf_item_to_section(prev);
1263  }
1264  cf_item_add(modules, static_cs);
1265  }
1266  DEBUG2("#### Bootstrapping static modules ####");
1267  cf_log_debug(modules, " modules {");
1268  cf_log_debug(modules, " static {");
1269  cf_section_foreach(static_cs, mod_conf) {
1270  if (module_conf_parse(rlm_modules_static, mod_conf) < 0) return -1;
1271  }
1272  cf_log_debug(modules, " } # static");
1273 
1274  /*
1275  * Now we have a module tree, run bootstrap on all the modules.
1276  * This will bootstrap modules and then submodules.
1277  */
1278  if (unlikely(modules_bootstrap(rlm_modules_static) < 0)) return -1;
1279 
1280  if (fr_command_register_hook(NULL, NULL, static_cs, module_cmd_list_table) < 0) {
1281  PERROR("Failed registering radmin commands for modules");
1282  return -1;
1283  }
1284 
1285  /*
1286  * Build the configuration and parse dynamic modules
1287  */
1288  dynamic_cs = cf_section_find(modules, "dynamic", NULL);
1289  if (dynamic_cs) {
1290  DEBUG2("#### Bootstrapping dynamic modules ####");
1291  /*
1292  * Parse and then instantiate any dynamic modules configure
1293  */
1294  cf_log_debug(modules, " dynamic {");
1295  cf_section_foreach(dynamic_cs, mod_conf) {
1296  if (unlikely(module_conf_parse(rlm_modules_dynamic, mod_conf) < 0)) return -1;
1297  }
1298  cf_log_debug(modules, " } # dynamic");
1299  if (unlikely(modules_bootstrap(rlm_modules_dynamic) < 0)) return -1;
1300  cf_log_debug(modules, " } # modules");
1301  }
1302 
1303  /*
1304  * Check for duplicate policies. They're treated as
1305  * modules, so we might as well check them here.
1306  */
1307  cs = cf_section_find(root, "policy", NULL);
1308  if (cs) {
1309  cf_section_foreach(cs, policy_cs) {
1310  CONF_SECTION *problemcs;
1311  char const *name1 = cf_section_name1(policy_cs);
1312 
1313  if (unlang_compile_is_keyword(name1)) {
1314  cf_log_err(policy_cs, "Policy name '%s' cannot be an unlang keyword", name1);
1315  return -1;
1316  }
1317 
1318  if (cf_section_name2(policy_cs)) {
1319  cf_log_err(policy_cs, "Policies cannot have two names");
1320  return -1;
1321  }
1322 
1323  problemcs = cf_section_find_next(cs, policy_cs, name1, CF_IDENT_ANY);
1324  if (!problemcs) continue;
1325 
1326  cf_log_err(problemcs, "Duplicate policy '%s' is forbidden.",
1327  cf_section_name1(policy_cs));
1328  return -1;
1329  }
1330  }
1331 
1332  /*
1333  * Now that all of the xlat things have been registered,
1334  * register our redundant xlats. But only when all of
1335  * the items in such a section are the same.
1336  */
1338  vm;
1339  vm = fr_rb_iter_next_inorder(&iter)) {
1340  if (!vm->all_same) continue;
1341 
1342  if (xlat_register_redundant(vm->cs) < 0) return -1;
1343  }
1344 
1345  return 0;
1346 }
1347 
1348 /** Cleanup all global structures
1349  *
1350  * Automatically called on exit.
1351  */
1353 {
1354  if (talloc_free(rlm_modules_static) < 0) return -1;
1355  rlm_modules_static = NULL;
1356  if (talloc_free(module_rlm_virtual_name_tree) < 0) return -1;
1358 
1359  return 0;
1360 }
1361 
1363 {
1364  return modules_rlm_free();
1365 }
1366 
1367 /** Initialise the module list structure
1368  *
1369  */
1371 {
1374  module_list_mask_set(rlm_modules_dynamic, MODULE_INSTANCE_INSTANTIATED); /* Ensure we never instantiate dynamic modules */
1375 
1379 
1380  return 0;
1381 }
#define fr_atexit_global(_func, _uctx)
Add a free function to the global free list.
Definition: atexit.h:59
#define RCSID(id)
Definition: build.h:481
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
#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:110
#define unlikely(_x)
Definition: build.h:379
#define UNUSED
Definition: build.h:313
void const * uctx
User data accessible by the cf_parse_t func.
Definition: cf_parse.h:587
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:564
Internal data that is associated with a configuration section.
Definition: cf_priv.h:124
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:632
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: cf_util.c:664
char const * cf_pair_attr(CONF_PAIR const *pair)
Return the attr of a CONF_PAIR.
Definition: cf_util.c:1578
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:1028
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:1439
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1185
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1594
void * cf_data_value(CONF_DATA const *cd)
Return the user assigned value of CONF_DATA.
Definition: cf_util.c:1763
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition: cf_util.c:684
CONF_SECTION * cf_section_find_next(CONF_SECTION const *cs, CONF_SECTION const *prev, char const *name1, char const *name2)
Return the next matching section.
Definition: cf_util.c:1049
bool cf_item_is_section(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_SECTION.
Definition: cf_util.c:618
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1171
char const * cf_section_name(CONF_SECTION const *cs)
Return name2 if set, else name1.
Definition: cf_util.c:1197
#define cf_item_add(_parent, _child)
Definition: cf_util.h:83
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:289
#define cf_lineno(_cf)
Definition: cf_util.h:104
#define cf_section_foreach(_parent, _iter)
Definition: cf_util.h:152
#define cf_data_add(_cf, _data, _name, _free)
Definition: cf_util.h:255
#define cf_data_find(_cf, _type, _name)
Definition: cf_util.h:244
#define cf_data_remove_by_data(_cf, _cd)
Remove an item from a parent.
Definition: cf_util.h:274
#define cf_parent(_cf)
Definition: cf_util.h:101
#define cf_item_remove(_parent, _child)
Definition: cf_util.h:89
#define cf_log_perr(_cf, _fmt,...)
Definition: cf_util.h:296
#define cf_section_alloc(_ctx, _parent, _name1, _name2)
Definition: cf_util.h:140
#define cf_filename(_cf)
Definition: cf_util.h:107
#define cf_item_prev(_ci, _curr)
Definition: cf_util.h:95
#define cf_log_debug(_cf, _fmt,...)
Definition: cf_util.h:292
#define cf_item_next(_ci, _curr)
Definition: cf_util.h:92
#define CF_IDENT_ANY
Definition: cf_util.h:78
fr_command_register_hook_t fr_command_register_hook
Definition: command.c:42
bool unlang_compile_is_keyword(const char *name)
Check if name is an unlang keyword.
Definition: compile.c:5092
bool unlang_compile_actions(unlang_mod_actions_t *actions, CONF_SECTION *action_cs, bool module_retry)
Definition: compile.c:1847
next
Definition: dcursor.h:178
fr_dcursor_eval_t void const * uctx
Definition: dcursor.h:546
fr_dcursor_iter_t iter
Definition: dcursor.h:147
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:139
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
Definition: debug.h:210
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:156
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
fr_value_box_t const * value
Enum value (what name maps to).
Definition: dict.h:230
char const * name
Enum name.
Definition: dict.h:227
Value of an enumerated attribute.
Definition: dict.h:226
dl_module_type_t
Definition: dl_module.h:65
@ DL_MODULE_TYPE_MODULE
Standard loadable module.
Definition: dl_module.h:66
unsigned int refs
Number of references to this module.
Definition: dl_module.h:135
static void fr_dlist_sort(fr_dlist_head_t *list, fr_cmp_t cmp)
Sort a dlist using merge sort.
Definition: dlist.h:1064
#define fr_dlist_init(_head, _type, _field)
Initialise the head structure of a doubly linked list.
Definition: dlist.h:260
static void * fr_dlist_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
Definition: dlist.h:555
static unsigned int fr_dlist_num_elements(fr_dlist_head_t const *head)
Return the number of elements in the dlist.
Definition: dlist.h:939
static void * fr_dlist_tail(fr_dlist_head_t const *list_head)
Return the TAIL item of a list or NULL if the list is empty.
Definition: dlist.h:531
static void * fr_dlist_head(fr_dlist_head_t const *list_head)
Return the HEAD item of a list or NULL if the list is empty.
Definition: dlist.h:486
static int fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr)
Insert an item into the tail of a list.
Definition: dlist.h:378
#define fr_dlist_talloc_init(_head, _type, _field)
Initialise the head structure of a doubly linked list.
Definition: dlist.h:275
Head of a doubly linked list.
Definition: dlist.h:51
void exfile_enable_triggers(exfile_t *ef, CONF_SECTION *conf, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Enable triggers for an exfiles handle.
Definition: exfile.c:196
exfile_t * exfile_init(TALLOC_CTX *ctx, uint32_t max_entries, fr_time_delta_t max_idle, bool locking)
Initialize a way for multiple threads to log to one or more files.
Definition: exfile.c:148
int global_lib_instantiate(void)
Walk the tree of libraries and instantiate any which are pending.
Definition: global_lib.c:218
#define PERROR(_fmt,...)
Definition: log.h:228
#define DEBUG4(_fmt,...)
Definition: log.h:267
talloc_free(reap)
Stores all information relating to an event list.
Definition: event.c:411
static char const * mod_name(fr_listen_t *li)
Definition: master.c:2729
fr_type_t
Definition: merged_model.c:80
unsigned int uint32_t
Definition: merged_model.c:33
size_t fr_sbuff_out_bstrncpy_until(fr_sbuff_t *out, fr_sbuff_t *in, size_t len, fr_sbuff_term_t const *tt, fr_sbuff_unescape_rules_t const *u_rules)
Definition: merged_model.c:166
ssize_t fr_slen_t
Definition: merged_model.c:35
fr_cmd_table_t module_cmd_list_table[]
Definition: module.c:99
module_instance_t * mi
Instance of the module being instantiated.
Definition: module_ctx.h:51
Temporary structure to hold arguments for instantiation calls.
Definition: module_ctx.h:50
static module_list_t * rlm_modules_dynamic
Runtime instantiated list.
Definition: module_rlm.c:91
static int _modules_rlm_free_atexit(UNUSED void *uctx)
Definition: module_rlm.c:1362
void modules_rlm_thread_detach(void)
Frees thread-specific data for all registered backend modules.
Definition: module_rlm.c:963
int modules_rlm_bootstrap(CONF_SECTION *root)
Bootstrap modules and virtual modules.
Definition: module_rlm.c:1214
static int module_rlm_bootstrap_virtual(CONF_SECTION *cs)
Create a virtual module.
Definition: module_rlm.c:840
static int8_t binding_name_cmp(void const *one, void const *two)
Compare the section names of two module_method_binding_t structures.
Definition: module_rlm.c:994
static module_method_binding_t const * module_binding_find(module_method_group_t const *mmg, section_name_t const *section)
Iterate over an array of named module methods, looking for matches.
Definition: module_rlm.c:464
module_instance_t * module_rlm_static_by_name(module_instance_t const *parent, char const *asked_name)
Definition: module_rlm.c:828
fr_slen_t module_rlm_by_name_and_method(TALLOC_CTX *ctx, module_method_call_t *mmc_out, virtual_server_t const *vs, section_name_t const *section, fr_sbuff_t *name, tmpl_rules_t const *t_rules)
Find an existing module instance and verify it implements the specified method.
Definition: module_rlm.c:569
char const * name
module name
Definition: module_rlm.c:66
fr_rb_node_t name_node
Entry in the name tree.
Definition: module_rlm.c:65
module_instance_t * module_rlm_dynamic_by_name(module_instance_t const *parent, char const *asked_name)
Definition: module_rlm.c:823
int module_rlm_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, char const *name)
Resolve polymorphic item's from a module's CONF_SECTION to a subsection in another module.
Definition: module_rlm.c:168
static int8_t module_rlm_virtual_name_cmp(void const *one, void const *two)
Compare virtual modules by name.
Definition: module_rlm.c:73
void module_rlm_list_debug(void)
Print information on all loaded modules.
Definition: module_rlm.c:96
static module_instance_t * module_rlm_instance_alloc(module_list_t *ml, module_instance_t const *parent, dl_module_type_t type, char const *mod_name, char const *inst_name, module_instance_state_t init_state)
Allocate a rlm module instance.
Definition: module_rlm.c:1110
static int module_method_validate(module_instance_t *mi)
Definition: module_rlm.c:1088
exfile_t * module_rlm_exfile_init(TALLOC_CTX *ctx, CONF_SECTION *module, uint32_t max_entries, fr_time_delta_t max_idle, bool locking, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Initialise a module specific exfile handle.
Definition: module_rlm.c:116
static fr_rb_tree_t * module_rlm_virtual_name_tree
Lookup virtual module by name.
Definition: module_rlm.c:62
int module_rlm_submodule_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic conf_parser_t func for loading drivers.
Definition: module_rlm.c:950
bool module_rlm_section_type_set(request_t *request, fr_dict_attr_t const *type_da, fr_dict_enum_value_t const *enumv)
Set the next section type if it's not already set.
Definition: module_rlm.c:427
CONF_SECTION * module_rlm_virtual_by_name(char const *asked_name)
Definition: module_rlm.c:810
static int module_conf_parse(module_list_t *ml, CONF_SECTION *mod_conf)
Definition: module_rlm.c:1129
fr_pool_t * module_rlm_connection_pool_init(CONF_SECTION *module, void *opaque, fr_pool_connection_create_t c, fr_pool_connection_alive_t a, char const *log_prefix, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Initialise a module specific connection pool.
Definition: module_rlm.c:308
static void module_rlm_methods_to_strerror(module_method_group_t const *mmg)
Dump the available bindings for the module into the strerror stack.
Definition: module_rlm.c:517
int modules_rlm_free(void)
Cleanup all global structures.
Definition: module_rlm.c:1352
#define FIND_SIBLING_CF_KEY
int modules_rlm_thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el)
Allocates thread-specific data for all registered backend modules.
Definition: module_rlm.c:976
#define parent_name(_x)
static module_list_t * rlm_modules_static
Global module list for all backend modules.
Definition: module_rlm.c:86
int modules_rlm_instantiate(void)
Performs the instantiation phase for all backend modules.
Definition: module_rlm.c:987
int modules_rlm_init(void)
Initialise the module list structure.
Definition: module_rlm.c:1370
static int module_method_group_validate(module_method_group_t *group)
Definition: module_rlm.c:1002
CONF_SECTION * cs
CONF_SECTION where it is defined.
Definition: module_rlm.c:67
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_method_group_t method_group
named methods
Definition: module_rlm.h:40
module_instance_t * mi
The module instance that registered the xlat.
Definition: module_rlm.h:54
fr_dlist_head_t xlats
xlats registered to this module instance.
Definition: module_rlm.h:44
module_instance_t * mi
The process modules also push module calls onto the stack for execution.
Definition: module_rlm.h:63
xlat_t const * xlat
The xlat function.
Definition: module_rlm.h:53
tmpl_t * key
Dynamic key, only set for dynamic modules.
Definition: module_rlm.h:71
section_name_t asked
The actual <name1>.
Definition: module_rlm.h:67
module_method_binding_t mmb
Method we're calling.
Definition: module_rlm.h:70
static module_rlm_t * module_rlm_from_module(module_t *module)
Definition: module_rlm.h:74
module_rlm_t const * rlm
Cached module_rlm_t.
Definition: module_rlm.h:66
The output of module_rlm_by_name_and_method.
Definition: module_rlm.h:62
An xlat function registered to a module.
Definition: module_rlm.h:52
int fr_pool_start(fr_pool_t *pool)
Definition: pool.c:1116
void fr_pool_ref(fr_pool_t *pool)
Increment pool reference by one.
Definition: pool.c:1212
void fr_pool_enable_triggers(fr_pool_t *pool, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Enable triggers for a connection pool.
Definition: pool.c:933
fr_pool_t * fr_pool_init(TALLOC_CTX *ctx, CONF_SECTION const *cs, void *opaque, fr_pool_connection_create_t c, fr_pool_connection_alive_t a, char const *log_prefix)
Create a new connection pool.
Definition: pool.c:967
A connection pool.
Definition: pool.c:87
void *(* fr_pool_connection_create_t)(TALLOC_CTX *ctx, void *opaque, fr_time_delta_t timeout)
Create a new connection handle.
Definition: pool.h:111
int(* fr_pool_connection_alive_t)(void *opaque, void *connection)
Check a connection handle is still viable.
Definition: pool.h:126
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
#define DEBUG2(fmt,...)
Definition: radclient.h:43
#define WARN(fmt,...)
Definition: radclient.h:47
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
Definition: rb.c:850
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
#define fr_rb_inline_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black tree.
Definition: rb.h:271
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Iterator structure for in-order traversal of an rbtree.
Definition: rb.h:321
The main red black tree structure.
Definition: rb.h:73
static char const * name
size_t fr_sbuff_adv_until(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const *tt, char escape_chr)
Wind position until we hit a character in the terminal set.
Definition: sbuff.c:1830
size_t fr_sbuff_out_bstrncpy(fr_sbuff_t *out, fr_sbuff_t *in, size_t len)
Copy as many bytes as possible from a sbuff to a sbuff.
Definition: sbuff.c:700
#define fr_sbuff_set(_dst, _src)
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
Definition: sbuff.h:167
#define fr_sbuff_is_char(_sbuff_or_marker, _c)
#define fr_sbuff_error(_sbuff_or_marker)
#define FR_SBUFF(_sbuff_or_marker)
#define fr_sbuff_advance(_sbuff_or_marker, _len)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_ahead(_sbuff_or_marker)
#define FR_SBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
Set of terminal elements.
Definition: merged_model.c:161
int8_t section_name_cmp(void const *one, void const *two)
Compare two sections.
Definition: section.c:48
static int section_name2_match(section_name_t const *a, section_name_t const *b)
Definition: section.h:60
static int section_name_match(section_name_t const *a, section_name_t const *b)
Definition: section.h:84
static char const * section_name_str(char const *name)
Return a printable string for the section name.
Definition: section.h:98
static void section_name_dup(TALLOC_CTX *ctx, section_name_t *dst, section_name_t const *src)
Definition: section.h:105
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
Section name identifier.
Definition: section.h:44
char const * name
Instance name e.g. user_database.
Definition: module.h:335
@ MODULE_TYPE_RETRY
can handle retries
Definition: module.h:50
module_flags_t flags
Flags that control how a module starts up and how a module is called.
Definition: module.h:227
module_method_group_t * next
Next group in the list.
Definition: module.h:167
CONF_SECTION * conf
Module's instance configuration.
Definition: module.h:329
module_instance_state_t state
What's been done with this module so far.
Definition: module.h:328
unlang_mod_actions_t actions
default actions and retries.
Definition: module.h:303
dl_module_t * module
Dynamic loader handle.
Definition: module.h:286
bool validated
Set to true by module_method_group_validate.
Definition: module.h:166
#define MODULE_INSTANCE_LEN_MAX
The maximum size of a module instance.
Definition: module.h:147
fr_dlist_head_t same_name1
List of bindings with the same name1.
Definition: module.h:179
module_instance_state_t
What state the module instance is currently in.
Definition: module.h:243
@ MODULE_INSTANCE_INSTANTIATED
Module instance has been bootstrapped and instantiated.
Definition: module.h:246
void * uctx
Extra data passed to module_instance_alloc.
Definition: module.h:339
module_method_binding_t * bindings
named methods
Definition: module.h:164
section_name_t const * section
Identifier for a section.
Definition: module.h:174
module_t * exported
Public module structure.
Definition: module.h:276
Module instance data.
Definition: module.h:265
A list of modules.
Definition: module.h:385
Named methods exported by a module.
Definition: module.h:173
A group of methods exported by a module or added as an overlay.
Definition: module.h:163
Struct exported by a rlm_* module.
Definition: module.h:195
#define pair_update_control(_attr, _da)
Return or allocate a fr_pair_t in the control list.
Definition: pair.h:140
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
Optional arguments passed to vp_tmpl functions.
Definition: tmpl.h:341
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:689
void module_list_debug(module_list_t const *ml)
Print the contents of a module list.
Definition: module.c:623
module_list_type_t const module_list_type_thread_local
Callbacks for a thread local list.
Definition: module.c:590
module_instance_t * module_instance_by_name(module_list_t const *ml, module_instance_t const *parent, char const *asked_name)
Find an existing module instance by its name and parent.
Definition: module.c:903
void module_list_mask_set(module_list_t *ml, module_instance_state_t mask)
Set a new bootstrap/instantiate state for a list.
Definition: module.c:1835
fr_slen_t module_instance_name_from_conf(char const **name, CONF_SECTION *conf)
Avoid boilerplate when setting the module instance name.
Definition: module.c:735
void modules_thread_detach(module_list_t *ml)
Remove thread-specific data for a given module list.
Definition: module.c:1009
int modules_thread_instantiate(TALLOC_CTX *ctx, module_list_t const *ml, fr_event_list_t *el)
Creates per-thread instance data for modules which need it.
Definition: module.c:1160
int modules_instantiate(module_list_t const *ml)
Completes instantiation of modules.
Definition: module.c:1281
void module_instance_uctx_set(module_instance_t *mi, void *uctx)
Set the uctx pointer for a module instance.
Definition: module.c:1619
module_list_type_t const module_list_type_global
Callbacks for a global module list.
Definition: module.c:536
int modules_bootstrap(module_list_t const *ml)
Bootstrap any modules which have not been bootstrapped already.
Definition: module.c:1372
int module_instantiate(module_instance_t *instance)
Manually complete module setup by calling its instantiate function.
Definition: module.c:1195
int module_submodule_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic callback for conf_parser_t to load a submodule.
Definition: module.c:847
int module_instance_conf_parse(module_instance_t *mi, CONF_SECTION *conf)
Covert a CONF_SECTION into parsed module instance data.
Definition: module.c:764
module_instance_t * module_instance_alloc(module_list_t *ml, module_instance_t const *parent, dl_module_type_t type, char const *mod_name, char const *inst_name, module_instance_state_t init_state)
Allocate a new module and add it to a module list for later bootstrap/instantiation.
Definition: module.c:1651
module_list_t * module_list_alloc(TALLOC_CTX *ctx, module_list_type_t const *type, char const *name, bool write_protect)
Allocate a new module list.
Definition: module.c:1857
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition: pair.h:69
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
@ T_BARE_WORD
Definition: token.h:120
static fr_event_list_t * el
xlat_action_t(* xlat_func_t)(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
xlat callback function
Definition: xlat.h:214
static fr_slen_t parent
Definition: pair.h:851
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
Definition: strerror.h:84
#define fr_strerror_const_push(_msg)
Definition: strerror.h:227
#define fr_strerror_const(_msg)
Definition: strerror.h:223
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:3740
#define fr_box_strvalue_len(_val, _len)
Definition: value.h:286
int nonnull(2, 5))
static size_t char ** out
Definition: value.h:997
section_name_t const ** virtual_server_section_methods(virtual_server_t const *vs, section_name_t const *section)
Find the component for a section.
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_mctx_set(xlat_t *x, module_inst_ctx_t const *mctx)
Associate a module calling ctx with the xlat.
Definition: xlat_func.c:299
int xlat_register_redundant(CONF_SECTION *cs)
Registers a redundant xlat.