The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
module.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: a9150ac497fb48719805801cc2ce1d9e4898437e $
19  *
20  * @file src/lib/server/module.c
21  * @brief Defines functions for module initialisation
22  *
23  * @copyright 2016,2024 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24  * @copyright 2003,2006,2016 The FreeRADIUS server project
25  * @copyright 2000 Alan DeKok (aland@freeradius.org)
26  * @copyright 2000 Alan Curry (pacman@world.std.com)
27  */
28 
29 RCSID("$Id: a9150ac497fb48719805801cc2ce1d9e4898437e $")
30 
31 #include <freeradius-devel/server/base.h>
32 #include <freeradius-devel/server/cf_file.h>
33 #include <freeradius-devel/server/global_lib.h>
34 #include <freeradius-devel/server/modpriv.h>
35 #include <freeradius-devel/server/module_rlm.h>
36 #include <freeradius-devel/server/radmin.h>
37 #include <freeradius-devel/server/request_data.h>
38 #include <freeradius-devel/server/module.h>
39 #include <freeradius-devel/util/strerror.h>
40 #include <freeradius-devel/util/talloc.h>
41 #include <freeradius-devel/unlang/xlat_func.h>
42 
43 #include <talloc.h>
44 #include <sys/mman.h>
45 
47 
48 /** Heap of all lists/modules used to get a common index with mlg_thread->inst_list
49  */
51 
52 /** An array of thread-local module lists
53 *
54 * The indexes in this array are identical to module_list_global, allowing
55 * O(1) lookups. Arrays are used here as there's no performance penalty
56 * once they're populated.
57 */
59 
60 static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info);
61 static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx, fr_cmd_info_t *info, int max_expansions, char const **expansions);
62 static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info);
63 static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info);
64 static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info);
65 
67  {
68  .parent = "show module",
69  .add_name = true,
70  .name = "status",
71  .func = cmd_show_module_status,
72  .help = "Show the status of a particular module.",
73  .read_only = true,
74  },
75 
76  {
77  .parent = "show module",
78  .add_name = true,
79  .name = "config",
80  .func = cmd_show_module_config,
81  .help = "Show configuration for a module",
82  // @todo - do tab expand, by walking over the whole module list...
83  .read_only = true,
84  },
85 
86  {
87  .parent = "set module",
88  .add_name = true,
89  .name = "status",
90  .syntax = "(alive|disallow|fail|reject|handled|invalid|notfound|noop|ok|updated)",
91  .func = cmd_set_module_status,
92  .help = "Change module status to fixed value.",
93  .read_only = false,
94  },
95 
97 };
98 
100  {
101  .parent = "show",
102  .name = "module",
103  .help = "Show information about modules.",
104  .tab_expand = module_name_tab_expand,
105  .read_only = true,
106  },
107 
108  // @todo - what if there's a module called "list" ?
109  {
110  .parent = "show module",
111  .name = "list",
112  .func = cmd_show_module_list,
113  .help = "Show the list of modules loaded in the server.",
114  .read_only = true,
115  },
116 
117  {
118  .parent = "set",
119  .name = "module",
120  .help = "Change module settings.",
121  .tab_expand = module_name_tab_expand,
122  .read_only = false,
123  },
124 
125 
127 };
128 
129 static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
130 {
131  module_instance_t *mi = ctx;
132 
133  fr_assert(mi->conf != NULL);
134 
135  (void) cf_section_write(fp, mi->conf, 0);
136 
137  return 0;
138 }
139 
140 static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx,
141  fr_cmd_info_t *info, int max_expansions, char const **expansions)
142 {
143  char const *text;
144  int count;
145 
146  if (info->argc <= 0) return 0;
147 
148  text = info->argv[info->argc - 1];
149  count = 0;
150 
152  module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);
153 
154  if (count >= max_expansions) {
155  break;
156  }
157  if (fr_command_strncmp(text, mi->name)) {
158  expansions[count] = strdup(mi->name);
159  count++;
160  }
161  }}
162 
163  return count;
164 }
165 
166 static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info)
167 {
169  module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);
170 
171  fprintf(fp, "\t%s\n", mi->name);
172  }}
173 
174  return 0;
175 }
176 
177 static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
178 {
179  module_instance_t *mi = ctx;
180 
181  if (!mi->force) {
182  fprintf(fp, "alive\n");
183  return 0;
184  }
185 
186  fprintf(fp, "%s\n", fr_table_str_by_value(rcode_table, mi->code, "<invalid>"));
187 
188  return 0;
189 }
190 
191 static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
192 {
193  module_instance_t *mi = ctx;
194  rlm_rcode_t rcode;
195 
196  if (strcmp(info->argv[0], "alive") == 0) {
197  mi->force = false;
198  return 0;
199  }
200 
202  if (rcode == RLM_MODULE_NOT_SET) {
203  fprintf(fp_err, "Unknown status '%s'\n", info->argv[0]);
204  return -1;
205  }
206 
207  mi->code = rcode;
208  mi->force = true;
209 
210  return 0;
211 }
212 
213 /** Chars that are allowed in a module instance name
214  *
215  */
217  ['-'] = true, ['/'] = true, ['_'] = true, ['.'] = true,
218  ['0'] = true, ['1'] = true, ['2'] = true, ['3'] = true, ['4'] = true,
219  ['5'] = true, ['6'] = true, ['7'] = true, ['8'] = true, ['9'] = true,
220  ['A'] = true, ['B'] = true, ['C'] = true, ['D'] = true, ['E'] = true,
221  ['F'] = true, ['G'] = true, ['H'] = true, ['I'] = true, ['J'] = true,
222  ['K'] = true, ['L'] = true, ['M'] = true, ['N'] = true, ['O'] = true,
223  ['P'] = true, ['Q'] = true, ['R'] = true, ['S'] = true, ['T'] = true,
224  ['U'] = true, ['V'] = true, ['W'] = true, ['X'] = true, ['Y'] = true,
225  ['Z'] = true,
226  ['a'] = true, ['b'] = true, ['c'] = true, ['d'] = true, ['e'] = true,
227  ['f'] = true, ['g'] = true, ['h'] = true, ['i'] = true, ['j'] = true,
228  ['k'] = true, ['l'] = true, ['m'] = true, ['n'] = true, ['o'] = true,
229  ['p'] = true, ['q'] = true, ['r'] = true, ['s'] = true, ['t'] = true,
230  ['u'] = true, ['v'] = true, ['w'] = true, ['x'] = true, ['y'] = true,
231  ['z'] = true
232 };
233 
234 /** dl module tracking
235  *
236  * This is used by all module lists, irrespecitve of their type, and is thread safe.
237  */
239 
240 /** Callback to initialise any global structures required for the module list
241  *
242  * @param[in] ml to initialise global data for.
243  * @return
244  * - 0 on success.
245  * - -1 on failure.
246  */
247 typedef int (*module_list_init_t)(module_list_t *ml);
248 
249 /** Callback to free any global structures associated with the module list
250  *
251  * @param[in] ml to free.
252  */
253 typedef void (*module_list_free_t)(module_list_t *ml);
254 
255 /** Callback to add data for a module
256  *
257  * @param[in] mi to add data for.
258  * Use mi->ml for the module list.
259  * Use mi->data to access the data.
260  * @return
261  * - 0 on success.
262  * - -1 on failure.
263  */
265 
266 /** Callback to del data for a module
267  *
268  * @param[in] mi to add data to (use mi->ml for the module list).
269  *
270  */
272 
273 /** Callback to initialise a list for thread-local data, called once per thread
274  *
275  * @param[in] ctx talloc context for thread-local data.
276  * May be modified by the init function if the
277  * module_thread_instance_t need to be parented
278  * by another ctx.
279  * @param[in] ml to initialise thread-local data for.
280  * @return
281  * - 0 on success.
282  * - -1 on failure.
283  */
284 typedef int (*module_list_thread_init_t)(TALLOC_CTX **ctx, module_list_t const *ml);
285 
286 /** Callback to free thread-local structures, called once per thread as the thread is being destroyed
287  *
288  * @param[in] ml to free thread-local data for.
289  */
291 
292 /** Callback to add thread-local data for a module
293  *
294  * @param[in] ti to add data for.
295  * Use `ti->mi->ml` for the module list.
296  * Use `ti->mi` for the module instance.
297  * Use `ti->data` for the thread specific data.
298  * @return
299  * - 0 on success.
300  * - -1 on failure.
301  */
303 
304 /** Callback to remove thread-local data for a module
305  *
306  * @param[in] ti to del data for.
307  * Use `ti->mi->ml` for the module list.
308  * Use `ti->mi` for the module instance.
309  * Use `ti->data` for the thread specific data.
310  */
312 
313 /** Structure to hold callbacks for a module list type
314  *
315  * We care about performance for module lists, as they're used heavily at runtime.
316  *
317  * As much as possible we try to avoid jumping through unecessary functions and
318  * unecessary switch statements.
319  *
320  * This structure contains callbacks which change how the module list operates,
321  * making it either a global module list, or a thread-local module list, i.e. one
322  * which only be used by a single thread.
323  *
324  * Instances of this structure are created in this compilation unit, and exported
325  * for the caller to pass into module_list_alloc().
326  */
328  size_t list_size; //!< Size of talloc_chunk to allocate for the module_list_t.
329 
330  module_list_init_t init; //!< Initialise any global structures required for thread-local lookups.
331  module_list_free_t free; //!< Free any global structures required for thread-local lookups.
332 
333  size_t inst_size; //!< Size of talloc chunk to allocate for the module_instance_t.
334  ///< allows over-allocation if list types want to append fields.
335  module_list_data_add_t data_add; //!< Record that module data has been added.
336  module_list_data_del_t data_del; //!< Record that module data has been removed.
337 
338  /** Callbacks to manage thread-local data
339  */
340  struct {
341  module_list_thread_init_t init; //!< Initialise any thread-local structures required for thread-local lookups.
342  module_list_thread_free_t free; //!< Free any thread-local structures.
343 
344  module_list_thread_data_add_t data_add; //!< Add thread-local data for a module.
345  module_list_thread_data_get_t data_get; //!< Retrieve thread local-data for a module.
346  module_list_thread_data_del_t data_del; //!< Remove (but not free) thread-local data for a module.
347 
348  void *data; //!< Pointer to hold any global resources for the thread-local implementation.
350 };
351 
352 typedef struct {
353  module_instance_t mi; //!< Common module instance fields. Must come first.
354 
355  fr_heap_index_t inst_idx; //!< Entry in the bootstrap/instantiation heap.
356  //!< should be an identical value to the thread-specific
357  ///< data for this module.
359 
360 /** Sort module instance data first by list then by number
361  *
362  * The module's position in the global instance heap informs of us
363  * of its position in the thread-specific heap, which allows for
364  * O(1) lookups.
365  */
366 static int8_t _mlg_module_instance_cmp(void const *one, void const *two)
367 {
370  int8_t ret;
371 
372  fr_assert(a->ml && b->ml);
373 
374  ret = CMP(a->ml, b->ml);
375  if (ret != 0) return 0;
376 
377  return CMP(a->number, b->number);
378 }
379 
380 /** Free the global module index
381  *
382  */
383 static int _mlg_global_free(UNUSED void *uctx)
384 {
385  return talloc_free(mlg_index);
386 }
387 
388 /** Initialise the global module index
389  *
390  */
391 static int _mlg_global_init(UNUSED void *uctx)
392 {
394  return 0;
395 }
396 
397 /** Global initialisation for index heap and module array
398  *
399  */
401 {
402  /*
403  * Create the global module heap we use for
404  * common indexes in the thread-specific
405  * heaps.
406  */
408 
409  return 0;
410 }
411 
412 /** Add the unique index value so we can do thread local lookups
413  *
414  */
416 {
417  /*
418  * Insert the module into the global heap so
419  * we can get common thread-local indexes.
420  */
421  if (fr_heap_insert(&mlg_index, mi) < 0) {
422  ERROR("Failed inserting into global module index");
423  return -1;
424  }
425 
426  return 0;
427 }
428 
430 {
431  mlg_module_instance_t *mlg_mi = (mlg_module_instance_t *)talloc_get_type_abort(mi, module_instance_t);
432 
433  if (!fr_heap_entry_inserted(mlg_mi->inst_idx)) return;
434 
435  if (fr_heap_extract(&mlg_index, mi) == 0) return;
436 
437  fr_assert(0);
438 }
439 
440 /** Free the thread local heap on exit
441  *
442  * All thread local module lists should have been destroyed by this point
443  */
444 static int _module_thread_inst_list_free(void *tilp)
445 {
446  module_thread_instance_t **til = talloc_get_type_abort(tilp, module_thread_instance_t *);
447  size_t i, len = talloc_array_length(til);
448  unsigned int found = 0;
449 
450  for (i = 0; i < len; i++) if (til[i]) found++;
451 
452  if (!fr_cond_assert_msg(found == 0,
453  "Thread local array has %u non-null elements remaining on exit. This is a leak",
454  found)) {
455  return -1;
456  }
457 
458  return talloc_free(til);
459 }
460 
461 /** Allocate a thread-local array to hold thread data for each module thats been instantiated
462  *
463  * @param[in] ctx Talloc context for the thread-local data.
464  * Mutated by this function so that thread local data is allocated
465  * beneath the array.
466  * @param[in] ml Module list to initialise the thread-local data for.
467  */
468 static int mlg_thread_init(UNUSED TALLOC_CTX **ctx, UNUSED module_list_t const *ml)
469 {
470  /*
471  * Initialise the thread specific tree if this is the
472  * first time through or if everything else was
473  * de-initialised.
474  */
475  if (!mlg_thread_inst_list) {
477 
478  MEM(arr = talloc_zero_array(NULL, module_thread_instance_t *, fr_heap_num_elements(mlg_index)));
479 
481  }
482 
483  return 0;
484 }
485 
486 /** Retrieve the thread-specific data for a module from the thread-local array of instance data
487  *
488  * This looks complex, but it's just asserts for sanity. This is really only returning an array offset.
489  *
490  * @param[in] mi Module instance to get the thread-specific data for.
491  */
493 {
496  void *ti_p;
497 
498  fr_assert_msg(mlg_mi->inst_idx <= talloc_array_length(mlg_thread_inst_list),
499  "module instance index %u must be <= thread local array %zu",
500  mlg_mi->inst_idx, talloc_array_length(mlg_thread_inst_list));
501 
503  "mismatch between global module heap (%u entries) and thread local (%zu entries)",
504  fr_heap_num_elements(mlg_index), talloc_array_length(mlg_thread_inst_list));
505 
506  /*
507  * Check for a NULL entry. This can happen when a module's
508  * thread instantiate callback fails, and we try and cleanup
509  * a partially instantiated thread.
510  */
511  ti_p = mlg_thread_inst_list[mlg_mi->inst_idx - 1];
512  if (unlikely(!ti_p)) return NULL;
513 
514  ti = talloc_get_type_abort(ti_p, module_thread_instance_t);
515  fr_assert_msg(ti->mi == mi, "thread/module mismatch thread %s (%p), module %s (%p)",
516  ti->mi->name, ti->mi, mi->name, mi);
517 
518  return ti;
519 }
520 
522 {
524  mlg_thread_inst_list[mlg_mi->inst_idx - 1] = ti;
525  return 0;
526 }
527 
529 {
531  mlg_thread_inst_list[mlg_mi->inst_idx - 1] = NULL;
532 }
533 
534 /** Callbacks for a global module list
535  */
537  .init = mlg_init,
538 
539  .inst_size = sizeof(mlg_module_instance_t),
540  .data_add = mlg_data_add,
541  .data_del = mlg_data_del,
542 
543  .thread = {
544  .init = mlg_thread_init,
545  .data_add = mlg_thread_data_add,
546  .data_get = mlg_thread_data_get,
547  .data_del = mlg_thread_data_del
548  }
549 };
550 
551 /** A slightly larger module_instance structure to hold the module instance and thread instance
552  */
553 typedef struct {
554  module_instance_t mi; //!< Common module instance fields. Must come first.
555  module_thread_instance_t *ti; //!< Thread-specific data. Still in its own structure
556  ///< for talloc reasons.
558 
560 {
561  mltl_module_instance_t *mltl_mi = (mltl_module_instance_t *)talloc_get_type_abort(mi, module_instance_t);
562 
563  /*
564  * Only free thread instance data we allocated...
565  */
566  if (mltl_mi->ti) module_thread_detach(mltl_mi->ti);
567 }
568 
570 {
572  return mltl_mi->ti;
573 }
574 
576 {
577  mltl_module_instance_t *mltl_mi = (mltl_module_instance_t *)talloc_get_type_abort(ti->mi, module_instance_t);
578  mltl_mi->ti = ti;
579  return 0;
580 }
581 
583 {
584  mltl_module_instance_t *mltl_mi = (mltl_module_instance_t *)talloc_get_type_abort(ti->mi, module_instance_t);
585  mltl_mi->ti = NULL;
586 }
587 
588 /** Callbacks for a thread local list
589  */
592  .data_del = mltl_mlg_data_del,
593 
594  .thread = {
595  .data_add = mltl_thread_data_add,
596  .data_get = mltl_thread_data_get,
597  .data_del = mltl_thread_data_del
598  }
599 };
600 
601 /** Print debugging information for a module
602  *
603  * @param[in] mi Module instance to print.
604  */
606 {
607  FR_FAULT_LOG("%s (%p) {", mi->name, mi);
608  FR_FAULT_LOG(" type : %s", fr_table_str_by_value(dl_module_type_prefix, mi->module->type, "<invalid>"));
609  if (mi->parent) {
610  FR_FAULT_LOG(" parent : \"%s\" (%p)", mi->parent->name, mi->parent);
611  }
612  FR_FAULT_LOG(" bootstrapped : %s", mi->state & MODULE_INSTANCE_BOOTSTRAPPED ? "yes" : "no");
613  FR_FAULT_LOG(" instantiated : %s", mi->state & MODULE_INSTANCE_INSTANTIATED ? "yes" : "no");
614  FR_FAULT_LOG(" boot : %p", mi->boot);
615  FR_FAULT_LOG(" data : %p", mi->data);
616  FR_FAULT_LOG(" conf : %p", mi->conf);
617  FR_FAULT_LOG("}");
618 }
619 
620 /** Print the contents of a module list
621  *
622  */
624 {
625  module_instance_t const *inst;
627 
628  FR_FAULT_LOG("Module list \"%s\" (%p) {", ml->name, ml);
629  FR_FAULT_LOG(" phase masked:");
630  FR_FAULT_LOG(" bootstrap : %s", ml->mask & MODULE_INSTANCE_BOOTSTRAPPED ? "yes" : "no");
631  FR_FAULT_LOG(" instantiate : %s", ml->mask & MODULE_INSTANCE_INSTANTIATED ? "yes" : "no");
632  FR_FAULT_LOG(" thread : %s", ml->mask & MODULE_INSTANCE_INSTANTIATED ? "yes" : "no");
633  FR_FAULT_LOG("}");
634  /*
635  * Modules are printed in the same order
636  * they would be bootstrapped or inserted
637  * into the tree.
638  */
639  for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree);
640  inst;
641  inst = fr_rb_iter_next_inorder(&iter)) {
643  }
644 }
645 
646 /** Protect module data
647  *
648  * @param[in] pool to protect
649  * @return
650  * - 0 on success.
651  * - -1 on failure.
652  */
653 static inline CC_HINT(always_inline)
655 {
656  if ((pool->start == NULL) || !mi->ml->write_protect) return 0; /* noop */
657 
658  DEBUG3("Protecting data for module \"%s\" %p-%p",
659  mi->name, pool->start, ((uint8_t *)pool->start + pool->len - 1));
660 
661  if (unlikely(mprotect(pool->start, pool->len, PROT_READ) < 0)) {
662  fr_strerror_printf("Protecting \"%s\" module data failed: %s", mi->name, fr_syserror(errno));
663  return -1;
664  }
665 
666  return 0;
667 }
668 
669 /** Unprotect module data
670  *
671  * @param[in] pool to protect
672  * @return
673  * - 0 on success.
674  * - -1 on failure.
675  */
676 static inline CC_HINT(always_inline)
678 {
679  if ((pool->start == NULL) || !mi->ml->write_protect) return 0; /* noop */
680 
681  DEBUG3("Unprotecting data for module \"%s\" %p-%p",
682  mi->name, pool->start, ((uint8_t *)pool->start + pool->len - 1));
683 
684  if (unlikely(mprotect(pool->start, pool->len, PROT_READ | PROT_WRITE) < 0)) {
685  fr_strerror_printf("Unprotecting \"%s\" data failed: %s", mi->name, fr_syserror(errno));
686  return -1;
687  }
688 
689  return 0;
690 }
691 
692 /** Mark module data as read only
693  *
694  * @param[in] mi Instance data to protect (mark as read only).
695  * @return
696  * - 0 on success.
697  * - -1 on failure.
698  */
700 {
701  return module_data_unprotect(mi, &mi->inst_pool);
702 }
703 
704 /** Mark module data as read/write
705  *
706  * @param[in] mi Instance data to unprotect (mark as read/write).
707  * @return
708  * - 0 on success.
709  * - -1 on failure.
710  */
712 {
713  return module_data_unprotect(mi, &mi->inst_pool);
714 }
715 
716 /** Return the prefix string for the deepest module
717  *
718  * This is useful for submodules which don't have a prefix of their own.
719  * In this case we need to use the prefix of the shallowest module, which
720  * will be a proto or rlm module.
721  *
722  * @param[in] mi Instance to get the prefix for.
723  * @return The prefix string for the shallowest module.
724  */
726 {
727  module_instance_t const *root = module_instance_root(mi);
728 
729  return fr_table_str_by_value(dl_module_type_prefix, root->module->type, "<INVALID>");
730 }
731 
732 /** Avoid boilerplate when setting the module instance name
733  *
734  */
736 {
737  char const *name2;
738  char const *inst_name;
739  fr_slen_t slen;
740 
741  name2 = cf_section_name2(conf);
742  if (name2) {
743  inst_name = name2;
744  goto done;
745  }
746 
747  inst_name = cf_section_name1(conf);
748 done:
749  slen = module_instance_name_valid(inst_name);
750  if (slen < 0) {
751  cf_log_perr(conf, "Invalid module configuration");
752  *name = NULL;
753  return slen;
754  }
755 
756  *name = inst_name;
757 
758  return 0;
759 }
760 
761 /** Covert a CONF_SECTION into parsed module instance data
762  *
763  */
765 {
766  /*
767  * Associate the module instance with the conf section
768  * *before* executing any parse rules that might need it.
769  */
770  cf_data_add(conf, mi, mi->module->dl->name, false);
771  mi->conf = conf;
772 
773  if (mi->exported->config && mi->conf) {
774  if ((cf_section_rules_push(mi->conf, mi->exported->config)) < 0 ||
775  (cf_section_parse(mi->data, mi->data, mi->conf) < 0)) {
776  cf_log_err(mi->conf, "Failed evaluating configuration for module \"%s\"",
777  mi->module->dl->name);
778  return -1;
779  }
780  }
781 
782  return 0;
783 }
784 
785 /** Compare module instances by parent and name
786  *
787  * The reason why we need parent, is because we could have submodules with names
788  * that conflict with their parent.
789  */
790 static int8_t module_instance_name_cmp(void const *one, void const *two)
791 {
792  module_instance_t const *a = one;
793  module_instance_t const *b = two;
794  module_instance_t const *mi;
795  int a_depth = 0, b_depth = 0;
796  int ret;
797 
798 #ifdef STATIC_ANALYZER
799  if (!fr_cond_assert(a)) return +1;
800  if (!fr_cond_assert(b)) return -1;
801 #endif
802 
803  /*
804  * Sort by depth, so for tree walking we start
805  * at the shallowest node, and finish with
806  * the deepest child.
807  */
808  for (mi = a; mi; mi = mi->parent) a_depth++;
809  for (mi = b; mi; mi = mi->parent) b_depth++;
810 
811  ret = CMP(a_depth, b_depth);
812  if (ret != 0) return ret;
813 
814  ret = CMP(a->parent, b->parent);
815  if (ret != 0) return ret;
816 
817  ret = strcmp(a->name, b->name);
818  return CMP(ret, 0);
819 }
820 
821 /** Compare module's by their private instance data
822  *
823  */
824 static int8_t module_instance_data_cmp(void const *one, void const *two)
825 {
826  void const *a = ((module_instance_t const *)one)->data;
827  void const *b = ((module_instance_t const *)two)->data;
828 
829  return CMP(a, b);
830 }
831 
832 /** Generic callback for conf_parser_t to load a submodule
833  *
834  * conf_parser_t entry should point to a module_instance_t field in the instance data
835  *
836  * @param[in] ctx unused.
837  * @param[out] out A pointer to a pointer to a module_instance_t.
838  * @param[in] parent This _must_ point to the instance data of the parent
839  * module.
840  * @param[in] ci The CONF_PAIR containing the name of the submodule to load.
841  * @param[in] rule uctx pointer must be a pointer to a module_list_t **
842  * containing the list to search in.
843  * @return
844  * - 0 on success.
845  * - -1 if we failed to load the submodule.
846  */
847 int module_submodule_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent,
848  CONF_ITEM *ci, conf_parser_t const *rule)
849 {
850  char const *name = cf_pair_value(cf_item_to_pair(ci));
852  CONF_SECTION *submodule_cs;
853  module_instance_t *mi;
854  module_list_t *ml = talloc_get_type_abort(*((void * const *)rule->uctx), module_list_t);
855 
856  /*
857  * We assume the submodule's config is the
858  * in a section with the same name as
859  * the submodule.
860  */
861  submodule_cs = cf_section_find(cs, name, NULL);
862 
863  /*
864  * Allocate an empty section if one doesn't exist
865  * this is so defaults get parsed.
866  */
867  if (!submodule_cs) submodule_cs = cf_section_alloc(cs, cs, name, NULL);
868 
869  /*
870  * The submodule name dictates the module loaded
871  * the instance name is always the submodule name
872  * and will be appended to the parent's instance
873  * name.
874  */
876  if (unlikely(mi == NULL)) {
877  cf_log_err(submodule_cs, "Failed loading submodule");
878  return -1;
879  }
880 
881  if (unlikely(module_instance_conf_parse(mi, submodule_cs) < 0)) {
882  cf_log_err(submodule_cs, "Failed parsing submodule config");
883  talloc_free(mi);
884  return -1;
885  }
886 
887  *((module_instance_t **)out) = mi;
888 
889  return 0;
890 }
891 
892 /** Find an existing module instance by its name and parent
893  *
894  * @param[in] ml to search in.
895  * @param[in] parent to qualify search with.
896  * @param[in] asked_name The name of the module we're attempting to find.
897  * May include '-' which indicates that it's ok for
898  * the module not to be loaded.
899  * @return
900  * - Module instance matching name.
901  * - NULL if no such module exists.
902  */
904 {
905  char const *inst_name;
906  void *inst;
907 
908  if (!ml->name_tree) return NULL;
909 
910  /*
911  * Look for the real name. Ignore the first character,
912  * which tells the server "it's OK for this module to not
913  * exist."
914  */
915  inst_name = asked_name;
916  if (inst_name[0] == '-') inst_name++;
917 
918  inst = fr_rb_find(ml->name_tree,
920  .parent = UNCONST(module_instance_t *, parent),
921  .name = inst_name
922  });
923  if (!inst) return NULL;
924 
925  return talloc_get_type_abort(inst, module_instance_t);
926 }
927 
928 /** Find the module's shallowest parent
929  *
930  * @param[in] child to locate the root for.
931  * @return
932  * - The module's shallowest parent.
933  * - NULL on error.
934  */
936 {
937  module_instance_t const *next;
938 
939  for (;;) {
940  next = child->parent;
941  if (!next) break;
942 
943  child = next;
944  }
945 
946  return UNCONST(module_instance_t *, child);
947 }
948 
949 /** Find an existing module instance by its private instance data
950  *
951  * @param[in] ml to search in.
952  * @param[in] data to resolve to module_instance_t.
953  * @return
954  * - Module instance matching data.
955  * - NULL if no such module exists.
956  */
958 {
959  module_instance_t *mi;
960 
961  mi = fr_rb_find(ml->data_tree,
963  .data = UNCONST(void *, data)
964  });
965  if (!mi) return NULL;
966 
967  return talloc_get_type_abort(mi, module_instance_t);
968 }
969 
970 /** Retrieve module/thread specific instance data for a module
971  *
972  * @param[in] ml Module list module belongs to.
973  * @param[in] data Private instance data of the module.
974  * Same as what would be provided by
975  * #module_instance_by_data.
976  * @return
977  * - Thread specific instance data on success.
978  * - NULL if module has no thread instance data.
979  */
981 {
983 
984  if (!mi) return NULL;
985 
986  return module_thread(mi);
987 }
988 
990 {
991  module_list_t *ml;
992 
993  /*
994  * This can happen when a module's thread instantiate
995  * callback fails, and we try and cleanup a partially
996  * instantiated thread.
997  */
998  if (unlikely(!ti)) return;
999 
1000  ml = ti->mi->ml;
1001  ml->type->thread.data_del(ti);
1002  talloc_free(ti);
1003 }
1004 
1005 /** Remove thread-specific data for a given module list
1006  *
1007  * Removes all module thread data for the
1008  */
1010 {
1011  fr_rb_iter_inorder_t iter;
1012  void *inst;
1013 
1014  /*
1015  * Loop over all the modules in the module list
1016  * finding and extracting their thread specific
1017  * data, and calling their detach methods.
1018  */
1019  for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree);
1020  inst;
1021  inst = fr_rb_iter_next_inorder(&iter)) {
1022  module_instance_t *mi = talloc_get_type_abort(inst, module_instance_t);
1024 
1026  }
1027 
1028  /*
1029  * Cleanup any lists the module list added to this thread
1030  */
1031  if (ml->type->thread.free) ml->type->thread.free(ml);
1032 }
1033 
1034 /** Callback to free thread local data
1035  *
1036  * ti->data is allocated in the context of ti, so will be freed too.
1037  *
1038  * Calls the detach function for thread local data, and removes the data from the
1039  * thread local list.
1040  *
1041  * @param[in] ti to free.
1042  */
1044 {
1045  module_instance_t const *mi = ti->mi;
1046 
1047  /*
1048  * Never allocated a thread instance, so we don't need
1049  * to clean it up...
1050  */
1051  if (mi->state & MODULE_INSTANCE_NO_THREAD_INSTANTIATE) return 0;
1052 
1053  DEBUG4("Cleaning up %s thread instance data (%p/%p)",
1054  mi->exported->name, ti, ti->data);
1055 
1056  if (mi->exported->thread_detach) {
1058  .mi = ti->mi,
1059  .thread = ti->data,
1060  .el = ti->el
1061  });
1062  }
1063 
1064  ti->mi->ml->type->thread.data_del(ti);
1065 
1066  return 0;
1067 }
1068 
1069 /** Allocate thread-local instance data for a module
1070  *
1071  * The majority of modules will have a single set of thread-specific instance data.
1072  *
1073  * An exception is dynamic modules, which may have multiple sets of thread-specific instance data tied to
1074  * a specific dynamic use of that module.
1075  *
1076  * @param[in] ctx Talloc ctx to bind thread specific data to.
1077  * @param[in] mi Module instance to perform thread instantiation for.
1078  * @param[in] el Event list serviced by this thread.
1079  * @return
1080  * - 0 on success.
1081  * - -1 on failure.
1082  */
1084 {
1085  module_list_t *ml = mi->ml;
1087 
1088  /*
1089  * Allows the caller of module_instance_alloc to
1090  * skip thread instantiation for certain modules instances
1091  * whilst allowing modules to still register thread
1092  * instantiation callbacks.
1093  *
1094  * This is mainly there for the single global instance of
1095  * a module, which will only have run-time thread-specific
1096  * instances, like dynamic/keyed modules.
1097  */
1098  if (module_instance_skip_thread_instantiate(mi)) return 0;
1099 
1100  /*
1101  * Check the list pointers are ok
1102  */
1103  (void)talloc_get_type_abort(mi->ml, module_list_t);
1104 
1105  MEM(ti = talloc_zero(ctx, module_thread_instance_t));
1106  talloc_set_destructor(ti, _module_thread_inst_free);
1107  ti->el = el;
1108  ti->mi = mi;
1109 
1110  if (mi->exported->thread_inst_size) {
1111  MEM(ti->data = talloc_zero_array(ti, uint8_t, mi->exported->thread_inst_size));
1112 
1113  /*
1114  * Fixup the type name, in case something calls
1115  * talloc_get_type_abort() on it...
1116  */
1117  if (!mi->exported->thread_inst_type) {
1118  talloc_set_name(ti->data, "%s_%s_thread_t",
1120  mi->exported->name);
1121  } else {
1122  talloc_set_name_const(ti->data, mi->exported->thread_inst_type);
1123  }
1124  }
1125 
1126  if (ml->type->thread.data_add(ti) < 0) {
1127  PERROR("Failed adding thread data for module \"%s\"", mi->name);
1128  error:
1129  ml->type->thread.data_del(ti);
1130  talloc_free(ti);
1131  return -1;
1132  }
1133 
1134  /*
1135  * So we don't get spurious errors
1136  */
1138 
1139  DEBUG4("Alloced %s thread instance data (%p/%p)", ti->mi->exported->name, ti, ti->data);
1140  if (mi->exported->thread_instantiate &&
1142  PERROR("Thread instantiation failed for module \"%s\"", mi->name);
1143  goto error;
1144  }
1145 
1146  return 0;
1147 }
1148 
1149 /** Creates per-thread instance data for modules which need it
1150  *
1151  * Must be called by any new threads before attempting to execute unlang sections.
1152  *
1153  * @param[in] ctx Talloc ctx to bind thread specific data to.
1154  * @param[in] ml Module list to perform thread instantiation for.
1155  * @param[in] el Event list serviced by this thread.
1156  * @return
1157  * - 0 on success.
1158  * - -1 on failure.
1159  */
1161 {
1162  void *inst;
1163  fr_rb_iter_inorder_t iter;
1164  int ret;
1165 
1166  /*
1167  * Do any thread-local instantiation necessary
1168  */
1169  if (ml->type->thread.init) {
1170  ret = ml->type->thread.init(&ctx, ml);
1171  if (unlikely(ret < 0)) return ret;
1172  }
1173 
1174  for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree);
1175  inst;
1176  inst = fr_rb_iter_next_inorder(&iter)) {
1177  module_instance_t *mi = talloc_get_type_abort(inst, module_instance_t); /* Sanity check*/
1178 
1179  if (module_thread_instantiate(ctx, mi, el) < 0) {
1181  return -1;
1182  }
1183  }
1184 
1185  return 0;
1186 }
1187 
1188 /** Manually complete module setup by calling its instantiate function
1189  *
1190  * @param[in] instance of module to complete instantiation for.
1191  * @return
1192  * - 0 on success.
1193  * - -1 on failure.
1194  */
1196 {
1197  module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);
1198  CONF_SECTION *cs = mi->conf;
1199 
1200  /*
1201  * If we're instantiating, then nothing should be able to
1202  * modify the boot data for this module.
1203  *
1204  * mprotect is thread-safe, so we don't need to worry about
1205  * synchronisation. There is the overhead of a system call
1206  * but dynamic module instantiation is relatively rare.
1207  *
1208  * We need to wait until all modules have registered things
1209  * like xlat functions, as the xlat functions themselves may
1210  * end up being allocated in boot pool data, and have inline
1211  * rbtree node structures, which may be modified as additional
1212  * xlat functions are registered.
1213  */
1214  if (unlikely(module_data_protect(mi, &mi->boot_pool) < 0)) {
1215  cf_log_perr(mi->conf, "\"%s\"", mi->name);
1216  return -1;
1217  }
1218 
1219  /*
1220  * We only instantiate modules in the bootstrapped state
1221  */
1222  if (module_instance_skip_instantiate(mi)) return 0;
1223 
1224  if (mi->module->type == DL_MODULE_TYPE_MODULE) {
1225  if (fr_command_register_hook(NULL, mi->name, mi, module_cmd_table) < 0) {
1226  PERROR("Failed registering radmin commands for module %s", mi->name);
1227  return -1;
1228  }
1229  }
1230 
1231  /*
1232  * Now that ALL modules are instantiated, and ALL xlats
1233  * are defined, go compile the config items marked as XLAT.
1234  */
1235  if (mi->exported->config && (cf_section_parse_pass2(mi->data,
1236  mi->conf) < 0)) return -1;
1237 
1238  /*
1239  * Call the instantiate method, if any.
1240  */
1241  if (mi->exported->instantiate) {
1242  cf_log_debug(cs, "Instantiating %s_%s \"%s\"",
1244  mi->module->exported->name,
1245  mi->name);
1246 
1247  /*
1248  * Call the module's instantiation routine.
1249  */
1250  if (mi->exported->instantiate(MODULE_INST_CTX(mi)) < 0) {
1251  cf_log_err(mi->conf, "Instantiation failed for module \"%s\"", mi->name);
1252 
1253  return -1;
1254  }
1255  }
1256 
1257  /*
1258  * Instantiate shouldn't modify any global resources
1259  * so we can protect the data now without the side
1260  * effects we might see with boot data.
1261  */
1262  if (unlikely(module_data_protect(mi, &mi->inst_pool) < 0)) {
1263  cf_log_perr(mi->conf, "\"%s\"", mi->name);
1264  return -1;
1265  }
1267 
1268  return 0;
1269 }
1270 
1271 /** Completes instantiation of modules
1272  *
1273  * Allows the module to initialise connection pools, and complete any registrations that depend on
1274  * attributes created during the bootstrap phase.
1275  *
1276  * @param[in] ml containing modules to instantiate.
1277  * @return
1278  * - 0 on success.
1279  * - -1 on failure.
1280  */
1282 {
1283  void *inst;
1284  fr_rb_iter_inorder_t iter;
1285 
1286  DEBUG2("#### Instantiating %s modules ####", ml->name);
1287 
1288  for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree);
1289  inst;
1290  inst = fr_rb_iter_next_inorder(&iter)) {
1291  module_instance_t *mi = talloc_get_type_abort(inst, module_instance_t);
1292  if (module_instantiate(mi) < 0) return -1;
1293  }
1294 
1295  return 0;
1296 }
1297 
1298 /** Manually complete module bootstrap by calling its instantiate function
1299  *
1300  * - Parse the module configuration.
1301  * - Call the modules "bootstrap" method.
1302  *
1303  * @param[in] mi Module instance to bootstrap.
1304  * @return
1305  * - 0 on success.
1306  * - -1 on failure.
1307  */
1309 {
1310  /*
1311  * We only bootstrap modules in the init state
1312  */
1313  if (module_instance_skip_bootstrap(mi)) return 0;
1314 
1315  /*
1316  * Bootstrap the module.
1317  * This must be done last so that the
1318  * module can find its module_instance_t
1319  * in the trees if it needs to bootstrap
1320  * submodules.
1321  */
1322  if (mi->exported->bootstrap) {
1323  CONF_SECTION *cs = mi->conf;
1324 
1325  cf_log_debug(cs, "Bootstrapping %s_%s \"%s\"",
1327  mi->module->exported->name,
1328  mi->name);
1329 
1330  /*
1331  * Modules MUST NOT modify their instance data during
1332  * bootstrap. This is because dynamic (runtime) modules
1333  * don't run their boostrap callbacks, and MUST re-resolve
1334  * any resources added during bootstrap in the
1335  * instantiate callback.
1336  *
1337  * Bootstrap is ONLY there for adding global,
1338  * module-specific resources.
1339  *
1340  * If the module has MODULE_TYPE_DYNAMIC_UNSAFE is set,
1341  * then we don't need the restriction.
1342  */
1343  if ((!(mi->exported->flags & MODULE_TYPE_DYNAMIC_UNSAFE)) &&
1344  unlikely(module_data_protect(mi, &mi->inst_pool) < 0)) {
1345  cf_log_perr(cs, "\"%s\"", mi->name);
1346  return -1;
1347  }
1348  if (mi->exported->bootstrap(MODULE_INST_CTX(mi)) < 0) {
1349  cf_log_err(cs, "Bootstrap failed for module \"%s\"", mi->name);
1350  return -1;
1351  }
1352  if (unlikely(module_data_unprotect(mi, &mi->inst_pool) < 0)) {
1353  cf_log_perr(cs, "\"%s\"", mi->name);
1354  return -1;
1355  }
1356  }
1358 
1359  return 0;
1360 }
1361 
1362 /** Bootstrap any modules which have not been bootstrapped already
1363  *
1364  * Allows the module to initialise connection pools, and complete any registrations that depend on
1365  * attributes created during the bootstrap phase.
1366  *
1367  * @param[in] ml containing modules to bootstrap.
1368  * @return
1369  * - 0 on success.
1370  * - -1 on failure.
1371  */
1373 {
1374  void *instance;
1375  fr_rb_iter_inorder_t iter;
1376 
1377  DEBUG2("#### Bootstrapping %s modules ####", ml->name);
1378 
1379  for (instance = fr_rb_iter_init_inorder(&iter, ml->name_tree);
1380  instance;
1381  instance = fr_rb_iter_next_inorder(&iter)) {
1382  module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);
1383  if (module_bootstrap(mi) < 0) return -1;
1384  }
1385 
1386  return 0;
1387 }
1388 
1389 /** Generate a module name from the module's name and its parents
1390  *
1391  * @param[in] ctx Where to allocate the module name.
1392  * @param[out] out Where to write a pointer to the instance name.
1393  * @param[in] parent of the module.
1394  * @param[in] inst_name module's instance name.
1395  */
1396 static fr_slen_t module_instance_name(TALLOC_CTX *ctx, char **out,
1397  module_instance_t const *parent, char const *inst_name)
1398 {
1399  fr_sbuff_t *agg;
1400 
1402 
1403  /*
1404  * Parent has all of the qualifiers of its ancestors
1405  * already in the name, so we just need to concatenate.
1406  */
1407  if (parent) {
1408  FR_SBUFF_IN_STRCPY_RETURN(agg, parent->name);
1409  FR_SBUFF_IN_CHAR_RETURN(agg, '.');
1410  }
1411  FR_SBUFF_IN_STRCPY_RETURN(agg, inst_name);
1412 
1413  MEM(*out = talloc_bstrndup(ctx, fr_sbuff_start(agg), fr_sbuff_used(agg)));
1414 
1415  return fr_sbuff_used(agg);
1416 }
1417 
1418 /** Detach the shallowest parent first
1419  *
1420  * This ensures that the module's parent is detached before it is.
1421  *
1422  * Generally parents reach into their children and not the other way
1423  * around. Calling the parent's detach method first ensures that
1424  * there's no code that access the child module's instance data or
1425  * reach into its symbol space if it's being unloaded.
1426  *
1427  * @note If you don't want to detach the parent, maybe because its children
1428  * are ephemeral, consider using a seaprate thread-local module list
1429  * to hold the children instead.
1430  *
1431  * @param[in] mi to detach.
1432  */
1434 {
1436 
1438 
1439  if (mi->state & MODULE_INSTANCE_INSTANTIATED) {
1440  if (mi->exported && mi->exported->detach) {
1441  mi->exported->detach(MODULE_DETACH_CTX(mi));
1442  }
1444  }
1445 
1446  if (mi->state & MODULE_INSTANCE_BOOTSTRAPPED) {
1447  if (mi->exported && mi->exported->unstrap) {
1449  }
1451  }
1452 }
1453 
1454 /** Free module's instance data, and any xlats or paircmps
1455  *
1456  * @param[in] mi to free.
1457  * @return 0
1458  */
1460 {
1461  module_list_t *ml = mi->ml;
1462 
1463  DEBUG3("Freeing %s (%p)", mi->name, mi);
1464 
1465  /*
1466  * Allow writing to instance and bootstrap data again
1467  * so we can clean up without segving.
1468  */
1469  if (unlikely(module_data_unprotect(mi, &mi->inst_pool) < 0)) {
1470  cf_log_perr(mi->conf, "\"%s\"", mi->name);
1471  return -1;
1472  }
1473  if (unlikely(module_data_unprotect(mi, &mi->boot_pool) < 0)) {
1474  cf_log_perr(mi->conf, "\"%s\"", mi->name);
1475  return -1;
1476  }
1477 
1478  if (fr_rb_node_inline_in_tree(&mi->name_node) && !fr_cond_assert(fr_rb_delete(ml->name_tree, mi))) return 1;
1479  if (fr_rb_node_inline_in_tree(&mi->data_node) && !fr_cond_assert(fr_rb_delete(ml->data_tree, mi))) return 1;
1480  if (ml->type->data_del) ml->type->data_del(mi);
1481 
1482  /*
1483  * mi->exported may be NULL if we failed loading the module
1484  */
1485  if (mi->exported && ((mi->exported->flags & MODULE_TYPE_THREAD_UNSAFE) != 0)) {
1486 #ifndef NDEBUG
1487  int ret;
1488 
1489  /*
1490  * If the mutex is locked that means
1491  * the server exited without cleaning
1492  * up requests.
1493  *
1494  * Assert that the mutex is not held.
1495  */
1496  ret = pthread_mutex_trylock(&mi->mutex);
1497  fr_assert_msg(ret == 0, "Failed locking module mutex during exit: %s", fr_syserror(ret));
1498  pthread_mutex_unlock(&mi->mutex);
1499 #endif
1500  pthread_mutex_destroy(&mi->mutex);
1501  }
1502 
1503  /*
1504  * Remove all xlat's registered to module instance.
1505  */
1506  if (mi->data) {
1509  }
1510 
1512 
1513  /*
1514  * We need to explicitly free all children, so the module instance
1515  * destructors get executed before we unload the bytecode for the
1516  * module.
1517  *
1518  * If we don't do this, we get a SEGV deep inside the talloc code
1519  * when it tries to call a destructor that no longer exists.
1520  */
1521  talloc_free_children(mi);
1522 
1523  dl_module_free(mi->module);
1524 
1525  return 0;
1526 }
1527 
1528 /** Duplicate a module instance, placing it in a new module list
1529  *
1530  * @param[in] dst list to place the new module instance in.
1531  * @param[in] src to duplicate.
1532  * @param[in] inst_name new instance name. If null, src->name will be used.
1533  */
1535 {
1536  module_instance_t *mi = module_instance_alloc(dst, src->parent, src->module->type,
1537  src->module->name,
1538  inst_name ? inst_name : src->name, 0);
1539  if (!mi) return NULL;
1540 
1541  return mi;
1542 }
1543 
1544 /** Allocate module instance data
1545  *
1546  * @param[in] ctx talloc context to allocate data in.
1547  * @param[out] pool_out where to write pool details.
1548  * @param[out] out where to write data pointer.
1549  * @param[in] mi module instance.
1550  * @param[in] size of data to allocate.
1551  * @param[in] type talloc type to assign.
1552  */
1553 static inline CC_HINT(always_inline)
1554 void module_instance_data_alloc(TALLOC_CTX *ctx, module_data_pool_t *pool_out, void **out,
1555  module_instance_t *mi, size_t size, char const *type)
1556 {
1557  dl_module_t const *module = mi->module;
1558  void *data;
1559 
1560  /*
1561  * If there is supposed to be instance data, allocate it now.
1562  *
1563  * If the structure is zero length then allocation will still
1564  * succeed, and will create a talloc chunk header.
1565  *
1566  * This is needed so we can resolve instance data back to
1567  * module_instance_t/dl_module_t/dl_t.
1568  */
1569  pool_out->ctx = talloc_page_aligned_pool(ctx,
1570  &pool_out->start, &pool_out->len,
1571  1, size);
1572  MEM(data = talloc_zero_array(pool_out->ctx, uint8_t, size));
1573  if (!type) {
1574  talloc_set_name(data, "%s_t", module->dl->name ? module->dl->name : "config");
1575  } else {
1576  talloc_set_name_const(data, type);
1577  }
1578  *out = data;
1579 }
1580 
1581 /** Check to see if a module instance name is valid
1582  *
1583  * @note On failure the error message may be retrieved with fr_strerror().
1584  *
1585  * @param[in] inst_name to check.
1586  *
1587  * @return
1588  * - 0 on success.
1589  * - Negative value on error indicating the position of the bad char.
1590  */
1592 {
1593  /*
1594  * [] are used for dynamic module selection.
1595  * . is used as a method and submodule separator.
1596  * Quoting and other characters would just confuse the parser in too many
1597  * instances so they're disallowed too.
1598  */
1599  {
1600  size_t len = strlen(inst_name);
1601 
1602  for (size_t i = 0; i < len; i++) {
1603  if (!module_instance_allowed_chars[(uint8_t)inst_name[i]]) {
1604  fr_strerror_printf("Instance name \"%s\" contains an invalid character. "
1605  "Valid characters are [0-9a-zA-Z/_-]", inst_name);
1606  return -(i + 1);
1607  }
1608  }
1609  }
1610 
1611  return 0;
1612 }
1613 
1614 /** Set the uctx pointer for a module instance
1615  *
1616  * @param[in] mi to set the uctx for.
1617  * @param[in] uctx to set.
1618  */
1620 {
1621  mi->uctx = uctx;
1622 }
1623 
1624 /** Allocate a new module and add it to a module list for later bootstrap/instantiation
1625  *
1626  * - Load the module shared library.
1627  * - Allocate instance data for it.
1628  *
1629  * @param[in] ml To add module to.
1630  * @param[in] parent of the module being bootstrapped, if this is a submodule.
1631  * If this is not a submodule parent must be NULL.
1632  * @param[in] type What type of module we're loading. Determines the prefix
1633  * added to the library name. Should be one of:
1634  * - DL_MODULE_TYPE_MODULE - Standard backend module.
1635  * - DL_MODULE_TYPE_SUBMODULE - Usually a driver for a backend module.
1636  * - DL_MODULE_TYPE_PROTO - A module associated with a listen section.
1637  * - DL_MODULE_TYPE_PROCESS - Protocol state machine bound to a virtual server.
1638  * @param[in] mod_name The name of this module, i.e. 'redis' for 'rlm_redis'.
1639  * @param[in] inst_name Instance name for this module, i.e. "aws_redis_01".
1640  * The notable exception is if this is a submodule, in which case
1641  * inst_name is usually the mod_name.
1642  * @param[in] init_state The state the module "starts" in. Can be used to prevent
1643  * bootstrapping, instantiation, or thread instantiation of the module,
1644  * by passing one or more of the MODULE_INSTANCE_* flags.
1645  * Should usually be 0, unless special behaviour is required.
1646  * @return
1647  * - A new module instance handle, containing the module's public interface,
1648  * and private instance data.
1649  * - NULL on error.
1650  */
1652  module_instance_t const *parent,
1653  dl_module_type_t type, char const *mod_name, char const *inst_name,
1654  module_instance_state_t init_state)
1655 {
1656  char *qual_inst_name = NULL;
1657  module_instance_t *mi;
1658 
1660  (parent && (type == DL_MODULE_TYPE_SUBMODULE)) ||
1661  (type == DL_MODULE_TYPE_PROTO) ||
1663 
1664  /*
1665  * Takes the inst_name and adds qualifiers
1666  * if this is a submodule.
1667  */
1668  if (module_instance_name(NULL, &qual_inst_name, parent, inst_name) < 0) {
1669  ERROR("Module name too long");
1670  return NULL;
1671  }
1672 
1673  /*
1674  * See if the module already exists.
1675  */
1676  mi = module_instance_by_name(ml, parent, qual_inst_name);
1677  if (mi) {
1678  /*
1679  * We may not have configuration data yet
1680  * for the duplicate module.
1681  */
1682  if (mi->conf) {
1683  ERROR("Duplicate %s_%s instance \"%s\", previous instance defined at %s[%d]",
1685  mi->module->exported->name,
1686  qual_inst_name,
1687  cf_filename(mi->conf),
1688  cf_lineno(mi->conf));
1689 
1690  } else {
1691  ERROR("Duplicate %s_%s instance \"%s\"",
1693  mi->module->exported->name,
1694  qual_inst_name);
1695  }
1696  talloc_free(qual_inst_name);
1697  return NULL;
1698  }
1699 
1700  /*
1701  * Overallocate the module instance, so we can add
1702  * some module list type specific data to it.
1703  */
1704  MEM(mi = (module_instance_t *)talloc_zero_array(parent ? (void const *)parent : (void const *)ml, uint8_t, ml->type->inst_size));
1705  talloc_set_name_const(mi, "module_instance_t");
1706  mi->name = talloc_typed_strdup(mi, qual_inst_name);
1707  talloc_free(qual_inst_name); /* Avoid stealing */
1708 
1709  mi->ml = ml;
1710  mi->parent = parent;
1711  mi->state = init_state;
1712 
1713  /*
1714  * Increment the reference count on an already loaded module,
1715  * or load the .so or .dylib, and run all the global callbacks.
1716  */
1717  mi->module = dl_module_alloc(parent ? parent->module : NULL, mod_name, type);
1718  if (!mi->module) {
1719  error:
1720  talloc_free(mi);
1721  return NULL;
1722  }
1723 
1724  /*
1725  * We have no way of checking if this is correct... so we hope...
1726  */
1727  mi->exported = (module_t *)mi->module->exported;
1728  if (unlikely(mi->exported == NULL)) {
1729  ERROR("Missing public structure for \"%s\"", qual_inst_name);
1730  goto error;
1731  }
1732 
1733  /*
1734  * Allocate bootstrap data.
1735  */
1736  if (mi->exported->bootstrap) {
1737  module_instance_data_alloc(mi, &mi->boot_pool, &mi->boot,
1738  mi, mi->exported->boot_size, mi->exported->boot_type);
1739  }
1740  /*
1741  * Allocate the module instance data. We always allocate
1742  * this so the module can use it for lookup.
1743  */
1744  module_instance_data_alloc(mi, &mi->inst_pool, &mi->data,
1745  mi, mi->exported->inst_size, mi->exported->inst_type);
1746  /*
1747  * If we're threaded, check if the module is thread-safe.
1748  *
1749  * If it isn't, we init the mutex.
1750  *
1751  * Do this here so the destructor can trylock the mutex
1752  * correctly even if bootstrap/instantiation fails.
1753  */
1754  if ((mi->exported->flags & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_init(&mi->mutex, NULL);
1755  talloc_set_destructor(mi, _module_instance_free); /* Set late intentionally */
1756  mi->number = ml->last_number++;
1757 
1758  /*
1759  * Remember the module for later.
1760  */
1761  if (!fr_cond_assert(fr_rb_insert(ml->name_tree, mi))) goto error;
1762  if (!fr_cond_assert(fr_rb_insert(ml->data_tree, mi))) goto error;
1763  if (ml->type->data_add && unlikely(ml->type->data_add(mi) < 0)) goto error;
1764 
1765  return mi;
1766 }
1767 
1768 /** Free all modules loaded by the server
1769  *
1770  * @param[in] ml Module list being freed.
1771  * @return 0
1772  */
1774 {
1775  fr_rb_iter_inorder_t iter;
1776  module_instance_t *mi;
1777 
1778  /*
1779  * Re-initialize the iterator after freeing each module.
1780  * The module may have children which are also in the
1781  * tree. It can cause problems when we delete children
1782  * without the iterator knowing about it.
1783  */
1784  while ((mi = fr_rb_iter_init_inorder(&iter, ml->name_tree)) != NULL) {
1785  fr_rb_iter_delete_inorder(&iter); /* Keeps the iterator sane */
1786  talloc_free(mi);
1787  }
1788 
1789  if (ml->type->free) ml->type->free(ml);
1790 
1791  return 0;
1792 }
1793 
1794 /** Should we bootstrap this module instance?
1795  *
1796  * @param[in] mi to check.
1797  * @return
1798  * - true if the module instance should be bootstrapped.
1799  * - false if the module instance has already been bootstrapped.
1800  */
1802 {
1803  return ((mi->state | mi->ml->mask) & MODULE_INSTANCE_BOOTSTRAPPED);
1804 }
1805 
1806 /** Should we instantiate this module instance?
1807  *
1808  * @param[in] mi to check.
1809  * @return
1810  * - true if the module instance should be instantiated.
1811  * - false if the module instance has already been instantiated.
1812  */
1814 {
1815  return ((mi->state | mi->ml->mask) & MODULE_INSTANCE_INSTANTIATED);
1816 }
1817 
1818 /** Should we instantiate this module instance in a new thread?
1819  *
1820  * @param[in] mi to check.
1821  * @return
1822  * - true if the module instance should be instantiated in a new thread.
1823  * - false if the module instance has already been instantiated in a new thread.
1824  */
1826 {
1827  return ((mi->state | mi->ml->mask) & MODULE_INSTANCE_NO_THREAD_INSTANTIATE);
1828 }
1829 
1830 /** Set a new bootstrap/instantiate state for a list
1831  *
1832  * @param[in] ml To set the state for.
1833  * @param[in] mask New state.
1834  */
1836 {
1837  ml->mask = mask;
1838 }
1839 
1840 /** Allocate a new module list
1841  *
1842  * This is used to instantiate and destroy modules in distinct phases
1843  * for example, we may need to load all proto modules before rlm modules.
1844  *
1845  * If the list is freed all module instance data will be freed.
1846  * If no more instances of the module exist the module be unloaded.
1847  *
1848  * @param[in] ctx To allocate the list in.
1849  * @param[in] type of the list. Controls whether this is a global
1850  * module list, or a per-thread list containing
1851  * variants of an existing module.
1852  * @param[in] name of the list. Used for debugging.
1853  * @param[in] write_protect Whether to write protect the module data
1854  * after instantiation and bootstrapping.
1855  * @return A new module list.
1856  */
1858  char const *name, bool write_protect)
1859 {
1860  module_list_t *ml;
1861 
1862  /*
1863  * These callbacks are NOT optional, the rest are.
1864  */
1865  fr_assert(type->thread.data_add);
1866  fr_assert(type->thread.data_get);
1867  fr_assert(type->thread.data_del);
1868 
1869  MEM(ml = talloc_zero(ctx, module_list_t));
1870  ml->type = type;
1871 
1872  ml->thread_data_get = type->thread.data_get; /* Cache for access outside of the compilation unit */
1873  MEM(ml->name = talloc_typed_strdup(ml, name));
1876  talloc_set_destructor(ml, _module_list_free);
1877 
1878  if (ml->type->init && (ml->type->init(ml) < 0)) {
1879  talloc_free(ml);
1880  return NULL;
1881  }
1882  ml->write_protect = write_protect;
1883 
1884  return ml;
1885 }
1886 
1887 static int _module_dl_loader_init(void *uctx)
1888 {
1890 
1891  /*
1892  * Ensure the common library tracking
1893  * tree is in place...
1894  */
1895  global_lib_init();
1896 
1897  return 0;
1898 }
1899 
1900 static int _module_dl_loader_free(UNUSED void *uctx)
1901 {
1902  if (talloc_free(dl_modules) < 0) return -1;
1903  dl_modules = NULL;
1904  return 0;
1905 }
1906 
1907 /** Perform global initialisation for modules
1908  *
1909  */
1910 void modules_init(char const *lib_dir)
1911 {
1912  /*
1913  * Create the global module heap we use for
1914  * common indexes in the thread-specific
1915  * heaps.
1916  */
1918 }
#define fr_atexit_thread_local(_name, _free, _uctx)
Definition: atexit.h:221
#define fr_atexit_global_once(_init, _free, _uctx)
Definition: atexit.h:211
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition: build.h:165
#define RCSID(id)
Definition: build.h:446
#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
int cf_section_write(FILE *fp, CONF_SECTION *cs, int depth)
Definition: cf_file.c:3141
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
Definition: cf_parse.c:985
int cf_section_parse_pass2(void *base, CONF_SECTION *cs)
Fixup xlat expansions and attributes.
Definition: cf_parse.c:1163
void const * uctx
User data accessible by the cf_parse_t func.
Definition: cf_parse.h:586
#define cf_section_rules_push(_cs, _rule)
Definition: cf_parse.h:658
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
Common header for all CONF_* types.
Definition: cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: cf_util.c:664
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:1030
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1187
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1596
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition: cf_util.c:684
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1173
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:289
#define cf_lineno(_cf)
Definition: cf_util.h:104
#define cf_data_add(_cf, _data, _name, _free)
Definition: cf_util.h:255
#define cf_parent(_cf)
Definition: cf_util.h:101
#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_log_debug(_cf, _fmt,...)
Definition: cf_util.h:292
fr_command_register_hook_t fr_command_register_hook
Definition: command.c:42
bool fr_command_strncmp(const char *word, const char *name)
Definition: command.c:2906
int argc
current argument count
Definition: command.h:39
char const * parent
e.g. "show module"
Definition: command.h:52
#define CMD_TABLE_END
Definition: command.h:62
char const ** argv
text version of commands
Definition: command.h:42
#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_FAULT_LOG(_fmt,...)
Definition: debug.h:49
#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
char const * name
Name of the module e.g. sql.
Definition: dl.h:61
fr_table_num_sorted_t const dl_module_type_prefix[]
Name prefixes matching the types of loadable module.
Definition: dl_module.c:57
dl_module_loader_t * dl_module_loader_init(char const *lib_dir)
Initialise structures needed by the dynamic linker.
Definition: dl_module.c:530
dl_module_t * dl_module_alloc(dl_module_t const *parent, char const *name, dl_module_type_t type)
Load a module library using dlopen() or return a previously loaded module from the cache.
Definition: dl_module.c:315
int dl_module_free(dl_module_t *dl_module)
Free a dl_module (when there are no more references to it)
Definition: dl_module.c:281
Wrapper struct around dl_loader_t.
Definition: dl_module.c:47
dl_t *_CONST dl
Dynamic loader handle.
Definition: dl_module.h:122
dl_module_common_t * exported
Symbol exported by the module, containing its public functions, name and behaviour control flags.
Definition: dl_module.h:128
dl_module_type_t _CONST type
of this module.
Definition: dl_module.h:126
dl_module_type_t
Definition: dl_module.h:65
@ DL_MODULE_TYPE_PROTO
Protocol module.
Definition: dl_module.h:67
@ DL_MODULE_TYPE_SUBMODULE
Driver (or method in the case of EAP)
Definition: dl_module.h:69
@ DL_MODULE_TYPE_MODULE
Standard loadable module.
Definition: dl_module.h:66
@ DL_MODULE_TYPE_PROCESS
protocol processor.
Definition: dl_module.h:68
char const *_CONST name
Name of the module. The name passed to dl_module_alloc.
Definition: dl_module.h:118
if(rcode > 0)
Definition: fd_read.h:9
int global_lib_init(void)
Initialise the global list of external libraries.
Definition: global_lib.c:204
int fr_heap_insert(fr_heap_t **hp, void *data)
Insert a new element into the heap.
Definition: heap.c:146
int fr_heap_extract(fr_heap_t **hp, void *data)
Remove a node from the heap.
Definition: heap.c:239
unsigned int fr_heap_index_t
Definition: heap.h:80
#define fr_heap_alloc(_ctx, _cmp, _type, _field, _init)
Creates a heap that can be used with non-talloced elements.
Definition: heap.h:100
static bool fr_heap_entry_inserted(fr_heap_index_t heap_idx)
Check if an entry is inserted into a heap.
Definition: heap.h:124
static unsigned int fr_heap_num_elements(fr_heap_t *h)
Return the number of elements in the heap.
Definition: heap.h:179
#define fr_heap_foreach(_heap, _type, _data)
Iterate over the contents of a heap.
Definition: heap.h:205
The main heap structure.
Definition: heap.h:66
#define PERROR(_fmt,...)
Definition: log.h:228
#define DEBUG3(_fmt,...)
Definition: log.h:266
#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:2723
unsigned char uint8_t
Definition: merged_model.c:30
ssize_t fr_slen_t
Definition: merged_model.c:35
#define UINT8_MAX
Definition: merged_model.c:32
#define MODULE_DETACH_CTX(_mi)
Wrapper to create a module_detach_ctx_t as a compound literal.
Definition: module_ctx.h:164
#define MODULE_THREAD_INST_CTX(_mi, _thread, _el)
Wrapper to create a module_thread_inst_ctx_t as a compound literal.
Definition: module_ctx.h:176
#define MODULE_INST_CTX(_mi)
Wrapper to create a module_inst_ctx_t as a compound literal.
Definition: module_ctx.h:158
Temporary structure to hold arguments for thread_instantiation calls.
Definition: module_ctx.h:63
static bool done
Definition: radclient.c:80
#define DEBUG2(fmt,...)
Definition: radclient.h:43
static rs_t * conf
Definition: radsniff.c:53
void fr_rb_iter_delete_inorder(fr_rb_iter_inorder_t *iter)
Remove the current node from the tree.
Definition: rb.c:892
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
Definition: rb.c:844
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
Definition: rb.c:624
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
Definition: rb.c:736
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:818
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition: rb.c:576
#define fr_rb_inline_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black tree.
Definition: rb.h:271
static bool fr_rb_node_inline_in_tree(fr_rb_node_t const *node)
Check to see if an item is in a tree by examining its inline fr_rb_node_t.
Definition: rb.h:314
Iterator structure for in-order traversal of an rbtree.
Definition: rb.h:321
static uint32_t mask
Definition: rbmonkey.c:39
fr_table_num_sorted_t const rcode_table[]
Definition: rcode.c:35
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
Definition: rcode.h:51
static char const * name
#define fr_sbuff_start(_sbuff_or_marker)
#define FR_SBUFF_IN_CHAR_RETURN(_sbuff,...)
#define fr_sbuff_used(_sbuff_or_marker)
#define FR_SBUFF_IN_STRCPY_RETURN(...)
#define FR_SBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
module_thread_instance_t *(* module_list_thread_data_get_t)(module_instance_t const *mi)
Callback to retrieve thread-local data for a module.
Definition: module.h:372
module_instance_t * mi
As opposed to the thread local inst.
Definition: module.h:356
char const * name
Instance name e.g. user_database.
Definition: module.h:335
@ MODULE_TYPE_DYNAMIC_UNSAFE
Instances of this module cannot be created at runtime.
Definition: module.h:52
@ MODULE_TYPE_THREAD_UNSAFE
Module is not threadsafe.
Definition: module.h:48
module_flags_t flags
Flags that control how a module starts up and how a module is called.
Definition: module.h:227
static module_thread_instance_t * module_thread(module_instance_t const *mi)
Retrieve module/thread specific instance for a module.
Definition: module.h:481
fr_rb_node_t name_node
Entry in the name tree.
Definition: module.h:310
CONF_SECTION * conf
Module's instance configuration.
Definition: module.h:329
size_t inst_size
Size of the module's instance data.
Definition: module.h:203
module_detach_t detach
Clean up module resources from the instantiation pahses.
Definition: module.h:223
bool force
Force the module to return a specific code.
Definition: module.h:297
void * data
Module's instance data.
Definition: module.h:271
module_instance_state_t state
What's been done with this module so far.
Definition: module.h:328
module_instance_t const * parent
Parent module's instance (if any).
Definition: module.h:337
module_thread_instantiate_t thread_instantiate
Callback to populate a new module thread instance data.
Definition: module.h:230
module_instantiate_t instantiate
Callback to allow the module to register any per-instance resources like sockets and file handles.
Definition: module.h:218
void * boot
Data allocated during the boostrap phase.
Definition: module.h:274
module_instance_state_t mask
Prevent phases from being executed.
Definition: module.h:387
dl_module_t * module
Dynamic loader handle.
Definition: module.h:286
#define MODULE_INSTANCE_LEN_MAX
The maximum size of a module instance.
Definition: module.h:147
void * data
Thread specific instance data.
Definition: module.h:352
module_data_pool_t inst_pool
Data to allow mprotect state toggling for instance data.
Definition: module.h:319
bool write_protect
If true, pages containing module boot or instance data will be write protected after bootstrapping an...
Definition: module.h:394
rlm_rcode_t code
Code module will return when 'force' has has been set to true.
Definition: module.h:300
char const * boot_type
talloc type to assign to bootstrap data.
Definition: module.h:201
char const * inst_type
talloc type to assign to instance data.
Definition: module.h:204
module_data_pool_t boot_pool
Data to allow mprotect state toggling for bootstrap data.
Definition: module.h:321
module_detach_t unstrap
Clean up module resources from both the bootstrap phase.
Definition: module.h:225
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
@ MODULE_INSTANCE_NO_THREAD_INSTANTIATE
Not set internally, but can be used to prevent thread instantiation for certain modules.
Definition: module.h:248
@ MODULE_INSTANCE_BOOTSTRAPPED
Module instance has been bootstrapped, but not yet instantiated.
Definition: module.h:244
fr_rb_tree_t * data_tree
Modules indexed by data.
Definition: module.h:391
uint32_t number
Unique module number.
Definition: module.h:312
module_list_thread_data_get_t thread_data_get
Callback to get thread-specific data.
Definition: module.h:413
char const * thread_inst_type
talloc type to assign to thread instance data.
Definition: module.h:236
module_instantiate_t bootstrap
Callback to allow the module to register any global resources like xlat functions and attributes.
Definition: module.h:206
fr_rb_node_t data_node
Entry in the data tree.
Definition: module.h:311
module_thread_detach_t thread_detach
Callback to free thread-specific resources associated < with a module.
Definition: module.h:232
void * uctx
Extra data passed to module_instance_alloc.
Definition: module.h:339
size_t boot_size
Size of the module's bootstrap data.
Definition: module.h:200
module_list_t * ml
Module list this instance belongs to.
Definition: module.h:309
size_t thread_inst_size
Size of the module's thread-specific instance data.
Definition: module.h:235
conf_parser_t const * config
How to convert a CONF_SECTION to a module instance.
Definition: module.h:198
char const * name
Friendly list identifier.
Definition: module.h:386
fr_event_list_t * el
Event list associated with this thread.
Definition: module.h:354
module_list_type_t const * type
Type of module list.
Definition: module.h:412
uint32_t last_number
Last identifier assigned to a module instance.
Definition: module.h:389
fr_rb_tree_t * name_tree
Modules indexed by name.
Definition: module.h:390
module_t * exported
Public module structure.
Definition: module.h:276
pthread_mutex_t mutex
Used prevent multiple threads entering a thread unsafe module simultaneously.
Definition: module.h:283
Module instance data.
Definition: module.h:265
A list of modules.
Definition: module.h:385
Struct exported by a rlm_* module.
Definition: module.h:195
Per thread per instance data.
Definition: module.h:347
module_instance_t * module_instance_copy(module_list_t *dst, module_instance_t const *src, char const *inst_name)
Duplicate a module instance, placing it in a new module list.
Definition: module.c:1534
static int mltl_thread_data_add(module_thread_instance_t *ti)
Definition: module.c:575
int module_instance_data_protect(module_instance_t const *mi)
Mark module data as read only.
Definition: module.c:699
static void module_thread_detach(module_thread_instance_t *ti)
Definition: module.c:989
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
void modules_init(char const *lib_dir)
Perform global initialisation for modules.
Definition: module.c:1910
bool module_instance_skip_thread_instantiate(module_instance_t *mi)
Should we instantiate this module instance in a new thread?
Definition: module.c:1825
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
static int module_data_unprotect(module_instance_t const *mi, module_data_pool_t const *pool)
Unprotect module data.
Definition: module.c:677
static int mlg_init(UNUSED module_list_t *ml)
Global initialisation for index heap and module array.
Definition: module.c:400
static int _module_dl_loader_free(UNUSED void *uctx)
Definition: module.c:1900
module_list_free_t free
Free any global structures required for thread-local lookups.
Definition: module.c:331
static int _module_list_free(module_list_t *ml)
Free all modules loaded by the server.
Definition: module.c:1773
module_thread_instance_t * ti
Thread-specific data.
Definition: module.c:555
char const * module_instance_root_prefix_str(module_instance_t const *mi)
Return the prefix string for the deepest module.
Definition: module.c:725
static int _module_instance_free(module_instance_t *mi)
Free module's instance data, and any xlats or paircmps.
Definition: module.c:1459
module_instance_t * module_instance_root(module_instance_t const *child)
Find the module's shallowest parent.
Definition: module.c:935
static int module_data_protect(module_instance_t *mi, module_data_pool_t *pool)
Protect module data.
Definition: module.c:654
static void module_detach_parent(module_instance_t *mi)
Detach the shallowest parent first.
Definition: module.c:1433
static int _module_thread_inst_list_free(void *tilp)
Free the thread local heap on exit.
Definition: module.c:444
void(* module_list_free_t)(module_list_t *ml)
Callback to free any global structures associated with the module list.
Definition: module.c:253
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
static module_thread_instance_t * mlg_thread_data_get(module_instance_t const *mi)
Retrieve the thread-specific data for a module from the thread-local array of instance data.
Definition: module.c:492
static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
Definition: module.c:177
static int8_t module_instance_data_cmp(void const *one, void const *two)
Compare module's by their private instance data.
Definition: module.c:824
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
static int8_t module_instance_name_cmp(void const *one, void const *two)
Compare module instances by parent and name.
Definition: module.c:790
void modules_thread_detach(module_list_t *ml)
Remove thread-specific data for a given module list.
Definition: module.c:1009
static int mlg_data_add(module_instance_t *mi)
Add the unique index value so we can do thread local lookups.
Definition: module.c:415
module_list_data_add_t data_add
Record that module data has been added.
Definition: module.c:335
module_list_init_t init
Initialise any global structures required for thread-local lookups.
Definition: module.c:330
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
bool module_instance_skip_instantiate(module_instance_t *mi)
Should we instantiate this module instance?
Definition: module.c:1813
static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info)
Definition: module.c:166
static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx, fr_cmd_info_t *info, int max_expansions, char const **expansions)
Definition: module.c:140
void(* module_list_data_del_t)(module_instance_t *mi)
Callback to del data for a module.
Definition: module.c:271
size_t inst_size
Size of talloc chunk to allocate for the module_instance_t.
Definition: module.c:333
int(* module_list_thread_data_add_t)(module_thread_instance_t *ti)
Callback to add thread-local data for a module.
Definition: module.c:302
static void module_instance_data_alloc(TALLOC_CTX *ctx, module_data_pool_t *pool_out, void **out, module_instance_t *mi, size_t size, char const *type)
Allocate module instance data.
Definition: module.c:1554
int modules_instantiate(module_list_t const *ml)
Completes instantiation of modules.
Definition: module.c:1281
module_instance_t * module_instance_by_data(module_list_t const *ml, void const *data)
Find an existing module instance by its private instance data.
Definition: module.c:957
struct module_list_type_s::@64 thread
Callbacks to manage thread-local data.
int(* module_list_init_t)(module_list_t *ml)
Callback to initialise any global structures required for the module list.
Definition: module.c:247
static void mlg_thread_data_del(module_thread_instance_t *ti)
Definition: module.c:528
static int mlg_thread_data_add(module_thread_instance_t *ti)
Definition: module.c:521
static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
Definition: module.c:191
static int _module_dl_loader_init(void *uctx)
Definition: module.c:1887
static module_thread_instance_t * mltl_thread_data_get(module_instance_t const *mi)
Definition: module.c:569
void(* module_list_thread_free_t)(module_list_t *ml)
Callback to free thread-local structures, called once per thread as the thread is being destroyed.
Definition: module.c:290
void module_instance_uctx_set(module_instance_t *mi, void *uctx)
Set the uctx pointer for a module instance.
Definition: module.c:1619
static fr_slen_t module_instance_name(TALLOC_CTX *ctx, char **out, module_instance_t const *parent, char const *inst_name)
Generate a module name from the module's name and its parents.
Definition: module.c:1396
module_thread_instance_t * module_thread_by_data(module_list_t const *ml, void const *data)
Retrieve module/thread specific instance data for a module.
Definition: module.c:980
static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
Definition: module.c:129
void(* module_list_thread_data_del_t)(module_thread_instance_t *ti)
Callback to remove thread-local data for a module.
Definition: module.c:311
fr_slen_t module_instance_name_valid(char const *inst_name)
Check to see if a module instance name is valid.
Definition: module.c:1591
return count
Definition: module.c:163
int module_instance_data_unprotect(module_instance_t const *mi)
Mark module data as read/write.
Definition: module.c:711
static int _module_thread_inst_free(module_thread_instance_t *ti)
Callback to free thread local data.
Definition: module.c:1043
static int _mlg_global_free(UNUSED void *uctx)
Free the global module index.
Definition: module.c:383
int module_thread_instantiate(TALLOC_CTX *ctx, module_instance_t *mi, fr_event_list_t *el)
Allocate thread-local instance data for a module.
Definition: module.c:1083
module_list_data_del_t data_del
Record that module data has been removed.
Definition: module.c:336
module_list_type_t const module_list_type_global
Callbacks for a global module list.
Definition: module.c:536
static dl_module_loader_t * dl_modules
dl module tracking
Definition: module.c:238
fr_cmd_table_t module_cmd_list_table[]
Definition: module.c:99
fr_heap_index_t inst_idx
Entry in the bootstrap/instantiation heap.
Definition: module.c:355
int(* module_list_thread_init_t)(TALLOC_CTX **ctx, module_list_t const *ml)
Callback to initialise a list for thread-local data, called once per thread.
Definition: module.c:284
int modules_bootstrap(module_list_t const *ml)
Bootstrap any modules which have not been bootstrapped already.
Definition: module.c:1372
fr_cmd_table_t module_cmd_table[]
Definition: module.c:66
module_instance_t mi
Common module instance fields. Must come first.
Definition: module.c:353
static _Thread_local module_thread_instance_t ** mlg_thread_inst_list
An array of thread-local module lists.
Definition: module.c:58
int module_instantiate(module_instance_t *instance)
Manually complete module setup by calling its instantiate function.
Definition: module.c:1195
static int mlg_thread_init(UNUSED TALLOC_CTX **ctx, UNUSED module_list_t const *ml)
Allocate a thread-local array to hold thread data for each module thats been instantiated.
Definition: module.c:468
bool module_instance_skip_bootstrap(module_instance_t *mi)
Should we bootstrap this module instance?
Definition: module.c:1801
module_instance_t mi
Common module instance fields. Must come first.
Definition: module.c:554
static int _mlg_global_init(UNUSED void *uctx)
Initialise the global module index.
Definition: module.c:391
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_list_data_add_t)(module_instance_t *mi)
Callback to add data for a module.
Definition: module.c:264
size_t list_size
Size of talloc_chunk to allocate for the module_list_t.
Definition: module.c:328
static void mlg_data_del(module_instance_t *mi)
Definition: module.c:429
static void mltl_thread_data_del(module_thread_instance_t *ti)
Definition: module.c:582
bool const module_instance_allowed_chars[UINT8_MAX+1]
Chars that are allowed in a module instance name.
Definition: module.c:216
static void mltl_mlg_data_del(module_instance_t *mi)
Definition: module.c:559
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
static fr_heap_t * mlg_index
Heap of all lists/modules used to get a common index with mlg_thread->inst_list.
Definition: module.c:50
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
static int8_t _mlg_module_instance_cmp(void const *one, void const *two)
Sort module instance data first by list then by number.
Definition: module.c:366
int module_bootstrap(module_instance_t *mi)
Manually complete module bootstrap by calling its instantiate function.
Definition: module.c:1308
void module_instance_debug(module_instance_t const *mi)
Print debugging information for a module.
Definition: module.c:605
A slightly larger module_instance structure to hold the module instance and thread instance.
Definition: module.c:553
Structure to hold callbacks for a module list type.
Definition: module.c:327
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
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: syserror.c:243
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition: table.h:134
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:253
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition: talloc.c:445
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
Definition: talloc.c:564
TALLOC_CTX * talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, size_t *end_len, unsigned int headers, size_t size)
Return a page aligned talloc memory pool.
Definition: talloc.c:312
Functions which we wish were included in the standard talloc distribution.
#define talloc_get_type_abort_const
Definition: talloc.h:271
static fr_event_list_t * el
static fr_slen_t parent
Definition: pair.h:844
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition: strerror.c:577
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
static fr_slen_t data
Definition: value.h:1259
static size_t char ** out
Definition: value.h:984
void xlat_func_unregister_module(module_instance_t const *inst)
Definition: xlat_func.c:532
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition: xlat_func.c:518