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 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;
67 struct conf_part *parent;
83 struct conf_item *children;
84 struct conf_item *tail; /* for speed */
85 CONF_SECTION *template;
86 rbtree_t *pair_tree; /* and a partridge.. */
87 rbtree_t *section_tree; /* no jokes here */
88 rbtree_t *name2_tree; /* for sections of the same name2 */
92 const CONF_PARSER *variables;
95 CONF_SECTION *root_config = NULL;
98 * Internal data that is associated with a configuration section,
99 * so that we don't have to track it separately.
105 void *data; /* user data */
106 void (*free)(void *); /* free user data function */
109 static int cf_data_add_internal(CONF_SECTION *cs, char const *name,
110 void *data, void (*data_free)(void *),
112 static void *cf_data_find_internal(CONF_SECTION const *cs, char const *name,
114 static char const *cf_expand_variables(char const *cf, int *lineno,
115 CONF_SECTION *outercs,
116 char *output, size_t outsize,
120 * Isolate the scary casts in these tiny provably-safe functions
122 CONF_PAIR *cf_itemtopair(CONF_ITEM const *ci)
129 rad_assert(ci->type == CONF_ITEM_PAIR);
131 memcpy(&out, &ci, sizeof(out));
134 CONF_SECTION *cf_itemtosection(CONF_ITEM const *ci)
141 rad_assert(ci->type == CONF_ITEM_SECTION);
143 memcpy(&out, &ci, sizeof(out));
146 CONF_ITEM *cf_pairtoitem(CONF_PAIR const *cp)
154 memcpy(&out, &cp, sizeof(out));
157 CONF_ITEM *cf_sectiontoitem(CONF_SECTION const *cs)
165 memcpy(&out, &cs, sizeof(out));
169 static CONF_ITEM *cf_datatoitem(CONF_DATA const *cd)
177 memcpy(&out, &cd, sizeof(out));
182 * Create a new CONF_PAIR
184 static CONF_PAIR *cf_pair_alloc(CONF_SECTION *parent, char const *attr,
185 char const *value, FR_TOKEN op,
190 if (!attr) return NULL;
192 cp = talloc_zero(parent, CONF_PAIR);
193 if (!cp) return NULL;
195 cp->item.type = CONF_ITEM_PAIR;
196 cp->item.parent = parent;
197 cp->value_type = value_type;
200 cp->attr = talloc_strdup(cp, attr);
208 cp->value = talloc_strdup(cp, value);
209 if (!cp->value) goto error;
215 static int cf_data_free(void *ctx)
219 cd = talloc_get_type_abort(ctx, CONF_DATA);
230 * rbtree callback function
232 static int pair_cmp(void const *a, void const *b)
234 const CONF_PAIR *one = a;
235 const CONF_PAIR *two = b;
237 return strcmp(one->attr, two->attr);
242 * rbtree callback function
244 static int section_cmp(void const *a, void const *b)
246 const CONF_SECTION *one = a;
247 const CONF_SECTION *two = b;
249 return strcmp(one->name1, two->name1);
254 * rbtree callback function
256 static int name2_cmp(void const *a, void const *b)
258 const CONF_SECTION *one = a;
259 const CONF_SECTION *two = b;
261 rad_assert(strcmp(one->name1, two->name1) == 0);
263 if (!one->name2 && !two->name2) return 0;
264 if (!one->name2) return -1;
265 if (!two->name2) return +1;
267 return strcmp(one->name2, two->name2);
272 * rbtree callback function
274 static int data_cmp(void const *a, void const *b)
278 const CONF_DATA *one = a;
279 const CONF_DATA *two = b;
281 rcode = one->flag - two->flag;
282 if (rcode != 0) return rcode;
284 return strcmp(one->name, two->name);
287 static int cf_section_free(void *ctx)
291 cs = talloc_get_type_abort(ctx, CONF_SECTION);
294 * Name1 and name2 are allocated contiguous with
298 rbtree_free(cs->pair_tree);
299 cs->pair_tree = NULL;
301 if (cs->section_tree) {
302 rbtree_free(cs->section_tree);
303 cs->section_tree = NULL;
305 if (cs->name2_tree) {
306 rbtree_free(cs->name2_tree);
307 cs->name2_tree = NULL;
310 rbtree_free(cs->data_tree);
311 cs->data_tree = NULL;
319 * Allocate a CONF_SECTION
321 CONF_SECTION *cf_section_alloc(CONF_SECTION *parent, char const *name1,
327 if (!name1) return NULL;
330 if (strchr(name2, '$')) {
331 name2 = cf_expand_variables(parent->item.filename,
332 &parent->item.lineno,
334 buffer, sizeof(buffer), name2);
336 ERROR("Failed expanding section name");
342 cs = talloc_zero(parent, CONF_SECTION);
343 if (!cs) return NULL;
345 cs->item.type = CONF_ITEM_SECTION;
346 cs->item.parent = parent;
348 cs->name1 = talloc_strdup(cs, name1);
355 if (name2 && *name2) {
356 cs->name2 = talloc_strdup(cs, name2);
357 if (!cs->name2) goto error;
360 cs->pair_tree = rbtree_create(pair_cmp, NULL, 0);
361 if (!cs->pair_tree) goto error;
363 talloc_set_destructor((void *) cs, cf_section_free);
366 * Don't create a data tree, it may not be needed.
370 * Don't create the section tree here, it may not
374 if (parent) cs->depth = parent->depth + 1;
380 * Replace pair in a given section with a new pair,
381 * of the given value.
383 int cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value)
386 CONF_ITEM *ci, *cn, **last;
388 newp = cf_pair_alloc(cs, cp->attr, value, cp->op, cp->value_type);
389 if (!newp) return -1;
395 * Find the old one from the linked list, and replace it
398 for (last = &cs->children; (*last) != NULL; last = &(*last)->next) {
400 cn->next = (*last)->next;
407 rbtree_deletebydata(cs->pair_tree, ci);
409 rbtree_insert(cs->pair_tree, cn);
416 * Add an item to a configuration section.
418 static void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci)
420 if (!cs || !ci) return;
423 rad_assert(cs->tail == NULL);
426 rad_assert(cs->tail != NULL);
431 * Update the trees (and tail) for each item added.
433 for (/* nothing */; ci != NULL; ci = ci->next) {
437 * For fast lookups, pairs and sections get
442 rbtree_insert(cs->pair_tree, ci);
445 case CONF_ITEM_SECTION: {
446 CONF_SECTION *cs_new = cf_itemtosection(ci);
448 if (!cs->section_tree) {
449 cs->section_tree = rbtree_create(section_cmp, NULL, 0);
450 if (!cs->section_tree) {
451 ERROR("Out of memory");
456 rbtree_insert(cs->section_tree, cs_new);
459 * Two names: find the named instance.
462 CONF_SECTION *old_cs;
466 * CONF_SECTION having
467 * the given name1, and
471 old_cs = rbtree_finddata(cs->section_tree, cs_new);
472 if (!old_cs) return; /* this is a bad error! */
474 if (!old_cs->name2_tree) {
475 old_cs->name2_tree = rbtree_create(name2_cmp,
478 if (old_cs->name2_tree) {
479 rbtree_insert(old_cs->name2_tree, cs_new);
483 } /* was a section */
486 if (!cs->data_tree) {
487 cs->data_tree = rbtree_create(data_cmp, NULL, 0);
490 rbtree_insert(cs->data_tree, ci);
494 default: /* FIXME: assert & error! */
497 } /* switch over conf types */
502 CONF_ITEM *cf_reference_item(CONF_SECTION const *parentcs,
503 CONF_SECTION *outercs,
508 const CONF_SECTION *cs = outercs;
512 strlcpy(name, ptr, sizeof(name));
516 * ".foo" means "foo from the current section"
522 * Just '.' means the current section
525 return cf_sectiontoitem(cs);
529 * ..foo means "foo from the section
530 * enclosing this section" (etc.)
533 if (cs->item.parent) {
534 cs = cs->item.parent;
538 * .. means the section
539 * enclosing this section
542 return cf_sectiontoitem(cs);
547 * "foo.bar.baz" means "from the root"
549 } else if (strchr(p, '.') != NULL) {
550 if (!parentcs) goto no_such_item;
562 if (r && q > r) q = NULL;
563 if (q && q < r) r = NULL;
569 q = strchr(r + 1, ']');
570 if (!q) return NULL; /* parse error */
573 * Points to foo[bar]xx: parse error,
574 * it should be foo[bar] or foo[bar].baz
576 if (q[1] && q[1] != '.') goto no_such_item;
580 next = cf_section_sub_find_name2(cs, p, r + 1);
585 * Points to a named instance of a section.
588 if (!next) goto no_such_item;
589 return &(next->item);
592 q++; /* ensure we skip the ']' and '.' */
596 next = cf_section_sub_find(cs, p);
600 if (!next) break; /* it MAY be a pair in this section! */
606 if (!*p) goto no_such_item;
610 * Find it in the current referenced
613 cp = cf_pair_find(cs, p);
614 if (cp) return &(cp->item);
616 next = cf_section_sub_find(cs, p);
617 if (next) return &(next->item);
620 * "foo" is "in the current section, OR in main".
622 if ((p == name) && (parentcs != NULL) && (cs != parentcs)) {
628 WDEBUG2("No such configuration item %s", ptr);
633 CONF_SECTION *cf_top_section(CONF_SECTION *cs)
635 if (!cs) return NULL;
637 while (cs->item.parent != NULL) {
638 cs = cs->item.parent;
646 * Expand the variables in an input string.
648 static char const *cf_expand_variables(char const *cf, int *lineno,
649 CONF_SECTION *outercs,
650 char *output, size_t outsize,
654 char const *end, *ptr;
655 const CONF_SECTION *parentcs;
659 * Find the master parent conf section.
660 * We can't use mainconfig.config, because we're in the
661 * process of re-building it, and it isn't set up yet...
663 parentcs = cf_top_section(outercs);
669 * Ignore anything other than "${"
671 if ((*ptr == '$') && (ptr[1] == '{')) {
677 * FIXME: Add support for ${foo:-bar},
682 * Look for trailing '}', and log a
683 * warning for anything that doesn't match,
684 * and exit with a fatal error.
686 end = strchr(ptr, '}');
689 INFO("%s[%d]: Variable expansion missing }",
697 * Can't really happen because input lines are
698 * capped at 8k, which is sizeof(name)
700 if ((size_t) (end - ptr) >= sizeof(name)) {
701 ERROR("%s[%d]: Reference string is too large",
706 memcpy(name, ptr, end - ptr);
707 name[end - ptr] = '\0';
709 q = strchr(name, ':');
714 ci = cf_reference_item(parentcs, outercs, name);
716 ERROR("%s[%d]: Reference \"%s\" not found", cf, *lineno, input);
721 * The expansion doesn't refer to another item or section
722 * it's the property of a section.
725 CONF_SECTION *mycs = cf_itemtosection(ci);
727 if (ci->type != CONF_ITEM_SECTION) {
728 ERROR("%s[%d]: Can only reference properties of sections", cf, *lineno);
732 switch (fr_str2int(conf_property_name, q, CONF_PROPERTY_INVALID)) {
733 case CONF_PROPERTY_NAME:
734 strcpy(p, mycs->name1);
737 case CONF_PROPERTY_INSTANCE:
738 strcpy(p, mycs->name2 ? mycs->name2 : mycs->name1);
742 ERROR("%s[%d]: Invalid property '%s'", cf, *lineno, q);
748 } else if (ci->type == CONF_ITEM_PAIR) {
750 * Substitute the value of the variable.
752 cp = cf_itemtopair(ci);
754 ERROR("%s[%d]: Reference \"%s\" has no value",
759 if (p + strlen(cp->value) >= output + outsize) {
760 ERROR("%s[%d]: Reference \"%s\" is too long",
765 strcpy(p, cp->value);
769 } else if (ci->type == CONF_ITEM_SECTION) {
771 * Adding an entry again to a
772 * section is wrong. We don't
773 * want an infinite loop.
775 if (ci->parent == outercs) {
776 ERROR("%s[%d]: Cannot reference different item in same section", cf, *lineno);
779 cf_item_add(outercs, ci);
780 (void) talloc_reference(outercs, ci);
784 ERROR("%s[%d]: Reference \"%s\" type is invalid", cf, *lineno, input);
787 } else if (memcmp(ptr, "$ENV{", 5) == 0) {
793 * Look for trailing '}', and log a
794 * warning for anything that doesn't match,
795 * and exit with a fatal error.
797 end = strchr(ptr, '}');
800 INFO("%s[%d]: Environment variable expansion missing }",
806 * Can't really happen because input lines are
807 * capped at 8k, which is sizeof(name)
809 if ((size_t) (end - ptr) >= sizeof(name)) {
810 ERROR("%s[%d]: Environment variable name is too large",
815 memcpy(name, ptr, end - ptr);
816 name[end - ptr] = '\0';
819 * Get the environment variable.
820 * If none exists, then make it an empty string.
828 if (p + strlen(env) >= output + outsize) {
829 ERROR("%s[%d]: Reference \"%s\" is too long",
840 * Copy it over verbatim.
846 if (p >= (output + outsize)) {
847 ERROR("%s[%d]: Reference \"%s\" is too long",
851 } /* loop over all of the input string. */
858 static char const *parse_spaces = " ";
862 * Parses an item (not a CONF_ITEM) into the specified format,
863 * with a default value.
865 * Returns -1 on error, -2 if deprecated, 0 for correctly parsed,
866 * and 1 if the default value was used. Note that the default
867 * value will be used ONLY if the CONF_PAIR is NULL.
869 int cf_item_parse(CONF_SECTION *cs, char const *name, int type, void *data, char const *dflt)
872 bool deprecated, required, attribute;
876 const CONF_PAIR *cp = NULL;
881 deprecated = (type & PW_TYPE_DEPRECATED);
882 required = (type & PW_TYPE_REQUIRED);
883 attribute = (type & PW_TYPE_ATTRIBUTE);
885 type &= 0xff; /* normal types are small */
892 cp = cf_pair_find(cs, name);
902 cf_log_err(&(cs->item), "Configuration item '%s' must have a value", name);
908 if (!*value && required) {
911 cf_log_err(&(cs->item), "Configuration item '%s' must not be empty", name);
913 cf_log_err(&(cp->item), "Configuration item'%s' must not be empty", name);
919 cf_log_err(&(cs->item), "Configuration item \"%s\" is deprecated", name);
925 case PW_TYPE_BOOLEAN:
927 * Allow yes/no and on/off
929 if ((strcasecmp(value, "yes") == 0) ||
930 (strcasecmp(value, "on") == 0)) {
932 } else if ((strcasecmp(value, "no") == 0) ||
933 (strcasecmp(value, "off") == 0)) {
937 cf_log_err(&(cs->item), "Invalid value \"%s\" for boolean "
938 "variable %s", value, name);
941 cf_log_info(cs, "%.*s\t%s = %s",
942 cs->depth, parse_spaces, name, value);
945 case PW_TYPE_INTEGER:
946 *(int *)data = strtol(value, 0, 0);
947 cf_log_info(cs, "%.*s\t%s = %d",
948 cs->depth, parse_spaces, name, *(int *)data);
951 case PW_TYPE_STRING_PTR:
958 * Expand variables which haven't already been
959 * expanded automagically when the configuration
967 lineno = cs->item.lineno;
970 * FIXME: sizeof(buffer)?
972 value = cf_expand_variables("<internal>",
974 cs, buffer, sizeof(buffer),
977 cf_log_err(&(cs->item),"Failed expanding variable %s", name);
982 if (required && (!value || !*value)) goto is_required;
985 if (!dict_attrbyname(value)) {
987 cf_log_err(&(cs->item), "No such attribute '%s' for configuration '%s'",
990 cf_log_err(&(cp->item), "No such attribute '%s'",
997 cf_log_info(cs, "%.*s\t%s = \"%s\"",
998 cs->depth, parse_spaces, name, value ? value : "(null)");
999 *q = value ? talloc_strdup(cs, value) : NULL;
1003 * This is the same as PW_TYPE_STRING_PTR,
1004 * except that we also "stat" the file, and
1007 case PW_TYPE_FILE_INPUT:
1008 case PW_TYPE_FILE_OUTPUT:
1015 * Expand variables which haven't already been
1016 * expanded automagically when the configuration
1019 if ((value == dflt) && cs) {
1025 * FIXME: sizeof(buffer)?
1027 value = cf_expand_variables("?",
1029 cs, buffer, sizeof(buffer),
1031 if (!value) return -1;
1034 if (required && (!value || !*value)) goto is_required;
1036 cf_log_info(cs, "%.*s\t%s = \"%s\"",
1037 cs->depth, parse_spaces, name, value);
1038 *q = value ? talloc_strdup(cs, value) : NULL;
1041 * And now we "stat" the file.
1046 if (stat(*q, &buf) == 0) {
1047 time_t *mtime = talloc(cs, time_t);
1049 *mtime = buf.st_mtime;
1051 cf_data_add_internal(cs, *q, mtime, NULL, type);
1053 * We were expecting the file to exist...
1055 } else if (type == PW_TYPE_FILE_INPUT) {
1056 ERROR("File \"%s\" does not exist", value);
1063 case PW_TYPE_IPADDR:
1065 * Allow '*' as any address
1067 if (strcmp(value, "*") == 0) {
1068 *(uint32_t *) data = htonl(INADDR_ANY);
1069 cf_log_info(cs, "%.*s\t%s = *",
1070 cs->depth, parse_spaces, name);
1073 if (ip_hton(value, AF_INET, &ipaddr) < 0) {
1074 ERROR("Can't find IP address for host %s", value);
1078 if (strspn(value, "0123456789.") == strlen(value)) {
1079 cf_log_info(cs, "%.*s\t%s = %s",
1080 cs->depth, parse_spaces, name, value);
1082 cf_log_info(cs, "%.*s\t%s = %s IP address [%s]",
1083 cs->depth, parse_spaces, name, value,
1084 ip_ntoh(&ipaddr, ipbuf, sizeof(ipbuf)));
1086 *(uint32_t *) data = ipaddr.ipaddr.ip4addr.s_addr;
1089 case PW_TYPE_IPV6ADDR:
1090 if (ip_hton(value, AF_INET6, &ipaddr) < 0) {
1091 ERROR("Can't find IPv6 address for host %s", value);
1094 cf_log_info(cs, "%.*s\t%s = %s IPv6 address [%s]",
1095 cs->depth, parse_spaces, name, value,
1096 ip_ntoh(&ipaddr, ipbuf, sizeof(ipbuf)));
1097 memcpy(data, &ipaddr.ipaddr.ip6addr,
1098 sizeof(ipaddr.ipaddr.ip6addr));
1103 * If we get here, it's a sanity check error.
1104 * It's not an error parsing the configuration
1107 rad_assert(type > PW_TYPE_INVALID);
1108 rad_assert(type < PW_TYPE_MAX);
1110 ERROR("type '%s' is not supported in the configuration files",
1111 fr_int2str(dict_attr_types, type, "?Unknown?"));
1113 } /* switch over variable type */
1118 cpn = cf_pair_alloc(cs, name, value, T_OP_SET, T_BARE_WORD);
1119 if (!cpn) return -1;
1120 cpn->item.filename = "<internal>";
1121 cpn->item.lineno = 0;
1122 cf_item_add(cs, &(cpn->item));
1130 * A copy of cf_section_parse that initializes pointers before
1133 static void cf_section_parse_init(CONF_SECTION *cs, void *base,
1134 CONF_PARSER const *variables)
1139 for (i = 0; variables[i].name != NULL; i++) {
1140 if (variables[i].type == PW_TYPE_SUBSECTION) {
1141 CONF_SECTION *subcs;
1143 if (!variables[i].dflt) continue;
1145 subcs = cf_section_sub_find(cs, variables[i].name);
1148 * If there's no subsection in the
1149 * config, BUT the CONF_PARSER wants one,
1150 * then create an empty one. This is so
1151 * that we can track the strings,
1152 * etc. allocated in the subsection.
1155 subcs = cf_section_alloc(cs, variables[i].name,
1157 cf_item_add(cs, &(subcs->item));
1158 subcs->item.filename = cs->item.filename;
1159 subcs->item.lineno = cs->item.lineno;
1162 cf_section_parse_init(subcs, base,
1163 (CONF_PARSER const *) variables[i].dflt);
1167 if ((variables[i].type != PW_TYPE_STRING_PTR) &&
1168 (variables[i].type != PW_TYPE_FILE_INPUT) &&
1169 (variables[i].type != PW_TYPE_FILE_OUTPUT)) {
1173 if (variables[i].data) {
1174 data = variables[i].data; /* prefer this. */
1176 data = ((char *)base) + variables[i].offset;
1181 *(char **) data = NULL;
1182 } /* for all variables in the configuration section */
1187 * Parse a configuration section into user-supplied variables.
1189 int cf_section_parse(CONF_SECTION *cs, void *base,
1190 CONF_PARSER const *variables)
1196 cs->variables = variables; /* this doesn't hurt anything */
1199 cf_log_info(cs, "%.*s%s {", cs->depth, parse_spaces,
1202 cf_log_info(cs, "%.*s%s %s {", cs->depth, parse_spaces,
1203 cs->name1, cs->name2);
1206 cf_section_parse_init(cs, base, variables);
1209 * Handle the known configuration parameters.
1211 for (i = 0; variables[i].name != NULL; i++) {
1213 * Handle subsections specially
1215 if (variables[i].type == PW_TYPE_SUBSECTION) {
1216 CONF_SECTION *subcs;
1217 subcs = cf_section_sub_find(cs, variables[i].name);
1219 if (!variables[i].dflt || !subcs) {
1220 DEBUG2("Internal sanity check 1 failed in cf_section_parse %s",
1225 if (cf_section_parse(subcs, base,
1226 (CONF_PARSER const *) variables[i].dflt) < 0) {
1230 } /* else it's a CONF_PAIR */
1232 if (variables[i].data) {
1233 data = variables[i].data; /* prefer this. */
1235 data = ((char *)base) + variables[i].offset;
1237 DEBUG2("Internal sanity check 2 failed in cf_section_parse");
1242 * Parse the pair we found, or a default value.
1244 ret = cf_item_parse(cs, variables[i].name, variables[i].type, data, variables[i].dflt);
1247 * Be nice, and print the name of the new config item.
1249 if ((ret == -2) && (variables[i + 1].offset == variables[i].offset) &&
1250 (variables[i + 1].data == variables[i].data)) {
1251 cf_log_err(&(cs->item), "Replace \"%s\" with \"%s\"", variables[i].name,
1252 variables[i + 1].name);
1257 } /* for all variables in the configuration section */
1259 cf_log_info(cs, "%.*s}", cs->depth, parse_spaces);
1266 cf_log_info(cs, "%.*s}", cs->depth, parse_spaces);
1271 static char const *cf_local_file(char const *base, char const *filename,
1272 char *buffer, size_t bufsize)
1277 strlcpy(buffer, base, bufsize);
1279 p = strrchr(buffer, FR_DIR_SEP);
1280 if (!p) return filename;
1281 if (p[1]) { /* ./foo */
1285 dirsize = (p - buffer) + 1;
1287 if ((dirsize + strlen(filename)) >= bufsize) {
1291 strlcpy(p + 1, filename, bufsize - dirsize);
1296 static int seen_too_much(char const *filename, int lineno, char const *ptr)
1299 if (isspace(*ptr)) {
1304 if (*ptr == '#') return false;
1310 ERROR("%s[%d] Unexpected text %s. See \"man unlang\"",
1311 filename, lineno, ptr);
1320 * Read a part of the config file.
1322 static int cf_section_read(char const *filename, int *lineno, FILE *fp,
1323 CONF_SECTION *current)
1326 CONF_SECTION *this, *css;
1328 char const *ptr, *start;
1338 fr_cond_t *cond = NULL;
1340 this = current; /* add items here */
1343 * Read, checking for line continuations ('\\' at EOL)
1349 * Get data, and remember if we are at EOF.
1351 at_eof = (fgets(cbuf, sizeof(buf) - (cbuf - buf), fp) == NULL);
1355 * We read the entire 8k worth of data: complain.
1356 * Note that we don't care if the last character
1357 * is \n: it's still forbidden. This means that
1358 * the maximum allowed length of text is 8k-1, which
1362 if ((cbuf + len + 1) >= (buf + sizeof(buf))) {
1363 ERROR("%s[%d]: Line too long",
1370 while (isspace((int) *ptr)) ptr++;
1373 memmove(cbuf, ptr, len - (ptr - cbuf));
1374 len -= (ptr - cbuf);
1379 * Not doing continuations: check for edge
1386 while (*ptr && isspace((int) *ptr)) ptr++;
1388 if (!*ptr || (*ptr == '#')) continue;
1390 } else if (at_eof || (len == 0)) {
1391 ERROR("%s[%d]: Continuation at EOF is illegal",
1397 * See if there's a continuation.
1400 ((cbuf[len - 1] == '\n') || (cbuf[len - 1] == '\r'))) {
1405 if ((len > 0) && (cbuf[len - 1] == '\\')) {
1407 * Check for "suppress spaces" magic.
1409 if (!spaces && (len > 2) && (cbuf[len - 2] == '"')) {
1413 cbuf[len - 1] = '\0';
1422 * The parser is getting to be evil.
1424 while ((*ptr == ' ') || (*ptr == '\t')) ptr++;
1426 if (((ptr[0] == '%') && (ptr[1] == '{')) ||
1430 if (ptr[0] == '%') {
1431 hack = rad_copy_variable(buf1, ptr);
1433 hack = rad_copy_string(buf1, ptr);
1436 ERROR("%s[%d]: Invalid expansion: %s",
1437 filename, *lineno, ptr);
1444 t2 = gettoken(&ptr, buf2, sizeof(buf2));
1451 ERROR("%s[%d]: Invalid expansion: %s",
1452 filename, *lineno, ptr);
1456 t1 = gettoken(&ptr, buf1, sizeof(buf1));
1460 * The caller eats "name1 name2 {", and calls us
1461 * for the data inside of the section. So if we
1462 * receive a closing brace, then it must mean the
1463 * end of the section.
1465 if (t1 == T_RCBRACE) {
1466 if (this == current) {
1467 ERROR("%s[%d]: Too many closing braces",
1472 this = this->item.parent;
1473 if (seen_too_much(filename, *lineno, ptr)) return -1;
1478 * Allow for $INCLUDE files
1480 * This *SHOULD* work for any level include.
1481 * I really really really hate this file. -cparker
1483 if ((strcasecmp(buf1, "$INCLUDE") == 0) ||
1484 (strcasecmp(buf1, "$-INCLUDE") == 0)) {
1487 t2 = getword(&ptr, buf2, sizeof(buf2));
1489 if (buf2[0] == '$') relative = 0;
1491 value = cf_expand_variables(filename, lineno, this, buf, sizeof(buf), buf2);
1492 if (!value) return -1;
1494 if (!FR_DIR_IS_RELATIVE(value)) relative = 0;
1497 value = cf_local_file(filename, value, buf3,
1500 ERROR("%s[%d]: Directories too deep.",
1507 #ifdef HAVE_DIRENT_H
1511 * Include ALL non-"dot" files in the directory.
1514 if (value[strlen(value) - 1] == '/') {
1517 struct stat stat_buf;
1519 DEBUG2("including files in directory %s", value );
1524 if (stat(value, &stat_buf) < 0) {
1525 ERROR("%s[%d]: Failed reading directory %s: %s",
1527 value, strerror(errno));
1531 if ((stat_buf.st_mode & S_IWOTH) != 0) {
1532 ERROR("%s[%d]: Directory %s is globally writable. Refusing to start due to insecure configuration.",
1533 filename, *lineno, value);
1537 dir = opendir(value);
1539 ERROR("%s[%d]: Error reading directory %s: %s",
1540 filename, *lineno, value,
1546 * Read the directory, ignoring "." files.
1548 while ((dp = readdir(dir)) != NULL) {
1551 if (dp->d_name[0] == '.') continue;
1554 * Check for valid characters
1556 for (p = dp->d_name; *p != '\0'; p++) {
1557 if (isalpha((int)*p) ||
1561 (*p == '.')) continue;
1564 if (*p != '\0') continue;
1566 snprintf(buf2, sizeof(buf2), "%s%s",
1568 if ((stat(buf2, &stat_buf) != 0) ||
1569 S_ISDIR(stat_buf.st_mode)) continue;
1571 * Read the file into the current
1572 * configuration section.
1574 if (cf_file_include(this, buf2) < 0) {
1582 { /* it was a normal file */
1583 if (buf1[1] == '-') {
1584 struct stat statbuf;
1586 if (stat(value, &statbuf) < 0) {
1587 WDEBUG("Not including file %s: %s", value, strerror(errno));
1592 if (cf_file_include(this, value) < 0) {
1597 } /* we were in an include */
1599 if (strcasecmp(buf1, "$template") == 0) {
1601 CONF_SECTION *parentcs, *templatecs;
1602 t2 = getword(&ptr, buf2, sizeof(buf2));
1604 parentcs = cf_top_section(current);
1606 templatecs = cf_section_sub_find(parentcs, "templates");
1608 ERROR("%s[%d]: No \"templates\" section for reference \"%s\"",
1609 filename, *lineno, buf2);
1613 ci = cf_reference_item(parentcs, templatecs, buf2);
1614 if (!ci || (ci->type != CONF_ITEM_SECTION)) {
1615 ERROR("%s[%d]: Reference \"%s\" not found",
1616 filename, *lineno, buf2);
1620 if (this->template) {
1621 ERROR("%s[%d]: Section already has a template",
1626 this->template = cf_itemtosection(ci);
1631 * Ensure that the user can't add CONF_PAIRs
1632 * with 'internal' names;
1634 if (buf1[0] == '_') {
1635 ERROR("%s[%d]: Illegal configuration pair name \"%s\"",
1636 filename, *lineno, buf1);
1641 * Handle if/elsif specially.
1643 if ((strcmp(buf1, "if") == 0) || (strcmp(buf1, "elsif") == 0)) {
1645 char const *error = NULL;
1647 CONF_SECTION *server;
1650 * if / elsif MUST be inside of a
1651 * processing section, which MUST in turn
1652 * be inside of a "server" directive.
1654 if (!this->item.parent) {
1656 ERROR("%s[%d]: Invalid location for '%s'",
1657 filename, *lineno, buf1);
1662 * If there's a ${...}. If so, expand it.
1665 if (strchr(ptr, '$') != NULL) {
1667 ptr = cf_expand_variables(filename, lineno,
1672 ERROR("%s[%d]: Parse error expanding ${...} in condition",
1676 } /* else leave it alone */
1678 p = strrchr(ptr, '{'); /* ugh */
1681 server = this->item.parent;
1682 while ((strcmp(server->name1, "server") != 0) &&
1683 (strcmp(server->name1, "policy") != 0)) {
1684 server = server->item.parent;
1685 if (!server) goto invalid_location;
1688 slen = fr_condition_tokenize(this, ptr, &cond, &error);
1696 offset += ptr - start;
1698 spbuf = malloc(offset + 1);
1699 memset(spbuf, ' ', offset);
1700 spbuf[offset] = '\0';
1702 ERROR("%s[%d]: Parse error in condition",
1705 EDEBUG("%s", start);
1706 EDEBUG("%.*s^%s", (int) offset, spbuf, error);
1711 if ((size_t) slen >= (sizeof(buf2) - 1)) {
1713 EDEBUG("%s[%d]: Condition is too large after \"%s\"",
1714 filename, *lineno, buf1);
1718 memcpy(buf2, ptr, slen);
1723 if (gettoken(&ptr, buf3, sizeof(buf3)) != T_LCBRACE) {
1725 EDEBUG("%s[%d]: Expected '{'",
1734 * Grab the next token.
1736 t2 = gettoken(&ptr, buf2, sizeof(buf2));
1752 case T_OP_CMP_FALSE:
1753 if (!this || (strcmp(this->name1, "update") != 0)) {
1754 ERROR("%s[%d]: Invalid operator in assignment",
1762 t3 = getstring(&ptr, buf3, sizeof(buf3));
1763 if (t3 == T_OP_INVALID) {
1764 ERROR("%s[%d]: Parse error: %s",
1771 * These are not allowed. Print a
1772 * helpful error message.
1774 if ((t3 == T_BACK_QUOTED_STRING) &&
1775 (!this || (strcmp(this->name1, "update") != 0))) {
1776 ERROR("%s[%d]: Syntax error: Invalid string `...` in assignment",
1782 * Handle variable substitution via ${foo}
1784 if ((t3 == T_BARE_WORD) ||
1785 (t3 == T_DOUBLE_QUOTED_STRING)) {
1786 value = cf_expand_variables(filename, lineno, this,
1787 buf, sizeof(buf), buf3);
1788 if (!value) return -1;
1789 } else if ((t3 == T_EOL) ||
1797 * Add this CONF_PAIR to our CONF_SECTION
1800 cpn = cf_pair_alloc(this, buf1, value, t2, t3);
1801 cpn->item.filename = filename;
1802 cpn->item.lineno = *lineno;
1803 cf_item_add(this, &(cpn->item));
1807 * No '=', must be a section or sub-section.
1810 case T_DOUBLE_QUOTED_STRING:
1811 case T_SINGLE_QUOTED_STRING:
1812 t3 = gettoken(&ptr, buf3, sizeof(buf3));
1813 if (t3 != T_LCBRACE) {
1814 ERROR("%s[%d]: Expecting section start brace '{' after \"%s %s\"",
1815 filename, *lineno, buf1, buf2);
1822 if (seen_too_much(filename, *lineno, ptr)) {
1823 if (cond) talloc_free(cond);
1827 css = cf_section_alloc(this, buf1,
1828 t2 == T_LCBRACE ? NULL : buf2);
1830 ERROR("%s[%d]: Failed allocating memory for section",
1834 cf_item_add(this, &(css->item));
1835 css->item.filename = filename;
1836 css->item.lineno = *lineno;
1839 cf_data_add_internal(css, "if", cond, NULL, false);
1840 cond = NULL; /* eaten by the above line */
1844 * The current section is now the child section.
1850 ERROR("%s[%d]: Parse error after \"%s\": unexpected token \"%s\"",
1851 filename, *lineno, buf1, fr_int2str(fr_tokens, t2, "<INVALID>"));
1857 * See if EOF was unexpected ..
1859 if (feof(fp) && (this != current)) {
1860 ERROR("%s[%d]: EOF reached without closing brace for section %s starting at line %d",
1862 cf_section_name1(this), cf_section_lineno(this));
1870 * Include one config file in another.
1872 int cf_file_include(CONF_SECTION *cs, char const *filename)
1876 struct stat statbuf;
1880 DEBUG2("including configuration file %s", filename);
1882 fp = fopen(filename, "r");
1884 ERROR("Unable to open file \"%s\": %s",
1885 filename, strerror(errno));
1889 if (stat(filename, &statbuf) == 0) {
1891 if ((statbuf.st_mode & S_IWOTH) != 0) {
1893 ERROR("Configuration file %s is globally writable. Refusing to start due to insecure configuration.",
1900 if (0 && (statbuf.st_mode & S_IROTH) != 0) {
1902 ERROR("Configuration file %s is globally readable. Refusing to start due to insecure configuration.",
1909 if (cf_data_find_internal(cs, filename, PW_TYPE_FILE_INPUT)) {
1911 ERROR("Cannot include the same file twice: \"%s\"",
1917 * Add the filename to the section
1919 mtime = talloc(cs, time_t);
1920 *mtime = statbuf.st_mtime;
1922 if (cf_data_add_internal(cs, filename, mtime, NULL, PW_TYPE_FILE_INPUT) < 0) {
1924 ERROR("Internal error opening file \"%s\"",
1929 cd = cf_data_find_internal(cs, filename, PW_TYPE_FILE_INPUT);
1932 ERROR("Internal error opening file \"%s\"",
1937 if (!cs->item.filename) cs->item.filename = filename;
1940 * Read the section. It's OK to have EOF without a
1941 * matching close brace.
1943 if (cf_section_read(cd->name, &lineno, fp, cs) < 0) {
1953 * Bootstrap a config file.
1955 CONF_SECTION *cf_file_read(char const *filename)
1961 cs = cf_section_alloc(NULL, "main", NULL);
1962 if (!cs) return NULL;
1964 cp = cf_pair_alloc(cs, "confdir", filename, T_OP_SET, T_BARE_WORD);
1965 if (!cp) return NULL;
1967 p = strrchr(cp->value, FR_DIR_SEP);
1970 cp->item.filename = "internal";
1971 cp->item.lineno = 0;
1972 cf_item_add(cs, &(cp->item));
1974 if (cf_file_include(cs, filename) < 0) {
1983 void cf_file_free(CONF_SECTION *cs)
1990 * Return a CONF_PAIR within a CONF_SECTION.
1992 CONF_PAIR *cf_pair_find(CONF_SECTION const *cs, char const *name)
1995 CONF_PAIR *cp = NULL;
1997 if (!cs) return NULL;
2000 * Find the name in the tree, for speed.
2006 cp = rbtree_finddata(cs->pair_tree, &mycp);
2009 * Else find the first one that matches
2011 for (ci = cs->children; ci; ci = ci->next) {
2012 if (ci->type == CONF_ITEM_PAIR) {
2013 return cf_itemtopair(ci);
2018 if (cp || !cs->template) return cp;
2020 return cf_pair_find(cs->template, name);
2024 * Return the attr of a CONF_PAIR
2027 char const *cf_pair_attr(CONF_PAIR const *pair)
2029 return (pair ? pair->attr : NULL);
2033 * Return the value of a CONF_PAIR
2036 char const *cf_pair_value(CONF_PAIR const *pair)
2038 return (pair ? pair->value : NULL);
2041 FR_TOKEN cf_pair_operator(CONF_PAIR const *pair)
2043 return (pair ? pair->op : T_OP_INVALID);
2047 * Return the value type, should be one of the following:
2048 * T_BARE_WORD, T_SINGLE_QUOTED_STRING, T_BACK_QUOTED_STRING
2049 * T_DOUBLE_QUOTED_STRING or T_OP_INVALID if the pair is NULL.
2051 FR_TOKEN cf_pair_value_type(CONF_PAIR const *pair)
2053 return (pair ? pair->value_type : T_OP_INVALID);
2057 * Copied here for error reporting.
2059 extern void fr_strerror_printf(char const *, ...);
2062 * Turn a CONF_PAIR into a VALUE_PAIR
2063 * For now, ignore the "value_type" field...
2065 VALUE_PAIR *cf_pairtovp(CONF_PAIR *pair)
2068 fr_strerror_printf("Internal error");
2073 fr_strerror_printf("No value given for attribute %s", pair->attr);
2078 * false comparisons never match. BUT if it's a "string"
2079 * or `string`, then remember to expand it later.
2081 if ((pair->op != T_OP_CMP_FALSE) &&
2082 ((pair->value_type == T_DOUBLE_QUOTED_STRING) ||
2083 (pair->value_type == T_BACK_QUOTED_STRING))) {
2086 vp = pairmake(pair, NULL, pair->attr, NULL, pair->op);
2091 if (pairmark_xlat(vp, pair->value) < 0) {
2100 return pairmake(pair, NULL, pair->attr, pair->value, pair->op);
2104 * Return the first label of a CONF_SECTION
2107 char const *cf_section_name1(CONF_SECTION const *cs)
2109 return (cs ? cs->name1 : NULL);
2113 * Return the second label of a CONF_SECTION
2116 char const *cf_section_name2(CONF_SECTION const *cs)
2118 return (cs ? cs->name2 : NULL);
2122 * Find a value in a CONF_SECTION
2124 char const *cf_section_value_find(CONF_SECTION const *cs, char const *attr)
2128 cp = cf_pair_find(cs, attr);
2130 return (cp ? cp->value : NULL);
2134 CONF_SECTION *cf_section_find_name2(CONF_SECTION const *cs,
2135 char const *name1, char const *name2)
2138 const CONF_ITEM *ci;
2140 if (!cs || !name1) return NULL;
2142 for (ci = &(cs->item); ci; ci = ci->next) {
2143 if (ci->type != CONF_ITEM_SECTION)
2146 if (strcmp(cf_itemtosection(ci)->name1, name1) != 0) {
2150 their2 = cf_itemtosection(ci)->name2;
2152 if ((!name2 && !their2) ||
2153 (name2 && their2 && (strcmp(name2, their2) == 0))) {
2154 return cf_itemtosection(ci);
2162 * Return the next pair after a CONF_PAIR
2163 * with a certain name (char *attr) If the requested
2164 * attr is NULL, any attr matches.
2167 CONF_PAIR *cf_pair_find_next(CONF_SECTION const *cs,
2168 CONF_PAIR const *pair, char const *attr)
2172 if (!cs) return NULL;
2175 * If pair is NULL this must be a first time run
2176 * Find the pair with correct name
2179 if (!pair) return cf_pair_find(cs, attr);
2181 for (ci = pair->item.next; ci; ci = ci->next) {
2182 if (ci->type != CONF_ITEM_PAIR)
2185 if (!attr || strcmp(cf_itemtopair(ci)->attr, attr) == 0)
2189 return cf_itemtopair(ci);
2193 * Find a CONF_SECTION, or return the root if name is NULL
2196 CONF_SECTION *cf_section_find(char const *name)
2199 return cf_section_sub_find(root_config, name);
2204 /** Find a sub-section in a section
2206 CONF_SECTION *cf_section_sub_find(CONF_SECTION const *cs, char const *name)
2210 if (!name) return NULL; /* can't find an un-named section */
2213 * Do the fast lookup if possible.
2215 if (cs->section_tree) {
2220 return rbtree_finddata(cs->section_tree, &mycs);
2223 for (ci = cs->children; ci; ci = ci->next) {
2224 if (ci->type != CONF_ITEM_SECTION)
2226 if (strcmp(cf_itemtosection(ci)->name1, name) == 0)
2230 return cf_itemtosection(ci);
2235 /** Find a CONF_SECTION with both names.
2238 CONF_SECTION *cf_section_sub_find_name2(CONF_SECTION const *cs,
2239 char const *name1, char const *name2)
2243 if (!cs) cs = root_config;
2245 if (name1 && (cs->section_tree)) {
2246 CONF_SECTION mycs, *master_cs;
2251 master_cs = rbtree_finddata(cs->section_tree, &mycs);
2253 return rbtree_finddata(master_cs->name2_tree, &mycs);
2258 * Else do it the old-fashioned way.
2260 for (ci = cs->children; ci; ci = ci->next) {
2261 CONF_SECTION *subcs;
2263 if (ci->type != CONF_ITEM_SECTION)
2266 subcs = cf_itemtosection(ci);
2268 if (!subcs->name2) {
2269 if (strcmp(subcs->name1, name2) == 0) break;
2271 if (strcmp(subcs->name2, name2) == 0) break;
2273 continue; /* don't do the string comparisons below */
2276 if ((strcmp(subcs->name1, name1) == 0) &&
2277 (subcs->name2 != NULL) &&
2278 (strcmp(subcs->name2, name2) == 0))
2282 return cf_itemtosection(ci);
2286 * Return the next subsection after a CONF_SECTION
2287 * with a certain name1 (char *name1). If the requested
2288 * name1 is NULL, any name1 matches.
2291 CONF_SECTION *cf_subsection_find_next(CONF_SECTION const *section,
2292 CONF_SECTION const *subsection,
2297 if (!section) return NULL;
2300 * If subsection is NULL this must be a first time run
2301 * Find the subsection with correct name
2305 ci = section->children;
2307 ci = subsection->item.next;
2310 for (; ci; ci = ci->next) {
2311 if (ci->type != CONF_ITEM_SECTION)
2313 if ((name1 == NULL) ||
2314 (strcmp(cf_itemtosection(ci)->name1, name1) == 0))
2318 return cf_itemtosection(ci);
2323 * Return the next section after a CONF_SECTION
2324 * with a certain name1 (char *name1). If the requested
2325 * name1 is NULL, any name1 matches.
2328 CONF_SECTION *cf_section_find_next(CONF_SECTION const *section,
2329 CONF_SECTION const *subsection,
2332 if (!section) return NULL;
2334 if (!section->item.parent) return NULL;
2336 return cf_subsection_find_next(section->item.parent, subsection, name1);
2340 * Return the next item after a CONF_ITEM.
2343 CONF_ITEM *cf_item_find_next(CONF_SECTION const *section, CONF_ITEM const *item)
2345 if (!section) return NULL;
2348 * If item is NULL this must be a first time run
2349 * Return the first item
2353 return section->children;
2359 CONF_SECTION *cf_item_parent(CONF_ITEM const *ci)
2361 if (!ci) return NULL;
2366 int cf_section_lineno(CONF_SECTION const *section)
2368 return section->item.lineno;
2371 char const *cf_pair_filename(CONF_PAIR const *pair)
2373 return pair->item.filename;
2376 char const *cf_section_filename(CONF_SECTION const *section)
2378 return section->item.filename;
2381 int cf_pair_lineno(CONF_PAIR const *pair)
2383 return pair->item.lineno;
2386 int cf_item_is_section(CONF_ITEM const *item)
2388 return item->type == CONF_ITEM_SECTION;
2390 int cf_item_is_pair(CONF_ITEM const *item)
2392 return item->type == CONF_ITEM_PAIR;
2396 static CONF_DATA *cf_data_alloc(CONF_SECTION *parent, char const *name,
2397 void *data, void (*data_free)(void *))
2401 cd = talloc_zero(parent, CONF_DATA);
2402 if (!cd) return NULL;
2404 cd->item.type = CONF_ITEM_DATA;
2405 cd->item.parent = parent;
2406 cd->name = talloc_strdup(cd, name);
2413 cd->free = data_free;
2416 talloc_set_destructor((void *) cd, cf_data_free);
2423 static void *cf_data_find_internal(CONF_SECTION const *cs, char const *name,
2426 if (!cs || !name) return NULL;
2429 * Find the name in the tree, for speed.
2431 if (cs->data_tree) {
2436 return rbtree_finddata(cs->data_tree, &mycd);
2443 * Find data from a particular section.
2445 void *cf_data_find(CONF_SECTION const *cs, char const *name)
2447 CONF_DATA *cd = cf_data_find_internal(cs, name, 0);
2449 if (cd) return cd->data;
2455 * Add named data to a configuration section.
2457 static int cf_data_add_internal(CONF_SECTION *cs, char const *name,
2458 void *data, void (*data_free)(void *),
2463 if (!cs || !name) return -1;
2466 * Already exists. Can't add it.
2468 if (cf_data_find_internal(cs, name, flag) != NULL) return -1;
2470 cd = cf_data_alloc(cs, name, data, data_free);
2474 cf_item_add(cs, cf_datatoitem(cd));
2480 * Add named data to a configuration section.
2482 int cf_data_add(CONF_SECTION *cs, char const *name,
2483 void *data, void (*data_free)(void *))
2485 return cf_data_add_internal(cs, name, data, data_free, 0);
2490 * Copy CONF_DATA from src to dst
2492 static void cf_section_copy_data(CONF_SECTION *s, CONF_SECTION *d)
2495 CONF_ITEM *cd, *next, **last;
2498 * Don't check if s->data_tree is NULL. It's child
2499 * sections may have data, even if this section doesn't.
2502 rad_assert(d->data_tree == NULL);
2503 d->data_tree = s->data_tree;
2504 s->data_tree = NULL;
2507 * Walk through src, moving CONF_ITEM_DATA
2510 last = &(s->children);
2511 for (cd = s->children; cd != NULL; cd = next) {
2515 * Recursively copy data from child sections.
2517 if (cd->type == CONF_ITEM_SECTION) {
2518 CONF_SECTION *s1, *d1;
2520 s1 = cf_itemtosection(cd);
2521 d1 = cf_section_sub_find_name2(d, s1->name1, s1->name2);
2523 cf_section_copy_data(s1, d1);
2530 * Not conf data, remember last ptr.
2532 if (cd->type != CONF_ITEM_DATA) {
2538 * Remove it from the src list
2544 * Add it to the dst list
2547 rad_assert(d->tail == NULL);
2550 rad_assert(d->tail != NULL);
2558 * For a CONF_DATA element, stat the filename, if necessary.
2560 static int filename_stat(UNUSED void *context, void *data)
2563 CONF_DATA *cd = data;
2565 if (cd->flag != PW_TYPE_FILE_INPUT) return 0;
2567 if (stat(cd->name, &buf) < 0) return -1;
2569 if (buf.st_mtime != *(time_t *) cd->data) return -1;
2576 * Compare two CONF_SECTIONS. The items MUST be in the same
2579 static int cf_section_cmp(CONF_SECTION *a, CONF_SECTION *b)
2581 CONF_ITEM *ca = a->children;
2582 CONF_ITEM *cb = b->children;
2590 if (!ca && !cb) break;
2595 if (ca && ca->type == CONF_ITEM_DATA) {
2599 if (cb && cb->type == CONF_ITEM_DATA) {
2605 * One is smaller than the other. Exit.
2607 if (!ca || !cb) return 0;
2609 if (ca->type != cb->type) return 0;
2612 * Deal with subsections.
2614 if (ca->type == CONF_ITEM_SECTION) {
2615 CONF_SECTION *sa = cf_itemtosection(ca);
2616 CONF_SECTION *sb = cf_itemtosection(cb);
2618 if (!cf_section_cmp(sa, sb)) return 0;
2622 rad_assert(ca->type == CONF_ITEM_PAIR);
2624 pa = cf_itemtopair(ca);
2625 pb = cf_itemtopair(cb);
2628 * Different attr and/or value, Exit.
2630 if ((strcmp(pa->attr, pb->attr) != 0) ||
2631 (strcmp(pa->value, pb->value) != 0)) return 0;
2635 * And go to the next element.
2643 * Walk over the CONF_DATA, stat'ing PW_TYPE_FILE_INPUT.
2646 (rbtree_walk(a->data_tree, InOrder, filename_stat, NULL) != 0)) {
2651 * They must be the same, say so.
2658 * Migrate CONF_DATA from one section to another.
2660 int cf_section_migrate(CONF_SECTION *dst, CONF_SECTION *src)
2663 CONF_SECTION *s, *d;
2665 for (ci = src->children; ci != NULL; ci = ci->next) {
2666 if (ci->type != CONF_ITEM_SECTION)
2669 s = cf_itemtosection(ci);
2670 d = cf_section_sub_find_name2(dst, s->name1, s->name2);
2672 if (!d) continue; /* not in new one, don't migrate it */
2675 * A section of the same name is in BOTH src & dst,
2676 * compare the CONF_PAIR's. If they're all the same,
2677 * then copy the CONF_DATA from one to the other.
2679 if (cf_section_cmp(s, d)) {
2680 cf_section_copy_data(s, d);
2684 return 1; /* rcode means anything? */
2688 int cf_section_template(CONF_SECTION *cs, CONF_SECTION *template)
2690 if (!cs || !template || cs->template || template->template) return -1;
2692 cs->template = template;
2699 * This is here to make the rest of the code easier to read. It
2700 * ties conffile.c to log.c, but it means we don't have to
2701 * pollute every other function with the knowledge of the
2702 * configuration internals.
2704 void cf_log_err(CONF_ITEM const *ci, char const *fmt, ...)
2710 vsnprintf(buffer, sizeof(buffer), fmt, ap);
2715 ci->filename ? ci->filename : "unknown",
2716 ci->lineno ? ci->lineno : 0,
2719 ERROR("<unknown>[*]: %s", buffer);
2723 void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt, ...)
2729 vsnprintf(buffer, sizeof(buffer), fmt, ap);
2732 rad_assert(cs != NULL);
2735 cs->item.filename ? cs->item.filename : "unknown",
2736 cs->item.lineno ? cs->item.lineno : 0,
2740 void cf_log_err_cp(CONF_PAIR const *cp, char const *fmt, ...)
2746 vsnprintf(buffer, sizeof(buffer), fmt, ap);
2749 rad_assert(cp != NULL);
2752 cp->item.filename ? cp->item.filename : "unknown",
2753 cp->item.lineno ? cp->item.lineno : 0,
2757 void cf_log_info(CONF_SECTION const *cs, char const *fmt, ...)
2762 if ((debug_flag > 1) && cs) vradlog(L_DBG, fmt, ap);
2767 * Wrapper to simplify the code.
2769 void cf_log_module(CONF_SECTION const *cs, char const *fmt, ...)
2775 if (debug_flag > 1 && cs) {
2776 vsnprintf(buffer, sizeof(buffer), fmt, ap);
2778 DEBUG("%.*s# %s", cs->depth, parse_spaces, buffer);
2783 const CONF_PARSER *cf_section_parse_table(CONF_SECTION *cs)
2785 if (!cs) return NULL;
2787 return cs->variables;
2792 * JMG dump_config tries to dump the config structure in a readable format
2796 static int dump_config_section(CONF_SECTION const *cs, int indent)
2802 /* The DEBUG macro doesn't let me
2803 * for(i=0;i<indent;++i) debugputchar('\t');
2804 * so I had to get creative. --Pac. */
2806 for (ci = cs->children; ci; ci = ci->next) {
2808 case CONF_ITEM_PAIR:
2809 cp=cf_itemtopair(ci);
2810 DEBUG("%.*s%s = %s",
2811 indent, "\t\t\t\t\t\t\t\t\t\t\t",
2812 cp->attr, cp->value);
2815 case CONF_ITEM_SECTION:
2816 scs=cf_itemtosection(ci);
2817 DEBUG("%.*s%s %s%s{",
2818 indent, "\t\t\t\t\t\t\t\t\t\t\t",
2820 scs->name2 ? scs->name2 : "",
2821 scs->name2 ? " " : "");
2822 dump_config_section(scs, indent+1);
2824 indent, "\t\t\t\t\t\t\t\t\t\t\t");
2827 default: /* FIXME: Do more! */
2835 int dump_config(CONF_SECTION *cs)
2837 return dump_config_section(cs, 0);
2841 static char const *cf_pair_print_value(CONF_PAIR const *cp,
2842 char *buffer, size_t buflen)
2846 if (!cp->value) return "";
2848 switch (cp->value_type) {
2851 snprintf(buffer, buflen, "%s", cp->value);
2854 case T_SINGLE_QUOTED_STRING:
2855 snprintf(buffer, buflen, "'%s'", cp->value);
2858 case T_DOUBLE_QUOTED_STRING:
2860 fr_print_string(cp->value, strlen(cp->value),
2861 buffer + 1, buflen - 3);
2862 p = buffer + strlen(buffer); /* yuck... */
2872 int cf_pair2xml(FILE *fp, CONF_PAIR const *cp)
2874 fprintf(fp, "<%s>", cp->attr);
2879 char const *q = cp->value;
2881 while (*q && (p < (buffer + sizeof(buffer) - 1))) {
2883 memcpy(p, "&", 4);
2886 } else if (q[0] == '<') {
2887 memcpy(p, "<", 4);
2890 } else if (q[0] == '>') {
2891 memcpy(p, ">", 4);
2901 fprintf(fp, "%s", buffer);
2904 fprintf(fp, "</%s>\n", cp->attr);
2909 int cf_section2xml(FILE *fp, CONF_SECTION const *cs)
2911 CONF_ITEM *ci, *next;
2916 fprintf(fp, "<%s>\n", cs->name1);
2918 fprintf(fp, "<_name2>%s</_name2>\n", cs->name2);
2922 * Loop over contents.
2924 for (ci = cs->children; ci; ci = next) {
2928 case CONF_ITEM_PAIR:
2929 if (!cf_pair2xml(fp, (CONF_PAIR *) ci)) return 0;
2932 case CONF_ITEM_SECTION:
2933 if (!cf_section2xml(fp, (CONF_SECTION *) ci)) return 0;
2936 default: /* should really be an error. */
2942 fprintf(fp, "</%s>\n", cs->name1);
2944 return 1; /* success */
2947 int cf_pair2file(FILE *fp, CONF_PAIR const *cp)
2951 fprintf(fp, "\t%s = %s\n", cp->attr,
2952 cf_pair_print_value(cp, buffer, sizeof(buffer)));
2957 int cf_section2file(FILE *fp, CONF_SECTION const *cs)
2959 const CONF_ITEM *ci, *next;
2965 fprintf(fp, "%s {\n", cs->name1);
2967 fprintf(fp, "%s %s {\n",
2968 cs->name1, cs->name2);
2972 * Loop over contents.
2974 for (ci = cs->children; ci; ci = next) {
2978 case CONF_ITEM_PAIR:
2979 if (!cf_pair2file(fp, (CONF_PAIR const *) ci)) return 0;
2982 case CONF_ITEM_SECTION:
2983 if (!cf_section2file(fp, (CONF_SECTION const *) ci)) return 0;
2986 default: /* should really be an error. */
2994 return 1; /* success */