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: b0c063daa35a667673df5961e8d6842829f999d2 $
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 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: b0c063daa35a667673df5961e8d6842829f999d2 $")
30 
31 #include <freeradius-devel/server/cf_file.h>
32 #include <freeradius-devel/server/global_lib.h>
33 #include <freeradius-devel/server/modpriv.h>
34 #include <freeradius-devel/server/module_rlm.h>
35 #include <freeradius-devel/server/pair.h>
36 #include <freeradius-devel/server/virtual_servers.h>
37 #include <freeradius-devel/util/atexit.h>
38 #include <freeradius-devel/unlang/xlat_func.h>
39 #include <freeradius-devel/unlang/xlat_redundant.h>
40 
41 /** Lookup virtual module by name
42  */
44 
45 typedef struct {
46  fr_rb_node_t name_node; //!< Entry in the name tree.
47  char const *name; //!< module name
48  CONF_SECTION *cs; //!< CONF_SECTION where it is defined
49  bool all_same;
51 
52 /** Compare virtual modules by name
53  */
54 static int8_t module_rlm_virtual_name_cmp(void const *one, void const *two)
55 {
56  module_rlm_virtual_t const *a = one;
57  module_rlm_virtual_t const *b = two;
58  int ret;
59 
60  ret = strcmp(a->name, b->name);
61  return CMP(ret, 0);
62 }
63 
64 char const *section_type_value[MOD_COUNT] = {
65  "authenticate",
66  "authorize",
67  "preacct",
68  "accounting",
69  "post-auth"
70 };
71 
72 /** Global module list for all backend modules
73  *
74  */
76 
77 /** Initialise a module specific exfile handle
78  *
79  * @see exfile_init
80  *
81  * @param[in] ctx to bind the lifetime of the exfile handle to.
82  * @param[in] module section.
83  * @param[in] max_entries Max file descriptors to cache, and manage locks for.
84  * @param[in] max_idle Maximum time a file descriptor can be idle before it's closed.
85  * @param[in] locking Whether or not to lock the files.
86  * @param[in] trigger_prefix if NULL will be set automatically from the module CONF_SECTION.
87  * @param[in] trigger_args to make available in any triggers executed by the connection pool.
88  * @return
89  * - New connection pool.
90  * - NULL on error.
91  */
93  CONF_SECTION *module,
94  uint32_t max_entries,
95  fr_time_delta_t max_idle,
96  bool locking,
97  char const *trigger_prefix,
98  fr_pair_list_t *trigger_args)
99 {
100  char trigger_prefix_buff[128];
101  exfile_t *handle;
102 
103  if (!trigger_prefix) {
104  snprintf(trigger_prefix_buff, sizeof(trigger_prefix_buff), "modules.%s.file", cf_section_name1(module));
105  trigger_prefix = trigger_prefix_buff;
106  }
107 
108  handle = exfile_init(ctx, max_entries, max_idle, locking);
109  if (!handle) return NULL;
110 
111  exfile_enable_triggers(handle, cf_section_find(module, "file", NULL), trigger_prefix, trigger_args);
112 
113  return handle;
114 }
115 
116 /** Resolve polymorphic item's from a module's #CONF_SECTION to a subsection in another module
117  *
118  * This allows certain module sections to reference module sections in other instances
119  * of the same module and share #CONF_DATA associated with them.
120  *
121  * @verbatim
122  example {
123  data {
124  ...
125  }
126  }
127 
128  example inst {
129  data = example
130  }
131  * @endverbatim
132  *
133  * @param[out] out where to write the pointer to a module's config section. May be NULL on success,
134  * indicating the config item was not found within the module #CONF_SECTION
135  * or the chain of module references was followed and the module at the end of the chain
136  * did not a subsection.
137  * @param[in] module #CONF_SECTION.
138  * @param[in] name of the polymorphic sub-section.
139  * @return
140  * - 0 on success with referenced section.
141  * - 1 on success with local section.
142  * - -1 on failure.
143  */
145 {
146  CONF_PAIR *cp;
147  CONF_SECTION *cs;
148  CONF_DATA const *cd;
149 
150 
151  module_instance_t *mi;
152  char const *inst_name;
153 
154 #define FIND_SIBLING_CF_KEY "find_sibling"
155 
156  *out = NULL;
157 
158  /*
159  * Is a real section (not referencing sibling module).
160  */
161  cs = cf_section_find(module, name, NULL);
162  if (cs) {
163  *out = cs;
164 
165  return 0;
166  }
167 
168  /*
169  * Item omitted completely from module config.
170  */
171  cp = cf_pair_find(module, name);
172  if (!cp) return 0;
173 
175  cf_log_err(cp, "Module reference loop found");
176 
177  return -1;
178  }
179  cd = cf_data_add(module, module, FIND_SIBLING_CF_KEY, false);
180 
181  /*
182  * Item found, resolve it to a module instance.
183  * This triggers module loading, so we don't have
184  * instantiation order issues.
185  */
186  inst_name = cf_pair_value(cp);
187  mi = module_by_name(rlm_modules, NULL, inst_name);
188  if (!mi) {
189  cf_log_err(cp, "Unknown module instance \"%s\"", inst_name);
190 
191  return -1;
192  }
193 
194  if (mi->state != MODULE_INSTANCE_INSTANTIATED) {
195  CONF_SECTION *parent = module;
196 
197  /*
198  * Find the root of the config...
199  */
200  do {
201  CONF_SECTION *tmp;
202 
204  if (!tmp) break;
205 
206  parent = tmp;
207  } while (true);
208 
209  if (unlikely(module_instantiate(module_by_name(rlm_modules, NULL, inst_name)) < 0)) return -1;
210  }
211 
212  /*
213  * Remove the config data we added for loop
214  * detection.
215  */
216  cf_data_remove_by_data(module, cd);
217 
218  /*
219  * Check the module instances are of the same type.
220  */
221  if (strcmp(cf_section_name1(mi->dl_inst->conf), cf_section_name1(module)) != 0) {
222  cf_log_err(cp, "Referenced module is a rlm_%s instance, must be a rlm_%s instance",
224 
225  return -1;
226  }
227 
228  *out = cf_section_find(mi->dl_inst->conf, name, NULL);
229 
230  return 1;
231 }
232 
233 /** Initialise a module specific connection pool
234  *
235  * @see fr_pool_init
236  *
237  * @param[in] module section.
238  * @param[in] opaque data pointer to pass to callbacks.
239  * @param[in] c Callback to create new connections.
240  * @param[in] a Callback to check the status of connections.
241  * @param[in] log_prefix override, if NULL will be set automatically from the module CONF_SECTION.
242  * @param[in] trigger_prefix if NULL will be set automatically from the module CONF_SECTION.
243  * @param[in] trigger_args to make available in any triggers executed by the connection pool.
244  * @return
245  * - New connection pool.
246  * - NULL on error.
247  */
249  void *opaque,
252  char const *log_prefix,
253  char const *trigger_prefix,
254  fr_pair_list_t *trigger_args)
255 {
256  CONF_SECTION *cs, *mycs;
257  char log_prefix_buff[128];
258  char trigger_prefix_buff[128];
259 
260  fr_pool_t *pool;
261  char const *cs_name1, *cs_name2;
262 
263  int ret;
264 
265 #define parent_name(_x) cf_section_name(cf_item_to_section(cf_parent(_x)))
266 
267  cs_name1 = cf_section_name1(module);
268  cs_name2 = cf_section_name2(module);
269  if (!cs_name2) cs_name2 = cs_name1;
270 
271  if (!trigger_prefix) {
272  snprintf(trigger_prefix_buff, sizeof(trigger_prefix_buff), "modules.%s.pool", cs_name1);
273  trigger_prefix = trigger_prefix_buff;
274  }
275 
276  if (!log_prefix) {
277  snprintf(log_prefix_buff, sizeof(log_prefix_buff), "rlm_%s (%s)", cs_name1, cs_name2);
278  log_prefix = log_prefix_buff;
279  }
280 
281  /*
282  * Get sibling's pool config section
283  */
284  ret = module_rlm_sibling_section_find(&cs, module, "pool");
285  switch (ret) {
286  case -1:
287  return NULL;
288 
289  case 1:
290  DEBUG4("%s: Using pool section from \"%s\"", log_prefix, parent_name(cs));
291  break;
292 
293  case 0:
294  DEBUG4("%s: Using local pool section", log_prefix);
295  break;
296  }
297 
298  /*
299  * Get our pool config section
300  */
301  mycs = cf_section_find(module, "pool", NULL);
302  if (!mycs) {
303  DEBUG4("%s: Adding pool section to config item \"%s\" to store pool references", log_prefix,
304  cf_section_name(module));
305 
306  mycs = cf_section_alloc(module, module, "pool", NULL);
307  }
308 
309  /*
310  * Sibling didn't have a pool config section
311  * Use our own local pool.
312  */
313  if (!cs) {
314  DEBUG4("%s: \"%s.pool\" section not found, using \"%s.pool\"", log_prefix,
315  parent_name(cs), parent_name(mycs));
316  cs = mycs;
317  }
318 
319  /*
320  * If fr_pool_init has already been called
321  * for this config section, reuse the previous instance.
322  *
323  * This allows modules to pass in the config sections
324  * they would like to use the connection pool from.
325  */
326  pool = cf_data_value(cf_data_find(cs, fr_pool_t, NULL));
327  if (!pool) {
328  DEBUG4("%s: No pool reference found for config item \"%s.pool\"", log_prefix, parent_name(cs));
329  pool = fr_pool_init(cs, cs, opaque, c, a, log_prefix);
330  if (!pool) return NULL;
331 
332  fr_pool_enable_triggers(pool, trigger_prefix, trigger_args);
333 
334  if (fr_pool_start(pool) < 0) {
335  ERROR("%s: Starting initial connections failed", log_prefix);
336  return NULL;
337  }
338 
339  DEBUG4("%s: Adding pool reference %p to config item \"%s.pool\"", log_prefix, pool, parent_name(cs));
340  cf_data_add(cs, pool, NULL, false);
341  return pool;
342  }
343  fr_pool_ref(pool);
344 
345  DEBUG4("%s: Found pool reference %p in config item \"%s.pool\"", log_prefix, pool, parent_name(cs));
346 
347  /*
348  * We're reusing pool data add it to our local config
349  * section. This allows other modules to transitively
350  * reuse a pool through this module.
351  */
352  if (mycs != cs) {
353  DEBUG4("%s: Copying pool reference %p from config item \"%s.pool\" to config item \"%s.pool\"",
354  log_prefix, pool, parent_name(cs), parent_name(mycs));
355  cf_data_add(mycs, pool, NULL, false);
356  }
357 
358  return pool;
359 }
360 
361 /*
362  * Convert a string to an integer
363  */
365  char const *name, module_method_t def)
366 {
367  module_state_func_table_t const *this;
368 
369  if (!name) return def;
370 
371  for (this = table; this->name != NULL; this++) {
372  if (strcasecmp(this->name, name) == 0) return this->func;
373  }
374 
375  return def;
376 }
377 
378 /*
379  * Convert an integer to a string.
380  */
382  module_method_t method, char const *def)
383 {
384  module_state_func_table_t const *this;
385 
386  for (this = table; this->name != NULL; this++) if (this->func == method) return this->name;
387 
388  return def;
389 }
390 
391 /** Set the next section type if it's not already set
392  *
393  * @param[in] request The current request.
394  * @param[in] type_da to use. Usually attr_auth_type.
395  * @param[in] enumv Enumeration value of the specified type_da.
396  */
397 bool module_rlm_section_type_set(request_t *request, fr_dict_attr_t const *type_da, fr_dict_enum_value_t const *enumv)
398 {
399  fr_pair_t *vp;
400 
401  switch (pair_update_control(&vp, type_da)) {
402  case 0:
403  fr_value_box_copy(vp, &vp->data, enumv->value);
404  vp->data.enumv = vp->da; /* So we get the correct string alias */
405  RDEBUG2("Setting &control.%pP", vp);
406  return true;
407 
408  case 1:
409  RDEBUG2("&control.%s already set. Not setting to %s", vp->da->name, enumv->name);
410  return false;
411 
412  default:
413  return false;
414  }
415 }
416 
417 /** Find an existing module instance and verify it implements the specified method
418  *
419  * Extracts the method from the module name where the format is @verbatim <module>.<method> @endverbatim
420  * and ensures the module implements the specified method.
421  *
422  * @param[out] method the method function we will call
423  * @param[out] method_env the module_call_env to evaluate when compiling the method.
424  * @param[out] name1 name1 of the method being called
425  * @param[out] name2 name2 of the method being called
426  * @param[in] name The name of the module we're attempting to find, possibly concatenated with the method
427  * @return
428  * - The module instance on success.
429  * - NULL on not found
430  *
431  * If the module exists but the method doesn't exist, then `method` is set to NULL.
432  */
434  char const **name1, char const **name2,
435  char const *name)
436 {
437  char *p, *q, *inst_name;
438  size_t len;
439  int j;
440  module_instance_t *mi;
441  module_method_name_t const *methods;
442  char const *method_name1, *method_name2;
443  module_rlm_t const *mrlm;
444 
445  if (method) *method = NULL;
446 
447  method_name1 = method_name2 = NULL;
448  if (name1) {
449  method_name1 = *name1;
450  *name1 = NULL;
451  }
452  if (name2) {
453  method_name2 = *name2;
454  *name2 = NULL;
455  }
456 
457  /*
458  * Module names are allowed to contain '.'
459  * so we search for the bare module name first.
460  */
461  mi = module_by_name(rlm_modules, NULL, name);
462  if (mi) {
463  virtual_server_method_t const *allowed_list;
464 
465  if (!method) return mi;
466 
467  mrlm = module_rlm_from_module(mi->module);
468 
469  /*
470  * We're not searching for a named method, OR the
471  * module has no named methods. Try to return a
472  * method based on the component.
473  */
474  if (!method_name1 || !mrlm->method_names) goto return_component;
475 
476  /*
477  * Walk through the module, finding a matching
478  * method.
479  */
480  for (j = 0; mrlm->method_names[j].name1 != NULL; j++) {
481  methods = &mrlm->method_names[j];
482 
483  /*
484  * Wildcard match name1, we're
485  * done.
486  */
487  if (methods->name1 == CF_IDENT_ANY) {
488  found:
489  *method = methods->method;
490  if (method_env) *method_env = methods->method_env;
491  if (name1) *name1 = method_name1;
492  if (name2) *name2 = method_name2;
493  return mi;
494  }
495 
496  /*
497  * If name1 doesn't match, skip it.
498  */
499  if (strcasecmp(methods->name1, method_name1) != 0) continue;
500 
501  /*
502  * The module can declare a
503  * wildcard for name2, in which
504  * case it's a match.
505  */
506  if (methods->name2 == CF_IDENT_ANY) goto found;
507 
508  /*
509  * No name2 is also a match to no name2.
510  */
511  if (!methods->name2 && !method_name2) goto found;
512 
513  /*
514  * Don't do strcmp on NULLs
515  */
516  if (!methods->name2 || !method_name2) continue;
517 
518  if (strcasecmp(methods->name2, method_name2) == 0) goto found;
519  }
520 
521  /*
522  * No match for "recv Access-Request", or
523  * whatever else the section is. Let's see if
524  * the section has a list of allowed methods.
525  */
526  allowed_list = virtual_server_section_methods(method_name1, method_name2);
527  if (!allowed_list) goto return_component;
528 
529  /*
530  * Walk over allowed methods for this section,
531  * (implicitly ordered by priority), and see if
532  * the allowed method matches any of the module
533  * methods. This process lets us reference a
534  * module as "foo" in the configuration. If the
535  * module exports a "recv bar" method, and the
536  * virtual server has a "recv bar" processing
537  * section, then they should match.
538  *
539  * Unfortunately, this process is O(N*M).
540  * Luckily, we only do it if all else fails, so
541  * it's mostly OK.
542  *
543  * Note that the "allowed" list CANNOT include
544  * CF_IDENT_ANY. Only the module can do that.
545  * If the "allowed" list exported CF_IDENT_ANY,
546  * then any module method would match, which is
547  * bad.
548  */
549  for (j = 0; allowed_list[j].name != NULL; j++) {
550  int k;
551  virtual_server_method_t const *allowed = &allowed_list[j];
552 
553  for (k = 0; mrlm->method_names[k].name1 != NULL; k++) {
554  methods = &mrlm->method_names[k];
555 
556  fr_assert(methods->name1 != CF_IDENT_ANY); /* should have been caught above */
557 
558  if (strcasecmp(methods->name1, allowed->name) != 0) continue;
559 
560  /*
561  * The module matches "recv *",
562  * call this method.
563  */
564  if (methods->name2 == CF_IDENT_ANY) {
565  found_allowed:
566  *method = methods->method;
567  return mi;
568  }
569 
570  /*
571  * No name2 is also a match to no name2.
572  */
573  if (!methods->name2 && !allowed->name2) goto found_allowed;
574 
575  /*
576  * Don't do strcasecmp on NULLs
577  */
578  if (!methods->name2 || !allowed->name2) continue;
579 
580  if (strcasecmp(methods->name2, allowed->name2) == 0) goto found_allowed;
581  }
582  }
583 
584  return_component:
585  /*
586  * Didn't find a matching method. Just return
587  * the module.
588  */
589  return mi;
590  }
591 
592  /*
593  * Find out if the instance name contains
594  * a method, if it doesn't, then the module
595  * doesn't exist.
596  */
597  p = strchr(name, '.');
598  if (!p) {
599  fr_strerror_printf("No such module '%s'", name);
600  return NULL;
601  }
602 
603  /*
604  * The module name may have a '.' in it, AND it may have
605  * a method <sigh> So we try to find out which is which.
606  */
607  inst_name = talloc_strdup(NULL, name);
608  p = inst_name + (p - name);
609 
610  /*
611  * Loop over the '.' portions, gradually looking up a
612  * longer string, in order to find the full module name.
613  */
614  do {
615  *p = '\0';
616 
617  mi = module_by_name(rlm_modules, NULL, inst_name);
618  if (mi) break;
619 
620  /*
621  * Find the next '.'
622  */
623  *p = '.';
624  p = strchr(p + 1, '.');
625  } while (p);
626 
627  /*
628  * No such module, we're done.
629  */
630  if (!mi) {
631  fr_strerror_printf("Failed to find module '%s'", inst_name);
632  talloc_free(inst_name);
633  return NULL;
634  }
635 
636  mrlm = module_rlm_from_module(mi->module);
637 
638  /*
639  * We have a module, but the caller doesn't care about
640  * method or names, so just return the module.
641  */
642  if (!method || !method_name1 || !method_name2) goto finish;
643 
644  /*
645  * We MAY have two names.
646  */
647  p++;
648  q = strchr(p, '.');
649  /*
650  * We've found the module, but it has no named methods.
651  */
652  if (!mrlm->method_names) {
653  *name1 = name + (p - inst_name);
654  *name2 = NULL;
655  goto finish;
656  }
657 
658  /*
659  * We have "module.METHOD", but METHOD doesn't match
660  * "authorize", "authenticate", etc. Let's see if it
661  * matches anything else.
662  */
663  if (!q) {
664  for (j = 0; mrlm->method_names[j].name1 != NULL; j++) {
665  methods = &mrlm->method_names[j];
666 
667  /*
668  * If we do not have the second $method, then ignore it!
669  */
670  if (methods->name2 && (methods->name2 != CF_IDENT_ANY)) continue;
671 
672  /*
673  * Wildcard match name1, we're
674  * done.
675  */
676  if (!methods->name1 || (methods->name1 == CF_IDENT_ANY)) goto found_name1;
677 
678  /*
679  * If name1 doesn't match, skip it.
680  */
681  if (strcasecmp(methods->name1, p) != 0) continue;
682 
683  found_name1:
684  /*
685  * We've matched "*", or "name1" or
686  * "name1 *". Return that.
687  */
688  *name1 = name + (p - inst_name);
689  *name2 = NULL;
690  *method = methods->method;
691  if (method_env) *method_env = methods->method_env;
692  break;
693  }
694 
695  /*
696  * Return the found module.
697  */
698  goto finish;
699  }
700 
701  /*
702  * We CANNOT have '.' in method names.
703  */
704  if (strchr(q + 1, '.') != 0) goto finish;
705 
706  len = q - p;
707 
708  /*
709  * Trim the '.'.
710  */
711  if (*q == '.' && *(q + 1)) q++;
712 
713  /*
714  * We have "module.METHOD1.METHOD2".
715  *
716  * Loop over the method names, seeing if we have a match.
717  */
718  for (j = 0; mrlm->method_names[j].name1 != NULL; j++) {
719  methods = &mrlm->method_names[j];
720 
721  /*
722  * If name1 doesn't match, skip it.
723  */
724  if (strncasecmp(methods->name1, p, len) != 0) continue;
725 
726  /*
727  * It may have been a partial match, like "rec",
728  * instead of "recv". In which case check if it
729  * was a FULL match.
730  */
731  if (strlen(methods->name1) != len) continue;
732 
733  /*
734  * The module can declare a
735  * wildcard for name2, in which
736  * case it's a match.
737  */
738  if (!methods->name2 || (methods->name2 == CF_IDENT_ANY)) goto found_name2;
739 
740  /*
741  * Don't do strcmp on NULLs
742  */
743  if (!methods->name2) continue;
744 
745  if (strcasecmp(methods->name2, q) != 0) continue;
746 
747  found_name2:
748  /*
749  * Update name1/name2 with the methods
750  * that were found.
751  */
752  *name1 = methods->name1;
753  *name2 = name + (q - inst_name);
754  *method = methods->method;
755  if (method_env) *method_env = methods->method_env;
756  goto finish;
757  }
758 
759  *name1 = name + (p - inst_name);
760  *name2 = NULL;
761 
762 finish:
763  talloc_free(inst_name);
764  return mi;
765 }
766 
767 CONF_SECTION *module_rlm_by_name_virtual(char const *asked_name)
768 {
770 
773  .name = asked_name,
774  });
775  if (!inst) return NULL;
776 
777  return inst->cs;
778 }
779 
781 {
783 }
784 
786 {
787  return module_by_name(rlm_modules, parent, asked_name);
788 }
789 
790 /** Create a virtual module.
791  *
792  * @param[in] cs that defines the virtual module.
793  * @return
794  * - 0 on success.
795  * - -1 on failure.
796  */
798 {
799  char const *name;
800  bool all_same;
801  module_t const *last = NULL;
802  CONF_ITEM *sub_ci = NULL;
803  CONF_PAIR *cp;
804  module_instance_t *mi;
806 
807  name = cf_section_name1(cs);
808 
809  /*
810  * Groups, etc. must have a name.
811  */
812  if ((strcmp(name, "group") == 0) ||
813  (strcmp(name, "redundant") == 0) ||
814  (strcmp(name, "redundant-load-balance") == 0) ||
815  (strcmp(name, "load-balance") == 0)) {
816  name = cf_section_name2(cs);
817  if (!name) {
818  cf_log_err(cs, "Keyword module must have a second name");
819  return -1;
820  }
821 
822  /*
823  * name2 was already checked in modules_rlm_bootstrap()
824  */
826  } else {
827  cf_log_err(cs, "Module names cannot be unlang keywords '%s'", name);
828  return -1;
829  }
830 
831  /*
832  * Ensure that the module doesn't exist.
833  */
834  mi = module_by_name(rlm_modules, NULL, name);
835  if (mi) {
836  ERROR("Duplicate module \"%s\" in file %s[%d] and file %s[%d]",
837  name,
838  cf_filename(cs),
839  cf_lineno(cs),
840  cf_filename(mi->dl_inst->conf),
841  cf_lineno(mi->dl_inst->conf));
842  return -1;
843  }
844 
845  /*
846  * Don't bother registering redundant xlats for a simple "group".
847  */
848  all_same = (strcmp(cf_section_name1(cs), "group") != 0);
849 
850  /*
851  * Ensure that the modules we reference here exist.
852  */
853  while ((sub_ci = cf_item_next(cs, sub_ci))) {
854  if (cf_item_is_pair(sub_ci)) {
855  cp = cf_item_to_pair(sub_ci);
856  if (cf_pair_value(cp)) {
857  cf_log_err(sub_ci, "Cannot set return codes in a %s block", cf_section_name1(cs));
858  return -1;
859  }
860 
861  /*
862  * Allow "foo.authorize" in subsections.
863  *
864  * Note that we don't care what the method is, just that it exists.
865  *
866  * This check is needed only because we
867  * want to know if we need to register a
868  * redundant xlat for the virtual module.
869  */
870  mi = module_rlm_by_name_and_method(NULL, NULL, NULL, NULL, cf_pair_attr(cp));
871  if (!mi) {
872  cf_log_err(sub_ci, "Module instance \"%s\" referenced in %s block, does not exist",
873  cf_pair_attr(cp), cf_section_name1(cs));
874  return -1;
875  }
876 
877  if (all_same) {
878  if (!last) {
879  last = mi->module;
880  } else if (last != mi->module) {
881  last = NULL;
882  all_same = false;
883  }
884  }
885  } else {
886  all_same = false;
887  }
888 
889  /*
890  * Don't check subsections for now. That check
891  * happens later in the unlang compiler.
892  */
893  } /* loop over things in a virtual module section */
894 
895  inst = talloc_zero(cs, module_rlm_virtual_t);
896  if (!inst) return -1;
897 
898  inst->cs = cs;
899  inst->name = talloc_strdup(inst, name);
900  inst->all_same = all_same;
901 
903  talloc_free(inst);
904  return -1;
905  }
906 
907  return 0;
908 }
909 
910 /** Generic conf_parser_t func for loading drivers
911  *
912  */
913 int module_rlm_submodule_parse(TALLOC_CTX *ctx, void *out, void *parent,
914  CONF_ITEM *ci, conf_parser_t const *rule)
915 {
916  conf_parser_t our_rule = *rule;
917 
918  our_rule.uctx = &rlm_modules;
919 
920  return module_submodule_parse(ctx, out, parent, ci, &our_rule);
921 }
922 
923 /** Frees thread-specific data for all registered backend modules
924  *
925  */
927 {
929 }
930 
931 /** Allocates thread-specific data for all registered backend modules
932  *
933  * @param[in] ctx To allocate any thread-specific data in.
934  * @param[in] el to register events.
935  * @return
936  * - 0 if all modules were instantiated successfully.
937  * - -1 if a module failed instantiation.
938  */
940 {
942 }
943 
944 /** Performs the instantiation phase for all backend modules
945  *
946  * @return
947  * - 0 if all modules were instantiated successfully.
948  * - -1 if a module failed instantiation.
949  */
951 {
953 }
954 
955 /** Bootstrap modules and virtual modules
956  *
957  * Parse the module config sections, and load and call each module's init() function.
958  *
959  * @param[in] root of the server configuration.
960  * @return
961  * - 0 if all modules were bootstrapped successfully.
962  * - -1 if a module/virtual module failed to bootstrap.
963  */
965 {
966  CONF_ITEM *ci;
967  CONF_SECTION *cs, *modules;
970  CONF_SECTION *actions;
971 
972  /*
973  * Ensure any libraries the modules depend on are instantiated
974  */
976 
977  /*
978  * Remember where the modules were stored.
979  */
980  modules = cf_section_find(root, "modules", NULL);
981  if (!modules) {
982  WARN("Cannot find a \"modules\" section in the configuration file!");
983  return 0;
984  }
985 
986  DEBUG2("#### Bootstrapping modules ####");
987 
988  cf_log_debug(modules, " modules {");
989 
990  /*
991  * Loop over module definitions, looking for duplicates.
992  *
993  * This is O(N^2) in the number of modules, but most
994  * systems should have less than 100 modules.
995  */
996  for (ci = cf_item_next(modules, NULL);
997  ci != NULL;
998  ci = cf_item_next(modules, ci)) {
999  char const *name;
1000  CONF_SECTION *subcs;
1001  module_instance_t *mi = NULL;
1002 
1003  /*
1004  * @todo - maybe this should be a warning?
1005  */
1006  if (!cf_item_is_section(ci)) continue;
1007 
1008  subcs = cf_item_to_section(ci);
1009 
1010  /*
1011  * name2 can't be a keyword
1012  */
1013  name = cf_section_name2(subcs);
1015  invalid_name:
1016  cf_log_err(subcs, "Module names cannot be unlang keywords '%s'", name);
1017  return -1;
1018  }
1019 
1020  name = cf_section_name1(subcs);
1021 
1022  /*
1023  * For now, ignore name1 which is a keyword.
1024  */
1026  if (!cf_section_name2(subcs)) {
1027  cf_log_err(subcs, "Missing second name at '%s'", name);
1028  return -1;
1029  }
1030  if (module_rlm_bootstrap_virtual(subcs) < 0) return -1;
1031  continue;
1032  }
1033 
1034  /*
1035  * Skip inline templates, and disallow "template { ... }"
1036  */
1037  if (strcmp(name, "template") == 0) {
1038  if (!cf_section_name2(subcs)) goto invalid_name;
1039  continue;
1040  }
1041 
1043  if (unlikely(mi == NULL)) {
1044  cf_log_perr(subcs, "Failed loading module");
1045  return -1;
1046 
1047  }
1048 
1049  if (module_conf_parse(mi, subcs) < 0) {
1050  cf_log_perr(subcs, "Failed parsing module config");
1051  error:
1052  talloc_free(mi);
1053  return -1;
1054  }
1055 
1056  /*
1057  * Compile the default "actions" subsection, which includes retries.
1058  */
1059  actions = cf_section_find(subcs, "actions", NULL);
1060  if (actions && unlang_compile_actions(&mi->actions, actions, (mi->module->flags & MODULE_TYPE_RETRY) != 0)) goto error;
1061  }
1062 
1063  /*
1064  * Having parsed all the modules, bootstrap them.
1065  * This needs to be after parsing so that submodules can access
1066  * their parent's fully parsed data.
1067  */
1068  {
1069  int ret = modules_bootstrap(rlm_modules);
1070 
1071  cf_log_debug(modules, " } # modules");
1072 
1073  if (unlikely(ret < 0)) return -1;
1074  }
1075 
1076  if (fr_command_register_hook(NULL, NULL, modules, module_cmd_list_table) < 0) {
1077  PERROR("Failed registering radmin commands for modules");
1078  return -1;
1079  }
1080 
1081  /*
1082  * Check for duplicate policies. They're treated as
1083  * modules, so we might as well check them here.
1084  */
1085  cs = cf_section_find(root, "policy", NULL);
1086  if (cs) {
1087  while ((ci = cf_item_next(cs, ci))) {
1088  CONF_SECTION *subcs, *problemcs;
1089  char const *name1;
1090 
1091  /*
1092  * Skip anything that isn't a section.
1093  */
1094  if (!cf_item_is_section(ci)) continue;
1095 
1096  subcs = cf_item_to_section(ci);
1097  name1 = cf_section_name1(subcs);
1098 
1099  if (unlang_compile_is_keyword(name1)) {
1100  cf_log_err(subcs, "Policy name '%s' cannot be an unlang keyword", name1);
1101  return -1;
1102  }
1103 
1104  if (cf_section_name2(subcs)) {
1105  cf_log_err(subcs, "Policies cannot have two names");
1106  return -1;
1107  }
1108 
1109  problemcs = cf_section_find_next(cs, subcs, name1, CF_IDENT_ANY);
1110  if (!problemcs) continue;
1111 
1112  cf_log_err(problemcs, "Duplicate policy '%s' is forbidden.",
1113  cf_section_name1(subcs));
1114  return -1;
1115  }
1116  }
1117 
1118  /*
1119  * Now that all of the xlat things have been registered,
1120  * register our redundant xlats. But only when all of
1121  * the items in such a section are the same.
1122  */
1124  vm;
1125  vm = fr_rb_iter_next_inorder(&iter)) {
1126  if (!vm->all_same) continue;
1127 
1128  if (xlat_register_redundant(vm->cs) < 0) return -1;
1129  }
1130 
1131  return 0;
1132 }
1133 
1134 /** Cleanup all global structures
1135  *
1136  * Automatically called on exit.
1137  */
1139 {
1140  if (talloc_free(rlm_modules) < 0) return -1;
1141  rlm_modules = NULL;
1142  if (talloc_free(module_rlm_virtual_name_tree) < 0) return -1;
1144 
1145  return 0;
1146 }
1147 
1148 static int _modules_rlm_free_atexit(UNUSED void *uctx)
1149 {
1150  return modules_rlm_free();
1151 }
1152 
1153 /** Initialise the module list structure
1154  *
1155  */
1157 {
1158  MEM(rlm_modules = module_list_alloc(NULL, "rlm"));
1162 
1163  return 0;
1164 }
#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:444
#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:378
#define UNUSED
Definition: build.h:313
void const * uctx
User data accessible by the cf_parse_t func.
Definition: cf_parse.h:586
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
Internal data that is associated with a configuration section.
Definition: cf_priv.h:113
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:89
bool cf_item_is_pair(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_PAIR.
Definition: cf_util.c:597
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: cf_util.c:629
char const * cf_pair_attr(CONF_PAIR const *pair)
Return the attr of a CONF_PAIR.
Definition: cf_util.c:1495
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:970
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:1356
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1126
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1511
void * cf_data_value(CONF_DATA const *cd)
Return the user assigned value of CONF_DATA.
Definition: cf_util.c:1680
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition: cf_util.c:649
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:991
bool cf_item_is_section(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_SECTION.
Definition: cf_util.c:583
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1112
char const * cf_section_name(CONF_SECTION const *cs)
Return name2 if set, else name1.
Definition: cf_util.c:1138
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:265
#define cf_lineno(_cf)
Definition: cf_util.h:101
#define cf_data_add(_cf, _data, _name, _free)
Definition: cf_util.h:231
#define cf_data_find(_cf, _type, _name)
Definition: cf_util.h:220
#define cf_data_remove_by_data(_cf, _cd)
Remove an item from a parent.
Definition: cf_util.h:250
#define cf_parent(_cf)
Definition: cf_util.h:98
#define cf_item_next(_ci, _prev)
Definition: cf_util.h:92
#define cf_log_perr(_cf, _fmt,...)
Definition: cf_util.h:272
#define cf_section_alloc(_ctx, _parent, _name1, _name2)
Definition: cf_util.h:137
#define cf_filename(_cf)
Definition: cf_util.h:104
#define cf_log_debug(_cf, _fmt,...)
Definition: cf_util.h:268
#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:4935
bool unlang_compile_actions(unlang_actions_t *actions, CONF_SECTION *action_cs, bool module_retry)
Definition: compile.c:1970
@ MOD_COUNT
10 how many components there are.
Definition: components.h:38
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:137
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
fr_value_box_t const * value
Enum value (what name maps to).
Definition: dict.h:213
char const * name
Enum name.
Definition: dict.h:210
Value of an enumerated attribute.
Definition: dict.h:209
char const * dl_module_inst_name_from_conf(CONF_SECTION *conf)
Avoid boilerplate when setting the module instance name.
Definition: dl_module.c:584
@ DL_MODULE_TYPE_MODULE
Standard loadable module.
Definition: dl_module.h:68
CONF_SECTION *_CONST conf
Module's instance configuration.
Definition: dl_module.h:166
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:195
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:147
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
unsigned int uint32_t
Definition: merged_model.c:33
int strncasecmp(char *s1, char *s2, int n)
Definition: missing.c:36
int strcasecmp(char *s1, char *s2)
Definition: missing.c:66
fr_cmd_table_t module_cmd_list_table[]
Definition: module.c:111
char const * name1
module method name1 which is allowed in this section
Definition: module_method.c:43
char const * name2
module method name2 which is allowed in this section
Definition: module_method.c:44
Specifies a module method identifier.
Definition: module_method.c:36
char const * module_rlm_state_method_to_str(module_state_func_table_t const *table, module_method_t method, char const *def)
Definition: module_rlm.c:381
static int _modules_rlm_free_atexit(UNUSED void *uctx)
Definition: module_rlm.c:1148
module_instance_t * module_rlm_by_name(module_instance_t const *parent, char const *asked_name)
Definition: module_rlm.c:785
void modules_rlm_thread_detach(void)
Frees thread-specific data for all registered backend modules.
Definition: module_rlm.c:926
int modules_rlm_bootstrap(CONF_SECTION *root)
Bootstrap modules and virtual modules.
Definition: module_rlm.c:964
static int module_rlm_bootstrap_virtual(CONF_SECTION *cs)
Create a virtual module.
Definition: module_rlm.c:797
CONF_SECTION * module_rlm_by_name_virtual(char const *asked_name)
Definition: module_rlm.c:767
char const * name
module name
Definition: module_rlm.c:47
static module_list_t * rlm_modules
Global module list for all backend modules.
Definition: module_rlm.c:75
fr_rb_node_t name_node
Entry in the name tree.
Definition: module_rlm.c:46
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:144
static int8_t module_rlm_virtual_name_cmp(void const *one, void const *two)
Compare virtual modules by name.
Definition: module_rlm.c:54
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:92
static fr_rb_tree_t * module_rlm_virtual_name_tree
Lookup virtual module by name.
Definition: module_rlm.c:43
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:913
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:397
module_instance_t * module_rlm_by_name_and_method(module_method_t *method, call_env_method_t const **method_env, char const **name1, char const **name2, char const *name)
Find an existing module instance and verify it implements the specified method.
Definition: module_rlm.c:433
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:248
module_method_t module_rlm_state_str_to_method(module_state_func_table_t const *table, char const *name, module_method_t def)
Definition: module_rlm.c:364
int modules_rlm_free(void)
Cleanup all global structures.
Definition: module_rlm.c:1138
#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:939
module_thread_instance_t * module_rlm_thread_by_data(void const *data)
Definition: module_rlm.c:780
#define parent_name(_x)
int modules_rlm_instantiate(void)
Performs the instantiation phase for all backend modules.
Definition: module_rlm.c:950
int modules_rlm_init(void)
Initialise the module list structure.
Definition: module_rlm.c:1156
char const * section_type_value[MOD_COUNT]
Definition: module_rlm.c:64
CONF_SECTION * cs
CONF_SECTION where it is defined.
Definition: module_rlm.c:48
module_method_name_t const * method_names
named methods
Definition: module_rlm.h:38
static module_rlm_t const * module_rlm_from_module(module_t const *module)
Cast a module_t to a module_rlm_t.
Definition: module_rlm.h:45
int fr_pool_start(fr_pool_t *pool)
Definition: pool.c:1114
void fr_pool_ref(fr_pool_t *pool)
Increment pool reference by one.
Definition: pool.c:1210
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:931
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:965
A connection pool.
Definition: pool.c:85
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:844
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
Definition: rb.c:624
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
Iterator structure for in-order traversal of an rbtree.
Definition: rb.h:321
The main red black tree structure.
Definition: rb.h:73
static const call_env_method_t method_env
Definition: rlm_detail.c:489
static char const * name
unlang_actions_t actions
default actions and retries.
Definition: module.h:206
@ MODULE_TYPE_RETRY
can handle retries
Definition: module.h:54
module_instance_state_t state
What's been done with this module so far.
Definition: module.h:195
dl_module_inst_t * dl_inst
Structure containing the module's instance data, configuration, and dl handle.
Definition: module.h:183
@ MODULE_INSTANCE_INSTANTIATED
Definition: module.h:160
int flags
Definition: module.h:147
module_t const * module
Public module structure.
Definition: module.h:188
unlang_action_t(* module_method_t)(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Module section callback.
Definition: module.h:69
Per instance data.
Definition: module.h:169
A list of modules.
Definition: module.h:235
Struct exported by a rlm_* module.
Definition: module.h:142
Map string values to module state method.
Definition: module.h:245
Per thread per instance data.
Definition: module.h:215
#define pair_update_control(_attr, _da)
Return or allocate a fr_pair_t in the control list.
Definition: pair.h:140
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:689
module_instance_t * module_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:367
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:663
int modules_instantiate(module_list_t const *ml)
Completes instantiation of modules.
Definition: module.c:759
module_instance_t * module_alloc(module_list_t *ml, module_instance_t const *parent, dl_module_type_t type, char const *mod_name, char const *inst_name)
Allocate a new module and add it to a module list for later bootstrap/instantiation.
Definition: module.c:976
int module_conf_parse(module_instance_t *mi, CONF_SECTION *mod_conf)
Parse the configuration associated with a module.
Definition: module.c:946
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:485
void modules_thread_detach(module_list_t const *ml)
Remove thread-specific data for a given module list.
Definition: module.c:516
int modules_bootstrap(module_list_t const *ml)
Bootstrap any modules which have not been bootstrapped already.
Definition: module.c:830
int module_instantiate(module_instance_t *instance)
Manually complete module setup by calling its instantiate function.
Definition: module.c:702
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:311
module_list_t * module_list_alloc(TALLOC_CTX *ctx, char const *name)
Allocate a new module list.
Definition: module.c:1118
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
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
static fr_event_list_t * el
static fr_slen_t parent
Definition: pair.h:844
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
Definition: value.c:3689
static fr_slen_t data
Definition: value.h:1259
static size_t char ** out
Definition: value.h:984
virtual_server_method_t const * virtual_server_section_methods(char const *name1, char const *name2)
Find the component for a section.
char const * name
module method name1 which is allowed in this section
char const * name2
module method name2 which is allowed in this section
Module methods which are allowed in virtual servers.
int xlat_register_redundant(CONF_SECTION *cs)
Registers a redundant xlat.