Remove redundant file from freeradius-abfab list.
[freeradius.git] / src / main / conffile.c
1 /*
2  * conffile.c   Read the radiusd.conf file.
3  *
4  *              Yep I should learn to use lex & yacc, or at least
5  *              write a decent parser. I know how to do that, really :)
6  *              miquels@cistron.nl
7  *
8  * Version:     $Id$
9  *
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.
14  *
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.
19  *
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
23  *
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>
27  */
28
29 RCSID("$Id$")
30
31 #include <freeradius-devel/radiusd.h>
32 #include <freeradius-devel/parser.h>
33 #include <freeradius-devel/rad_assert.h>
34
35 #ifdef HAVE_DIRENT_H
36 #include <dirent.h>
37 #endif
38
39 #ifdef HAVE_SYS_STAT_H
40 #include <sys/stat.h>
41 #endif
42
43 #include <ctype.h>
44
45 bool check_config = false;
46
47 typedef enum conf_property {
48         CONF_PROPERTY_INVALID = 0,
49         CONF_PROPERTY_NAME,
50         CONF_PROPERTY_INSTANCE,
51 } CONF_PROPERTY;
52
53 static const FR_NAME_NUMBER conf_property_name[] = {
54         { "name",       CONF_PROPERTY_NAME},
55         { "instance",   CONF_PROPERTY_INSTANCE},
56
57         {  NULL , -1 }
58 };
59
60 typedef enum conf_type {
61         CONF_ITEM_INVALID = 0,
62         CONF_ITEM_PAIR,
63         CONF_ITEM_SECTION,
64         CONF_ITEM_DATA
65 } CONF_ITEM_TYPE;
66
67 struct conf_item {
68         struct conf_item *next;         //!< Sibling.
69         struct conf_part *parent;       //!< Parent.
70         int lineno;                     //!< The line number the config item began on.
71         char const *filename;           //!< The file the config item was parsed from.
72         CONF_ITEM_TYPE type;            //!< Whether the config item is a config_pair, conf_section or conf_data.
73 };
74
75 /** Configuration AVP similar to a VALUE_PAIR
76  *
77  */
78 struct conf_pair {
79         CONF_ITEM       item;
80         char const      *attr;          //!< Attribute name
81         char const      *value;         //!< Attribute value
82         FR_TOKEN        op;             //!< Operator e.g. =, :=
83         FR_TOKEN        lhs_type;       //!< Name quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD.
84         FR_TOKEN        rhs_type;       //!< Value Quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD.
85         bool            pass2;          //!< do expansion in pass2.
86         bool            parsed;         //!< Was this item used during parsing?
87 };
88
89 /** Internal data that is associated with a configuration section
90  *
91  */
92 struct conf_data {
93         CONF_ITEM       item;
94         char const      *name;
95         int             flag;
96         void            *data;          //!< User data
97         void            (*free)(void *);        //!< Free user data function
98 };
99
100 struct conf_part {
101         CONF_ITEM       item;
102         char const      *name1;         //!< First name token.  Given ``foo bar {}`` would be ``foo``.
103         char const      *name2;         //!< Second name token. Given ``foo bar {}`` would be ``bar``.
104
105         FR_TOKEN        name2_type;     //!< The type of quoting around name2.
106
107         CONF_ITEM       *children;
108         CONF_ITEM       *tail;          //!< For speed.
109         CONF_SECTION    *template;
110
111         rbtree_t        *pair_tree;     //!< and a partridge..
112         rbtree_t        *section_tree;  //!< no jokes here.
113         rbtree_t        *name2_tree;    //!< for sections of the same name2
114         rbtree_t        *data_tree;
115
116         void            *base;
117         int             depth;
118
119         CONF_PARSER const *variables;
120 };
121
122 typedef struct cf_file_t {
123         char const      *filename;
124         CONF_SECTION    *cs;
125         bool            input;
126         struct stat     buf;
127 } cf_file_t;
128
129 CONF_SECTION *root_config = NULL;
130 bool cf_new_escape = false;
131
132
133 static int              cf_data_add_internal(CONF_SECTION *cs, char const *name, void *data,
134                                              void (*data_free)(void *), int flag);
135
136 static void             *cf_data_find_internal(CONF_SECTION const *cs, char const *name, int flag);
137
138 static char const       *cf_expand_variables(char const *cf, int *lineno,
139                                              CONF_SECTION *outercs,
140                                              char *output, size_t outsize,
141                                              char const *input, bool *soft_fail);
142
143 static int cf_file_include(CONF_SECTION *cs, char const *filename_in);
144
145
146
147 /*
148  *      Isolate the scary casts in these tiny provably-safe functions
149  */
150
151 /** Cast a CONF_ITEM to a CONF_PAIR
152  *
153  */
154 CONF_PAIR *cf_item_to_pair(CONF_ITEM const *ci)
155 {
156         CONF_PAIR *out;
157
158         if (ci == NULL) return NULL;
159
160         rad_assert(ci->type == CONF_ITEM_PAIR);
161
162         memcpy(&out, &ci, sizeof(out));
163         return out;
164 }
165
166 /** Cast a CONF_ITEM to a CONF_SECTION
167  *
168  */
169 CONF_SECTION *cf_item_to_section(CONF_ITEM const *ci)
170 {
171         CONF_SECTION *out;
172
173         if (ci == NULL) return NULL;
174
175         rad_assert(ci->type == CONF_ITEM_SECTION);
176
177         memcpy(&out, &ci, sizeof(out));
178         return out;
179 }
180
181 /** Cast a CONF_PAIR to a CONF_ITEM
182  *
183  */
184 CONF_ITEM *cf_pair_to_item(CONF_PAIR const *cp)
185 {
186         CONF_ITEM *out;
187
188         if (cp == NULL) return NULL;
189
190         memcpy(&out, &cp, sizeof(out));
191         return out;
192 }
193
194 /** Cast a CONF_SECTION to a CONF_ITEM
195  *
196  */
197 CONF_ITEM *cf_section_to_item(CONF_SECTION const *cs)
198 {
199         CONF_ITEM *out;
200
201         if (cs == NULL) return NULL;
202
203         memcpy(&out, &cs, sizeof(out));
204         return out;
205 }
206
207 /** Cast CONF_DATA to a CONF_ITEM
208  *
209  */
210 static CONF_ITEM *cf_data_to_item(CONF_DATA const *cd)
211 {
212         CONF_ITEM *out;
213
214         if (cd == NULL) {
215                 return NULL;
216         }
217
218         memcpy(&out, &cd, sizeof(out));
219         return out;
220 }
221
222 static int _cf_data_free(CONF_DATA *cd)
223 {
224         if (cd->free) cd->free(cd->data);
225
226         return 0;
227 }
228
229 /*
230  *      rbtree callback function
231  */
232 static int pair_cmp(void const *a, void const *b)
233 {
234         CONF_PAIR const *one = a;
235         CONF_PAIR const *two = b;
236
237         return strcmp(one->attr, two->attr);
238 }
239
240
241 /*
242  *      rbtree callback function
243  */
244 static int section_cmp(void const *a, void const *b)
245 {
246         CONF_SECTION const *one = a;
247         CONF_SECTION const *two = b;
248
249         return strcmp(one->name1, two->name1);
250 }
251
252
253 /*
254  *      rbtree callback function
255  */
256 static int name2_cmp(void const *a, void const *b)
257 {
258         CONF_SECTION const *one = a;
259         CONF_SECTION const *two = b;
260
261         rad_assert(strcmp(one->name1, two->name1) == 0);
262
263         if (!one->name2 && !two->name2) return 0;
264         if (one->name2 && !two->name2) return -1;
265         if (!one->name2 && two->name2) return +1;
266
267         return strcmp(one->name2, two->name2);
268 }
269
270
271 /*
272  *      rbtree callback function
273  */
274 static int data_cmp(void const *a, void const *b)
275 {
276         int rcode;
277
278         CONF_DATA const *one = a;
279         CONF_DATA const *two = b;
280
281         rcode = one->flag - two->flag;
282         if (rcode != 0) return rcode;
283
284         return strcmp(one->name, two->name);
285 }
286
287 /*
288  *      Functions for tracking filenames.
289  */
290 static int filename_cmp(void const *a, void const *b)
291 {
292         cf_file_t const *one = a;
293         cf_file_t const *two = b;
294
295         if (one->buf.st_dev < two->buf.st_dev) return -1;
296         if (one->buf.st_dev > two->buf.st_dev) return +1;
297
298         if (one->buf.st_ino < two->buf.st_ino) return -1;
299         if (one->buf.st_ino > two->buf.st_ino) return +1;
300
301         return 0;
302 }
303
304 static FILE *cf_file_open(CONF_SECTION *cs, char const *filename)
305 {
306         cf_file_t *file;
307         CONF_DATA *cd;
308         CONF_SECTION *top;
309         rbtree_t *tree;
310         int fd;
311         FILE *fp;
312
313         top = cf_top_section(cs);
314         cd = cf_data_find_internal(top, "filename", 0);
315         if (!cd) return NULL;
316
317         tree = cd->data;
318
319         fp = fopen(filename, "r");
320         if (!fp) {
321                 ERROR("Unable to open file \"%s\": %s",
322                       filename, fr_syserror(errno));
323                 return NULL;
324         }
325
326         fd = fileno(fp);
327
328         file = talloc(tree, cf_file_t);
329         if (!file) {
330                 fclose(fp);
331                 return NULL;
332         }
333
334         file->filename = filename;
335         file->cs = cs;
336         file->input = true;
337
338         if (fstat(fd, &file->buf) == 0) {
339 #ifdef S_IWOTH
340                 if ((file->buf.st_mode & S_IWOTH) != 0) {
341                         ERROR("Configuration file %s is globally writable.  "
342                               "Refusing to start due to insecure configuration.", filename);
343
344                         fclose(fp);
345                         talloc_free(file);
346                         return NULL;
347                 }
348 #endif
349         }
350
351         /*
352          *      We can include the same file twice.  e.g. when it
353          *      contains common definitions, such as for SQL.
354          *
355          *      Though the admin should really use templates for that.
356          */
357         if (!rbtree_insert(tree, file)) {
358                 talloc_free(file);
359         }
360
361         return fp;
362 }
363
364 /*
365  *      Do some checks on the file as an "input" file.  i.e. one read
366  *      by a module.
367  */
368 static bool cf_file_input(CONF_SECTION *cs, char const *filename)
369 {
370         cf_file_t *file;
371         CONF_DATA *cd;
372         CONF_SECTION *top;
373         rbtree_t *tree;
374
375         top = cf_top_section(cs);
376         cd = cf_data_find_internal(top, "filename", 0);
377         if (!cd) return false;
378
379         tree = cd->data;
380
381         file = talloc(tree, cf_file_t);
382         if (!file) return false;
383
384         file->filename = filename;
385         file->cs = cs;
386         file->input = true;
387
388         if (stat(filename, &file->buf) < 0) {
389                 ERROR("Unable to open file \"%s\": %s", filename, fr_syserror(errno));
390                 talloc_free(file);
391                 return false;
392         }
393
394 #ifdef S_IWOTH
395         if ((file->buf.st_mode & S_IWOTH) != 0) {
396                 ERROR("Configuration file %s is globally writable.  "
397                       "Refusing to start due to insecure configuration.", filename);
398                 talloc_free(file);
399                 return false;
400         }
401 #endif
402
403         /*
404          *      It's OK to include the same file twice...
405          */
406         if (!rbtree_insert(tree, file)) {
407                 talloc_free(file);
408         }
409
410         return true;
411
412 }
413
414
415 typedef struct cf_file_callback_t {
416         int             rcode;
417         rb_walker_t     callback;
418         CONF_SECTION    *modules;
419 } cf_file_callback_t;
420
421
422 /*
423  *      Return 0 for keep going, 1 for stop.
424  */
425 static int file_callback(void *ctx, void *data)
426 {
427         cf_file_callback_t *cb = ctx;
428         cf_file_t *file = data;
429         struct stat buf;
430
431         /*
432          *      The file doesn't exist or we can no longer read it.
433          */
434         if (stat(file->filename, &buf) < 0) {
435                 cb->rcode = CF_FILE_ERROR;
436                 return 1;
437         }
438
439         /*
440          *      The file changed, we'll need to re-read it.
441          */
442         if (buf.st_mtime != file->buf.st_mtime) {
443                 if (!file->input) {
444                         cb->rcode |= CF_FILE_CONFIG;
445                 } else {
446                         (void) cb->callback(cb->modules, file->cs);
447                         cb->rcode |= CF_FILE_MODULE;
448                 }
449         }
450
451         return 0;
452 }
453
454
455 /*
456  *      See if any of the files have changed.
457  */
458 int cf_file_changed(CONF_SECTION *cs, rb_walker_t callback)
459 {
460         CONF_DATA *cd;
461         CONF_SECTION *top;
462         cf_file_callback_t cb;
463         rbtree_t *tree;
464
465         top = cf_top_section(cs);
466         cd = cf_data_find_internal(top, "filename", 0);
467         if (!cd) return true;
468
469         tree = cd->data;
470
471         cb.rcode = CF_FILE_NONE;
472         cb.callback = callback;
473         cb.modules = cf_section_sub_find(cs, "modules");
474
475         (void) rbtree_walk(tree, RBTREE_IN_ORDER, file_callback, &cb);
476
477         return cb.rcode;
478 }
479
480 static int _cf_section_free(CONF_SECTION *cs)
481 {
482         /*
483          *      Name1 and name2 are allocated contiguous with
484          *      cs.
485          */
486         if (cs->pair_tree) {
487                 rbtree_free(cs->pair_tree);
488                 cs->pair_tree = NULL;
489         }
490         if (cs->section_tree) {
491                 rbtree_free(cs->section_tree);
492                 cs->section_tree = NULL;
493         }
494         if (cs->name2_tree) {
495                 rbtree_free(cs->name2_tree);
496                 cs->name2_tree = NULL;
497         }
498         if (cs->data_tree) {
499                 rbtree_free(cs->data_tree);
500                 cs->data_tree = NULL;
501         }
502
503         return 0;
504 }
505
506 /** Allocate a CONF_PAIR
507  *
508  * @param parent CONF_SECTION to hang this CONF_PAIR off of.
509  * @param attr name.
510  * @param value of CONF_PAIR.
511  * @param op T_OP_EQ, T_OP_SET etc.
512  * @param lhs_type T_BARE_WORD, T_DOUBLE_QUOTED_STRING, T_BACK_QUOTED_STRING
513  * @param rhs_type T_BARE_WORD, T_DOUBLE_QUOTED_STRING, T_BACK_QUOTED_STRING
514  * @return NULL on error, else a new CONF_SECTION parented by parent.
515  */
516 CONF_PAIR *cf_pair_alloc(CONF_SECTION *parent, char const *attr, char const *value,
517                          FR_TOKEN op, FR_TOKEN lhs_type, FR_TOKEN rhs_type)
518 {
519         CONF_PAIR *cp;
520
521         rad_assert(fr_equality_op[op] || fr_assignment_op[op]);
522         if (!attr) return NULL;
523
524         cp = talloc_zero(parent, CONF_PAIR);
525         if (!cp) return NULL;
526
527         cp->item.type = CONF_ITEM_PAIR;
528         cp->item.parent = parent;
529         cp->lhs_type = lhs_type;
530         cp->rhs_type = rhs_type;
531         cp->op = op;
532
533         cp->attr = talloc_typed_strdup(cp, attr);
534         if (!cp->attr) {
535         error:
536                 talloc_free(cp);
537                 return NULL;
538         }
539
540         if (value) {
541                 cp->value = talloc_typed_strdup(cp, value);
542                 if (!cp->value) goto error;
543         }
544
545         return cp;
546 }
547
548 /** Duplicate a CONF_PAIR
549  *
550  * @param parent to allocate new pair in.
551  * @param cp to duplicate.
552  * @return NULL on error, else a duplicate of the input pair.
553  */
554 CONF_PAIR *cf_pair_dup(CONF_SECTION *parent, CONF_PAIR *cp)
555 {
556         CONF_PAIR *new;
557
558         rad_assert(parent);
559         rad_assert(cp);
560
561         new = cf_pair_alloc(parent, cp->attr, cf_pair_value(cp),
562                             cp->op, cp->lhs_type, cp->rhs_type);
563         if (!new) return NULL;
564
565         new->parsed = cp->parsed;
566         new->item.lineno = cp->item.lineno;
567
568         /*
569          *      Avoid mallocs if possible.
570          */
571         if (!cp->item.filename || (strcmp(parent->item.filename, cp->item.filename) == 0)) {
572                 new->item.filename = parent->item.filename;
573         } else {
574                 new->item.filename = talloc_strdup(new, cp->item.filename);
575         }
576
577         return new;
578 }
579
580 /** Add a configuration pair to a section
581  *
582  * @param parent section to add pair to.
583  * @param cp to add.
584  */
585 void cf_pair_add(CONF_SECTION *parent, CONF_PAIR *cp)
586 {
587         cf_item_add(parent, cf_pair_to_item(cp));
588 }
589
590 /** Allocate a CONF_SECTION
591  *
592  * @param parent CONF_SECTION to hang this CONF_SECTION off of.
593  * @param name1 Primary name.
594  * @param name2 Secondary name.
595  * @return NULL on error, else a new CONF_SECTION parented by parent.
596  */
597 CONF_SECTION *cf_section_alloc(CONF_SECTION *parent, char const *name1, char const *name2)
598 {
599         CONF_SECTION *cs;
600         char buffer[1024];
601
602         if (!name1) return NULL;
603
604         if (name2 && parent) {
605                 if (strchr(name2, '$')) {
606                         name2 = cf_expand_variables(parent->item.filename,
607                                                     &parent->item.lineno,
608                                                     parent,
609                                                     buffer, sizeof(buffer), name2, NULL);
610                         if (!name2) {
611                                 ERROR("Failed expanding section name");
612                                 return NULL;
613                         }
614                 }
615         }
616
617         cs = talloc_zero(parent, CONF_SECTION);
618         if (!cs) return NULL;
619
620         cs->item.type = CONF_ITEM_SECTION;
621         cs->item.parent = parent;
622
623         cs->name1 = talloc_typed_strdup(cs, name1);
624         if (!cs->name1) {
625         error:
626                 talloc_free(cs);
627                 return NULL;
628         }
629
630         if (name2) {
631                 cs->name2 = talloc_typed_strdup(cs, name2);
632                 if (!cs->name2) goto error;
633         }
634
635         cs->pair_tree = rbtree_create(cs, pair_cmp, NULL, 0);
636         if (!cs->pair_tree) goto error;
637
638         talloc_set_destructor(cs, _cf_section_free);
639
640         /*
641          *      Don't create a data tree, it may not be needed.
642          */
643
644         /*
645          *      Don't create the section tree here, it may not
646          *      be needed.
647          */
648
649         if (parent) cs->depth = parent->depth + 1;
650
651         return cs;
652 }
653
654 /** Duplicate a configuration section
655  *
656  * @note recursively duplicates any child sections.
657  * @note does not duplicate any data associated with a section, or its child sections.
658  *
659  * @param parent section (may be NULL).
660  * @param cs to duplicate.
661  * @param name1 of new section.
662  * @param name2 of new section.
663  * @param copy_meta Copy additional meta data for a section (like template, base, depth and variables).
664  * @return a duplicate of the existing section, or NULL on error.
665  */
666 CONF_SECTION *cf_section_dup(CONF_SECTION *parent, CONF_SECTION const *cs,
667                              char const *name1, char const *name2, bool copy_meta)
668 {
669         CONF_SECTION *new, *subcs;
670         CONF_PAIR *cp;
671         CONF_ITEM *ci;
672
673         new = cf_section_alloc(parent, name1, name2);
674
675         if (copy_meta) {
676                 new->template = cs->template;
677                 new->base = cs->base;
678                 new->depth = cs->depth;
679                 new->variables = cs->variables;
680         }
681
682         new->item.lineno = cs->item.lineno;
683
684         if (!cs->item.filename || (parent && (strcmp(parent->item.filename, cs->item.filename) == 0))) {
685                 new->item.filename = parent->item.filename;
686         } else {
687                 new->item.filename = talloc_strdup(new, cs->item.filename);
688         }
689
690         for (ci = cs->children; ci; ci = ci->next) {
691                 switch (ci->type) {
692                 case CONF_ITEM_SECTION:
693                         subcs = cf_item_to_section(ci);
694                         subcs = cf_section_dup(new, subcs,
695                                                cf_section_name1(subcs), cf_section_name2(subcs),
696                                                copy_meta);
697                         if (!subcs) {
698                                 talloc_free(new);
699                                 return NULL;
700                         }
701                         cf_section_add(new, subcs);
702                         break;
703
704                 case CONF_ITEM_PAIR:
705                         cp = cf_pair_dup(new, cf_item_to_pair(ci));
706                         if (!cp) {
707                                 talloc_free(new);
708                                 return NULL;
709                         }
710                         cf_pair_add(new, cp);
711                         break;
712
713                 case CONF_ITEM_DATA: /* Skip data */
714                         break;
715
716                 case CONF_ITEM_INVALID:
717                         rad_assert(0);
718                 }
719         }
720
721         return new;
722 }
723
724 void cf_section_add(CONF_SECTION *parent, CONF_SECTION *cs)
725 {
726         cf_item_add(parent, &(cs->item));
727 }
728
729 /** Replace pair in a given section with a new pair, of the given value.
730  *
731  * @param cs to replace pair in.
732  * @param cp to replace.
733  * @param value New value to assign to cp.
734  * @return 0 on success, -1 on failure.
735  */
736 int cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value)
737 {
738         CONF_PAIR *newp;
739         CONF_ITEM *ci, *cn, **last;
740
741         newp = cf_pair_alloc(cs, cp->attr, value, cp->op, cp->lhs_type, cp->rhs_type);
742         if (!newp) return -1;
743
744         ci = &(cp->item);
745         cn = &(newp->item);
746
747         /*
748          *      Find the old one from the linked list, and replace it
749          *      with the new one.
750          */
751         for (last = &cs->children; (*last) != NULL; last = &(*last)->next) {
752                 if (*last == ci) {
753                         cn->next = (*last)->next;
754                         *last = cn;
755                         ci->next = NULL;
756                         break;
757                 }
758         }
759
760         rbtree_deletebydata(cs->pair_tree, ci);
761
762         rbtree_insert(cs->pair_tree, cn);
763
764         return 0;
765 }
766
767
768 /*
769  *      Add an item to a configuration section.
770  */
771 void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci)
772 {
773 #ifndef NDEBUG
774         CONF_ITEM *first = ci;
775 #endif
776
777         rad_assert((void *)cs != (void *)ci);
778
779         if (!cs || !ci) return;
780
781         if (!cs->children) {
782                 rad_assert(cs->tail == NULL);
783                 cs->children = ci;
784         } else {
785                 rad_assert(cs->tail != NULL);
786                 cs->tail->next = ci;
787         }
788
789         /*
790          *      Update the trees (and tail) for each item added.
791          */
792         for (/* nothing */; ci != NULL; ci = ci->next) {
793                 rad_assert(ci->next != first);  /* simple cycle detection */
794
795                 cs->tail = ci;
796
797                 /*
798                  *      For fast lookups, pairs and sections get
799                  *      added to rbtree's.
800                  */
801                 switch (ci->type) {
802                 case CONF_ITEM_PAIR:
803                         if (!rbtree_insert(cs->pair_tree, ci)) {
804                                 CONF_PAIR *cp = cf_item_to_pair(ci);
805
806                                 if (strcmp(cp->attr, "confdir") == 0) break;
807                                 if (!cp->value) break; /* module name, "ok", etc. */
808                         }
809                         break;
810
811                 case CONF_ITEM_SECTION: {
812                         CONF_SECTION *cs_new = cf_item_to_section(ci);
813                         CONF_SECTION *name1_cs;
814
815                         if (!cs->section_tree) {
816                                 cs->section_tree = rbtree_create(cs, section_cmp, NULL, 0);
817                                 if (!cs->section_tree) {
818                                         ERROR("Out of memory");
819                                         fr_exit_now(1);
820                                 }
821                         }
822
823                         name1_cs = rbtree_finddata(cs->section_tree, cs_new);
824                         if (!name1_cs) {
825                                 if (!rbtree_insert(cs->section_tree, cs_new)) {
826                                         ERROR("Failed inserting section into tree");
827                                         fr_exit_now(1);
828                                 }
829                                 break;
830                         }
831
832                         /*
833                          *      We already have a section of
834                          *      this "name1".  Add a new
835                          *      sub-section based on name2.
836                          */
837                         if (!name1_cs->name2_tree) {
838                                 name1_cs->name2_tree = rbtree_create(name1_cs, name2_cmp, NULL, 0);
839                                 if (!name1_cs->name2_tree) {
840                                         ERROR("Out of memory");
841                                         fr_exit_now(1);
842                                 }
843                         }
844
845                         /*
846                          *      We don't care if this fails.
847                          *      If the user tries to create
848                          *      two sections of the same
849                          *      name1/name2, the duplicate
850                          *      section is just silently
851                          *      ignored.
852                          */
853                         rbtree_insert(name1_cs->name2_tree, cs_new);
854                         break;
855                 } /* was a section */
856
857                 case CONF_ITEM_DATA:
858                         if (!cs->data_tree) {
859                                 cs->data_tree = rbtree_create(cs, data_cmp, NULL, 0);
860                         }
861                         if (cs->data_tree) {
862                                 rbtree_insert(cs->data_tree, ci);
863                         }
864                         break;
865
866                 default: /* FIXME: assert & error! */
867                         break;
868
869                 } /* switch over conf types */
870         } /* loop over ci */
871 }
872
873
874 CONF_ITEM *cf_reference_item(CONF_SECTION const *parentcs,
875                              CONF_SECTION *outercs,
876                              char const *ptr)
877 {
878         CONF_PAIR *cp;
879         CONF_SECTION *next;
880         CONF_SECTION const *cs = outercs;
881         char name[8192];
882         char *p;
883
884         if (!cs) goto no_such_item;
885
886         strlcpy(name, ptr, sizeof(name));
887         p = name;
888
889         /*
890          *      ".foo" means "foo from the current section"
891          */
892         if (*p == '.') {
893                 p++;
894
895                 /*
896                  *      Just '.' means the current section
897                  */
898                 if (*p == '\0') {
899                         return cf_section_to_item(cs);
900                 }
901
902                 /*
903                  *      ..foo means "foo from the section
904                  *      enclosing this section" (etc.)
905                  */
906                 while (*p == '.') {
907                         if (cs->item.parent) {
908                                 cs = cs->item.parent;
909                         }
910
911                         /*
912                          *      .. means the section
913                          *      enclosing this section
914                          */
915                         if (!*++p) {
916                                 return cf_section_to_item(cs);
917                         }
918                 }
919
920                 /*
921                  *      "foo.bar.baz" means "from the root"
922                  */
923         } else if (strchr(p, '.') != NULL) {
924                 if (!parentcs) goto no_such_item;
925
926                 cs = parentcs;
927         }
928
929         while (*p) {
930                 char *q, *r;
931
932                 r = strchr(p, '[');
933                 q = strchr(p, '.');
934                 if (!r && !q) break;
935
936                 if (r && q > r) q = NULL;
937                 if (q && q < r) r = NULL;
938
939                 /*
940                  *      Split off name2.
941                  */
942                 if (r) {
943                         q = strchr(r + 1, ']');
944                         if (!q) return NULL; /* parse error */
945
946                         /*
947                          *      Points to foo[bar]xx: parse error,
948                          *      it should be foo[bar] or foo[bar].baz
949                          */
950                         if (q[1] && q[1] != '.') goto no_such_item;
951
952                         *r = '\0';
953                         *q = '\0';
954                         next = cf_section_sub_find_name2(cs, p, r + 1);
955                         *r = '[';
956                         *q = ']';
957
958                         /*
959                          *      Points to a named instance of a section.
960                          */
961                         if (!q[1]) {
962                                 if (!next) goto no_such_item;
963                                 return &(next->item);
964                         }
965
966                         q++;    /* ensure we skip the ']' and '.' */
967
968                 } else {
969                         *q = '\0';
970                         next = cf_section_sub_find(cs, p);
971                         *q = '.';
972                 }
973
974                 if (!next) break; /* it MAY be a pair in this section! */
975
976                 cs = next;
977                 p = q + 1;
978         }
979
980         if (!*p) goto no_such_item;
981
982  retry:
983         /*
984          *      Find it in the current referenced
985          *      section.
986          */
987         cp = cf_pair_find(cs, p);
988         if (cp) {
989                 cp->parsed = true;      /* conf pairs which are referenced count as parsed */
990                 return &(cp->item);
991         }
992
993         next = cf_section_sub_find(cs, p);
994         if (next) return &(next->item);
995
996         /*
997          *      "foo" is "in the current section, OR in main".
998          */
999         if ((p == name) && (parentcs != NULL) && (cs != parentcs)) {
1000                 cs = parentcs;
1001                 goto retry;
1002         }
1003
1004 no_such_item:
1005         return NULL;
1006 }
1007
1008
1009 CONF_SECTION *cf_top_section(CONF_SECTION *cs)
1010 {
1011         if (!cs) return NULL;
1012
1013         while (cs->item.parent != NULL) {
1014                 cs = cs->item.parent;
1015         }
1016
1017         return cs;
1018 }
1019
1020
1021 /*
1022  *      Expand the variables in an input string.
1023  */
1024 static char const *cf_expand_variables(char const *cf, int *lineno,
1025                                        CONF_SECTION *outercs,
1026                                        char *output, size_t outsize,
1027                                        char const *input, bool *soft_fail)
1028 {
1029         char *p;
1030         char const *end, *ptr;
1031         CONF_SECTION const *parentcs;
1032         char name[8192];
1033
1034         if (soft_fail) *soft_fail = false;
1035
1036         /*
1037          *      Find the master parent conf section.
1038          *      We can't use main_config.config, because we're in the
1039          *      process of re-building it, and it isn't set up yet...
1040          */
1041         parentcs = cf_top_section(outercs);
1042
1043         p = output;
1044         ptr = input;
1045         while (*ptr) {
1046                 /*
1047                  *      Ignore anything other than "${"
1048                  */
1049                 if ((*ptr == '$') && (ptr[1] == '{')) {
1050                         CONF_ITEM *ci;
1051                         CONF_PAIR *cp;
1052                         char *q;
1053
1054                         /*
1055                          *      FIXME: Add support for ${foo:-bar},
1056                          *      like in xlat.c
1057                          */
1058
1059                         /*
1060                          *      Look for trailing '}', and log a
1061                          *      warning for anything that doesn't match,
1062                          *      and exit with a fatal error.
1063                          */
1064                         end = strchr(ptr, '}');
1065                         if (end == NULL) {
1066                                 *p = '\0';
1067                                 INFO("%s[%d]: Variable expansion missing }",
1068                                        cf, *lineno);
1069                                 return NULL;
1070                         }
1071
1072                         ptr += 2;
1073
1074                         /*
1075                          *      Can't really happen because input lines are
1076                          *      capped at 8k, which is sizeof(name)
1077                          */
1078                         if ((size_t) (end - ptr) >= sizeof(name)) {
1079                                 ERROR("%s[%d]: Reference string is too large",
1080                                       cf, *lineno);
1081                                 return NULL;
1082                         }
1083
1084                         memcpy(name, ptr, end - ptr);
1085                         name[end - ptr] = '\0';
1086
1087                         q = strchr(name, ':');
1088                         if (q) {
1089                                 *(q++) = '\0';
1090                         }
1091
1092                         ci = cf_reference_item(parentcs, outercs, name);
1093                         if (!ci) {
1094                                 if (soft_fail) *soft_fail = true;
1095                                 ERROR("%s[%d]: Reference \"${%s}\" not found", cf, *lineno, name);
1096                                 return NULL;
1097                         }
1098
1099                         /*
1100                          *      The expansion doesn't refer to another item or section
1101                          *      it's the property of a section.
1102                          */
1103                         if (q) {
1104                                 CONF_SECTION *mycs = cf_item_to_section(ci);
1105
1106                                 if (ci->type != CONF_ITEM_SECTION) {
1107                                         ERROR("%s[%d]: Can only reference properties of sections", cf, *lineno);
1108                                         return NULL;
1109                                 }
1110
1111                                 switch (fr_str2int(conf_property_name, q, CONF_PROPERTY_INVALID)) {
1112                                 case CONF_PROPERTY_NAME:
1113                                         strcpy(p, mycs->name1);
1114                                         break;
1115
1116                                 case CONF_PROPERTY_INSTANCE:
1117                                         strcpy(p, mycs->name2 ? mycs->name2 : mycs->name1);
1118                                         break;
1119
1120                                 default:
1121                                         ERROR("%s[%d]: Invalid property '%s'", cf, *lineno, q);
1122                                         return NULL;
1123                                 }
1124                                 p += strlen(p);
1125                                 ptr = end + 1;
1126
1127                         } else if (ci->type == CONF_ITEM_PAIR) {
1128                                 /*
1129                                  *  Substitute the value of the variable.
1130                                  */
1131                                 cp = cf_item_to_pair(ci);
1132
1133                                 /*
1134                                  *      If the thing we reference is
1135                                  *      marked up as being expanded in
1136                                  *      pass2, don't expand it now.
1137                                  *      Let it be expanded in pass2.
1138                                  */
1139                                 if (cp->pass2) {
1140                                         if (soft_fail) *soft_fail = true;
1141
1142                                         ERROR("%s[%d]: Reference \"%s\" points to a variable which has not been expanded.",
1143                                               cf, *lineno, input);
1144                                         return NULL;
1145                                 }
1146
1147                                 if (!cp->value) {
1148                                         ERROR("%s[%d]: Reference \"%s\" has no value",
1149                                                cf, *lineno, input);
1150                                         return NULL;
1151                                 }
1152
1153                                 if (p + strlen(cp->value) >= output + outsize) {
1154                                         ERROR("%s[%d]: Reference \"%s\" is too long",
1155                                                cf, *lineno, input);
1156                                         return NULL;
1157                                 }
1158
1159                                 strcpy(p, cp->value);
1160                                 p += strlen(p);
1161                                 ptr = end + 1;
1162
1163                         } else if (ci->type == CONF_ITEM_SECTION) {
1164                                 CONF_SECTION *subcs;
1165
1166                                 /*
1167                                  *      Adding an entry again to a
1168                                  *      section is wrong.  We don't
1169                                  *      want an infinite loop.
1170                                  */
1171                                 if (ci->parent == outercs) {
1172                                         ERROR("%s[%d]: Cannot reference different item in same section", cf, *lineno);
1173                                         return NULL;
1174                                 }
1175
1176                                 /*
1177                                  *      Copy the section instead of
1178                                  *      referencing it.
1179                                  */
1180                                 subcs = cf_item_to_section(ci);
1181                                 subcs = cf_section_dup(outercs, subcs,
1182                                                        cf_section_name1(subcs), cf_section_name2(subcs),
1183                                                        false);
1184                                 if (!subcs) {
1185                                         ERROR("%s[%d]: Failed copying reference %s", cf, *lineno, name);
1186                                         return NULL;
1187                                 }
1188
1189                                 subcs->item.filename = ci->filename;
1190                                 subcs->item.lineno = ci->lineno;
1191                                 cf_item_add(outercs, &(subcs->item));
1192
1193                                 ptr = end + 1;
1194
1195                         } else {
1196                                 ERROR("%s[%d]: Reference \"%s\" type is invalid", cf, *lineno, input);
1197                                 return NULL;
1198                         }
1199                 } else if (memcmp(ptr, "$ENV{", 5) == 0) {
1200                         char *env;
1201
1202                         ptr += 5;
1203
1204                         /*
1205                          *      Look for trailing '}', and log a
1206                          *      warning for anything that doesn't match,
1207                          *      and exit with a fatal error.
1208                          */
1209                         end = strchr(ptr, '}');
1210                         if (end == NULL) {
1211                                 *p = '\0';
1212                                 INFO("%s[%d]: Environment variable expansion missing }",
1213                                        cf, *lineno);
1214                                 return NULL;
1215                         }
1216
1217                         /*
1218                          *      Can't really happen because input lines are
1219                          *      capped at 8k, which is sizeof(name)
1220                          */
1221                         if ((size_t) (end - ptr) >= sizeof(name)) {
1222                                 ERROR("%s[%d]: Environment variable name is too large",
1223                                        cf, *lineno);
1224                                 return NULL;
1225                         }
1226
1227                         memcpy(name, ptr, end - ptr);
1228                         name[end - ptr] = '\0';
1229
1230                         /*
1231                          *      Get the environment variable.
1232                          *      If none exists, then make it an empty string.
1233                          */
1234                         env = getenv(name);
1235                         if (env == NULL) {
1236                                 *name = '\0';
1237                                 env = name;
1238                         }
1239
1240                         if (p + strlen(env) >= output + outsize) {
1241                                 ERROR("%s[%d]: Reference \"%s\" is too long",
1242                                        cf, *lineno, input);
1243                                 return NULL;
1244                         }
1245
1246                         strcpy(p, env);
1247                         p += strlen(p);
1248                         ptr = end + 1;
1249
1250                 } else {
1251                         /*
1252                          *      Copy it over verbatim.
1253                          */
1254                         *(p++) = *(ptr++);
1255                 }
1256
1257
1258                 if (p >= (output + outsize)) {
1259                         ERROR("%s[%d]: Reference \"%s\" is too long",
1260                                cf, *lineno, input);
1261                         return NULL;
1262                 }
1263         } /* loop over all of the input string. */
1264
1265         *p = '\0';
1266
1267         return output;
1268 }
1269
1270 static char const parse_spaces[] = "                                                                                                                                                                                                                                                                ";
1271
1272 /** Validation function for ipaddr conffile types
1273  *
1274  */
1275 static inline int fr_item_validate_ipaddr(CONF_SECTION *cs, char const *name, PW_TYPE type, char const *value,
1276                                           fr_ipaddr_t *ipaddr)
1277 {
1278         char ipbuf[128];
1279
1280         if (strcmp(value, "*") == 0) {
1281                 cf_log_info(cs, "%.*s\t%s = *", cs->depth, parse_spaces, name);
1282         } else if (strspn(value, ".0123456789abdefABCDEF:%[]/") == strlen(value)) {
1283                 cf_log_info(cs, "%.*s\t%s = %s", cs->depth, parse_spaces, name, value);
1284         } else {
1285                 cf_log_info(cs, "%.*s\t%s = %s IPv%s address [%s]", cs->depth, parse_spaces, name, value,
1286                             (ipaddr->af == AF_INET ? "4" : " 6"), ip_ntoh(ipaddr, ipbuf, sizeof(ipbuf)));
1287         }
1288
1289         switch (type) {
1290         case PW_TYPE_IPV4_ADDR:
1291         case PW_TYPE_IPV6_ADDR:
1292         case PW_TYPE_COMBO_IP_ADDR:
1293                 switch (ipaddr->af) {
1294                 case AF_INET:
1295                 if (ipaddr->prefix != 32) {
1296                         ERROR("Invalid IPv4 mask length \"/%i\".  Only \"/32\" permitted for non-prefix types",
1297                               ipaddr->prefix);
1298
1299                         return -1;
1300                 }
1301                         break;
1302
1303                 case AF_INET6:
1304                 if (ipaddr->prefix != 128) {
1305                         ERROR("Invalid IPv6 mask length \"/%i\".  Only \"/128\" permitted for non-prefix types",
1306                               ipaddr->prefix);
1307
1308                         return -1;
1309                 }
1310                         break;
1311
1312                 default:
1313                         return -1;
1314                 }
1315         default:
1316                 return 0;
1317         }
1318 }
1319
1320 /** Parses a #CONF_PAIR into a C data type, with a default value.
1321  *
1322  * Takes fields from a #CONF_PARSER struct and uses them to parse the string value
1323  * of a #CONF_PAIR into a C data type matching the type argument.
1324  *
1325  * The format of the types are the same as #value_data_t types.
1326  *
1327  * @note The dflt value will only be used if no matching #CONF_PAIR is found. Empty strings will not
1328  *       result in the dflt value being used.
1329  *
1330  * **PW_TYPE to data type mappings**
1331  * | PW_TYPE                 | Data type          | Dynamically allocated  |
1332  * | ----------------------- | ------------------ | ---------------------- |
1333  * | PW_TYPE_TMPL            | ``vp_tmpl_t``      | Yes                    |
1334  * | PW_TYPE_BOOLEAN         | ``bool``           | No                     |
1335  * | PW_TYPE_INTEGER         | ``uint32_t``       | No                     |
1336  * | PW_TYPE_SHORT           | ``uint16_t``       | No                     |
1337  * | PW_TYPE_INTEGER64       | ``uint64_t``       | No                     |
1338  * | PW_TYPE_SIGNED          | ``int32_t``        | No                     |
1339  * | PW_TYPE_STRING          | ``char const *``   | Yes                    |
1340  * | PW_TYPE_IPV4_ADDR       | ``fr_ipaddr_t``    | No                     |
1341  * | PW_TYPE_IPV4_PREFIX     | ``fr_ipaddr_t``    | No                     |
1342  * | PW_TYPE_IPV6_ADDR       | ``fr_ipaddr_t``    | No                     |
1343  * | PW_TYPE_IPV6_PREFIX     | ``fr_ipaddr_t``    | No                     |
1344  * | PW_TYPE_COMBO_IP_ADDR   | ``fr_ipaddr_t``    | No                     |
1345  * | PW_TYPE_COMBO_IP_PREFIX | ``fr_ipaddr_t``    | No                     |
1346  * | PW_TYPE_TIMEVAL         | ``struct timeval`` | No                     |
1347  *
1348  * @param cs to search for matching #CONF_PAIR in.
1349  * @param name of #CONF_PAIR to search for.
1350  * @param type Data type to parse #CONF_PAIR value as.
1351  *      Should be one of the following ``data`` types, and one or more of the following ``flag`` types or'd together:
1352  *      - ``data`` #PW_TYPE_TMPL                - @copybrief PW_TYPE_TMPL
1353  *                                                Feeds the value into #tmpl_afrom_str. Value can be
1354  *                                                obtained when processing requests, with #tmpl_expand or #tmpl_aexpand.
1355  *      - ``data`` #PW_TYPE_BOOLEAN             - @copybrief PW_TYPE_BOOLEAN
1356  *      - ``data`` #PW_TYPE_INTEGER             - @copybrief PW_TYPE_INTEGER
1357  *      - ``data`` #PW_TYPE_SHORT               - @copybrief PW_TYPE_SHORT
1358  *      - ``data`` #PW_TYPE_INTEGER64           - @copybrief PW_TYPE_INTEGER64
1359  *      - ``data`` #PW_TYPE_SIGNED              - @copybrief PW_TYPE_SIGNED
1360  *      - ``data`` #PW_TYPE_STRING              - @copybrief PW_TYPE_STRING
1361  *      - ``data`` #PW_TYPE_IPV4_ADDR           - @copybrief PW_TYPE_IPV4_ADDR (IPv4 address with prefix 32).
1362  *      - ``data`` #PW_TYPE_IPV4_PREFIX         - @copybrief PW_TYPE_IPV4_PREFIX (IPv4 address with variable prefix).
1363  *      - ``data`` #PW_TYPE_IPV6_ADDR           - @copybrief PW_TYPE_IPV6_ADDR (IPv6 address with prefix 128).
1364  *      - ``data`` #PW_TYPE_IPV6_PREFIX         - @copybrief PW_TYPE_IPV6_PREFIX (IPv6 address with variable prefix).
1365  *      - ``data`` #PW_TYPE_COMBO_IP_ADDR       - @copybrief PW_TYPE_COMBO_IP_ADDR (IPv4/IPv6 address with
1366  *                                                prefix 32/128).
1367  *      - ``data`` #PW_TYPE_COMBO_IP_PREFIX     - @copybrief PW_TYPE_COMBO_IP_PREFIX (IPv4/IPv6 address with
1368  *                                                variable prefix).
1369  *      - ``data`` #PW_TYPE_TIMEVAL             - @copybrief PW_TYPE_TIMEVAL
1370  *      - ``flag`` #PW_TYPE_DEPRECATED          - @copybrief PW_TYPE_DEPRECATED
1371  *      - ``flag`` #PW_TYPE_REQUIRED            - @copybrief PW_TYPE_REQUIRED
1372  *      - ``flag`` #PW_TYPE_ATTRIBUTE           - @copybrief PW_TYPE_ATTRIBUTE
1373  *      - ``flag`` #PW_TYPE_SECRET              - @copybrief PW_TYPE_SECRET
1374  *      - ``flag`` #PW_TYPE_FILE_INPUT          - @copybrief PW_TYPE_FILE_INPUT
1375  *      - ``flag`` #PW_TYPE_NOT_EMPTY           - @copybrief PW_TYPE_NOT_EMPTY
1376  * @param data Pointer to a global variable, or pointer to a field in the struct being populated with values.
1377  * @param dflt value to use, if no #CONF_PAIR is found.
1378  * @return
1379  *      - 1 if default value was used.
1380  *      - 0 on success.
1381  *      - -1 on error.
1382  *      - -2 if deprecated.
1383  */
1384 int cf_item_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *data, char const *dflt)
1385 {
1386         int rcode;
1387         bool deprecated, required, attribute, secret, file_input, cant_be_empty, tmpl, multi;
1388         char **q;
1389         char const *value;
1390         CONF_PAIR *cp = NULL;
1391         fr_ipaddr_t *ipaddr;
1392         char buffer[8192];
1393         CONF_ITEM *c_item = &cs->item;
1394
1395         if (!cs) return -1;
1396
1397         deprecated = (type & PW_TYPE_DEPRECATED);
1398         required = (type & PW_TYPE_REQUIRED);
1399         attribute = (type & PW_TYPE_ATTRIBUTE);
1400         secret = (type & PW_TYPE_SECRET);
1401         file_input = (type == PW_TYPE_FILE_INPUT);      /* check, not and */
1402         cant_be_empty = (type & PW_TYPE_NOT_EMPTY);
1403         tmpl = (type & PW_TYPE_TMPL);
1404         multi = (type & PW_TYPE_MULTI);
1405
1406         if (attribute) required = true;
1407         if (required) cant_be_empty = true;     /* May want to review this in the future... */
1408
1409         /*
1410          *      Everything except templates must have a base type.
1411          */
1412         if (!(type & 0xff) && !tmpl) {
1413                 cf_log_err(c_item, "Configuration item \"%s\" must have a data type", name);
1414                 return -1;
1415         }
1416
1417         type &= 0xff;                           /* normal types are small */
1418
1419         rcode = 0;
1420
1421         cp = cf_pair_find(cs, name);
1422
1423         /*
1424          *      No pairs match the configuration item name in the current
1425          *      section, use the default value.
1426          */
1427         if (!cp) {
1428                 if (deprecated) return 0;       /* Don't set the default value */
1429
1430                 rcode = 1;
1431                 value = dflt;
1432         /*
1433          *      Something matched, used the CONF_PAIR value.
1434          */
1435         } else {
1436                 CONF_PAIR *next = cp;
1437                 value = cp->value;
1438                 cp->parsed = true;
1439                 c_item = &cp->item;
1440
1441                 /*
1442                  *      @fixme We should actually validate
1443                  *      the value of the pairs too
1444                  */
1445                 if (multi) while ((next = cf_pair_find_next(cs, next, name))) {
1446                         next->parsed = true;
1447                 }
1448
1449                 if (deprecated) {
1450                         cf_log_err(c_item, "Configuration item \"%s\" is deprecated", name);
1451
1452                         return -2;
1453                 }
1454         }
1455
1456         if (!value) {
1457                 if (required) {
1458                 is_required:
1459                         cf_log_err(c_item, "Configuration item \"%s\" must have a value", name);
1460
1461                         return -1;
1462                 }
1463                 return rcode;
1464         }
1465
1466         if ((value[0] == '\0') && cant_be_empty) {
1467         cant_be_empty:
1468                 cf_log_err(c_item, "Configuration item \"%s\" must not be empty (zero length)", name);
1469                 if (!required) cf_log_err(c_item, "Comment item to silence this message");
1470
1471                 return -1;
1472         }
1473
1474
1475         /*
1476          *      Process a value as a LITERAL template.  Once all of
1477          *      the attrs and xlats are defined, the pass2 code
1478          *      converts it to the appropriate type.
1479          */
1480         if (tmpl) {
1481                 vp_tmpl_t *vpt;
1482
1483                 if (!value) {
1484                         *(vp_tmpl_t **)data = NULL;
1485                         return 0;
1486                 }
1487
1488                 rad_assert(!attribute);
1489                 vpt = tmpl_alloc(cs, TMPL_TYPE_LITERAL, value, strlen(value));
1490                 *(vp_tmpl_t **)data = vpt;
1491
1492                 return 0;
1493         }
1494
1495         switch (type) {
1496         case PW_TYPE_BOOLEAN:
1497                 /*
1498                  *      Allow yes/no, true/false, and on/off
1499                  */
1500                 if ((strcasecmp(value, "yes") == 0) ||
1501                     (strcasecmp(value, "true") == 0) ||
1502                     (strcasecmp(value, "on") == 0)) {
1503                         *(bool *)data = true;
1504                 } else if ((strcasecmp(value, "no") == 0) ||
1505                            (strcasecmp(value, "false") == 0) ||
1506                            (strcasecmp(value, "off") == 0)) {
1507                         *(bool *)data = false;
1508                 } else {
1509                         *(bool *)data = false;
1510                         cf_log_err(&(cs->item), "Invalid value \"%s\" for boolean "
1511                                "variable %s", value, name);
1512                         return -1;
1513                 }
1514                 cf_log_info(cs, "%.*s\t%s = %s",
1515                             cs->depth, parse_spaces, name, value);
1516                 break;
1517
1518         case PW_TYPE_INTEGER:
1519         {
1520                 unsigned long v = strtoul(value, 0, 0);
1521
1522                 /*
1523                  *      Restrict integer values to 0-INT32_MAX, this means
1524                  *      it will always be safe to cast them to a signed type
1525                  *      for comparisons, and imposes the same range limit as
1526                  *      before we switched to using an unsigned type to
1527                  *      represent config item integers.
1528                  */
1529                 if (v > INT32_MAX) {
1530                         cf_log_err(&(cs->item), "Invalid value \"%s\" for variable %s, must be between 0-%u", value,
1531                                    name, INT32_MAX);
1532                         return -1;
1533                 }
1534
1535                 *(uint32_t *)data = v;
1536                 cf_log_info(cs, "%.*s\t%s = %u", cs->depth, parse_spaces, name, *(uint32_t *)data);
1537         }
1538                 break;
1539
1540         case PW_TYPE_BYTE:
1541         {
1542                 unsigned long v = strtoul(value, 0, 0);
1543
1544                 if (v > UINT8_MAX) {
1545                         cf_log_err(&(cs->item), "Invalid value \"%s\" for variable %s, must be between 0-%u", value,
1546                                    name, UINT8_MAX);
1547                         return -1;
1548                 }
1549                 *(uint8_t *)data = (uint8_t) v;
1550                 cf_log_info(cs, "%.*s\t%s = %u", cs->depth, parse_spaces, name, *(uint8_t *)data);
1551         }
1552                 break;
1553
1554         case PW_TYPE_SHORT:
1555         {
1556                 unsigned long v = strtoul(value, 0, 0);
1557
1558                 if (v > UINT16_MAX) {
1559                         cf_log_err(&(cs->item), "Invalid value \"%s\" for variable %s, must be between 0-%u", value,
1560                                    name, UINT16_MAX);
1561                         return -1;
1562                 }
1563                 *(uint16_t *)data = (uint16_t) v;
1564                 cf_log_info(cs, "%.*s\t%s = %u", cs->depth, parse_spaces, name, *(uint16_t *)data);
1565         }
1566                 break;
1567
1568         case PW_TYPE_INTEGER64:
1569                 *(uint64_t *)data = strtoull(value, 0, 0);
1570                 cf_log_info(cs, "%.*s\t%s = %" PRIu64, cs->depth, parse_spaces, name, *(uint64_t *)data);
1571                 break;
1572
1573         case PW_TYPE_SIGNED:
1574                 *(int32_t *)data = strtol(value, 0, 0);
1575                 cf_log_info(cs, "%.*s\t%s = %d", cs->depth, parse_spaces, name, *(int32_t *)data);
1576                 break;
1577
1578         case PW_TYPE_STRING:
1579                 q = (char **) data;
1580                 if (*q != NULL) {
1581                         talloc_free(*q);
1582                 }
1583
1584                 /*
1585                  *      Expand variables which haven't already been
1586                  *      expanded automagically when the configuration
1587                  *      file was read.
1588                  */
1589                 if (value == dflt) {
1590                         int lineno = 0;
1591
1592                         lineno = cs->item.lineno;
1593
1594                         value = cf_expand_variables("<internal>",
1595                                                     &lineno,
1596                                                     cs, buffer, sizeof(buffer),
1597                                                     value, NULL);
1598                         if (!value) {
1599                                 cf_log_err(&(cs->item),"Failed expanding variable %s", name);
1600                                 return -1;
1601                         }
1602                 }
1603
1604                 if (required && !value) goto is_required;
1605                 if (cant_be_empty && (value[0] == '\0')) goto cant_be_empty;
1606
1607                 if (attribute) {
1608                         if (!dict_attrbyname(value)) {
1609                                 if (!cp) {
1610                                         cf_log_err(&(cs->item), "No such attribute '%s' for configuration '%s'",
1611                                                    value, name);
1612                                 } else {
1613                                         cf_log_err(&(cp->item), "No such attribute '%s'", value);
1614                                 }
1615                                 return -1;
1616                         }
1617                 }
1618
1619                 /*
1620                  *      Hide secrets when using "radiusd -X".
1621                  */
1622                 if (secret && (rad_debug_lvl <= 2)) {
1623                         cf_log_info(cs, "%.*s\t%s = <<< secret >>>",
1624                                     cs->depth, parse_spaces, name);
1625                 } else {
1626                         cf_log_info(cs, "%.*s\t%s = \"%s\"",
1627                                     cs->depth, parse_spaces, name, value ? value : "(null)");
1628                 }
1629                 *q = value ? talloc_typed_strdup(cs, value) : NULL;
1630
1631                 /*
1632                  *      If there's data AND it's an input file, check
1633                  *      that we can read it.  This check allows errors
1634                  *      to be caught as early as possible, during
1635                  *      server startup.
1636                  */
1637                 if (*q && file_input && !cf_file_input(cs, *q)) {
1638                         return -1;
1639                 }
1640                 break;
1641
1642         case PW_TYPE_IPV4_ADDR:
1643         case PW_TYPE_IPV4_PREFIX:
1644                 ipaddr = data;
1645
1646                 if (fr_pton4(ipaddr, value, -1, true, false) < 0) {
1647                         ERROR("%s", fr_strerror());
1648                         return -1;
1649                 }
1650                 if (fr_item_validate_ipaddr(cs, name, type, value, ipaddr) < 0) return -1;
1651                 break;
1652
1653         case PW_TYPE_IPV6_ADDR:
1654         case PW_TYPE_IPV6_PREFIX:
1655                 ipaddr = data;
1656
1657                 if (fr_pton6(ipaddr, value, -1, true, false) < 0) {
1658                         ERROR("%s", fr_strerror());
1659                         return -1;
1660                 }
1661                 if (fr_item_validate_ipaddr(cs, name, type, value, ipaddr) < 0) return -1;
1662                 break;
1663
1664         case PW_TYPE_COMBO_IP_ADDR:
1665         case PW_TYPE_COMBO_IP_PREFIX:
1666                 ipaddr = data;
1667
1668                 if (fr_pton(ipaddr, value, -1, AF_UNSPEC, true) < 0) {
1669                         ERROR("%s", fr_strerror());
1670                         return -1;
1671                 }
1672                 if (fr_item_validate_ipaddr(cs, name, type, value, ipaddr) < 0) return -1;
1673                 break;
1674
1675         case PW_TYPE_TIMEVAL: {
1676                 int sec;
1677                 char *end;
1678                 struct timeval tv;
1679
1680                 sec = strtoul(value, &end, 10);
1681                 tv.tv_sec = sec;
1682                 tv.tv_usec = 0;
1683                 if (*end == '.') {
1684                         size_t len;
1685
1686                         len = strlen(end + 1);
1687
1688                         if (len > 6) {
1689                                 ERROR("Too much precision for timeval");
1690                                 return -1;
1691                         }
1692
1693                         /*
1694                          *      If they write "0.1", that means
1695                          *      "10000" microseconds.
1696                          */
1697                         sec = strtoul(end + 1, NULL, 10);
1698                         while (len < 6) {
1699                                 sec *= 10;
1700                                 len++;
1701                         }
1702
1703                         tv.tv_usec = sec;
1704                 }
1705                 cf_log_info(cs, "%.*s\t%s = %d.%06d",
1706                             cs->depth, parse_spaces, name, (int) tv.tv_sec, (int) tv.tv_usec);
1707                 memcpy(data, &tv, sizeof(tv));
1708                 }
1709                 break;
1710
1711         default:
1712                 /*
1713                  *      If we get here, it's a sanity check error.
1714                  *      It's not an error parsing the configuration
1715                  *      file.
1716                  */
1717                 rad_assert(type > PW_TYPE_INVALID);
1718                 rad_assert(type < PW_TYPE_MAX);
1719
1720                 ERROR("type '%s' is not supported in the configuration files",
1721                        fr_int2str(dict_attr_types, type, "?Unknown?"));
1722                 return -1;
1723         } /* switch over variable type */
1724
1725         if (!cp) {
1726                 CONF_PAIR *cpn;
1727
1728                 cpn = cf_pair_alloc(cs, name, value, T_OP_SET, T_BARE_WORD, T_BARE_WORD);
1729                 if (!cpn) return -1;
1730                 cpn->parsed = true;
1731                 cpn->item.filename = "<internal>";
1732                 cpn->item.lineno = 0;
1733                 cf_item_add(cs, &(cpn->item));
1734         }
1735
1736         return rcode;
1737 }
1738
1739
1740 /*
1741  *      A copy of cf_section_parse that initializes pointers before
1742  *      parsing them.
1743  */
1744 static void cf_section_parse_init(CONF_SECTION *cs, void *base,
1745                                   CONF_PARSER const *variables)
1746 {
1747         int i;
1748
1749         for (i = 0; variables[i].name != NULL; i++) {
1750                 if (variables[i].type == PW_TYPE_SUBSECTION) {
1751                         CONF_SECTION *subcs;
1752
1753                         if (!variables[i].dflt) continue;
1754
1755                         subcs = cf_section_sub_find(cs, variables[i].name);
1756
1757                         /*
1758                          *      If there's no subsection in the
1759                          *      config, BUT the CONF_PARSER wants one,
1760                          *      then create an empty one.  This is so
1761                          *      that we can track the strings,
1762                          *      etc. allocated in the subsection.
1763                          */
1764                         if (!subcs) {
1765                                 subcs = cf_section_alloc(cs, variables[i].name, NULL);
1766                                 if (!subcs) return;
1767
1768                                 subcs->item.filename = cs->item.filename;
1769                                 subcs->item.lineno = cs->item.lineno;
1770                                 cf_item_add(cs, &(subcs->item));
1771                         }
1772
1773                         cf_section_parse_init(subcs, (uint8_t *)base + variables[i].offset,
1774                                               (CONF_PARSER const *) variables[i].dflt);
1775                         continue;
1776                 }
1777
1778                 if ((variables[i].type != PW_TYPE_STRING) &&
1779                     (variables[i].type != PW_TYPE_FILE_INPUT) &&
1780                     (variables[i].type != PW_TYPE_FILE_OUTPUT)) {
1781                         continue;
1782                 }
1783
1784                 if (variables[i].data) {
1785                         *(char **) variables[i].data = NULL;
1786                 } else if (base) {
1787                         *(char **) (((char *)base) + variables[i].offset) = NULL;
1788                 } else {
1789                         continue;
1790                 }
1791         } /* for all variables in the configuration section */
1792 }
1793
1794
1795 static void cf_section_parse_warn(CONF_SECTION *cs)
1796 {
1797         CONF_ITEM *ci;
1798
1799         for (ci = cs->children; ci; ci = ci->next) {
1800                 /*
1801                  *      Don't recurse on sections. We can only safely
1802                  *      check conf pairs at the same level as the
1803                  *      section that was just parsed.
1804                  */
1805                 if (ci->type == CONF_ITEM_SECTION) continue;
1806                 if (ci->type == CONF_ITEM_PAIR) {
1807                         CONF_PAIR *cp;
1808
1809                         cp = cf_item_to_pair(ci);
1810                         if (cp->parsed) continue;
1811
1812                         WARN("%s[%d]: The item '%s' is defined, but is unused by the configuration",
1813                              cp->item.filename ? cp->item.filename : "unknown",
1814                              cp->item.lineno ? cp->item.lineno : 0,
1815                                 cp->attr);
1816                 }
1817
1818                 /*
1819                  *      Skip everything else.
1820                  */
1821         }
1822 }
1823
1824 /** Parse a configuration section into user-supplied variables
1825  *
1826  * @param cs to parse.
1827  * @param base pointer to a struct to fill with data.  Any buffers will also be talloced
1828  *      using this parent as a pointer.
1829  * @param variables mappings between struct fields and #CONF_ITEM s.
1830  * @return
1831  *      - 0 on success.
1832  *      - -1 on general error.
1833  *      - -2 if a deprecated #CONF_ITEM was found.
1834  */
1835 int cf_section_parse(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
1836 {
1837         int ret = 0;
1838         int i;
1839         void *data;
1840
1841         cs->variables = variables; /* this doesn't hurt anything */
1842
1843         if (!cs->name2) {
1844                 cf_log_info(cs, "%.*s%s {", cs->depth, parse_spaces, cs->name1);
1845         } else {
1846                 cf_log_info(cs, "%.*s%s %s {", cs->depth, parse_spaces, cs->name1, cs->name2);
1847         }
1848
1849         cf_section_parse_init(cs, base, variables);
1850
1851         /*
1852          *      Handle the known configuration parameters.
1853          */
1854         for (i = 0; variables[i].name != NULL; i++) {
1855                 /*
1856                  *      Handle subsections specially
1857                  */
1858                 if (variables[i].type == PW_TYPE_SUBSECTION) {
1859                         CONF_SECTION *subcs;
1860
1861                         subcs = cf_section_sub_find(cs, variables[i].name);
1862                         /*
1863                          *      Default in this case is overloaded to mean a pointer
1864                          *      to the CONF_PARSER struct for the subsection.
1865                          */
1866                         if (!variables[i].dflt || !subcs) {
1867                                 ERROR("Internal sanity check 1 failed in cf_section_parse %s", variables[i].name);
1868                                 ret = -1;
1869                                 goto finish;
1870                         }
1871
1872                         ret = cf_section_parse(subcs, (uint8_t *)base + variables[i].offset,
1873                                                (CONF_PARSER const *) variables[i].dflt);
1874                         if (ret < 0) goto finish;
1875                         continue;
1876                 } /* else it's a CONF_PAIR */
1877
1878                 if (variables[i].data) {
1879                         data = variables[i].data; /* prefer this. */
1880                 } else if (base) {
1881                         data = ((char *)base) + variables[i].offset;
1882                 } else {
1883                         ERROR("Internal sanity check 2 failed in cf_section_parse");
1884                         ret = -1;
1885                         goto finish;
1886                 }
1887
1888                 /*
1889                  *      Parse the pair we found, or a default value.
1890                  */
1891                 ret = cf_item_parse(cs, variables[i].name, variables[i].type, data, variables[i].dflt);
1892                 switch (ret) {
1893                 case 1:         /* Used default */
1894                         ret = 0;
1895                         break;
1896
1897                 case 0:         /* OK */
1898                         break;
1899
1900                 case -1:        /* Parse error */
1901                         goto finish;
1902
1903                 case -2:        /* Deprecated CONF ITEM */
1904                         if ((variables[i + 1].offset == variables[i].offset) &&
1905                             (variables[i + 1].data == variables[i].data)) {
1906                                 cf_log_err(&(cs->item), "Replace \"%s\" with \"%s\"", variables[i].name,
1907                                            variables[i + 1].name);
1908                         }
1909                         goto finish;
1910                 }
1911         } /* for all variables in the configuration section */
1912
1913         /*
1914          *      Ensure we have a proper terminator, type so we catch
1915          *      missing terminators reliably
1916          */
1917         rad_assert(variables[i].type == -1);
1918
1919         /*
1920          *      Warn about items in the configuration which weren't
1921          *      checked during parsing.
1922          */
1923         if (rad_debug_lvl >= 3) cf_section_parse_warn(cs);
1924
1925         cs->base = base;
1926
1927         cf_log_info(cs, "%.*s}", cs->depth, parse_spaces);
1928
1929 finish:
1930         return ret;
1931 }
1932
1933
1934 /*
1935  *      Check XLAT things in pass 2.  But don't cache the xlat stuff anywhere.
1936  */
1937 int cf_section_parse_pass2(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
1938 {
1939         int i;
1940         ssize_t slen;
1941         char const *error;
1942         char *value = NULL;
1943         xlat_exp_t *xlat;
1944
1945         /*
1946          *      Handle the known configuration parameters.
1947          */
1948         for (i = 0; variables[i].name != NULL; i++) {
1949                 CONF_PAIR *cp;
1950                 void *data;
1951
1952                 /*
1953                  *      Handle subsections specially
1954                  */
1955                 if (variables[i].type == PW_TYPE_SUBSECTION) {
1956                         CONF_SECTION *subcs;
1957                         subcs = cf_section_sub_find(cs, variables[i].name);
1958
1959                         if (cf_section_parse_pass2(subcs, (uint8_t *)base + variables[i].offset,
1960                                                    (CONF_PARSER const *) variables[i].dflt) < 0) {
1961                                 return -1;
1962                         }
1963                         continue;
1964                 } /* else it's a CONF_PAIR */
1965
1966                 /*
1967                  *      Figure out which data we need to fix.
1968                  */
1969                 if (variables[i].data) {
1970                         data = variables[i].data; /* prefer this. */
1971                 } else if (base) {
1972                         data = ((char *)base) + variables[i].offset;
1973                 } else {
1974                         data = NULL;
1975                 }
1976
1977                 cp = cf_pair_find(cs, variables[i].name);
1978                 xlat = NULL;
1979
1980         redo:
1981                 if (!cp || !cp->value || !data) continue;
1982
1983                 if ((cp->rhs_type != T_DOUBLE_QUOTED_STRING) &&
1984                     (cp->rhs_type != T_BARE_WORD)) continue;
1985
1986                 /*
1987                  *      Non-xlat expansions shouldn't have xlat!
1988                  */
1989                 if (((variables[i].type & PW_TYPE_XLAT) == 0) &&
1990                     ((variables[i].type & PW_TYPE_TMPL) == 0)) {
1991                         /*
1992                          *      Ignore %{... in shared secrets.
1993                          *      They're never dynamically expanded.
1994                          */
1995                         if ((variables[i].type & PW_TYPE_SECRET) != 0) continue;
1996
1997                         if (strstr(cp->value, "%{") != NULL) {
1998                                 WARN("%s[%d]: Found dynamic expansion in string which will not be dynamically expanded",
1999                                      cp->item.filename ? cp->item.filename : "unknown",
2000                                      cp->item.lineno ? cp->item.lineno : 0);
2001                         }
2002                         continue;
2003                 }
2004
2005                 /*
2006                  *      Parse (and throw away) the xlat string.
2007                  *
2008                  *      FIXME: All of these should be converted from PW_TYPE_XLAT
2009                  *      to PW_TYPE_TMPL.
2010                  */
2011                 if ((variables[i].type & PW_TYPE_XLAT) != 0) {
2012                         /*
2013                          *      xlat expansions should be parseable.
2014                          */
2015                         value = talloc_strdup(cs, cp->value); /* modified by xlat_tokenize */
2016                         xlat = NULL;
2017
2018                         slen = xlat_tokenize(cs, value, &xlat, &error);
2019                         if (slen < 0) {
2020                                 char *spaces, *text;
2021
2022                         error:
2023                                 fr_canonicalize_error(cs, &spaces, &text, slen, cp->value);
2024
2025                                 cf_log_err(&cp->item, "Failed parsing expanded string:");
2026                                 cf_log_err(&cp->item, "%s", text);
2027                                 cf_log_err(&cp->item, "%s^ %s", spaces, error);
2028
2029                                 talloc_free(spaces);
2030                                 talloc_free(text);
2031                                 talloc_free(value);
2032                                 talloc_free(xlat);
2033                                 return -1;
2034                         }
2035
2036                         talloc_free(value);
2037                         talloc_free(xlat);
2038                 }
2039
2040                 /*
2041                  *      Convert the LITERAL template to the actual
2042                  *      type.
2043                  */
2044                 if ((variables[i].type & PW_TYPE_TMPL) != 0) {
2045                         vp_tmpl_t *vpt;
2046
2047                         slen = tmpl_afrom_str(cs, &vpt, cp->value, talloc_array_length(cp->value) - 1,
2048                                               cp->rhs_type,
2049                                               REQUEST_CURRENT, PAIR_LIST_REQUEST, true);
2050                         if (slen < 0) {
2051                                 error = fr_strerror();
2052                                 goto error;
2053                         }
2054
2055                         /*
2056                          *      Sanity check
2057                          *
2058                          *      Don't add default - update with new types.
2059                          */
2060                         switch (vpt->type) {
2061                         /*
2062                          *      All attributes should have been defined by this point.
2063                          */
2064                         case TMPL_TYPE_ATTR_UNDEFINED:
2065                                 cf_log_err(&cp->item, "Unknown attribute '%s'", vpt->tmpl_unknown_name);
2066                                 return -1;
2067
2068                         case TMPL_TYPE_LITERAL:
2069                         case TMPL_TYPE_ATTR:
2070                         case TMPL_TYPE_LIST:
2071                         case TMPL_TYPE_DATA:
2072                         case TMPL_TYPE_EXEC:
2073                         case TMPL_TYPE_XLAT:
2074                         case TMPL_TYPE_XLAT_STRUCT:
2075                                 break;
2076
2077                         case TMPL_TYPE_UNKNOWN:
2078                         case TMPL_TYPE_REGEX:
2079                         case TMPL_TYPE_REGEX_STRUCT:
2080                         case TMPL_TYPE_NULL:
2081                                 rad_assert(0);
2082                         }
2083
2084                         talloc_free(*(vp_tmpl_t **)data);
2085                         *(vp_tmpl_t **)data = vpt;
2086                 }
2087
2088                 /*
2089                  *      If the "multi" flag is set, check all of them.
2090                  */
2091                 if ((variables[i].type & PW_TYPE_MULTI) != 0) {
2092                         cp = cf_pair_find_next(cs, cp, cp->attr);
2093                         goto redo;
2094                 }
2095         } /* for all variables in the configuration section */
2096
2097         return 0;
2098 }
2099
2100 /*
2101  *      Merge the template so everyting else "just works".
2102  */
2103 static bool cf_template_merge(CONF_SECTION *cs, CONF_SECTION const *template)
2104 {
2105         CONF_ITEM *ci;
2106
2107         if (!cs || !template) return true;
2108
2109         cs->template = NULL;
2110
2111         /*
2112          *      Walk over the template, adding its' entries to the
2113          *      current section.  But only if the entries don't
2114          *      already exist in the current section.
2115          */
2116         for (ci = template->children; ci; ci = ci->next) {
2117                 if (ci->type == CONF_ITEM_PAIR) {
2118                         CONF_PAIR *cp1, *cp2;
2119
2120                         /*
2121                          *      It exists, don't over-write it.
2122                          */
2123                         cp1 = cf_item_to_pair(ci);
2124                         if (cf_pair_find(cs, cp1->attr)) {
2125                                 continue;
2126                         }
2127
2128                         /*
2129                          *      Create a new pair with all of the data
2130                          *      of the old one.
2131                          */
2132                         cp2 = cf_pair_dup(cs, cp1);
2133                         if (!cp2) return false;
2134
2135                         cp2->item.filename = cp1->item.filename;
2136                         cp2->item.lineno = cp1->item.lineno;
2137
2138                         cf_item_add(cs, &(cp2->item));
2139                         continue;
2140                 }
2141
2142                 if (ci->type == CONF_ITEM_SECTION) {
2143                         CONF_SECTION *subcs1, *subcs2;
2144
2145                         subcs1 = cf_item_to_section(ci);
2146                         rad_assert(subcs1 != NULL);
2147
2148                         subcs2 = cf_section_sub_find_name2(cs, subcs1->name1, subcs1->name2);
2149                         if (subcs2) {
2150                                 /*
2151                                  *      sub-sections get merged.
2152                                  */
2153                                 if (!cf_template_merge(subcs2, subcs1)) {
2154                                         return false;
2155                                 }
2156                                 continue;
2157                         }
2158
2159                         /*
2160                          *      Our section doesn't have a matching
2161                          *      sub-section.  Copy it verbatim from
2162                          *      the template.
2163                          */
2164                         subcs2 = cf_section_dup(cs, subcs1,
2165                                                 cf_section_name1(subcs1), cf_section_name2(subcs1),
2166                                                 false);
2167                         if (!subcs2) return false;
2168
2169                         subcs2->item.filename = subcs1->item.filename;
2170                         subcs2->item.lineno = subcs1->item.lineno;
2171
2172                         cf_item_add(cs, &(subcs2->item));
2173                         continue;
2174                 }
2175
2176                 /* ignore everything else */
2177         }
2178
2179         return true;
2180 }
2181
2182 static char const *cf_local_file(char const *base, char const *filename,
2183                                  char *buffer, size_t bufsize)
2184 {
2185         size_t dirsize;
2186         char *p;
2187
2188         strlcpy(buffer, base, bufsize);
2189
2190         p = strrchr(buffer, FR_DIR_SEP);
2191         if (!p) return filename;
2192         if (p[1]) {             /* ./foo */
2193                 p[1] = '\0';
2194         }
2195
2196         dirsize = (p - buffer) + 1;
2197
2198         if ((dirsize + strlen(filename)) >= bufsize) {
2199                 return NULL;
2200         }
2201
2202         strlcpy(p + 1, filename, bufsize - dirsize);
2203
2204         return buffer;
2205 }
2206
2207
2208 /*
2209  *      Read a part of the config file.
2210  */
2211 static int cf_section_read(char const *filename, int *lineno, FILE *fp,
2212                            CONF_SECTION *current)
2213
2214 {
2215         CONF_SECTION *this, *css;
2216         CONF_PAIR *cpn;
2217         char const *ptr;
2218         char const *value;
2219         char buf[8192];
2220         char buf1[8192];
2221         char buf2[8192];
2222         char buf3[8192];
2223         char buf4[8192];
2224         FR_TOKEN t1 = T_INVALID, t2, t3;
2225         bool has_spaces = false;
2226         bool pass2;
2227         char *cbuf = buf;
2228         size_t len;
2229
2230         this = current;         /* add items here */
2231
2232         /*
2233          *      Read, checking for line continuations ('\\' at EOL)
2234          */
2235         for (;;) {
2236                 int at_eof;
2237                 css = NULL;
2238
2239                 /*
2240                  *      Get data, and remember if we are at EOF.
2241                  */
2242                 at_eof = (fgets(cbuf, sizeof(buf) - (cbuf - buf), fp) == NULL);
2243                 (*lineno)++;
2244
2245                 /*
2246                  *      We read the entire 8k worth of data: complain.
2247                  *      Note that we don't care if the last character
2248                  *      is \n: it's still forbidden.  This means that
2249                  *      the maximum allowed length of text is 8k-1, which
2250                  *      should be plenty.
2251                  */
2252                 len = strlen(cbuf);
2253                 if ((cbuf + len + 1) >= (buf + sizeof(buf))) {
2254                         ERROR("%s[%d]: Line too long",
2255                                filename, *lineno);
2256                         return -1;
2257                 }
2258
2259                 if (has_spaces) {
2260                         ptr = cbuf;
2261                         while (isspace((int) *ptr)) ptr++;
2262
2263                         if (ptr > cbuf) {
2264                                 memmove(cbuf, ptr, len - (ptr - cbuf));
2265                                 len -= (ptr - cbuf);
2266                         }
2267                 }
2268
2269                 /*
2270                  *      Not doing continuations: check for edge
2271                  *      conditions.
2272                  */
2273                 if (cbuf == buf) {
2274                         if (at_eof) break;
2275
2276                         ptr = buf;
2277                         while (*ptr && isspace((int) *ptr)) ptr++;
2278
2279                         if (!*ptr || (*ptr == '#')) continue;
2280
2281                 } else if (at_eof || (len == 0)) {
2282                         ERROR("%s[%d]: Continuation at EOF is illegal",
2283                                filename, *lineno);
2284                         return -1;
2285                 }
2286
2287                 /*
2288                  *      See if there's a continuation.
2289                  */
2290                 while ((len > 0) &&
2291                        ((cbuf[len - 1] == '\n') || (cbuf[len - 1] == '\r'))) {
2292                         len--;
2293                         cbuf[len] = '\0';
2294                 }
2295
2296                 if ((len > 0) && (cbuf[len - 1] == '\\')) {
2297                         /*
2298                          *      Check for "suppress spaces" magic.
2299                          */
2300                         if (!has_spaces && (len > 2) && (cbuf[len - 2] == '"')) {
2301                                 has_spaces = true;
2302                         }
2303
2304                         cbuf[len - 1] = '\0';
2305                         cbuf += len - 1;
2306                         continue;
2307                 }
2308
2309                 ptr = cbuf = buf;
2310                 has_spaces = false;
2311
2312         get_more:
2313                 pass2 = false;
2314
2315                 /*
2316                  *      The parser is getting to be evil.
2317                  */
2318                 while ((*ptr == ' ') || (*ptr == '\t')) ptr++;
2319
2320                 if (((ptr[0] == '%') && (ptr[1] == '{')) ||
2321                     (ptr[0] == '`')) {
2322                         int hack;
2323
2324                         if (ptr[0] == '%') {
2325                                 hack = rad_copy_variable(buf1, ptr);
2326                         } else {
2327                                 hack = rad_copy_string(buf1, ptr);
2328                         }
2329                         if (hack < 0) {
2330                                 ERROR("%s[%d]: Invalid expansion: %s",
2331                                        filename, *lineno, ptr);
2332                                 return -1;
2333                         }
2334
2335                         ptr += hack;
2336
2337                         t2 = gettoken(&ptr, buf2, sizeof(buf2), true);
2338                         switch (t2) {
2339                         case T_EOL:
2340                         case T_HASH:
2341                                 goto do_bare_word;
2342
2343                         default:
2344                                 ERROR("%s[%d]: Invalid expansion: %s",
2345                                        filename, *lineno, ptr);
2346                                 return -1;
2347                         }
2348                 } else {
2349                         t1 = gettoken(&ptr, buf1, sizeof(buf1), true);
2350                 }
2351
2352                 /*
2353                  *      The caller eats "name1 name2 {", and calls us
2354                  *      for the data inside of the section.  So if we
2355                  *      receive a closing brace, then it must mean the
2356                  *      end of the section.
2357                  */
2358                if (t1 == T_RCBRACE) {
2359                        if (this == current) {
2360                                ERROR("%s[%d]: Too many closing braces",
2361                                       filename, *lineno);
2362                                return -1;
2363                        }
2364
2365                        /*
2366                         *       Merge the template into the existing
2367                         *       section.  This uses more memory, but
2368                         *       means that templates now work with
2369                         *       sub-sections, etc.
2370                         */
2371                        if (!cf_template_merge(this, this->template)) {
2372                                return -1;
2373                        }
2374
2375                        this = this->item.parent;
2376                        goto check_for_more;
2377                }
2378
2379                if (t1 != T_BARE_WORD) goto skip_keywords;
2380
2381                 /*
2382                  *      Allow for $INCLUDE files
2383                  *
2384                  *      This *SHOULD* work for any level include.
2385                  *      I really really really hate this file.  -cparker
2386                  */
2387                if ((strcasecmp(buf1, "$INCLUDE") == 0) ||
2388                    (strcasecmp(buf1, "$-INCLUDE") == 0)) {
2389                         bool relative = true;
2390
2391                         t2 = getword(&ptr, buf2, sizeof(buf2), true);
2392                         if (t2 != T_EOL) {
2393                                ERROR("%s[%d]: Unexpected text after $INCLUDE",
2394                                      filename, *lineno);
2395                                return -1;
2396                         }
2397
2398                         if (buf2[0] == '$') relative = false;
2399
2400                         value = cf_expand_variables(filename, lineno, this, buf4, sizeof(buf4), buf2, NULL);
2401                         if (!value) return -1;
2402
2403                         if (!FR_DIR_IS_RELATIVE(value)) relative = false;
2404
2405                         if (relative) {
2406                                 value = cf_local_file(filename, value, buf3,
2407                                                       sizeof(buf3));
2408                                 if (!value) {
2409                                         ERROR("%s[%d]: Directories too deep.",
2410                                                filename, *lineno);
2411                                         return -1;
2412                                 }
2413                         }
2414
2415
2416 #ifdef HAVE_DIRENT_H
2417                         /*
2418                          *      $INCLUDE foo/
2419                          *
2420                          *      Include ALL non-"dot" files in the directory.
2421                          *      careful!
2422                          */
2423                         if (value[strlen(value) - 1] == '/') {
2424                                 DIR             *dir;
2425                                 struct dirent   *dp;
2426                                 struct stat stat_buf;
2427
2428                                 DEBUG2("including files in directory %s", value );
2429 #ifdef S_IWOTH
2430                                 /*
2431                                  *      Security checks.
2432                                  */
2433                                 if (stat(value, &stat_buf) < 0) {
2434                                         ERROR("%s[%d]: Failed reading directory %s: %s",
2435                                                filename, *lineno,
2436                                                value, fr_syserror(errno));
2437                                         return -1;
2438                                 }
2439
2440                                 if ((stat_buf.st_mode & S_IWOTH) != 0) {
2441                                         ERROR("%s[%d]: Directory %s is globally writable.  Refusing to start due to "
2442                                               "insecure configuration", filename, *lineno, value);
2443                                         return -1;
2444                                 }
2445 #endif
2446                                 dir = opendir(value);
2447                                 if (!dir) {
2448                                         ERROR("%s[%d]: Error reading directory %s: %s",
2449                                                filename, *lineno, value,
2450                                                fr_syserror(errno));
2451                                         return -1;
2452                                 }
2453
2454                                 /*
2455                                  *      Read the directory, ignoring "." files.
2456                                  */
2457                                 while ((dp = readdir(dir)) != NULL) {
2458                                         char const *p;
2459
2460                                         if (dp->d_name[0] == '.') continue;
2461
2462                                         /*
2463                                          *      Check for valid characters
2464                                          */
2465                                         for (p = dp->d_name; *p != '\0'; p++) {
2466                                                 if (isalpha((int)*p) ||
2467                                                     isdigit((int)*p) ||
2468                                                     (*p == '-') ||
2469                                                     (*p == '_') ||
2470                                                     (*p == '.')) continue;
2471                                                 break;
2472                                         }
2473                                         if (*p != '\0') continue;
2474
2475                                         snprintf(buf2, sizeof(buf2), "%s%s",
2476                                                  value, dp->d_name);
2477                                         if ((stat(buf2, &stat_buf) != 0) ||
2478                                             S_ISDIR(stat_buf.st_mode)) continue;
2479                                         /*
2480                                          *      Read the file into the current
2481                                          *      configuration section.
2482                                          */
2483                                         if (cf_file_include(this, buf2) < 0) {
2484                                                 closedir(dir);
2485                                                 return -1;
2486                                         }
2487                                 }
2488                                 closedir(dir);
2489                         }  else
2490 #endif
2491                         { /* it was a normal file */
2492                                 if (buf1[1] == '-') {
2493                                         struct stat statbuf;
2494
2495                                         if (stat(value, &statbuf) < 0) {
2496                                                 WARN("Not including file %s: %s", value, fr_syserror(errno));
2497                                                 continue;
2498                                         }
2499                                 }
2500
2501                                 if (cf_file_include(this, value) < 0) {
2502                                         return -1;
2503                                 }
2504                         }
2505                         continue;
2506                 } /* we were in an include */
2507
2508                if (strcasecmp(buf1, "$template") == 0) {
2509                        CONF_ITEM *ci;
2510                        CONF_SECTION *parentcs, *templatecs;
2511                        t2 = getword(&ptr, buf2, sizeof(buf2), true);
2512
2513                        if (t2 != T_EOL) {
2514                                ERROR("%s[%d]: Unexpected text after $TEMPLATE", filename, *lineno);
2515                                return -1;
2516                        }
2517
2518                        parentcs = cf_top_section(current);
2519
2520                        templatecs = cf_section_sub_find(parentcs, "templates");
2521                        if (!templatecs) {
2522                                 ERROR("%s[%d]: No \"templates\" section for reference \"%s\"", filename, *lineno, buf2);
2523                                 return -1;
2524                        }
2525
2526                        ci = cf_reference_item(parentcs, templatecs, buf2);
2527                        if (!ci || (ci->type != CONF_ITEM_SECTION)) {
2528                                 ERROR("%s[%d]: Reference \"%s\" not found", filename, *lineno, buf2);
2529                                 return -1;
2530                        }
2531
2532                        if (!this) {
2533                                 ERROR("%s[%d]: Internal sanity check error in template reference", filename, *lineno);
2534                                 return -1;
2535                        }
2536
2537                        if (this->template) {
2538                                 ERROR("%s[%d]: Section already has a template", filename, *lineno);
2539                                 return -1;
2540                        }
2541
2542                        this->template = cf_item_to_section(ci);
2543                        continue;
2544                }
2545
2546                 /*
2547                  *      Ensure that the user can't add CONF_PAIRs
2548                  *      with 'internal' names;
2549                  */
2550                 if (buf1[0] == '_') {
2551                         ERROR("%s[%d]: Illegal configuration pair name \"%s\"", filename, *lineno, buf1);
2552                         return -1;
2553                 }
2554
2555                 /*
2556                  *      Handle if/elsif specially.
2557                  */
2558                 if ((strcmp(buf1, "if") == 0) || (strcmp(buf1, "elsif") == 0)) {
2559                         ssize_t slen;
2560                         char const *error = NULL;
2561                         char *p;
2562                         CONF_SECTION *server;
2563                         fr_cond_t *cond = NULL;
2564
2565                         /*
2566                          *      if / elsif MUST be inside of a
2567                          *      processing section, which MUST in turn
2568                          *      be inside of a "server" directive.
2569                          */
2570                         if (!this->item.parent) {
2571                         invalid_location:
2572                                 ERROR("%s[%d]: Invalid location for '%s'",
2573                                        filename, *lineno, buf1);
2574                                 return -1;
2575                         }
2576
2577                         /*
2578                          *      Can only have "if" in 3 named sections.
2579                          */
2580                         server = this->item.parent;
2581                         while (server &&
2582                                (strcmp(server->name1, "server") != 0) &&
2583                                (strcmp(server->name1, "policy") != 0) &&
2584                                (strcmp(server->name1, "instantiate") != 0)) {
2585                                 server = server->item.parent;
2586                                 if (!server) goto invalid_location;
2587                         }
2588
2589                         /*
2590                          *      Skip (...) to find the {
2591                          */
2592                         slen = fr_condition_tokenize(this, cf_section_to_item(this), ptr, &cond,
2593                                                      &error, FR_COND_TWO_PASS);
2594                         memcpy(&p, &ptr, sizeof(p));
2595
2596                         if (slen < 0) {
2597                                 if (p[-slen] != '{') goto cond_error;
2598                                 slen = -slen;
2599                         }
2600                         TALLOC_FREE(cond);
2601
2602                         /*
2603                          *      This hack is so that the NEXT stage
2604                          *      doesn't go "too far" in expanding the
2605                          *      variable.  We can parse the conditions
2606                          *      without expanding the ${...} stuff.
2607                          *      BUT we don't want to expand all of the
2608                          *      stuff AFTER the condition.  So we do
2609                          *      two passes.
2610                          *
2611                          *      The first pass is to discover the end
2612                          *      of the condition.  We then expand THAT
2613                          *      string, and do a second pass parsing
2614                          *      the expanded condition.
2615                          */
2616                         p += slen;
2617                         *p = '\0';
2618
2619                         /*
2620                          *      If there's a ${...}.  If so, expand it.
2621                          */
2622                         if (strchr(ptr, '$') != NULL) {
2623                                 ptr = cf_expand_variables(filename, lineno,
2624                                                           this,
2625                                                           buf3, sizeof(buf3),
2626                                                           ptr, NULL);
2627                                 if (!ptr) {
2628                                         ERROR("%s[%d]: Parse error expanding ${...} in condition",
2629                                               filename, *lineno);
2630                                         return -1;
2631                                 }
2632                         } /* else leave it alone */
2633
2634                         css = cf_section_alloc(this, buf1, ptr);
2635                         if (!css) {
2636                                 ERROR("%s[%d]: Failed allocating memory for section",
2637                                       filename, *lineno);
2638                                 return -1;
2639                         }
2640                         css->item.filename = filename;
2641                         css->item.lineno = *lineno;
2642
2643                         slen = fr_condition_tokenize(css, cf_section_to_item(css), ptr, &cond,
2644                                                      &error, FR_COND_TWO_PASS);
2645                         *p = '{'; /* put it back */
2646
2647                 cond_error:
2648                         if (slen < 0) {
2649                                 char *spaces, *text;
2650
2651                                 fr_canonicalize_error(this, &spaces, &text, slen, ptr);
2652
2653                                 ERROR("%s[%d]: Parse error in condition",
2654                                       filename, *lineno);
2655                                 ERROR("%s[%d]: %s", filename, *lineno, text);
2656                                 ERROR("%s[%d]: %s^ %s", filename, *lineno, spaces, error);
2657
2658                                 talloc_free(spaces);
2659                                 talloc_free(text);
2660                                 talloc_free(css);
2661                                 return -1;
2662                         }
2663
2664                         if ((size_t) slen >= (sizeof(buf2) - 1)) {
2665                                 talloc_free(css);
2666                                 ERROR("%s[%d]: Condition is too large after \"%s\"",
2667                                        filename, *lineno, buf1);
2668                                 return -1;
2669                         }
2670
2671                         /*
2672                          *      Copy the expanded and parsed condition
2673                          *      into buf2.  Then, parse the text after
2674                          *      the condition, which now MUST be a '{.
2675                          *
2676                          *      If it wasn't '{' it would have been
2677                          *      caught in the first pass of
2678                          *      conditional parsing, above.
2679                          */
2680                         memcpy(buf2, ptr, slen);
2681                         buf2[slen] = '\0';
2682                         ptr = p;
2683
2684                         if ((t3 = gettoken(&ptr, buf3, sizeof(buf3), true)) != T_LCBRACE) {
2685                                 talloc_free(css);
2686                                 ERROR("%s[%d]: Expected '{' %d",
2687                                       filename, *lineno, t3);
2688                                 return -1;
2689                         }
2690
2691                         /*
2692                          *      Swap the condition with trailing stuff for
2693                          *      the final condition.
2694                          */
2695                         memcpy(&p, &css->name2, sizeof(css->name2));
2696                         talloc_free(p);
2697                         css->name2 = talloc_typed_strdup(css, buf2);
2698
2699                         cf_item_add(this, &(css->item));
2700                         cf_data_add_internal(css, "if", cond, NULL, false);
2701
2702                         /*
2703                          *      The current section is now the child section.
2704                          */
2705                         this = css;
2706                         css = NULL;
2707                         goto check_for_more;
2708                 }
2709
2710         skip_keywords:
2711                 /*
2712                  *      Grab the next token.
2713                  */
2714                 t2 = gettoken(&ptr, buf2, sizeof(buf2), !cf_new_escape);
2715                 switch (t2) {
2716                 case T_EOL:
2717                 case T_HASH:
2718                 case T_COMMA:
2719                 do_bare_word:
2720                         t3 = t2;
2721                         t2 = T_OP_EQ;
2722                         value = NULL;
2723                         goto do_set;
2724
2725                 case T_OP_INCRM:
2726                 case T_OP_ADD:
2727                 case T_OP_CMP_EQ:
2728                 case T_OP_SUB:
2729                 case T_OP_LE:
2730                 case T_OP_GE:
2731                 case T_OP_CMP_FALSE:
2732                         if (!this || (strcmp(this->name1, "update") != 0)) {
2733                                 ERROR("%s[%d]: Invalid operator in assignment",
2734                                        filename, *lineno);
2735                                 return -1;
2736                         }
2737                         /* FALL-THROUGH */
2738
2739                 case T_OP_EQ:
2740                 case T_OP_SET:
2741                         while (isspace((int) *ptr)) ptr++;
2742
2743                         /*
2744                          *      New parser: non-quoted strings are
2745                          *      bare words, and we parse everything
2746                          *      until the next newline, or the next
2747                          *      comma.  If they have { or } in a bare
2748                          *      word, well... too bad.
2749                          */
2750                         if (cf_new_escape && (*ptr != '"') && (*ptr != '\'')
2751                             && (*ptr != '`') && (*ptr != '/')) {
2752                                 const char *q = ptr;
2753
2754                                 t3 = T_BARE_WORD;
2755                                 while (*q && (*q >= ' ') && (*q != ',') &&
2756                                        !isspace(*q)) q++;
2757
2758                                 if ((size_t) (q - ptr) >= sizeof(buf3)) {
2759                                         ERROR("%s[%d]: Parse error: value too long",
2760                                               filename, *lineno);
2761                                         return -1;
2762                                 }
2763
2764                                 memcpy(buf3, ptr, (q - ptr));
2765                                 buf3[q - ptr] = '\0';
2766                                 ptr = q;
2767
2768                         } else {
2769                                 t3 = getstring(&ptr, buf3, sizeof(buf3), !cf_new_escape);
2770                         }
2771
2772                         if (t3 == T_INVALID) {
2773                                 ERROR("%s[%d]: Parse error: %s",
2774                                        filename, *lineno,
2775                                        fr_strerror());
2776                                 return -1;
2777                         }
2778
2779                         /*
2780                          *      Allow "foo" by itself, or "foo = bar"
2781                          */
2782                         switch (t3) {
2783                                 bool soft_fail;
2784
2785                         case T_BARE_WORD:
2786                         case T_DOUBLE_QUOTED_STRING:
2787                         case T_BACK_QUOTED_STRING:
2788                                 value = cf_expand_variables(filename, lineno, this, buf4, sizeof(buf4), buf3, &soft_fail);
2789                                 if (!value) {
2790                                         if (!soft_fail) return -1;
2791
2792                                         /*
2793                                          *      References an item which doesn't exist,
2794                                          *      or which is already marked up as being
2795                                          *      expanded in pass2.  Wait for pass2 to
2796                                          *      do the expansions.
2797                                          */
2798                                         pass2 = true;
2799                                         value = buf3;
2800                                 }
2801                                 break;
2802
2803                         case T_EOL:
2804                         case T_HASH:
2805                                 value = NULL;
2806                                 break;
2807
2808                         default:
2809                                 value = buf3;
2810                                 break;
2811                         }
2812
2813                         /*
2814                          *      Add this CONF_PAIR to our CONF_SECTION
2815                          */
2816                 do_set:
2817                         cpn = cf_pair_alloc(this, buf1, value, t2, t1, t3);
2818                         if (!cpn) return -1;
2819                         cpn->item.filename = filename;
2820                         cpn->item.lineno = *lineno;
2821                         cpn->pass2 = pass2;
2822                         cf_item_add(this, &(cpn->item));
2823
2824                         /*
2825                          *      Hacks for escaping
2826                          */
2827                         if (!cf_new_escape && !this->item.parent && value &&
2828                             (strcmp(buf1, "correct_escapes") == 0) &&
2829                             ((strcmp(value, "true") == 0) ||
2830                              (strcmp(value, "yes") == 0) ||
2831                              (strcmp(value, "1") == 0))) {
2832                                 cf_new_escape = true;
2833                         }
2834
2835                         /*
2836                          *      Require a comma, unless there's a comment.
2837                          */
2838                         while (isspace(*ptr)) ptr++;
2839
2840                         if (*ptr == ',') {
2841                                 ptr++;
2842                                 break;
2843                         }
2844
2845                         /*
2846                          *      module # stuff!
2847                          *      foo = bar # other stuff
2848                          */
2849                         if ((t3 == T_HASH) || (t3 == T_COMMA) || (t3 == T_EOL) || (*ptr == '#')) continue;
2850
2851                         if (!*ptr || (*ptr == '}')) break;
2852
2853                         ERROR("%s[%d]: Syntax error: Expected comma after '%s': %s",
2854                               filename, *lineno, value, ptr);
2855                         return -1;
2856
2857                         /*
2858                          *      No '=', must be a section or sub-section.
2859                          */
2860                 case T_BARE_WORD:
2861                 case T_DOUBLE_QUOTED_STRING:
2862                 case T_SINGLE_QUOTED_STRING:
2863                         t3 = gettoken(&ptr, buf3, sizeof(buf3), true);
2864                         if (t3 != T_LCBRACE) {
2865                                 ERROR("%s[%d]: Expecting section start brace '{' after \"%s %s\"",
2866                                        filename, *lineno, buf1, buf2);
2867                                 return -1;
2868                         }
2869                         /* FALL-THROUGH */
2870
2871                 case T_LCBRACE:
2872                         css = cf_section_alloc(this, buf1,
2873                                                t2 == T_LCBRACE ? NULL : buf2);
2874                         if (!css) {
2875                                 ERROR("%s[%d]: Failed allocating memory for section",
2876                                       filename, *lineno);
2877                                 return -1;
2878                         }
2879
2880                         css->item.filename = filename;
2881                         css->item.lineno = *lineno;
2882                         cf_item_add(this, &(css->item));
2883
2884                         /*
2885                          *      There may not be a name2
2886                          */
2887                         css->name2_type = (t2 == T_LCBRACE) ? T_INVALID : t2;
2888
2889                         /*
2890                          *      The current section is now the child section.
2891                          */
2892                         this = css;
2893                         break;
2894
2895                 case T_INVALID:
2896                         ERROR("%s[%d]: Syntax error in '%s': %s", filename, *lineno, ptr, fr_strerror());
2897
2898                         return -1;
2899
2900                 default:
2901                         ERROR("%s[%d]: Parse error after \"%s\": unexpected token \"%s\"",
2902                               filename, *lineno, buf1, fr_int2str(fr_tokens, t2, "<INVALID>"));
2903
2904                         return -1;
2905                 }
2906
2907         check_for_more:
2908                 /*
2909                  *      Done parsing one thing.  Skip to EOL if possible.
2910                  */
2911                 while (isspace(*ptr)) ptr++;
2912
2913                 if (*ptr == '#') continue;
2914
2915                 if (*ptr) {
2916                         goto get_more;
2917                 }
2918
2919         }
2920
2921         /*
2922          *      See if EOF was unexpected ..
2923          */
2924         if (feof(fp) && (this != current)) {
2925                 ERROR("%s[%d]: EOF reached without closing brace for section %s starting at line %d",
2926                       filename, *lineno, cf_section_name1(this), cf_section_lineno(this));
2927                 return -1;
2928         }
2929
2930         return 0;
2931 }
2932
2933 /*
2934  *      Include one config file in another.
2935  */
2936 static int cf_file_include(CONF_SECTION *cs, char const *filename_in)
2937 {
2938         FILE            *fp;
2939         int             lineno = 0;
2940         char const      *filename;
2941
2942         /*
2943          *      So we only need to do this once.
2944          */
2945         filename = talloc_strdup(cs, filename_in);
2946
2947         DEBUG2("including configuration file %s", filename);
2948
2949         fp = cf_file_open(cs, filename);
2950         if (!fp) return -1;
2951
2952         if (!cs->item.filename) cs->item.filename = filename;
2953
2954         /*
2955          *      Read the section.  It's OK to have EOF without a
2956          *      matching close brace.
2957          */
2958         if (cf_section_read(filename, &lineno, fp, cs) < 0) {
2959                 fclose(fp);
2960                 return -1;
2961         }
2962
2963         fclose(fp);
2964         return 0;
2965 }
2966
2967
2968 /*
2969  *      Do variable expansion in pass2.
2970  *
2971  *      This is a breadth-first expansion.  "deep
2972  */
2973 static int cf_section_pass2(CONF_SECTION *cs)
2974 {
2975         CONF_ITEM *ci;
2976
2977         for (ci = cs->children; ci; ci = ci->next) {
2978                 char const *value;
2979                 CONF_PAIR *cp;
2980                 char buffer[8192];
2981
2982                 if (ci->type != CONF_ITEM_PAIR) continue;
2983
2984                 cp = cf_item_to_pair(ci);
2985                 if (!cp->value || !cp->pass2) continue;
2986
2987                 rad_assert((cp->rhs_type == T_BARE_WORD) ||
2988                            (cp->rhs_type == T_DOUBLE_QUOTED_STRING) ||
2989                            (cp->rhs_type == T_BACK_QUOTED_STRING));
2990
2991                 value = cf_expand_variables(ci->filename, &ci->lineno, cs, buffer, sizeof(buffer), cp->value, NULL);
2992                 if (!value) return -1;
2993
2994                 rad_const_free(cp->value);
2995                 cp->value = talloc_typed_strdup(cp, value);
2996         }
2997
2998         for (ci = cs->children; ci; ci = ci->next) {
2999                 if (ci->type != CONF_ITEM_SECTION) continue;
3000
3001                 if (cf_section_pass2(cf_item_to_section(ci)) < 0) return -1;
3002         }
3003
3004         return 0;
3005 }
3006
3007
3008 /*
3009  *      Bootstrap a config file.
3010  */
3011 int cf_file_read(CONF_SECTION *cs, char const *filename)
3012 {
3013         char *p;
3014         CONF_PAIR *cp;
3015         rbtree_t *tree;
3016
3017         cp = cf_pair_alloc(cs, "confdir", filename, T_OP_SET, T_BARE_WORD, T_SINGLE_QUOTED_STRING);
3018         if (!cp) return -1;
3019
3020         p = strrchr(cp->value, FR_DIR_SEP);
3021         if (p) *p = '\0';
3022
3023         cp->item.filename = "<internal>";
3024         cp->item.lineno = -1;
3025         cf_item_add(cs, &(cp->item));
3026
3027         tree = rbtree_create(cs, filename_cmp, NULL, 0);
3028         if (!tree) return -1;
3029
3030         cf_data_add_internal(cs, "filename", tree, NULL, 0);
3031
3032         if (cf_file_include(cs, filename) < 0) return -1;
3033
3034         /*
3035          *      Now that we've read the file, go back through it and
3036          *      expand the variables.
3037          */
3038         if (cf_section_pass2(cs) < 0) return -1;
3039
3040         return 0;
3041 }
3042
3043
3044 void cf_file_free(CONF_SECTION *cs)
3045 {
3046         talloc_free(cs);
3047 }
3048
3049
3050 /*
3051  * Return a CONF_PAIR within a CONF_SECTION.
3052  */
3053 CONF_PAIR *cf_pair_find(CONF_SECTION const *cs, char const *name)
3054 {
3055         CONF_PAIR *cp, mycp;
3056
3057         if (!cs || !name) return NULL;
3058
3059         mycp.attr = name;
3060         cp = rbtree_finddata(cs->pair_tree, &mycp);
3061         if (cp) return cp;
3062
3063         if (!cs->template) return NULL;
3064
3065         return rbtree_finddata(cs->template->pair_tree, &mycp);
3066 }
3067
3068 /*
3069  * Return the attr of a CONF_PAIR
3070  */
3071
3072 char const *cf_pair_attr(CONF_PAIR const *pair)
3073 {
3074         return (pair ? pair->attr : NULL);
3075 }
3076
3077 /*
3078  * Return the value of a CONF_PAIR
3079  */
3080
3081 char const *cf_pair_value(CONF_PAIR const *pair)
3082 {
3083         return (pair ? pair->value : NULL);
3084 }
3085
3086 FR_TOKEN cf_pair_operator(CONF_PAIR const *pair)
3087 {
3088         return (pair ? pair->op : T_INVALID);
3089 }
3090
3091 /** Return the value (lhs) type
3092  *
3093  * @param pair to extract value type from.
3094  * @return one of T_BARE_WORD, T_SINGLE_QUOTED_STRING, T_BACK_QUOTED_STRING
3095  *      T_DOUBLE_QUOTED_STRING or T_INVALID if the pair is NULL.
3096  */
3097 FR_TOKEN cf_pair_attr_type(CONF_PAIR const *pair)
3098 {
3099         return (pair ? pair->lhs_type : T_INVALID);
3100 }
3101
3102 /** Return the value (rhs) type
3103  *
3104  * @param pair to extract value type from.
3105  * @return one of T_BARE_WORD, T_SINGLE_QUOTED_STRING, T_BACK_QUOTED_STRING
3106  *      T_DOUBLE_QUOTED_STRING or T_INVALID if the pair is NULL.
3107  */
3108 FR_TOKEN cf_pair_value_type(CONF_PAIR const *pair)
3109 {
3110         return (pair ? pair->rhs_type : T_INVALID);
3111 }
3112
3113 /*
3114  * Turn a CONF_PAIR into a VALUE_PAIR
3115  * For now, ignore the "value_type" field...
3116  */
3117 VALUE_PAIR *cf_pairtovp(CONF_PAIR *pair)
3118 {
3119         if (!pair) {
3120                 fr_strerror_printf("Internal error");
3121                 return NULL;
3122         }
3123
3124         if (!pair->value) {
3125                 fr_strerror_printf("No value given for attribute %s", pair->attr);
3126                 return NULL;
3127         }
3128
3129         /*
3130          *      false comparisons never match.  BUT if it's a "string"
3131          *      or `string`, then remember to expand it later.
3132          */
3133         if ((pair->op != T_OP_CMP_FALSE) &&
3134             ((pair->rhs_type == T_DOUBLE_QUOTED_STRING) ||
3135              (pair->rhs_type == T_BACK_QUOTED_STRING))) {
3136                 VALUE_PAIR *vp;
3137
3138                 vp = fr_pair_make(pair, NULL, pair->attr, NULL, pair->op);
3139                 if (!vp) {
3140                         return NULL;
3141                 }
3142
3143                 if (fr_pair_mark_xlat(vp, pair->value) < 0) {
3144                         talloc_free(vp);
3145
3146                         return NULL;
3147                 }
3148
3149                 return vp;
3150         }
3151
3152         return fr_pair_make(pair, NULL, pair->attr, pair->value, pair->op);
3153 }
3154
3155 /*
3156  * Return the first label of a CONF_SECTION
3157  */
3158
3159 char const *cf_section_name1(CONF_SECTION const *cs)
3160 {
3161         return (cs ? cs->name1 : NULL);
3162 }
3163
3164 /*
3165  * Return the second label of a CONF_SECTION
3166  */
3167
3168 char const *cf_section_name2(CONF_SECTION const *cs)
3169 {
3170         return (cs ? cs->name2 : NULL);
3171 }
3172
3173 /** Return name2 if set, else name1
3174  *
3175  */
3176 char const *cf_section_name(CONF_SECTION const *cs)
3177 {
3178         char const *name;
3179
3180         name = cf_section_name2(cs);
3181         if (name) return name;
3182
3183         return cf_section_name1(cs);
3184 }
3185
3186 /*
3187  * Find a value in a CONF_SECTION
3188  */
3189 char const *cf_section_value_find(CONF_SECTION const *cs, char const *attr)
3190 {
3191         CONF_PAIR       *cp;
3192
3193         cp = cf_pair_find(cs, attr);
3194
3195         return (cp ? cp->value : NULL);
3196 }
3197
3198
3199 CONF_SECTION *cf_section_find_name2(CONF_SECTION const *cs,
3200                                     char const *name1, char const *name2)
3201 {
3202         char const      *their2;
3203         CONF_ITEM const *ci;
3204
3205         if (!cs || !name1) return NULL;
3206
3207         for (ci = &(cs->item); ci; ci = ci->next) {
3208                 if (ci->type != CONF_ITEM_SECTION)
3209                         continue;
3210
3211                 if (strcmp(cf_item_to_section(ci)->name1, name1) != 0) {
3212                         continue;
3213                 }
3214
3215                 their2 = cf_item_to_section(ci)->name2;
3216
3217                 if ((!name2 && !their2) ||
3218                     (name2 && their2 && (strcmp(name2, their2) == 0))) {
3219                         return cf_item_to_section(ci);
3220                 }
3221         }
3222
3223         return NULL;
3224 }
3225
3226 /** Find a pair with a name matching attr, after specified pair.
3227  *
3228  * @param cs to search in.
3229  * @param pair to search from (may be NULL).
3230  * @param attr to find (may be NULL in which case any attribute matches).
3231  * @return the next matching CONF_PAIR or NULL if none matched.
3232  */
3233 CONF_PAIR *cf_pair_find_next(CONF_SECTION const *cs,
3234                              CONF_PAIR const *pair, char const *attr)
3235 {
3236         CONF_ITEM       *ci;
3237
3238         if (!cs) return NULL;
3239
3240         /*
3241          *      If pair is NULL and we're trying to find a specific
3242          *      attribute this must be a first time run.
3243          *
3244          *      Find the pair with correct name.
3245          */
3246         if (!pair && attr) return cf_pair_find(cs, attr);
3247
3248         /*
3249          *      Start searching from the next child, or from the head
3250          *      of the list of children (if no pair was provided).
3251          */
3252         for (ci = pair ? pair->item.next : cs->children;
3253              ci;
3254              ci = ci->next) {
3255                 if (ci->type != CONF_ITEM_PAIR) continue;
3256
3257                 if (!attr || strcmp(cf_item_to_pair(ci)->attr, attr) == 0) break;
3258         }
3259
3260         return cf_item_to_pair(ci);
3261 }
3262
3263 /*
3264  * Find a CONF_SECTION, or return the root if name is NULL
3265  */
3266
3267 CONF_SECTION *cf_section_find(char const *name)
3268 {
3269         if (name)
3270                 return cf_section_sub_find(root_config, name);
3271         else
3272                 return root_config;
3273 }
3274
3275 /** Find a sub-section in a section
3276  *
3277  *      This finds ANY section having the same first name.
3278  *      The second name is ignored.
3279  */
3280 CONF_SECTION *cf_section_sub_find(CONF_SECTION const *cs, char const *name)
3281 {
3282         CONF_SECTION mycs;
3283
3284         if (!cs || !name) return NULL;  /* can't find an un-named section */
3285
3286         /*
3287          *      No sub-sections have been defined, so none exist.
3288          */
3289         if (!cs->section_tree) return NULL;
3290
3291         mycs.name1 = name;
3292         mycs.name2 = NULL;
3293         return rbtree_finddata(cs->section_tree, &mycs);
3294 }
3295
3296
3297 /** Find a CONF_SECTION with both names.
3298  *
3299  */
3300 CONF_SECTION *cf_section_sub_find_name2(CONF_SECTION const *cs,
3301                                         char const *name1, char const *name2)
3302 {
3303         CONF_ITEM    *ci;
3304
3305         if (!cs) cs = root_config;
3306         if (!cs) return NULL;
3307
3308         if (name1) {
3309                 CONF_SECTION mycs, *master_cs;
3310
3311                 if (!cs->section_tree) return NULL;
3312
3313                 mycs.name1 = name1;
3314                 mycs.name2 = name2;
3315
3316                 master_cs = rbtree_finddata(cs->section_tree, &mycs);
3317                 if (!master_cs) return NULL;
3318
3319                 /*
3320                  *      Look it up in the name2 tree.  If it's there,
3321                  *      return it.
3322                  */
3323                 if (master_cs->name2_tree) {
3324                         CONF_SECTION *subcs;
3325
3326                         subcs = rbtree_finddata(master_cs->name2_tree, &mycs);
3327                         if (subcs) return subcs;
3328                 }
3329
3330                 /*
3331                  *      We don't insert ourselves into the name2 tree.
3332                  *      So if there's nothing in the name2 tree, maybe
3333                  *      *we* are the answer.
3334                  */
3335                 if (!master_cs->name2 && name2) return NULL;
3336                 if (master_cs->name2 && !name2) return NULL;
3337                 if (!master_cs->name2 && !name2) return master_cs;
3338
3339                 if (strcmp(master_cs->name2, name2) == 0) {
3340                         return master_cs;
3341                 }
3342
3343                 return NULL;
3344         }
3345
3346         /*
3347          *      Else do it the old-fashioned way.
3348          */
3349         for (ci = cs->children; ci; ci = ci->next) {
3350                 CONF_SECTION *subcs;
3351
3352                 if (ci->type != CONF_ITEM_SECTION)
3353                         continue;
3354
3355                 subcs = cf_item_to_section(ci);
3356                 if (!subcs->name2) {
3357                         if (strcmp(subcs->name1, name2) == 0) break;
3358                 } else {
3359                         if (strcmp(subcs->name2, name2) == 0) break;
3360                 }
3361         }
3362
3363         return cf_item_to_section(ci);
3364 }
3365
3366 /*
3367  * Return the next subsection after a CONF_SECTION
3368  * with a certain name1 (char *name1). If the requested
3369  * name1 is NULL, any name1 matches.
3370  */
3371
3372 CONF_SECTION *cf_subsection_find_next(CONF_SECTION const *section,
3373                                       CONF_SECTION const *subsection,
3374                                       char const *name1)
3375 {
3376         CONF_ITEM       *ci;
3377
3378         if (!section) return NULL;
3379
3380         /*
3381          * If subsection is NULL this must be a first time run
3382          * Find the subsection with correct name
3383          */
3384
3385         if (!subsection) {
3386                 ci = section->children;
3387         } else {
3388                 ci = subsection->item.next;
3389         }
3390
3391         for (; ci; ci = ci->next) {
3392                 if (ci->type != CONF_ITEM_SECTION)
3393                         continue;
3394                 if ((name1 == NULL) ||
3395                     (strcmp(cf_item_to_section(ci)->name1, name1) == 0))
3396                         break;
3397         }
3398
3399         return cf_item_to_section(ci);
3400 }
3401
3402
3403 /*
3404  * Return the next section after a CONF_SECTION
3405  * with a certain name1 (char *name1). If the requested
3406  * name1 is NULL, any name1 matches.
3407  */
3408
3409 CONF_SECTION *cf_section_find_next(CONF_SECTION const *section,
3410                                    CONF_SECTION const *subsection,
3411                                    char const *name1)
3412 {
3413         if (!section) return NULL;
3414
3415         if (!section->item.parent) return NULL;
3416
3417         return cf_subsection_find_next(section->item.parent, subsection, name1);
3418 }
3419
3420 /** Return the next item after a CONF_ITEM.
3421  *
3422  */
3423 CONF_ITEM *cf_item_find_next(CONF_SECTION const *section, CONF_ITEM const *item)
3424 {
3425         if (!section) return NULL;
3426
3427         /*
3428          *      If item is NULL this must be a first time run
3429          *      Return the first item
3430          */
3431         if (item == NULL) {
3432                 return section->children;
3433         } else {
3434                 return item->next;
3435         }
3436 }
3437
3438 static void _pair_count(int *count, CONF_SECTION const *cs)
3439 {
3440         CONF_ITEM const *ci;
3441
3442         for (ci = cf_item_find_next(cs, NULL);
3443              ci != NULL;
3444              ci = cf_item_find_next(cs, ci)) {
3445
3446                 if (cf_item_is_section(ci)) {
3447                         _pair_count(count, cf_item_to_section(ci));
3448                         continue;
3449                 }
3450
3451                 (*count)++;
3452         }
3453 }
3454
3455 /** Count the number of conf pairs beneath a section
3456  *
3457  * @param[in] cs to search for items in.
3458  * @return number of pairs nested within section.
3459  */
3460 int cf_pair_count(CONF_SECTION const *cs)
3461 {
3462         int count = 0;
3463
3464         _pair_count(&count, cs);
3465
3466         return count;
3467 }
3468
3469 CONF_SECTION *cf_item_parent(CONF_ITEM const *ci)
3470 {
3471         if (!ci) return NULL;
3472
3473         return ci->parent;
3474 }
3475
3476 int cf_section_lineno(CONF_SECTION const *section)
3477 {
3478         return section->item.lineno;
3479 }
3480
3481 char const *cf_pair_filename(CONF_PAIR const *pair)
3482 {
3483         return pair->item.filename;
3484 }
3485
3486 char const *cf_section_filename(CONF_SECTION const *section)
3487 {
3488         return section->item.filename;
3489 }
3490
3491 int cf_pair_lineno(CONF_PAIR const *pair)
3492 {
3493         return pair->item.lineno;
3494 }
3495
3496 bool cf_item_is_section(CONF_ITEM const *item)
3497 {
3498         return item->type == CONF_ITEM_SECTION;
3499 }
3500
3501 bool cf_item_is_pair(CONF_ITEM const *item)
3502 {
3503         return item->type == CONF_ITEM_PAIR;
3504 }
3505
3506
3507 static CONF_DATA *cf_data_alloc(CONF_SECTION *parent, char const *name,
3508                                 void *data, void (*data_free)(void *))
3509 {
3510         CONF_DATA *cd;
3511
3512         cd = talloc_zero(parent, CONF_DATA);
3513         if (!cd) return NULL;
3514
3515         cd->item.type = CONF_ITEM_DATA;
3516         cd->item.parent = parent;
3517         cd->name = talloc_typed_strdup(cd, name);
3518         if (!cd->name) {
3519                 talloc_free(cd);
3520                 return NULL;
3521         }
3522
3523         cd->data = data;
3524         cd->free = data_free;
3525
3526         if (cd->free) {
3527                 talloc_set_destructor(cd, _cf_data_free);
3528         }
3529
3530         return cd;
3531 }
3532
3533 static void *cf_data_find_internal(CONF_SECTION const *cs, char const *name, int flag)
3534 {
3535         if (!cs || !name) return NULL;
3536
3537         /*
3538          *      Find the name in the tree, for speed.
3539          */
3540         if (cs->data_tree) {
3541                 CONF_DATA mycd;
3542
3543                 mycd.name = name;
3544                 mycd.flag = flag;
3545                 return rbtree_finddata(cs->data_tree, &mycd);
3546         }
3547
3548         return NULL;
3549 }
3550
3551 /*
3552  *      Find data from a particular section.
3553  */
3554 void *cf_data_find(CONF_SECTION const *cs, char const *name)
3555 {
3556         CONF_DATA *cd = cf_data_find_internal(cs, name, 0);
3557
3558         if (cd) return cd->data;
3559         return NULL;
3560 }
3561
3562
3563 /*
3564  *      Add named data to a configuration section.
3565  */
3566 static int cf_data_add_internal(CONF_SECTION *cs, char const *name,
3567                                 void *data, void (*data_free)(void *),
3568                                 int flag)
3569 {
3570         CONF_DATA *cd;
3571
3572         if (!cs || !name) return -1;
3573
3574         /*
3575          *      Already exists.  Can't add it.
3576          */
3577         if (cf_data_find_internal(cs, name, flag) != NULL) return -1;
3578
3579         cd = cf_data_alloc(cs, name, data, data_free);
3580         if (!cd) return -1;
3581         cd->flag = flag;
3582
3583         cf_item_add(cs, cf_data_to_item(cd));
3584
3585         return 0;
3586 }
3587
3588 /*
3589  *      Add named data to a configuration section.
3590  */
3591 int cf_data_add(CONF_SECTION *cs, char const *name,
3592                 void *data, void (*data_free)(void *))
3593 {
3594         return cf_data_add_internal(cs, name, data, data_free, 0);
3595 }
3596
3597 /** Remove named data from a configuration section
3598  *
3599  */
3600 void *cf_data_remove(CONF_SECTION *cs, char const *name)
3601 {
3602         CONF_DATA mycd;
3603         CONF_DATA *cd;
3604         void *data;
3605
3606         if (!cs || !name) return NULL;
3607         if (!cs->data_tree) return NULL;
3608
3609         /*
3610          *      Find the name in the tree, for speed.
3611          */
3612         mycd.name = name;
3613         mycd.flag = 0;
3614         cd = rbtree_finddata(cs->data_tree, &mycd);
3615         if (!cd) return NULL;
3616
3617         talloc_set_destructor(cd, NULL);        /* Disarm the destructor */
3618         rbtree_deletebydata(cs->data_tree, &mycd);
3619
3620         data = cd->data;
3621         talloc_free(cd);
3622
3623         return data;
3624 }
3625
3626 /*
3627  *      This is here to make the rest of the code easier to read.  It
3628  *      ties conffile.c to log.c, but it means we don't have to
3629  *      pollute every other function with the knowledge of the
3630  *      configuration internals.
3631  */
3632 void cf_log_err(CONF_ITEM const *ci, char const *fmt, ...)
3633 {
3634         va_list ap;
3635         char buffer[256];
3636
3637         va_start(ap, fmt);
3638         vsnprintf(buffer, sizeof(buffer), fmt, ap);
3639         va_end(ap);
3640
3641         if (ci) {
3642                 ERROR("%s[%d]: %s",
3643                        ci->filename ? ci->filename : "unknown",
3644                        ci->lineno ? ci->lineno : 0,
3645                        buffer);
3646         } else {
3647                 ERROR("<unknown>[*]: %s", buffer);
3648         }
3649 }
3650
3651 void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt, ...)
3652 {
3653         va_list ap;
3654         char buffer[256];
3655
3656         va_start(ap, fmt);
3657         vsnprintf(buffer, sizeof(buffer), fmt, ap);
3658         va_end(ap);
3659
3660         rad_assert(cs != NULL);
3661
3662         ERROR("%s[%d]: %s",
3663                cs->item.filename ? cs->item.filename : "unknown",
3664                cs->item.lineno ? cs->item.lineno : 0,
3665                buffer);
3666 }
3667
3668 void cf_log_err_cp(CONF_PAIR const *cp, char const *fmt, ...)
3669 {
3670         va_list ap;
3671         char buffer[256];
3672
3673         va_start(ap, fmt);
3674         vsnprintf(buffer, sizeof(buffer), fmt, ap);
3675         va_end(ap);
3676
3677         rad_assert(cp != NULL);
3678
3679         ERROR("%s[%d]: %s",
3680                cp->item.filename ? cp->item.filename : "unknown",
3681                cp->item.lineno ? cp->item.lineno : 0,
3682                buffer);
3683 }
3684
3685 void cf_log_info(CONF_SECTION const *cs, char const *fmt, ...)
3686 {
3687         va_list ap;
3688
3689         va_start(ap, fmt);
3690         if ((rad_debug_lvl > 1) && cs) vradlog(L_DBG, fmt, ap);
3691         va_end(ap);
3692 }
3693
3694 /*
3695  *      Wrapper to simplify the code.
3696  */
3697 void cf_log_module(CONF_SECTION const *cs, char const *fmt, ...)
3698 {
3699         va_list ap;
3700         char buffer[256];
3701
3702         va_start(ap, fmt);
3703         if (rad_debug_lvl > 1 && cs) {
3704                 vsnprintf(buffer, sizeof(buffer), fmt, ap);
3705
3706                 DEBUG("%.*s# %s", cs->depth, parse_spaces, buffer);
3707         }
3708         va_end(ap);
3709 }
3710
3711 const CONF_PARSER *cf_section_parse_table(CONF_SECTION *cs)
3712 {
3713         if (!cs) return NULL;
3714
3715         return cs->variables;
3716 }
3717
3718 /*
3719  *      For "switch" and "case" statements.
3720  */
3721 FR_TOKEN cf_section_name2_type(CONF_SECTION const *cs)
3722 {
3723         if (!cs) return T_INVALID;
3724
3725         return cs->name2_type;
3726 }