2 * conffile.c Read the radiusd.conf file.
4 * Yep I should learn to use lex & yacc, or at least
5 * write a decent parser. I know how to do that, really :)
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 * Copyright 2000,2006 The FreeRADIUS server project
25 * Copyright 2000 Miquel van Smoorenburg <miquels@cistron.nl>
26 * Copyright 2000 Alan DeKok <aland@ox.org>
31 #include <freeradius-devel/radiusd.h>
32 #include <freeradius-devel/parser.h>
33 #include <freeradius-devel/rad_assert.h>
39 #ifdef HAVE_SYS_STAT_H
45 typedef enum conf_property {
46 CONF_PROPERTY_INVALID = 0,
48 CONF_PROPERTY_INSTANCE,
51 static const FR_NAME_NUMBER conf_property_name[] = {
52 { "name", CONF_PROPERTY_NAME},
53 { "instance", CONF_PROPERTY_INSTANCE},
58 typedef enum conf_type {
59 CONF_ITEM_INVALID = 0,
66 struct conf_item *next; //!< Sibling.
67 struct conf_part *parent; //!< Parent.
68 int lineno; //!< The line number the config item began on.
69 char const *filename; //!< The file the config item was parsed from.
70 CONF_ITEM_TYPE type; //!< Whether the config item is a config_pair, conf_section or conf_data.
73 /** Configuration AVP similar to a VALUE_PAIR
78 char const *attr; //!< Attribute name
79 char const *value; //!< Attribute value
80 FR_TOKEN op; //!< Operator e.g. =, :=
81 FR_TOKEN lhs_type; //!< Name quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD.
82 FR_TOKEN rhs_type; //!< Value Quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD.
83 bool pass2; //!< do expansion in pass2.
86 /** Internal data that is associated with a configuration section
93 void *data; //!< User data
94 void (*free)(void *); //!< Free user data function
99 char const *name1; //!< First name token. Given ``foo bar {}`` would be ``foo``.
100 char const *name2; //!< Second name token. Given ``foo bar {}`` would be ``bar``.
102 FR_TOKEN name2_type; //!< The type of quoting around name2.
105 CONF_ITEM *tail; //!< For speed.
106 CONF_SECTION *template;
108 rbtree_t *pair_tree; //!< and a partridge..
109 rbtree_t *section_tree; //!< no jokes here.
110 rbtree_t *name2_tree; //!< for sections of the same name2
116 CONF_PARSER const *variables;
119 CONF_SECTION *root_config = NULL;
120 bool cf_new_escape = false;
123 static int cf_data_add_internal(CONF_SECTION *cs, char const *name, void *data,
124 void (*data_free)(void *), int flag);
126 static void *cf_data_find_internal(CONF_SECTION const *cs, char const *name, int flag);
128 static char const *cf_expand_variables(char const *cf, int *lineno,
129 CONF_SECTION *outercs,
130 char *output, size_t outsize,
131 char const *input, bool *soft_fail);
134 * Isolate the scary casts in these tiny provably-safe functions
137 /** Cast a CONF_ITEM to a CONF_PAIR
140 CONF_PAIR *cf_item_to_pair(CONF_ITEM const *ci)
144 if (ci == NULL) return NULL;
146 rad_assert(ci->type == CONF_ITEM_PAIR);
148 memcpy(&out, &ci, sizeof(out));
152 /** Cast a CONF_ITEM to a CONF_SECTION
155 CONF_SECTION *cf_item_to_section(CONF_ITEM const *ci)
159 if (ci == NULL) return NULL;
161 rad_assert(ci->type == CONF_ITEM_SECTION);
163 memcpy(&out, &ci, sizeof(out));
167 /** Cast a CONF_PAIR to a CONF_ITEM
170 CONF_ITEM *cf_pair_to_item(CONF_PAIR const *cp)
174 if (cp == NULL) return NULL;
176 memcpy(&out, &cp, sizeof(out));
180 /** Cast a CONF_SECTION to a CONF_ITEM
183 CONF_ITEM *cf_section_to_item(CONF_SECTION const *cs)
187 if (cs == NULL) return NULL;
189 memcpy(&out, &cs, sizeof(out));
193 /** Cast CONF_DATA to a CONF_ITEM
196 static CONF_ITEM *cf_data_to_item(CONF_DATA const *cd)
204 memcpy(&out, &cd, sizeof(out));
208 static int _cf_data_free(CONF_DATA *cd)
210 if (cd->free) cd->free(cd->data);
216 * rbtree callback function
218 static int pair_cmp(void const *a, void const *b)
220 CONF_PAIR const *one = a;
221 CONF_PAIR const *two = b;
223 return strcmp(one->attr, two->attr);
228 * rbtree callback function
230 static int section_cmp(void const *a, void const *b)
232 CONF_SECTION const *one = a;
233 CONF_SECTION const *two = b;
235 return strcmp(one->name1, two->name1);
240 * rbtree callback function
242 static int name2_cmp(void const *a, void const *b)
244 CONF_SECTION const *one = a;
245 CONF_SECTION const *two = b;
247 rad_assert(strcmp(one->name1, two->name1) == 0);
249 if (!one->name2 && !two->name2) return 0;
250 if (one->name2 && !two->name2) return -1;
251 if (!one->name2 && two->name2) return +1;
253 return strcmp(one->name2, two->name2);
258 * rbtree callback function
260 static int data_cmp(void const *a, void const *b)
264 CONF_DATA const *one = a;
265 CONF_DATA const *two = b;
267 rcode = one->flag - two->flag;
268 if (rcode != 0) return rcode;
270 return strcmp(one->name, two->name);
273 static int _cf_section_free(CONF_SECTION *cs)
276 * Name1 and name2 are allocated contiguous with
280 rbtree_free(cs->pair_tree);
281 cs->pair_tree = NULL;
283 if (cs->section_tree) {
284 rbtree_free(cs->section_tree);
285 cs->section_tree = NULL;
287 if (cs->name2_tree) {
288 rbtree_free(cs->name2_tree);
289 cs->name2_tree = NULL;
292 rbtree_free(cs->data_tree);
293 cs->data_tree = NULL;
299 /** Allocate a CONF_PAIR
301 * @param parent CONF_SECTION to hang this CONF_PAIR off of.
303 * @param value of CONF_PAIR.
304 * @param op T_OP_EQ, T_OP_SET etc.
305 * @param lhs_type T_BARE_WORD, T_DOUBLE_QUOTED_STRING, T_BACK_QUOTED_STRING
306 * @param rhs_type T_BARE_WORD, T_DOUBLE_QUOTED_STRING, T_BACK_QUOTED_STRING
307 * @return NULL on error, else a new CONF_SECTION parented by parent.
309 CONF_PAIR *cf_pair_alloc(CONF_SECTION *parent, char const *attr, char const *value,
310 FR_TOKEN op, FR_TOKEN lhs_type, FR_TOKEN rhs_type)
314 rad_assert(fr_equality_op[op] || fr_assignment_op[op]);
315 if (!attr) return NULL;
317 cp = talloc_zero(parent, CONF_PAIR);
318 if (!cp) return NULL;
320 cp->item.type = CONF_ITEM_PAIR;
321 cp->item.parent = parent;
322 cp->lhs_type = lhs_type;
323 cp->rhs_type = rhs_type;
326 cp->attr = talloc_typed_strdup(cp, attr);
334 cp->value = talloc_typed_strdup(cp, value);
335 if (!cp->value) goto error;
341 /** Duplicate a CONF_PAIR
343 * @param parent to allocate new pair in.
344 * @param cp to duplicate.
345 * @return NULL on error, else a duplicate of the input pair.
347 CONF_PAIR *cf_pair_dup(CONF_SECTION *parent, CONF_PAIR *cp)
354 new = cf_pair_alloc(parent, cp->attr, cf_pair_value(cp),
355 cp->op, cp->lhs_type, cp->rhs_type);
357 new->item.lineno = cp->item.lineno;
358 new->item.filename = talloc_strdup(new, cp->item.filename);
364 /** Add a configuration pair to a section
366 * @param parent section to add pair to.
369 void cf_pair_add(CONF_SECTION *parent, CONF_PAIR *cp)
371 cf_item_add(parent, cf_pair_to_item(cp));
374 /** Allocate a CONF_SECTION
376 * @param parent CONF_SECTION to hang this CONF_SECTION off of.
377 * @param name1 Primary name.
378 * @param name2 Secondary name.
379 * @return NULL on error, else a new CONF_SECTION parented by parent.
381 CONF_SECTION *cf_section_alloc(CONF_SECTION *parent, char const *name1, char const *name2)
386 if (!name1) return NULL;
389 if (strchr(name2, '$')) {
390 name2 = cf_expand_variables(parent->item.filename,
391 &parent->item.lineno,
393 buffer, sizeof(buffer), name2, NULL);
395 ERROR("Failed expanding section name");
401 cs = talloc_zero(parent, CONF_SECTION);
402 if (!cs) return NULL;
404 cs->item.type = CONF_ITEM_SECTION;
405 cs->item.parent = parent;
407 cs->name1 = talloc_typed_strdup(cs, name1);
415 cs->name2 = talloc_typed_strdup(cs, name2);
416 if (!cs->name2) goto error;
419 cs->pair_tree = rbtree_create(cs, pair_cmp, NULL, 0);
420 if (!cs->pair_tree) goto error;
422 talloc_set_destructor(cs, _cf_section_free);
425 * Don't create a data tree, it may not be needed.
429 * Don't create the section tree here, it may not
433 if (parent) cs->depth = parent->depth + 1;
438 /** Duplicate a configuration section
440 * @note recursively duplicates any child sections.
441 * @note does not duplicate any data associated with a section, or its child sections.
443 * @param parent section.
444 * @param cs to duplicate.
445 * @param name1 of new section.
446 * @param name2 of new section.
447 * @param copy_meta Copy additional meta data for a section (like template, base, depth and variables).
448 * @return a duplicate of the existing section, or NULL on error.
450 CONF_SECTION *cf_section_dup(CONF_SECTION *parent, CONF_SECTION const *cs,
451 char const *name1, char const *name2, bool copy_meta)
453 CONF_SECTION *new, *subcs;
457 new = cf_section_alloc(parent, name1, name2);
460 new->template = cs->template;
461 new->base = cs->base;
462 new->depth = cs->depth;
463 new->variables = cs->variables;
466 new->item.lineno = cs->item.lineno;
467 new->item.filename = talloc_strdup(new, cs->item.filename);
469 for (ci = cs->children; ci; ci = ci->next) {
471 case CONF_ITEM_SECTION:
472 subcs = cf_item_to_section(ci);
473 subcs = cf_section_dup(new, subcs,
474 cf_section_name1(subcs), cf_section_name2(subcs),
480 cf_section_add(new, subcs);
484 cp = cf_pair_dup(new, cf_item_to_pair(ci));
489 cf_pair_add(new, cp);
492 case CONF_ITEM_DATA: /* Skip data */
495 case CONF_ITEM_INVALID:
503 void cf_section_add(CONF_SECTION *parent, CONF_SECTION *cs)
505 cf_item_add(parent, &(cs->item));
508 /** Replace pair in a given section with a new pair, of the given value.
510 * @param cs to replace pair in.
511 * @param cp to replace.
512 * @param value New value to assign to cp.
513 * @return 0 on success, -1 on failure.
515 int cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value)
518 CONF_ITEM *ci, *cn, **last;
520 newp = cf_pair_alloc(cs, cp->attr, value, cp->op, cp->lhs_type, cp->rhs_type);
521 if (!newp) return -1;
527 * Find the old one from the linked list, and replace it
530 for (last = &cs->children; (*last) != NULL; last = &(*last)->next) {
532 cn->next = (*last)->next;
539 rbtree_deletebydata(cs->pair_tree, ci);
541 rbtree_insert(cs->pair_tree, cn);
548 * Add an item to a configuration section.
550 void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci)
553 CONF_ITEM *first = ci;
556 rad_assert((void *)cs != (void *)ci);
558 if (!cs || !ci) return;
561 rad_assert(cs->tail == NULL);
564 rad_assert(cs->tail != NULL);
569 * Update the trees (and tail) for each item added.
571 for (/* nothing */; ci != NULL; ci = ci->next) {
572 rad_assert(ci->next != first); /* simple cycle detection */
577 * For fast lookups, pairs and sections get
582 if (!rbtree_insert(cs->pair_tree, ci)) {
583 CONF_PAIR *cp = cf_item_to_pair(ci);
585 if (strcmp(cp->attr, "confdir") == 0) break;
586 if (!cp->value) break; /* module name, "ok", etc. */
590 case CONF_ITEM_SECTION: {
591 CONF_SECTION *cs_new = cf_item_to_section(ci);
592 CONF_SECTION *name1_cs;
594 if (!cs->section_tree) {
595 cs->section_tree = rbtree_create(cs, section_cmp, NULL, 0);
596 if (!cs->section_tree) {
597 ERROR("Out of memory");
602 name1_cs = rbtree_finddata(cs->section_tree, cs_new);
604 if (!rbtree_insert(cs->section_tree, cs_new)) {
605 ERROR("Failed inserting section into tree");
612 * We already have a section of
613 * this "name1". Add a new
614 * sub-section based on name2.
616 if (!name1_cs->name2_tree) {
617 name1_cs->name2_tree = rbtree_create(name1_cs, name2_cmp, NULL, 0);
618 if (!name1_cs->name2_tree) {
619 ERROR("Out of memory");
625 * We don't care if this fails.
626 * If the user tries to create
627 * two sections of the same
628 * name1/name2, the duplicate
629 * section is just silently
632 rbtree_insert(name1_cs->name2_tree, cs_new);
634 } /* was a section */
637 if (!cs->data_tree) {
638 cs->data_tree = rbtree_create(cs, data_cmp, NULL, 0);
641 rbtree_insert(cs->data_tree, ci);
645 default: /* FIXME: assert & error! */
648 } /* switch over conf types */
653 CONF_ITEM *cf_reference_item(CONF_SECTION const *parentcs,
654 CONF_SECTION *outercs,
659 CONF_SECTION const *cs = outercs;
663 if (!cs) goto no_such_item;
665 strlcpy(name, ptr, sizeof(name));
669 * ".foo" means "foo from the current section"
675 * Just '.' means the current section
678 return cf_section_to_item(cs);
682 * ..foo means "foo from the section
683 * enclosing this section" (etc.)
686 if (cs->item.parent) {
687 cs = cs->item.parent;
691 * .. means the section
692 * enclosing this section
695 return cf_section_to_item(cs);
700 * "foo.bar.baz" means "from the root"
702 } else if (strchr(p, '.') != NULL) {
703 if (!parentcs) goto no_such_item;
715 if (r && q > r) q = NULL;
716 if (q && q < r) r = NULL;
722 q = strchr(r + 1, ']');
723 if (!q) return NULL; /* parse error */
726 * Points to foo[bar]xx: parse error,
727 * it should be foo[bar] or foo[bar].baz
729 if (q[1] && q[1] != '.') goto no_such_item;
733 next = cf_section_sub_find_name2(cs, p, r + 1);
738 * Points to a named instance of a section.
741 if (!next) goto no_such_item;
742 return &(next->item);
745 q++; /* ensure we skip the ']' and '.' */
749 next = cf_section_sub_find(cs, p);
753 if (!next) break; /* it MAY be a pair in this section! */
759 if (!*p) goto no_such_item;
763 * Find it in the current referenced
766 cp = cf_pair_find(cs, p);
767 if (cp) return &(cp->item);
769 next = cf_section_sub_find(cs, p);
770 if (next) return &(next->item);
773 * "foo" is "in the current section, OR in main".
775 if ((p == name) && (parentcs != NULL) && (cs != parentcs)) {
785 CONF_SECTION *cf_top_section(CONF_SECTION *cs)
787 if (!cs) return NULL;
789 while (cs->item.parent != NULL) {
790 cs = cs->item.parent;
798 * Expand the variables in an input string.
800 static char const *cf_expand_variables(char const *cf, int *lineno,
801 CONF_SECTION *outercs,
802 char *output, size_t outsize,
803 char const *input, bool *soft_fail)
806 char const *end, *ptr;
807 CONF_SECTION const *parentcs;
810 if (soft_fail) *soft_fail = false;
813 * Find the master parent conf section.
814 * We can't use main_config.config, because we're in the
815 * process of re-building it, and it isn't set up yet...
817 parentcs = cf_top_section(outercs);
823 * Ignore anything other than "${"
825 if ((*ptr == '$') && (ptr[1] == '{')) {
831 * FIXME: Add support for ${foo:-bar},
836 * Look for trailing '}', and log a
837 * warning for anything that doesn't match,
838 * and exit with a fatal error.
840 end = strchr(ptr, '}');
843 INFO("%s[%d]: Variable expansion missing }",
851 * Can't really happen because input lines are
852 * capped at 8k, which is sizeof(name)
854 if ((size_t) (end - ptr) >= sizeof(name)) {
855 ERROR("%s[%d]: Reference string is too large",
860 memcpy(name, ptr, end - ptr);
861 name[end - ptr] = '\0';
863 q = strchr(name, ':');
868 ci = cf_reference_item(parentcs, outercs, name);
870 if (soft_fail) *soft_fail = true;
871 ERROR("%s[%d]: Reference \"%s\" not found", cf, *lineno, input);
876 * The expansion doesn't refer to another item or section
877 * it's the property of a section.
880 CONF_SECTION *mycs = cf_item_to_section(ci);
882 if (ci->type != CONF_ITEM_SECTION) {
883 ERROR("%s[%d]: Can only reference properties of sections", cf, *lineno);
887 switch (fr_str2int(conf_property_name, q, CONF_PROPERTY_INVALID)) {
888 case CONF_PROPERTY_NAME:
889 strcpy(p, mycs->name1);
892 case CONF_PROPERTY_INSTANCE:
893 strcpy(p, mycs->name2 ? mycs->name2 : mycs->name1);
897 ERROR("%s[%d]: Invalid property '%s'", cf, *lineno, q);
903 } else if (ci->type == CONF_ITEM_PAIR) {
905 * Substitute the value of the variable.
907 cp = cf_item_to_pair(ci);
910 * If the thing we reference is
911 * marked up as being expanded in
912 * pass2, don't expand it now.
913 * Let it be expanded in pass2.
916 if (soft_fail) *soft_fail = true;
918 ERROR("%s[%d]: Reference \"%s\" points to a variable which has not been expanded.",
924 ERROR("%s[%d]: Reference \"%s\" has no value",
929 if (p + strlen(cp->value) >= output + outsize) {
930 ERROR("%s[%d]: Reference \"%s\" is too long",
935 strcpy(p, cp->value);
939 } else if (ci->type == CONF_ITEM_SECTION) {
943 * Adding an entry again to a
944 * section is wrong. We don't
945 * want an infinite loop.
947 if (ci->parent == outercs) {
948 ERROR("%s[%d]: Cannot reference different item in same section", cf, *lineno);
953 * Copy the section instead of
956 subcs = cf_item_to_section(ci);
957 subcs = cf_section_dup(outercs, subcs,
958 cf_section_name1(subcs), cf_section_name2(subcs),
961 ERROR("%s[%d]: Failed copying reference %s", cf, *lineno, name);
965 subcs->item.filename = ci->filename;
966 subcs->item.lineno = ci->lineno;
967 cf_item_add(outercs, &(subcs->item));
972 ERROR("%s[%d]: Reference \"%s\" type is invalid", cf, *lineno, input);
975 } else if (memcmp(ptr, "$ENV{", 5) == 0) {
981 * Look for trailing '}', and log a
982 * warning for anything that doesn't match,
983 * and exit with a fatal error.
985 end = strchr(ptr, '}');
988 INFO("%s[%d]: Environment variable expansion missing }",
994 * Can't really happen because input lines are
995 * capped at 8k, which is sizeof(name)
997 if ((size_t) (end - ptr) >= sizeof(name)) {
998 ERROR("%s[%d]: Environment variable name is too large",
1003 memcpy(name, ptr, end - ptr);
1004 name[end - ptr] = '\0';
1007 * Get the environment variable.
1008 * If none exists, then make it an empty string.
1016 if (p + strlen(env) >= output + outsize) {
1017 ERROR("%s[%d]: Reference \"%s\" is too long",
1018 cf, *lineno, input);
1028 * Copy it over verbatim.
1034 if (p >= (output + outsize)) {
1035 ERROR("%s[%d]: Reference \"%s\" is too long",
1036 cf, *lineno, input);
1039 } /* loop over all of the input string. */
1046 static char const parse_spaces[] = " ";
1048 /** Validation function for ipaddr conffile types
1051 static inline int fr_item_validate_ipaddr(CONF_SECTION *cs, char const *name, PW_TYPE type, char const *value,
1052 fr_ipaddr_t *ipaddr)
1056 if (strcmp(value, "*") == 0) {
1057 cf_log_info(cs, "%.*s\t%s = *", cs->depth, parse_spaces, name);
1058 } else if (strspn(value, ".0123456789abdefABCDEF:%[]/") == strlen(value)) {
1059 cf_log_info(cs, "%.*s\t%s = %s", cs->depth, parse_spaces, name, value);
1061 cf_log_info(cs, "%.*s\t%s = %s IPv%s address [%s]", cs->depth, parse_spaces, name, value,
1062 (ipaddr->af == AF_INET ? "4" : " 6"), ip_ntoh(ipaddr, ipbuf, sizeof(ipbuf)));
1066 case PW_TYPE_IPV4_ADDR:
1067 case PW_TYPE_IPV6_ADDR:
1068 case PW_TYPE_COMBO_IP_ADDR:
1069 switch (ipaddr->af) {
1071 if (ipaddr->prefix != 32) {
1072 ERROR("Invalid IPv4 mask length \"/%i\". Only \"/32\" permitted for non-prefix types",
1080 if (ipaddr->prefix != 128) {
1081 ERROR("Invalid IPv6 mask length \"/%i\". Only \"/128\" permitted for non-prefix types",
1096 /** Parses a #CONF_PAIR into a C data type, with a default value.
1098 * Takes fields from a #CONF_PARSER struct and uses them to parse the string value
1099 * of a #CONF_PAIR into a C data type matching the type argument.
1101 * The format of the types are the same as #value_data_t types.
1103 * @note The dflt value will only be used if no matching #CONF_PAIR is found. Empty strings will not
1104 * result in the dflt value being used.
1106 * @param cs to search for matching #CONF_PAIR in.
1107 * @param name of #CONF_PAIR to search for.
1108 * @param type Data type to parse #CONF_PAIR value as.
1109 * Should be one of the following ``data`` types, and one or more of the following ``flag`` types or'd together:
1110 * - ``data`` #PW_TYPE_TMPL - @copybrief PW_TYPE_TMPL
1111 Feeds the value into #tmpl_afrom_str. Value can be
1112 * obtained when processing requests, with #tmpl_expand or #tmpl_aexpand.
1113 * - ``data`` #PW_TYPE_BOOLEAN - @copybrief PW_TYPE_BOOLEAN
1114 * - ``data`` #PW_TYPE_INTEGER - @copybrief PW_TYPE_INTEGER
1115 * - ``data`` #PW_TYPE_SHORT - @copybrief PW_TYPE_SHORT
1116 * - ``data`` #PW_TYPE_INTEGER64 - @copybrief PW_TYPE_INTEGER64
1117 * - ``data`` #PW_TYPE_SIGNED - @copybrief PW_TYPE_SIGNED
1118 * - ``data`` #PW_TYPE_STRING - @copybrief PW_TYPE_STRING
1119 * - ``data`` #PW_TYPE_IPV4_ADDR - @copybrief PW_TYPE_IPV4_ADDR (IPv4 address with prefix 32).
1120 * - ``data`` #PW_TYPE_IPV4_PREFIX - @copybrief PW_TYPE_IPV4_PREFIX (IPv4 address with variable prefix).
1121 * - ``data`` #PW_TYPE_IPV6_ADDR - @copybrief PW_TYPE_IPV6_ADDR (IPv6 address with prefix 128).
1122 * - ``data`` #PW_TYPE_COMBO_IP_ADDR - @copybrief PW_TYPE_COMBO_IP_ADDR (IPv4/IPv6 address with
1124 * - ``data`` #PW_TYPE_COMBO_IP_PREFIX - @copybrief PW_TYPE_COMBO_IP_PREFIX (IPv4/IPv6 address with
1126 * - ``data`` #PW_TYPE_TIMEVAL - @copybrief PW_TYPE_TIMEVAL
1127 * - ``flag`` #PW_TYPE_DEPRECATED - @copybrief PW_TYPE_DEPRECATED
1128 * - ``flag`` #PW_TYPE_REQUIRED - @copybrief PW_TYPE_REQUIRED
1129 * - ``flag`` #PW_TYPE_ATTRIBUTE - @copybrief PW_TYPE_ATTRIBUTE
1130 * - ``flag`` #PW_TYPE_SECRET - @copybrief PW_TYPE_SECRET
1131 * - ``flag`` #PW_TYPE_FILE_INPUT - @copybrief PW_TYPE_FILE_INPUT
1132 * - ``flag`` #PW_TYPE_NOT_EMPTY - @copybrief PW_TYPE_NOT_EMPTY
1133 * @param data Pointer to a global variable, or pointer to a field in the struct being populated with values.
1134 * @param dflt value to use, if no #CONF_PAIR is found.
1135 * @return -1 on error, -2 if deprecated, 0 on success (correctly parsed), 1 if default value was used.
1137 int cf_item_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *data, char const *dflt)
1140 bool deprecated, required, attribute, secret, file_input, cant_be_empty, tmpl, xlat;
1143 CONF_PAIR const *cp = NULL;
1144 fr_ipaddr_t *ipaddr;
1149 deprecated = (type & PW_TYPE_DEPRECATED);
1150 required = (type & PW_TYPE_REQUIRED);
1151 attribute = (type & PW_TYPE_ATTRIBUTE);
1152 secret = (type & PW_TYPE_SECRET);
1153 file_input = (type == PW_TYPE_FILE_INPUT); /* check, not and */
1154 cant_be_empty = (type & PW_TYPE_NOT_EMPTY);
1155 tmpl = (type & PW_TYPE_TMPL);
1156 xlat = (type & PW_TYPE_XLAT);
1158 if (attribute) required = true;
1159 if (required) cant_be_empty = true; /* May want to review this in the future... */
1161 type &= 0xff; /* normal types are small */
1164 cp = cf_pair_find(cs, name);
1166 * No pairs match the configuration item name in the current
1167 * section, use the default value.
1173 * Something matched, used the CONF_PAIR value.
1183 cf_log_err(&(cs->item), "Configuration item '%s' must have a value", name);
1185 cf_log_err(&(cp->item), "Configuration item '%s' must have a value", name);
1192 if ((value[0] == '\0') && cant_be_empty) {
1195 cf_log_err(&(cs->item), "Configuration item '%s' must not be empty (zero length)", name);
1196 if (!required) cf_log_err(&(cs->item), "Comment item to silence this message");
1198 cf_log_err(&(cp->item), "Configuration item '%s' must not be empty (zero length)", name);
1199 if (!required) cf_log_err(&(cp->item), "Comment item to silence this message");
1205 cf_log_err(&(cs->item), "Configuration item \"%s\" is deprecated", name);
1211 * Process a value as a template.
1218 *(vp_tmpl_t **)data = NULL;
1222 slen = tmpl_afrom_str(cs, &vpt, value, strlen(value),
1223 cp ? cf_pair_value_type(cp) : T_DOUBLE_QUOTED_STRING,
1224 REQUEST_CURRENT, PAIR_LIST_REQUEST, true);
1226 char *spaces, *text;
1228 fr_canonicalize_error(cs, &spaces, &text, slen, fr_strerror());
1230 cf_log_err_cs(cs, "Failed parsing configuration item '%s'", name);
1231 cf_log_err_cs(cs, "%s", value);
1232 cf_log_err_cs(cs, "%s^ %s", spaces, text);
1234 talloc_free(spaces);
1243 * Don't add default - update with new types.
1245 switch (vpt->type) {
1246 case TMPL_TYPE_LITERAL:
1247 case TMPL_TYPE_ATTR:
1248 case TMPL_TYPE_ATTR_UNDEFINED:
1249 case TMPL_TYPE_LIST:
1250 case TMPL_TYPE_DATA:
1251 case TMPL_TYPE_EXEC:
1252 case TMPL_TYPE_XLAT:
1253 case TMPL_TYPE_XLAT_STRUCT:
1256 case TMPL_TYPE_UNKNOWN:
1257 case TMPL_TYPE_REGEX:
1258 case TMPL_TYPE_REGEX_STRUCT:
1259 case TMPL_TYPE_NULL:
1264 * If the attribute flag is set, the template must be an
1265 * attribute reference.
1267 if (attribute && (vpt->type != TMPL_TYPE_ATTR)) {
1268 cf_log_err(&(cs->item), "Configuration item '%s' must be an attr "
1269 "but is an %s", name, fr_int2str(tmpl_names, vpt->type, "<INVALID>"));
1275 * If the xlat flag is set, the template must be an xlat
1277 if (xlat && (vpt->type != TMPL_TYPE_XLAT_STRUCT)) {
1278 cf_log_err(&(cs->item), "Configuration item '%s' must be an xlat expansion but is an %s",
1279 name, fr_int2str(tmpl_names, vpt->type, "<INVALID>"));
1285 * If we have a type, and the template is an attribute reference
1286 * check that the attribute reference matches the type.
1288 if ((type > 0) && (vpt->type == TMPL_TYPE_ATTR) && (vpt->tmpl_da->type != type)) {
1289 cf_log_err(&(cs->item), "Configuration item '%s' attr must be an %s, but is an %s",
1290 name, fr_int2str(dict_attr_types, type, "<INVALID>"),
1291 fr_int2str(dict_attr_types, vpt->tmpl_da->type, "<INVALID>"));
1295 *(vp_tmpl_t **)data = vpt;
1301 case PW_TYPE_BOOLEAN:
1303 * Allow yes/no and on/off
1305 if ((strcasecmp(value, "yes") == 0) ||
1306 (strcasecmp(value, "on") == 0)) {
1307 *(bool *)data = true;
1308 } else if ((strcasecmp(value, "no") == 0) ||
1309 (strcasecmp(value, "off") == 0)) {
1310 *(bool *)data = false;
1312 *(bool *)data = false;
1313 cf_log_err(&(cs->item), "Invalid value \"%s\" for boolean "
1314 "variable %s", value, name);
1317 cf_log_info(cs, "%.*s\t%s = %s",
1318 cs->depth, parse_spaces, name, value);
1321 case PW_TYPE_INTEGER:
1323 unsigned long v = strtoul(value, 0, 0);
1326 * Restrict integer values to 0-INT32_MAX, this means
1327 * it will always be safe to cast them to a signed type
1328 * for comparisons, and imposes the same range limit as
1329 * before we switched to using an unsigned type to
1330 * represent config item integers.
1332 if (v > INT32_MAX) {
1333 cf_log_err(&(cs->item), "Invalid value \"%s\" for variable %s, must be between 0-%u", value,
1338 *(uint32_t *)data = v;
1339 cf_log_info(cs, "%.*s\t%s = %u", cs->depth, parse_spaces, name, *(uint32_t *)data);
1345 unsigned long v = strtoul(value, 0, 0);
1347 if (v > UINT16_MAX) {
1348 cf_log_err(&(cs->item), "Invalid value \"%s\" for variable %s, must be between 0-%u", value,
1352 *(uint16_t *)data = (uint16_t) v;
1353 cf_log_info(cs, "%.*s\t%s = %u", cs->depth, parse_spaces, name, *(uint16_t *)data);
1357 case PW_TYPE_INTEGER64:
1358 *(uint64_t *)data = strtoull(value, 0, 0);
1359 cf_log_info(cs, "%.*s\t%s = %" PRIu64, cs->depth, parse_spaces, name, *(uint64_t *)data);
1362 case PW_TYPE_SIGNED:
1363 *(int32_t *)data = strtol(value, 0, 0);
1364 cf_log_info(cs, "%.*s\t%s = %d", cs->depth, parse_spaces, name, *(int32_t *)data);
1367 case PW_TYPE_STRING:
1374 * Expand variables which haven't already been
1375 * expanded automagically when the configuration
1378 if (value == dflt) {
1381 lineno = cs->item.lineno;
1383 value = cf_expand_variables("<internal>",
1385 cs, buffer, sizeof(buffer),
1388 cf_log_err(&(cs->item),"Failed expanding variable %s", name);
1393 if (required && !value) goto is_required;
1394 if (cant_be_empty && (value[0] == '\0')) goto cant_be_empty;
1397 if (!dict_attrbyname(value)) {
1399 cf_log_err(&(cs->item), "No such attribute '%s' for configuration '%s'",
1402 cf_log_err(&(cp->item), "No such attribute '%s'", value);
1409 * Hide secrets when using "radiusd -X".
1411 if (secret && (debug_flag <= 2)) {
1412 cf_log_info(cs, "%.*s\t%s = <<< secret >>>",
1413 cs->depth, parse_spaces, name);
1415 cf_log_info(cs, "%.*s\t%s = \"%s\"",
1416 cs->depth, parse_spaces, name, value ? value : "(null)");
1418 *q = value ? talloc_typed_strdup(cs, value) : NULL;
1421 * If there's data AND it's an input file, check
1422 * that we can read it. This check allows errors
1423 * to be caught as early as possible, during
1426 if (*q && file_input) {
1429 if (stat(*q, &buf) < 0) {
1430 char user[255], group[255];
1432 ERROR("Unable to open file \"%s\": %s", value, fr_syserror(errno));
1433 ERROR("Our effective user and group was %s:%s",
1434 (rad_prints_uid(NULL, user, sizeof(user), geteuid()) < 0) ?
1436 (rad_prints_gid(NULL, group, sizeof(group), getegid()) < 0) ?
1437 "unknown" : group );
1444 case PW_TYPE_IPV4_ADDR:
1445 case PW_TYPE_IPV4_PREFIX:
1448 if (fr_pton4(ipaddr, value, -1, true, false) < 0) {
1449 ERROR("%s", fr_strerror());
1452 if (fr_item_validate_ipaddr(cs, name, type, value, ipaddr) < 0) return -1;
1455 case PW_TYPE_IPV6_ADDR:
1456 case PW_TYPE_IPV6_PREFIX:
1459 if (fr_pton6(ipaddr, value, -1, true, false) < 0) {
1460 ERROR("%s", fr_strerror());
1463 if (fr_item_validate_ipaddr(cs, name, type, value, ipaddr) < 0) return -1;
1466 case PW_TYPE_COMBO_IP_ADDR:
1467 case PW_TYPE_COMBO_IP_PREFIX:
1470 if (fr_pton(ipaddr, value, -1, true) < 0) {
1471 ERROR("%s", fr_strerror());
1474 if (fr_item_validate_ipaddr(cs, name, type, value, ipaddr) < 0) return -1;
1477 case PW_TYPE_TIMEVAL: {
1482 sec = strtoul(value, &end, 10);
1488 len = strlen(end + 1);
1491 ERROR("Too much precision for timeval");
1496 * If they write "0.1", that means
1497 * "10000" microseconds.
1499 sec = strtoul(end + 1, NULL, 10);
1507 cf_log_info(cs, "%.*s\t%s = %d.%06d",
1508 cs->depth, parse_spaces, name, (int) tv.tv_sec, (int) tv.tv_usec);
1509 memcpy(data, &tv, sizeof(tv));
1515 * If we get here, it's a sanity check error.
1516 * It's not an error parsing the configuration
1519 rad_assert(type > PW_TYPE_INVALID);
1520 rad_assert(type < PW_TYPE_MAX);
1522 ERROR("type '%s' is not supported in the configuration files",
1523 fr_int2str(dict_attr_types, type, "?Unknown?"));
1525 } /* switch over variable type */
1530 cpn = cf_pair_alloc(cs, name, value, T_OP_SET, T_BARE_WORD, T_BARE_WORD);
1531 if (!cpn) return -1;
1532 cpn->item.filename = "<internal>";
1533 cpn->item.lineno = 0;
1534 cf_item_add(cs, &(cpn->item));
1542 * A copy of cf_section_parse that initializes pointers before
1545 static void cf_section_parse_init(CONF_SECTION *cs, void *base,
1546 CONF_PARSER const *variables)
1550 for (i = 0; variables[i].name != NULL; i++) {
1551 if (variables[i].type == PW_TYPE_SUBSECTION) {
1552 CONF_SECTION *subcs;
1554 if (!variables[i].dflt) continue;
1556 subcs = cf_section_sub_find(cs, variables[i].name);
1559 * If there's no subsection in the
1560 * config, BUT the CONF_PARSER wants one,
1561 * then create an empty one. This is so
1562 * that we can track the strings,
1563 * etc. allocated in the subsection.
1566 subcs = cf_section_alloc(cs, variables[i].name, NULL);
1569 subcs->item.filename = cs->item.filename;
1570 subcs->item.lineno = cs->item.lineno;
1571 cf_item_add(cs, &(subcs->item));
1574 cf_section_parse_init(subcs, (uint8_t *)base + variables[i].offset,
1575 (CONF_PARSER const *) variables[i].dflt);
1579 if ((variables[i].type != PW_TYPE_STRING) &&
1580 (variables[i].type != PW_TYPE_FILE_INPUT) &&
1581 (variables[i].type != PW_TYPE_FILE_OUTPUT)) {
1585 if (variables[i].data) {
1586 *(char **) variables[i].data = NULL;
1588 *(char **) (((char *)base) + variables[i].offset) = NULL;
1592 } /* for all variables in the configuration section */
1597 * Parse a configuration section into user-supplied variables.
1599 int cf_section_parse(CONF_SECTION *cs, void *base,
1600 CONF_PARSER const *variables)
1606 cs->variables = variables; /* this doesn't hurt anything */
1609 cf_log_info(cs, "%.*s%s {", cs->depth, parse_spaces,
1612 cf_log_info(cs, "%.*s%s %s {", cs->depth, parse_spaces,
1613 cs->name1, cs->name2);
1616 cf_section_parse_init(cs, base, variables);
1619 * Handle the known configuration parameters.
1621 for (i = 0; variables[i].name != NULL; i++) {
1623 * Handle subsections specially
1625 if (variables[i].type == PW_TYPE_SUBSECTION) {
1626 CONF_SECTION *subcs;
1628 subcs = cf_section_sub_find(cs, variables[i].name);
1630 * Default in this case is overloaded to mean a pointer
1631 * to the CONF_PARSER struct for the subsection.
1633 if (!variables[i].dflt || !subcs) {
1634 ERROR("Internal sanity check 1 failed in cf_section_parse %s", variables[i].name);
1638 if (cf_section_parse(subcs, (uint8_t *)base + variables[i].offset,
1639 (CONF_PARSER const *) variables[i].dflt) < 0) goto error;
1641 } /* else it's a CONF_PAIR */
1643 if (variables[i].data) {
1644 data = variables[i].data; /* prefer this. */
1646 data = ((char *)base) + variables[i].offset;
1648 DEBUG2("Internal sanity check 2 failed in cf_section_parse");
1653 * Parse the pair we found, or a default value.
1655 ret = cf_item_parse(cs, variables[i].name, variables[i].type, data, variables[i].dflt);
1658 * Be nice, and print the name of the new config item.
1660 if ((ret == -2) && (variables[i + 1].offset == variables[i].offset) &&
1661 (variables[i + 1].data == variables[i].data)) {
1662 cf_log_err(&(cs->item), "Replace \"%s\" with \"%s\"", variables[i].name,
1663 variables[i + 1].name);
1668 } /* for all variables in the configuration section */
1670 cf_log_info(cs, "%.*s}", cs->depth, parse_spaces);
1677 cf_log_info(cs, "%.*s}", cs->depth, parse_spaces);
1683 * Check XLAT things in pass 2. But don't cache the xlat stuff anywhere.
1685 int cf_section_parse_pass2(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
1694 * Handle the known configuration parameters.
1696 for (i = 0; variables[i].name != NULL; i++) {
1700 * Handle subsections specially
1702 if (variables[i].type == PW_TYPE_SUBSECTION) {
1703 CONF_SECTION *subcs;
1704 subcs = cf_section_sub_find(cs, variables[i].name);
1706 if (cf_section_parse_pass2(subcs, (uint8_t *)base + variables[i].offset,
1707 (CONF_PARSER const *) variables[i].dflt) < 0) {
1711 } /* else it's a CONF_PAIR */
1713 cp = cf_pair_find(cs, variables[i].name);
1716 if (!cp || !cp->value) continue;
1718 if ((cp->rhs_type != T_DOUBLE_QUOTED_STRING) &&
1719 (cp->rhs_type != T_BARE_WORD)) continue;
1722 * Non-xlat expansions shouldn't have xlat!
1724 if (((variables[i].type & PW_TYPE_XLAT) == 0) &&
1725 ((variables[i].type & PW_TYPE_TMPL) == 0)) {
1727 * Ignore %{... in shared secrets.
1728 * They're never dynamically expanded.
1730 if ((variables[i].type & PW_TYPE_SECRET) != 0) continue;
1732 if (strstr(cp->value, "%{") != NULL) {
1733 WARN("%s[%d]: Found dynamic expansion in string which will not be dynamically expanded",
1734 cp->item.filename ? cp->item.filename : "unknown",
1735 cp->item.lineno ? cp->item.lineno : 0);
1741 * xlat expansions should be parseable.
1743 value = talloc_strdup(cs, cp->value); /* modified by xlat_tokenize */
1746 slen = xlat_tokenize(cs, value, &xlat, &error);
1748 char *spaces, *text;
1750 fr_canonicalize_error(cs, &spaces, &text, slen, cp->value);
1752 cf_log_err(&cp->item, "Failed parsing expanded string:");
1753 cf_log_err(&cp->item, "%s", text);
1754 cf_log_err(&cp->item, "%s^ %s", spaces, error);
1756 talloc_free(spaces);
1767 * If the "multi" flag is set, check all of them.
1769 if ((variables[i].type & PW_TYPE_MULTI) != 0) {
1770 cp = cf_pair_find_next(cs, cp, cp->attr);
1773 } /* for all variables in the configuration section */
1779 * Merge the template so everyting else "just works".
1781 static bool cf_template_merge(CONF_SECTION *cs, CONF_SECTION const *template)
1785 if (!cs || !template) return true;
1787 cs->template = NULL;
1790 * Walk over the template, adding its' entries to the
1791 * current section. But only if the entries don't
1792 * already exist in the current section.
1794 for (ci = template->children; ci; ci = ci->next) {
1795 if (ci->type == CONF_ITEM_PAIR) {
1796 CONF_PAIR *cp1, *cp2;
1799 * It exists, don't over-write it.
1801 cp1 = cf_item_to_pair(ci);
1802 if (cf_pair_find(cs, cp1->attr)) {
1807 * Create a new pair with all of the data
1810 cp2 = cf_pair_dup(cs, cp1);
1811 if (!cp2) return false;
1813 cp2->item.filename = cp1->item.filename;
1814 cp2->item.lineno = cp1->item.lineno;
1816 cf_item_add(cs, &(cp2->item));
1820 if (ci->type == CONF_ITEM_SECTION) {
1821 CONF_SECTION *subcs1, *subcs2;
1823 subcs1 = cf_item_to_section(ci);
1824 rad_assert(subcs1 != NULL);
1826 subcs2 = cf_section_sub_find_name2(cs, subcs1->name1, subcs1->name2);
1829 * sub-sections get merged.
1831 if (!cf_template_merge(subcs2, subcs1)) {
1838 * Our section doesn't have a matching
1839 * sub-section. Copy it verbatim from
1842 subcs2 = cf_section_dup(cs, subcs1,
1843 cf_section_name1(subcs1), cf_section_name2(subcs1),
1845 if (!subcs2) return false;
1847 subcs2->item.filename = subcs1->item.filename;
1848 subcs2->item.lineno = subcs1->item.lineno;
1850 cf_item_add(cs, &(subcs2->item));
1854 /* ignore everything else */
1860 static char const *cf_local_file(char const *base, char const *filename,
1861 char *buffer, size_t bufsize)
1866 strlcpy(buffer, base, bufsize);
1868 p = strrchr(buffer, FR_DIR_SEP);
1869 if (!p) return filename;
1870 if (p[1]) { /* ./foo */
1874 dirsize = (p - buffer) + 1;
1876 if ((dirsize + strlen(filename)) >= bufsize) {
1880 strlcpy(p + 1, filename, bufsize - dirsize);
1887 * Read a part of the config file.
1889 static int cf_section_read(char const *filename, int *lineno, FILE *fp,
1890 CONF_SECTION *current)
1893 CONF_SECTION *this, *css, *nextcs;
1902 FR_TOKEN t1 = T_INVALID, t2, t3;
1903 bool has_spaces = false;
1907 fr_cond_t *cond = NULL;
1909 this = current; /* add items here */
1912 * Read, checking for line continuations ('\\' at EOL)
1919 * Get data, and remember if we are at EOF.
1921 at_eof = (fgets(cbuf, sizeof(buf) - (cbuf - buf), fp) == NULL);
1925 * We read the entire 8k worth of data: complain.
1926 * Note that we don't care if the last character
1927 * is \n: it's still forbidden. This means that
1928 * the maximum allowed length of text is 8k-1, which
1932 if ((cbuf + len + 1) >= (buf + sizeof(buf))) {
1933 ERROR("%s[%d]: Line too long",
1940 while (isspace((int) *ptr)) ptr++;
1943 memmove(cbuf, ptr, len - (ptr - cbuf));
1944 len -= (ptr - cbuf);
1949 * Not doing continuations: check for edge
1956 while (*ptr && isspace((int) *ptr)) ptr++;
1958 if (!*ptr || (*ptr == '#')) continue;
1960 } else if (at_eof || (len == 0)) {
1961 ERROR("%s[%d]: Continuation at EOF is illegal",
1967 * See if there's a continuation.
1970 ((cbuf[len - 1] == '\n') || (cbuf[len - 1] == '\r'))) {
1975 if ((len > 0) && (cbuf[len - 1] == '\\')) {
1977 * Check for "suppress spaces" magic.
1979 if (!has_spaces && (len > 2) && (cbuf[len - 2] == '"')) {
1983 cbuf[len - 1] = '\0';
1995 * The parser is getting to be evil.
1997 while ((*ptr == ' ') || (*ptr == '\t')) ptr++;
1999 if (((ptr[0] == '%') && (ptr[1] == '{')) ||
2003 if (ptr[0] == '%') {
2004 hack = rad_copy_variable(buf1, ptr);
2006 hack = rad_copy_string(buf1, ptr);
2009 ERROR("%s[%d]: Invalid expansion: %s",
2010 filename, *lineno, ptr);
2016 t2 = gettoken(&ptr, buf2, sizeof(buf2), true);
2023 ERROR("%s[%d]: Invalid expansion: %s",
2024 filename, *lineno, ptr);
2028 t1 = gettoken(&ptr, buf1, sizeof(buf1), true);
2032 * The caller eats "name1 name2 {", and calls us
2033 * for the data inside of the section. So if we
2034 * receive a closing brace, then it must mean the
2035 * end of the section.
2037 if (t1 == T_RCBRACE) {
2038 if (this == current) {
2039 ERROR("%s[%d]: Too many closing braces",
2045 * Merge the template into the existing
2046 * section. This uses more memory, but
2047 * means that templates now work with
2048 * sub-sections, etc.
2050 if (!cf_template_merge(this, this->template)) {
2054 this = this->item.parent;
2055 goto check_for_more;
2059 * Allow for $INCLUDE files
2061 * This *SHOULD* work for any level include.
2062 * I really really really hate this file. -cparker
2064 if ((strcasecmp(buf1, "$INCLUDE") == 0) ||
2065 (strcasecmp(buf1, "$-INCLUDE") == 0)) {
2066 bool relative = true;
2068 t2 = getword(&ptr, buf2, sizeof(buf2), true);
2070 ERROR("%s[%d]: Unexpected text after $INCLUDE",
2075 if (buf2[0] == '$') relative = false;
2077 value = cf_expand_variables(filename, lineno, this, buf4, sizeof(buf4), buf2, NULL);
2078 if (!value) return -1;
2080 if (!FR_DIR_IS_RELATIVE(value)) relative = false;
2083 value = cf_local_file(filename, value, buf3,
2086 ERROR("%s[%d]: Directories too deep.",
2093 #ifdef HAVE_DIRENT_H
2097 * Include ALL non-"dot" files in the directory.
2100 if (value[strlen(value) - 1] == '/') {
2103 struct stat stat_buf;
2105 DEBUG2("including files in directory %s", value );
2110 if (stat(value, &stat_buf) < 0) {
2111 ERROR("%s[%d]: Failed reading directory %s: %s",
2113 value, fr_syserror(errno));
2117 if ((stat_buf.st_mode & S_IWOTH) != 0) {
2118 ERROR("%s[%d]: Directory %s is globally writable. Refusing to start due to "
2119 "insecure configuration", filename, *lineno, value);
2123 dir = opendir(value);
2125 ERROR("%s[%d]: Error reading directory %s: %s",
2126 filename, *lineno, value,
2127 fr_syserror(errno));
2132 * Read the directory, ignoring "." files.
2134 while ((dp = readdir(dir)) != NULL) {
2137 if (dp->d_name[0] == '.') continue;
2140 * Check for valid characters
2142 for (p = dp->d_name; *p != '\0'; p++) {
2143 if (isalpha((int)*p) ||
2147 (*p == '.')) continue;
2150 if (*p != '\0') continue;
2152 snprintf(buf2, sizeof(buf2), "%s%s",
2154 if ((stat(buf2, &stat_buf) != 0) ||
2155 S_ISDIR(stat_buf.st_mode)) continue;
2157 * Read the file into the current
2158 * configuration section.
2160 if (cf_file_include(this, buf2) < 0) {
2168 { /* it was a normal file */
2169 if (buf1[1] == '-') {
2170 struct stat statbuf;
2172 if (stat(value, &statbuf) < 0) {
2173 WARN("Not including file %s: %s", value, fr_syserror(errno));
2178 if (cf_file_include(this, value) < 0) {
2183 } /* we were in an include */
2185 if (strcasecmp(buf1, "$template") == 0) {
2187 CONF_SECTION *parentcs, *templatecs;
2188 t2 = getword(&ptr, buf2, sizeof(buf2), true);
2191 ERROR("%s[%d]: Unexpected text after $TEMPLATE", filename, *lineno);
2195 parentcs = cf_top_section(current);
2197 templatecs = cf_section_sub_find(parentcs, "templates");
2199 ERROR("%s[%d]: No \"templates\" section for reference \"%s\"", filename, *lineno, buf2);
2203 ci = cf_reference_item(parentcs, templatecs, buf2);
2204 if (!ci || (ci->type != CONF_ITEM_SECTION)) {
2205 ERROR("%s[%d]: Reference \"%s\" not found", filename, *lineno, buf2);
2210 ERROR("%s[%d]: Internal sanity check error in template reference", filename, *lineno);
2214 if (this->template) {
2215 ERROR("%s[%d]: Section already has a template", filename, *lineno);
2219 this->template = cf_item_to_section(ci);
2224 * Ensure that the user can't add CONF_PAIRs
2225 * with 'internal' names;
2227 if (buf1[0] == '_') {
2228 ERROR("%s[%d]: Illegal configuration pair name \"%s\"", filename, *lineno, buf1);
2233 * Handle if/elsif specially.
2235 if ((strcmp(buf1, "if") == 0) || (strcmp(buf1, "elsif") == 0)) {
2237 char const *error = NULL;
2239 CONF_SECTION *server;
2242 * if / elsif MUST be inside of a
2243 * processing section, which MUST in turn
2244 * be inside of a "server" directive.
2246 if (!this->item.parent) {
2248 ERROR("%s[%d]: Invalid location for '%s'",
2249 filename, *lineno, buf1);
2254 * Skip (...) to find the {
2256 slen = fr_condition_tokenize(nextcs, cf_section_to_item(nextcs), ptr, &cond,
2257 &error, FR_COND_TWO_PASS);
2258 memcpy(&p, &ptr, sizeof(p));
2261 if (p[-slen] != '{') goto cond_error;
2267 * This hack is so that the NEXT stage
2268 * doesn't go "too far" in expanding the
2269 * variable. We can parse the conditions
2270 * without expanding the ${...} stuff.
2271 * BUT we don't want to expand all of the
2272 * stuff AFTER the condition. So we do
2275 * The first pass is to discover the end
2276 * of the condition. We then expand THAT
2277 * string, and do a second pass parsing
2278 * the expanded condition.
2284 * If there's a ${...}. If so, expand it.
2286 if (strchr(ptr, '$') != NULL) {
2287 ptr = cf_expand_variables(filename, lineno,
2292 ERROR("%s[%d]: Parse error expanding ${...} in condition",
2296 } /* else leave it alone */
2298 server = this->item.parent;
2299 while ((strcmp(server->name1, "server") != 0) &&
2300 (strcmp(server->name1, "policy") != 0) &&
2301 (strcmp(server->name1, "instantiate") != 0)) {
2302 server = server->item.parent;
2303 if (!server) goto invalid_location;
2306 nextcs = cf_section_alloc(this, buf1, ptr);
2308 ERROR("%s[%d]: Failed allocating memory for section",
2312 nextcs->item.filename = talloc_strdup(nextcs, filename);
2313 nextcs->item.lineno = *lineno;
2315 slen = fr_condition_tokenize(nextcs, cf_section_to_item(nextcs), ptr, &cond,
2316 &error, FR_COND_TWO_PASS);
2317 *p = '{'; /* put it back */
2321 char *spaces, *text;
2323 fr_canonicalize_error(nextcs, &spaces, &text, slen, ptr);
2325 ERROR("%s[%d]: Parse error in condition",
2327 ERROR("%s[%d]: %s", filename, *lineno, text);
2328 ERROR("%s[%d]: %s^ %s", filename, *lineno, spaces, error);
2330 talloc_free(spaces);
2332 talloc_free(nextcs);
2336 if ((size_t) slen >= (sizeof(buf2) - 1)) {
2337 talloc_free(nextcs);
2338 ERROR("%s[%d]: Condition is too large after \"%s\"",
2339 filename, *lineno, buf1);
2344 * Copy the expanded and parsed condition
2345 * into buf2. Then, parse the text after
2346 * the condition, which now MUST be a '{.
2348 * If it wasn't '{' it would have been
2349 * caught in the first pass of
2350 * conditional parsing, above.
2352 memcpy(buf2, ptr, slen);
2357 if ((t3 = gettoken(&ptr, buf3, sizeof(buf3), true)) != T_LCBRACE) {
2358 talloc_free(nextcs);
2359 ERROR("%s[%d]: Expected '{' %d",
2360 filename, *lineno, t3);
2365 * Swap the condition with trailing stuff for
2366 * the final condition.
2368 memcpy(&p, &nextcs->name2, sizeof(nextcs->name2));
2370 nextcs->name2 = talloc_typed_strdup(nextcs, buf2);
2376 * Grab the next token.
2378 t2 = gettoken(&ptr, buf2, sizeof(buf2), !cf_new_escape);
2395 case T_OP_CMP_FALSE:
2396 if (!this || (strcmp(this->name1, "update") != 0)) {
2397 ERROR("%s[%d]: Invalid operator in assignment",
2405 while (isspace((int) *ptr)) ptr++;
2408 * New parser: non-quoted strings are
2409 * bare words, and we parse everything
2410 * until the next newline, or the next
2411 * comma. If they have { or } in a bare
2412 * word, well... too bad.
2414 if (cf_new_escape && (*ptr != '"') && (*ptr != '\'')
2415 && (*ptr != '`') && (*ptr != '/')) {
2416 const char *q = ptr;
2419 while (*q && (*q >= ' ') && (*q != ',') &&
2422 if ((size_t) (q - ptr) >= sizeof(buf3)) {
2423 ERROR("%s[%d]: Parse error: value too long",
2428 memcpy(buf3, ptr, (q - ptr));
2429 buf3[q - ptr] = '\0';
2433 t3 = getstring(&ptr, buf3, sizeof(buf3), !cf_new_escape);
2436 if (t3 == T_INVALID) {
2437 ERROR("%s[%d]: Parse error: %s",
2444 * Allow "foo" by itself, or "foo = bar"
2450 case T_DOUBLE_QUOTED_STRING:
2451 case T_BACK_QUOTED_STRING:
2452 value = cf_expand_variables(filename, lineno, this, buf4, sizeof(buf4), buf3, &soft_fail);
2454 if (!soft_fail) return -1;
2457 * References an item which doesn't exist,
2458 * or which is already marked up as being
2459 * expanded in pass2. Wait for pass2 to
2460 * do the expansions.
2478 * Add this CONF_PAIR to our CONF_SECTION
2481 cpn = cf_pair_alloc(this, buf1, value, t2, t1, t3);
2482 if (!cpn) return -1;
2483 cpn->item.filename = talloc_strdup(cpn, filename);
2484 cpn->item.lineno = *lineno;
2486 cf_item_add(this, &(cpn->item));
2489 * Hacks for escaping
2491 if (!cf_new_escape && !this->item.parent && value &&
2492 (strcmp(buf1, "correct_escapes") == 0) &&
2493 ((strcmp(value, "true") == 0) ||
2494 (strcmp(value, "yes") == 0) ||
2495 (strcmp(value, "1") == 0))) {
2496 cf_new_escape = true;
2500 * Require a comma, unless there's a comment.
2502 while (isspace(*ptr)) ptr++;
2511 * foo = bar # other stuff
2513 if ((t3 == T_HASH) || (t3 == T_COMMA) || (t3 == T_EOL) || (*ptr == '#')) continue;
2515 if (!*ptr || (*ptr == '}')) break;
2517 ERROR("%s[%d]: Syntax error: Expected comma after '%s': %s",
2518 filename, *lineno, value, ptr);
2522 * No '=', must be a section or sub-section.
2525 case T_DOUBLE_QUOTED_STRING:
2526 case T_SINGLE_QUOTED_STRING:
2527 t3 = gettoken(&ptr, buf3, sizeof(buf3), true);
2528 if (t3 != T_LCBRACE) {
2529 ERROR("%s[%d]: Expecting section start brace '{' after \"%s %s\"",
2530 filename, *lineno, buf1, buf2);
2538 css = cf_section_alloc(this, buf1,
2539 t2 == T_LCBRACE ? NULL : buf2);
2541 ERROR("%s[%d]: Failed allocating memory for section",
2546 css->item.filename = talloc_strdup(css, filename);
2547 css->item.lineno = *lineno;
2548 cf_item_add(this, &(css->item));
2554 cf_item_add(this, &(css->item));
2555 cf_data_add_internal(css, "if", cond, NULL, false);
2556 cond = NULL; /* eaten by the above line */
2560 * There may not be a name2
2562 css->name2_type = (t2 == T_LCBRACE) ? T_INVALID : t2;
2565 * The current section is now the child section.
2571 ERROR("%s[%d]: Syntax error in '%s': %s", filename, *lineno, ptr, fr_strerror());
2576 ERROR("%s[%d]: Parse error after \"%s\": unexpected token \"%s\"",
2577 filename, *lineno, buf1, fr_int2str(fr_tokens, t2, "<INVALID>"));
2584 * Done parsing one thing. Skip to EOL if possible.
2586 while (isspace(*ptr)) ptr++;
2588 if (*ptr == '#') continue;
2597 * See if EOF was unexpected ..
2599 if (feof(fp) && (this != current)) {
2600 ERROR("%s[%d]: EOF reached without closing brace for section %s starting at line %d",
2601 filename, *lineno, cf_section_name1(this), cf_section_lineno(this));
2609 * Include one config file in another.
2611 int cf_file_include(CONF_SECTION *cs, char const *filename)
2615 struct stat statbuf;
2619 DEBUG2("including configuration file %s", filename);
2621 fp = fopen(filename, "r");
2623 ERROR("Unable to open file \"%s\": %s",
2624 filename, fr_syserror(errno));
2628 if (stat(filename, &statbuf) == 0) {
2630 if ((statbuf.st_mode & S_IWOTH) != 0) {
2632 ERROR("Configuration file %s is globally writable. "
2633 "Refusing to start due to insecure configuration.", filename);
2638 #if 0 && defined(S_IROTH)
2639 if (statbuf.st_mode & S_IROTH) != 0) {
2641 ERROR("Configuration file %s is globally readable. "
2642 "Refusing to start due to insecure configuration", filename);
2648 if (cf_data_find_internal(cs, filename, PW_TYPE_FILE_INPUT)) {
2650 ERROR("Cannot include the same file twice: \"%s\"", filename);
2656 * Add the filename to the section
2658 mtime = talloc(cs, time_t);
2659 *mtime = statbuf.st_mtime;
2661 if (cf_data_add_internal(cs, filename, mtime, NULL, PW_TYPE_FILE_INPUT) < 0) {
2663 ERROR("Internal error opening file \"%s\"",
2668 cd = cf_data_find_internal(cs, filename, PW_TYPE_FILE_INPUT);
2671 ERROR("Internal error opening file \"%s\"",
2676 if (!cs->item.filename) cs->item.filename = talloc_strdup(cs, filename);
2679 * Read the section. It's OK to have EOF without a
2680 * matching close brace.
2682 if (cf_section_read(cd->name, &lineno, fp, cs) < 0) {
2693 * Do variable expansion in pass2.
2695 * This is a breadth-first expansion. "deep
2697 static int cf_section_pass2(CONF_SECTION *cs)
2701 for (ci = cs->children; ci; ci = ci->next) {
2706 if (ci->type != CONF_ITEM_PAIR) continue;
2708 cp = cf_item_to_pair(ci);
2709 if (!cp->value || !cp->pass2) continue;
2711 rad_assert((cp->rhs_type == T_BARE_WORD) ||
2712 (cp->rhs_type == T_DOUBLE_QUOTED_STRING) ||
2713 (cp->rhs_type == T_BACK_QUOTED_STRING));
2715 value = cf_expand_variables(ci->filename, &ci->lineno, cs, buffer, sizeof(buffer), cp->value, NULL);
2716 if (!value) return -1;
2718 rad_const_free(cp->value);
2719 cp->value = talloc_typed_strdup(cp, value);
2722 for (ci = cs->children; ci; ci = ci->next) {
2723 if (ci->type != CONF_ITEM_SECTION) continue;
2725 if (cf_section_pass2(cf_item_to_section(ci)) < 0) return -1;
2733 * Bootstrap a config file.
2735 int cf_file_read(CONF_SECTION *cs, char const *filename)
2740 cp = cf_pair_alloc(cs, "confdir", filename, T_OP_SET, T_BARE_WORD, T_SINGLE_QUOTED_STRING);
2743 p = strrchr(cp->value, FR_DIR_SEP);
2746 cp->item.filename = "internal";
2747 cp->item.lineno = -1;
2748 cf_item_add(cs, &(cp->item));
2750 if (cf_file_include(cs, filename) < 0) return -1;
2753 * Now that we've read the file, go back through it and
2754 * expand the variables.
2756 if (cf_section_pass2(cs) < 0) {
2765 void cf_file_free(CONF_SECTION *cs)
2772 * Return a CONF_PAIR within a CONF_SECTION.
2774 CONF_PAIR *cf_pair_find(CONF_SECTION const *cs, char const *name)
2776 CONF_PAIR *cp, mycp;
2778 if (!cs || !name) return NULL;
2781 cp = rbtree_finddata(cs->pair_tree, &mycp);
2784 if (!cs->template) return NULL;
2786 return rbtree_finddata(cs->template->pair_tree, &mycp);
2790 * Return the attr of a CONF_PAIR
2793 char const *cf_pair_attr(CONF_PAIR const *pair)
2795 return (pair ? pair->attr : NULL);
2799 * Return the value of a CONF_PAIR
2802 char const *cf_pair_value(CONF_PAIR const *pair)
2804 return (pair ? pair->value : NULL);
2807 FR_TOKEN cf_pair_operator(CONF_PAIR const *pair)
2809 return (pair ? pair->op : T_INVALID);
2812 /** Return the value (lhs) type
2814 * @param pair to extract value type from.
2815 * @return one of T_BARE_WORD, T_SINGLE_QUOTED_STRING, T_BACK_QUOTED_STRING
2816 * T_DOUBLE_QUOTED_STRING or T_INVALID if the pair is NULL.
2818 FR_TOKEN cf_pair_attr_type(CONF_PAIR const *pair)
2820 return (pair ? pair->lhs_type : T_INVALID);
2823 /** Return the value (rhs) type
2825 * @param pair to extract value type from.
2826 * @return one of T_BARE_WORD, T_SINGLE_QUOTED_STRING, T_BACK_QUOTED_STRING
2827 * T_DOUBLE_QUOTED_STRING or T_INVALID if the pair is NULL.
2829 FR_TOKEN cf_pair_value_type(CONF_PAIR const *pair)
2831 return (pair ? pair->rhs_type : T_INVALID);
2835 * Turn a CONF_PAIR into a VALUE_PAIR
2836 * For now, ignore the "value_type" field...
2838 VALUE_PAIR *cf_pairtovp(CONF_PAIR *pair)
2841 fr_strerror_printf("Internal error");
2846 fr_strerror_printf("No value given for attribute %s", pair->attr);
2851 * false comparisons never match. BUT if it's a "string"
2852 * or `string`, then remember to expand it later.
2854 if ((pair->op != T_OP_CMP_FALSE) &&
2855 ((pair->rhs_type == T_DOUBLE_QUOTED_STRING) ||
2856 (pair->rhs_type == T_BACK_QUOTED_STRING))) {
2859 vp = pairmake(pair, NULL, pair->attr, NULL, pair->op);
2864 if (pairmark_xlat(vp, pair->value) < 0) {
2873 return pairmake(pair, NULL, pair->attr, pair->value, pair->op);
2877 * Return the first label of a CONF_SECTION
2880 char const *cf_section_name1(CONF_SECTION const *cs)
2882 return (cs ? cs->name1 : NULL);
2886 * Return the second label of a CONF_SECTION
2889 char const *cf_section_name2(CONF_SECTION const *cs)
2891 return (cs ? cs->name2 : NULL);
2894 /** Return name2 if set, else name1
2897 char const *cf_section_name(CONF_SECTION const *cs)
2901 name = cf_section_name2(cs);
2902 if (name) return name;
2904 return cf_section_name1(cs);
2908 * Find a value in a CONF_SECTION
2910 char const *cf_section_value_find(CONF_SECTION const *cs, char const *attr)
2914 cp = cf_pair_find(cs, attr);
2916 return (cp ? cp->value : NULL);
2920 CONF_SECTION *cf_section_find_name2(CONF_SECTION const *cs,
2921 char const *name1, char const *name2)
2924 CONF_ITEM const *ci;
2926 if (!cs || !name1) return NULL;
2928 for (ci = &(cs->item); ci; ci = ci->next) {
2929 if (ci->type != CONF_ITEM_SECTION)
2932 if (strcmp(cf_item_to_section(ci)->name1, name1) != 0) {
2936 their2 = cf_item_to_section(ci)->name2;
2938 if ((!name2 && !their2) ||
2939 (name2 && their2 && (strcmp(name2, their2) == 0))) {
2940 return cf_item_to_section(ci);
2947 /** Find a pair with a name matching attr, after specified pair.
2949 * @param cs to search in.
2950 * @param pair to search from (may be NULL).
2951 * @param attr to find (may be NULL in which case any attribute matches).
2952 * @return the next matching CONF_PAIR or NULL if none matched.
2954 CONF_PAIR *cf_pair_find_next(CONF_SECTION const *cs,
2955 CONF_PAIR const *pair, char const *attr)
2959 if (!cs) return NULL;
2962 * If pair is NULL and we're trying to find a specific
2963 * attribute this must be a first time run.
2965 * Find the pair with correct name.
2967 if (!pair && attr) return cf_pair_find(cs, attr);
2970 * Start searching from the next child, or from the head
2971 * of the list of children (if no pair was provided).
2973 for (ci = pair ? pair->item.next : cs->children;
2976 if (ci->type != CONF_ITEM_PAIR) continue;
2978 if (!attr || strcmp(cf_item_to_pair(ci)->attr, attr) == 0) break;
2981 return cf_item_to_pair(ci);
2985 * Find a CONF_SECTION, or return the root if name is NULL
2988 CONF_SECTION *cf_section_find(char const *name)
2991 return cf_section_sub_find(root_config, name);
2996 /** Find a sub-section in a section
2998 * This finds ANY section having the same first name.
2999 * The second name is ignored.
3001 CONF_SECTION *cf_section_sub_find(CONF_SECTION const *cs, char const *name)
3005 if (!cs || !name) return NULL; /* can't find an un-named section */
3008 * No sub-sections have been defined, so none exist.
3010 if (!cs->section_tree) return NULL;
3014 return rbtree_finddata(cs->section_tree, &mycs);
3018 /** Find a CONF_SECTION with both names.
3021 CONF_SECTION *cf_section_sub_find_name2(CONF_SECTION const *cs,
3022 char const *name1, char const *name2)
3026 if (!cs) cs = root_config;
3027 if (!cs) return NULL;
3030 CONF_SECTION mycs, *master_cs;
3032 if (!cs->section_tree) return NULL;
3037 master_cs = rbtree_finddata(cs->section_tree, &mycs);
3038 if (!master_cs) return NULL;
3041 * Look it up in the name2 tree. If it's there,
3044 if (master_cs->name2_tree) {
3045 CONF_SECTION *subcs;
3047 subcs = rbtree_finddata(master_cs->name2_tree, &mycs);
3048 if (subcs) return subcs;
3052 * We don't insert ourselves into the name2 tree.
3053 * So if there's nothing in the name2 tree, maybe
3054 * *we* are the answer.
3056 if (!master_cs->name2 && name2) return NULL;
3057 if (master_cs->name2 && !name2) return NULL;
3058 if (!master_cs->name2 && !name2) return master_cs;
3060 if (strcmp(master_cs->name2, name2) == 0) {
3068 * Else do it the old-fashioned way.
3070 for (ci = cs->children; ci; ci = ci->next) {
3071 CONF_SECTION *subcs;
3073 if (ci->type != CONF_ITEM_SECTION)
3076 subcs = cf_item_to_section(ci);
3077 if (!subcs->name2) {
3078 if (strcmp(subcs->name1, name2) == 0) break;
3080 if (strcmp(subcs->name2, name2) == 0) break;
3084 return cf_item_to_section(ci);
3088 * Return the next subsection after a CONF_SECTION
3089 * with a certain name1 (char *name1). If the requested
3090 * name1 is NULL, any name1 matches.
3093 CONF_SECTION *cf_subsection_find_next(CONF_SECTION const *section,
3094 CONF_SECTION const *subsection,
3099 if (!section) return NULL;
3102 * If subsection is NULL this must be a first time run
3103 * Find the subsection with correct name
3107 ci = section->children;
3109 ci = subsection->item.next;
3112 for (; ci; ci = ci->next) {
3113 if (ci->type != CONF_ITEM_SECTION)
3115 if ((name1 == NULL) ||
3116 (strcmp(cf_item_to_section(ci)->name1, name1) == 0))
3120 return cf_item_to_section(ci);
3125 * Return the next section after a CONF_SECTION
3126 * with a certain name1 (char *name1). If the requested
3127 * name1 is NULL, any name1 matches.
3130 CONF_SECTION *cf_section_find_next(CONF_SECTION const *section,
3131 CONF_SECTION const *subsection,
3134 if (!section) return NULL;
3136 if (!section->item.parent) return NULL;
3138 return cf_subsection_find_next(section->item.parent, subsection, name1);
3141 /** Return the next item after a CONF_ITEM.
3144 CONF_ITEM *cf_item_find_next(CONF_SECTION const *section, CONF_ITEM const *item)
3146 if (!section) return NULL;
3149 * If item is NULL this must be a first time run
3150 * Return the first item
3153 return section->children;
3159 static void _pair_count(int *count, CONF_SECTION const *cs)
3161 CONF_ITEM const *ci;
3163 for (ci = cf_item_find_next(cs, NULL);
3165 ci = cf_item_find_next(cs, ci)) {
3167 if (cf_item_is_section(ci)) {
3168 _pair_count(count, cf_item_to_section(ci));
3176 /** Count the number of conf pairs beneath a section
3178 * @param[in] cs to search for items in.
3179 * @return number of pairs nested within section.
3181 int cf_pair_count(CONF_SECTION const *cs)
3185 _pair_count(&count, cs);
3190 CONF_SECTION *cf_item_parent(CONF_ITEM const *ci)
3192 if (!ci) return NULL;
3197 int cf_section_lineno(CONF_SECTION const *section)
3199 return section->item.lineno;
3202 char const *cf_pair_filename(CONF_PAIR const *pair)
3204 return pair->item.filename;
3207 char const *cf_section_filename(CONF_SECTION const *section)
3209 return section->item.filename;
3212 int cf_pair_lineno(CONF_PAIR const *pair)
3214 return pair->item.lineno;
3217 bool cf_item_is_section(CONF_ITEM const *item)
3219 return item->type == CONF_ITEM_SECTION;
3222 bool cf_item_is_pair(CONF_ITEM const *item)
3224 return item->type == CONF_ITEM_PAIR;
3228 static CONF_DATA *cf_data_alloc(CONF_SECTION *parent, char const *name,
3229 void *data, void (*data_free)(void *))
3233 cd = talloc_zero(parent, CONF_DATA);
3234 if (!cd) return NULL;
3236 cd->item.type = CONF_ITEM_DATA;
3237 cd->item.parent = parent;
3238 cd->name = talloc_typed_strdup(cd, name);
3245 cd->free = data_free;
3248 talloc_set_destructor(cd, _cf_data_free);
3254 static void *cf_data_find_internal(CONF_SECTION const *cs, char const *name, int flag)
3256 if (!cs || !name) return NULL;
3259 * Find the name in the tree, for speed.
3261 if (cs->data_tree) {
3266 return rbtree_finddata(cs->data_tree, &mycd);
3273 * Find data from a particular section.
3275 void *cf_data_find(CONF_SECTION const *cs, char const *name)
3277 CONF_DATA *cd = cf_data_find_internal(cs, name, 0);
3279 if (cd) return cd->data;
3285 * Add named data to a configuration section.
3287 static int cf_data_add_internal(CONF_SECTION *cs, char const *name,
3288 void *data, void (*data_free)(void *),
3293 if (!cs || !name) return -1;
3296 * Already exists. Can't add it.
3298 if (cf_data_find_internal(cs, name, flag) != NULL) return -1;
3300 cd = cf_data_alloc(cs, name, data, data_free);
3304 cf_item_add(cs, cf_data_to_item(cd));
3310 * Add named data to a configuration section.
3312 int cf_data_add(CONF_SECTION *cs, char const *name,
3313 void *data, void (*data_free)(void *))
3315 return cf_data_add_internal(cs, name, data, data_free, 0);
3318 /** Remove named data from a configuration section
3321 void *cf_data_remove(CONF_SECTION *cs, char const *name)
3327 if (!cs || !name) return NULL;
3328 if (!cs->data_tree) return NULL;
3331 * Find the name in the tree, for speed.
3335 cd = rbtree_finddata(cs->data_tree, &mycd);
3336 if (!cd) return NULL;
3338 talloc_set_destructor(cd, NULL); /* Disarm the destructor */
3339 rbtree_deletebydata(cs->data_tree, &mycd);
3348 * This is here to make the rest of the code easier to read. It
3349 * ties conffile.c to log.c, but it means we don't have to
3350 * pollute every other function with the knowledge of the
3351 * configuration internals.
3353 void cf_log_err(CONF_ITEM const *ci, char const *fmt, ...)
3359 vsnprintf(buffer, sizeof(buffer), fmt, ap);
3364 ci->filename ? ci->filename : "unknown",
3365 ci->lineno ? ci->lineno : 0,
3368 ERROR("<unknown>[*]: %s", buffer);
3372 void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt, ...)
3378 vsnprintf(buffer, sizeof(buffer), fmt, ap);
3381 rad_assert(cs != NULL);
3384 cs->item.filename ? cs->item.filename : "unknown",
3385 cs->item.lineno ? cs->item.lineno : 0,
3389 void cf_log_err_cp(CONF_PAIR const *cp, char const *fmt, ...)
3395 vsnprintf(buffer, sizeof(buffer), fmt, ap);
3398 rad_assert(cp != NULL);
3401 cp->item.filename ? cp->item.filename : "unknown",
3402 cp->item.lineno ? cp->item.lineno : 0,
3406 void cf_log_info(CONF_SECTION const *cs, char const *fmt, ...)
3411 if ((debug_flag > 1) && cs) vradlog(L_DBG, fmt, ap);
3416 * Wrapper to simplify the code.
3418 void cf_log_module(CONF_SECTION const *cs, char const *fmt, ...)
3424 if (debug_flag > 1 && cs) {
3425 vsnprintf(buffer, sizeof(buffer), fmt, ap);
3427 DEBUG("%.*s# %s", cs->depth, parse_spaces, buffer);
3432 const CONF_PARSER *cf_section_parse_table(CONF_SECTION *cs)
3434 if (!cs) return NULL;
3436 return cs->variables;
3440 * For "switch" and "case" statements.
3442 FR_TOKEN cf_section_name2_type(CONF_SECTION const *cs)
3444 if (!cs) return T_INVALID;
3446 return cs->name2_type;