in find_name2(), if name2 is NULL, look for a matching entry
[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 #include <freeradius-devel/ident.h>
30 RCSID("$Id$")
31
32 #include <freeradius-devel/radiusd.h>
33 #include <freeradius-devel/rad_assert.h>
34
35 #ifdef HAVE_DIRENT_H
36 #include <dirent.h>
37
38 #ifdef HAVE_SYS_STAT_H
39 #include <sys/stat.h>
40 #endif
41 #endif
42
43 #include <ctype.h>
44
45 typedef enum conf_type {
46         CONF_ITEM_INVALID = 0,
47         CONF_ITEM_PAIR,
48         CONF_ITEM_SECTION,
49         CONF_ITEM_DATA
50 } CONF_ITEM_TYPE;
51
52 struct conf_item {
53         struct conf_item *next;
54         struct conf_part *parent;
55         int lineno;
56         const char *filename;
57         CONF_ITEM_TYPE type;
58 };
59 struct conf_pair {
60         CONF_ITEM item;
61         char *attr;
62         char *value;
63         LRAD_TOKEN operator;
64         LRAD_TOKEN value_type;
65 };
66 struct conf_part {
67         CONF_ITEM item;
68         const char *name1;
69         const char *name2;
70         struct conf_item *children;
71         struct conf_item *tail; /* for speed */
72         CONF_SECTION    *template;
73         rbtree_t        *pair_tree; /* and a partridge.. */
74         rbtree_t        *section_tree; /* no jokes here */
75         rbtree_t        *name2_tree; /* for sections of the same name2 */
76         rbtree_t        *data_tree;
77         void            *base;
78         int depth;
79         const CONF_PARSER *variables;
80 };
81
82
83 /*
84  *      Internal data that is associated with a configuration section,
85  *      so that we don't have to track it separately.
86  */
87 struct conf_data {
88         CONF_ITEM  item;
89         const char *name;
90         int        flag;
91         void       *data;       /* user data */
92         void       (*free)(void *); /* free user data function */
93 };
94
95
96 static int cf_data_add_internal(CONF_SECTION *cs, const char *name,
97                                 void *data, void (*data_free)(void *),
98                                 int flag);
99 static void *cf_data_find_internal(CONF_SECTION *cs, const char *name,
100                                    int flag);
101
102 /*
103  *      Isolate the scary casts in these tiny provably-safe functions
104  */
105 CONF_PAIR *cf_itemtopair(CONF_ITEM *ci)
106 {
107         if (ci == NULL)
108                 return NULL;
109         rad_assert(ci->type == CONF_ITEM_PAIR);
110         return (CONF_PAIR *)ci;
111 }
112 CONF_SECTION *cf_itemtosection(CONF_ITEM *ci)
113 {
114         if (ci == NULL)
115                 return NULL;
116         rad_assert(ci->type == CONF_ITEM_SECTION);
117         return (CONF_SECTION *)ci;
118 }
119 CONF_ITEM *cf_pairtoitem(CONF_PAIR *cp)
120 {
121         if (cp == NULL)
122                 return NULL;
123         return (CONF_ITEM *)cp;
124 }
125 CONF_ITEM *cf_sectiontoitem(CONF_SECTION *cs)
126 {
127         if (cs == NULL)
128                 return NULL;
129         return (CONF_ITEM *)cs;
130 }
131
132 static CONF_DATA *cf_itemtodata(CONF_ITEM *ci)
133 {
134         if (ci == NULL)
135                 return NULL;
136         rad_assert(ci->type == CONF_ITEM_DATA);
137         return (CONF_DATA *)ci;
138 }
139 static CONF_ITEM *cf_datatoitem(CONF_DATA *cd)
140 {
141         if (cd == NULL)
142                 return NULL;
143         return (CONF_ITEM *)cd;
144 }
145
146 /*
147  *      Create a new CONF_PAIR
148  */
149 static CONF_PAIR *cf_pair_alloc(const char *attr, const char *value,
150                                 LRAD_TOKEN operator, LRAD_TOKEN value_type,
151                                 CONF_SECTION *parent)
152 {
153         CONF_PAIR *cp;
154
155         cp = rad_malloc(sizeof(*cp));
156         memset(cp, 0, sizeof(*cp));
157         cp->item.type = CONF_ITEM_PAIR;
158         cp->item.parent = parent;
159         cp->attr = strdup(attr);
160         if (value) cp->value = strdup(value);
161         cp->value_type = value_type;
162         cp->operator = operator;
163
164         return cp;
165 }
166
167 /*
168  *      Free a CONF_PAIR
169  */
170 void cf_pair_free(CONF_PAIR **cp)
171 {
172         if (!cp || !*cp) return;
173
174         if ((*cp)->attr)
175                 free((*cp)->attr);
176         if ((*cp)->value)
177                 free((*cp)->value);
178
179 #ifndef NDEBUG
180         memset(*cp, 0, sizeof(*cp));
181 #endif
182         free(*cp);
183
184         *cp = NULL;
185 }
186
187
188 static void cf_data_free(CONF_DATA **cd)
189 {
190         if (!cd || !*cd) return;
191
192         if ((*cd)->flag != 0) free((*cd)->name);
193         if (!(*cd)->free) {
194                 free((*cd)->data);
195         } else {
196                 ((*cd)->free)((*cd)->data);
197         }
198 #ifndef NDEBUG
199         memset(*cd, 0, sizeof(*cd));
200 #endif
201         free(*cd);
202         *cd = NULL;
203 }
204
205 /*
206  *      rbtree callback function
207  */
208 static int pair_cmp(const void *a, const void *b)
209 {
210         const CONF_PAIR *one = a;
211         const CONF_PAIR *two = b;
212
213         return strcmp(one->attr, two->attr);
214 }
215
216
217 /*
218  *      rbtree callback function
219  */
220 static int section_cmp(const void *a, const void *b)
221 {
222         const CONF_SECTION *one = a;
223         const CONF_SECTION *two = b;
224
225         return strcmp(one->name1, two->name1);
226 }
227
228
229 /*
230  *      rbtree callback function
231  */
232 static int name2_cmp(const void *a, const void *b)
233 {
234         const CONF_SECTION *one = a;
235         const CONF_SECTION *two = b;
236
237         rad_assert(strcmp(one->name1, two->name1) == 0);
238
239         if (!one->name2 && !two->name2) return 0;
240         if (!one->name2) return -1;
241         if (!two->name2) return +1;
242
243         return strcmp(one->name2, two->name2);
244 }
245
246
247 /*
248  *      rbtree callback function
249  */
250 static int data_cmp(const void *a, const void *b)
251 {
252         int rcode;
253
254         const CONF_DATA *one = a;
255         const CONF_DATA *two = b;
256
257         rcode = one->flag - two->flag;
258         if (rcode != 0) return rcode;
259
260         return strcmp(one->name, two->name);
261 }
262
263
264 /*
265  *      Free strings we've parsed into data structures.
266  */
267 static void cf_section_parse_free(void *base, const CONF_PARSER *variables)
268 {
269         int i;
270
271         /*
272          *      Don't automatically free the strings if we're being
273          *      called from a module.  This is also for clients.c,
274          *      where client_free() expects to be able to free the
275          *      client structure.  If we moved everything to key off
276          *      of the config files, we might solve some problems...
277          */
278         if (!variables) return;
279
280         /*
281          *      Free up dynamically allocated string pointers.
282          */
283         for (i = 0; variables[i].name != NULL; i++) {
284                 char **p;
285
286                 if ((variables[i].type != PW_TYPE_STRING_PTR) &&
287                     (variables[i].type != PW_TYPE_FILENAME)) {
288                         continue;
289                 }
290
291                 /*
292                  *      No base struct offset, data must be the pointer.
293                  *      If data doesn't exist, ignore the entry, there
294                  *      must be something wrong.
295                  */
296                 if (!base) {
297                         if (!variables[i].data) {
298                                 continue;
299                         }
300
301                         p = (char **) variables[i].data;;
302
303                 } else if (variables[i].data) {
304                         p = (char **) variables[i].data;;
305
306                 } else {
307                         p = (char **) (((char *)base) + variables[i].offset);
308                 }
309
310                 free(*p);
311                 *p = NULL;
312         }
313 }
314
315
316 /*
317  *      Free a CONF_SECTION
318  */
319 void cf_section_free(CONF_SECTION **cs)
320 {
321         CONF_ITEM       *ci, *next;
322
323         if (!cs || !*cs) return;
324
325         if ((*cs)->variables) {
326                 cf_section_parse_free((*cs)->base, (*cs)->variables);
327         }
328
329         for (ci = (*cs)->children; ci; ci = next) {
330                 next = ci->next;
331
332                 switch (ci->type) {
333                 case CONF_ITEM_PAIR: {
334                                 CONF_PAIR *pair = cf_itemtopair(ci);
335                                 cf_pair_free(&pair);
336                         }
337                         break;
338
339                 case CONF_ITEM_SECTION: {
340                                 CONF_SECTION *section = cf_itemtosection(ci);
341                                 cf_section_free(&section);
342                         }
343                         break;
344
345                 case CONF_ITEM_DATA: {
346                                 CONF_DATA *data = cf_itemtodata(ci);
347                                 cf_data_free(&data);
348                         }
349                         break;
350
351                 default:        /* should really be an error. */
352                         break;
353                 }
354         }
355
356         if ((*cs)->name1)
357                 free((*cs)->name1);
358         if ((*cs)->name2)
359                 free((*cs)->name2);
360         if ((*cs)->pair_tree)
361                 rbtree_free((*cs)->pair_tree);
362         if ((*cs)->section_tree)
363                 rbtree_free((*cs)->section_tree);
364         if ((*cs)->name2_tree)
365                 rbtree_free((*cs)->name2_tree);
366         if ((*cs)->data_tree)
367                 rbtree_free((*cs)->data_tree);
368
369         /*
370          * And free the section
371          */
372 #ifndef NDEBUG
373         memset(*cs, 0, sizeof(*cs));
374 #endif
375         free(*cs);
376
377         *cs = NULL;
378 }
379
380
381 /*
382  *      Allocate a CONF_SECTION
383  */
384 static CONF_SECTION *cf_section_alloc(const char *name1, const char *name2,
385                                       CONF_SECTION *parent)
386 {
387         CONF_SECTION    *cs;
388
389         if (!name1) return NULL;
390
391         cs = rad_malloc(sizeof(*cs));
392         memset(cs, 0, sizeof(*cs));
393         cs->item.type = CONF_ITEM_SECTION;
394         cs->item.parent = parent;
395         cs->name1 = strdup(name1);
396         if (!cs->name1) {
397                 cf_section_free(&cs);
398                 return NULL;
399         }
400
401         if (name2 && *name2) {
402                 cs->name2 = strdup(name2);
403                 if (!cs->name2) {
404                         cf_section_free(&cs);
405                         return NULL;
406                 }
407         }
408         cs->pair_tree = rbtree_create(pair_cmp, NULL, 0);
409         if (!cs->pair_tree) {
410                 cf_section_free(&cs);
411                 return NULL;
412         }
413
414         /*
415          *      Don't create a data tree, it may not be needed.
416          */
417
418         /*
419          *      Don't create the section tree here, it may not
420          *      be needed.
421          */
422
423         if (parent) cs->depth = parent->depth + 1;
424
425         return cs;
426 }
427
428
429 /*
430  *      Add an item to a configuration section.
431  */
432 static void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci)
433 {
434         if (!cs->children) {
435                 rad_assert(cs->tail == NULL);
436                 cs->children = ci;
437         } else {
438                 rad_assert(cs->tail != NULL);
439                 cs->tail->next = ci;
440         }
441
442         /*
443          *      Update the trees (and tail) for each item added.
444          */
445         for (/* nothing */; ci != NULL; ci = ci->next) {
446                 cs->tail = ci;
447
448                 /*
449                  *      For fast lookups, pair's and sections get
450                  *      added to rbtree's.
451                  */
452                 switch (ci->type) {
453                         case CONF_ITEM_PAIR:
454                                 rbtree_insert(cs->pair_tree, ci);
455                                 break;
456
457                         case CONF_ITEM_SECTION: {
458                                 const CONF_SECTION *cs_new = cf_itemtosection(ci);
459
460                                 if (!cs->section_tree) {
461                                         cs->section_tree = rbtree_create(section_cmp, NULL, 0);
462                                         /* ignore any errors */
463                                 }
464
465                                 if (cs->section_tree) {
466                                         rbtree_insert(cs->section_tree, cs_new);                                }
467
468                                 /*
469                                  *      Two names: find the named instance.
470                                  */
471                                 if (cs_new->name2) {
472                                         CONF_SECTION *old_cs;
473
474                                         /*
475                                          *      Find the FIRST
476                                          *      CONF_SECTION having
477                                          *      the given name1, and
478                                          *      create a new tree
479                                          *      under it.
480                                          */
481                                         old_cs = rbtree_finddata(cs->section_tree, cs_new);
482                                         if (!old_cs) return; /* this is a bad error! */
483
484                                         if (!old_cs->name2_tree) {
485                                                 old_cs->name2_tree = rbtree_create(name2_cmp,
486                                                                                    NULL, 0);
487                                         }
488                                         if (old_cs->name2_tree) {
489                                                 rbtree_insert(old_cs->name2_tree, cs_new);
490                                         }
491                                 } /* had a name2 */
492                                 break;
493                         } /* was a section */
494
495                         case CONF_ITEM_DATA:
496                                 if (!cs->data_tree) {
497                                         cs->data_tree = rbtree_create(data_cmp, NULL, 0);
498                                 }
499                                 if (cs->data_tree) {
500                                         rbtree_insert(cs->data_tree, ci);
501                                 }
502                                 break;
503
504                         default: /* FIXME: assert & error! */
505                                 break;
506
507                 } /* switch over conf types */
508         } /* loop over ci */
509 }
510
511 /*
512  *      Expand the variables in an input string.
513  */
514 static const char *cf_expand_variables(const char *cf, int *lineno,
515                                        const CONF_SECTION *outercs,
516                                        char *output, const char *input)
517 {
518         char *p;
519         const char *end, *ptr;
520         char name[8192];
521         const CONF_SECTION *parentcs;
522
523         /*
524          *      Find the master parent conf section.
525          *      We can't use mainconfig.config, because we're in the
526          *      process of re-building it, and it isn't set up yet...
527          */
528         for (parentcs = outercs;
529              parentcs->item.parent != NULL;
530              parentcs = parentcs->item.parent) {
531                 /* do nothing */
532         }
533
534         p = output;
535         ptr = input;
536         while (*ptr) {
537                 /*
538                  *      Ignore anything other than "${"
539                  */
540                 if ((*ptr == '$') && (ptr[1] == '{')) {
541                         int up;
542                         CONF_PAIR *cp;
543                         const CONF_SECTION *cs;
544
545                         /*
546                          *      FIXME: Add support for ${foo:-bar},
547                          *      like in xlat.c
548                          */
549
550                         /*
551                          *      Look for trailing '}', and log a
552                          *      warning for anything that doesn't match,
553                          *      and exit with a fatal error.
554                          */
555                         end = strchr(ptr, '}');
556                         if (end == NULL) {
557                                 *p = '\0';
558                                 radlog(L_INFO, "%s[%d]: Variable expansion missing }",
559                                        cf, *lineno);
560                                 return NULL;
561                         }
562
563                         ptr += 2;
564
565                         cp = NULL;
566                         up = 0;
567
568                         /*
569                          *      ${.foo} means "foo from the current section"
570                          */
571                         if (*ptr == '.') {
572                                 up = 1;
573                                 cs = outercs;
574                                 ptr++;
575
576                                 /*
577                                  *      ${..foo} means "foo from the section
578                                  *      enclosing this section" (etc.)
579                                  */
580                                 while (*ptr == '.') {
581                                         if (cs->item.parent)
582                                                 cs = cs->item.parent;
583                                         ptr++;
584                                 }
585
586                         } else {
587                                 const char *q;
588                                 /*
589                                  *      ${foo} is local, with
590                                  *      main as lower priority
591                                  */
592                                 cs = outercs;
593
594                                 /*
595                                  *      ${foo.bar.baz} is always rooted
596                                  *      from the top.
597                                  */
598                                 for (q = ptr; *q && q != end; q++) {
599                                         if (*q == '.') {
600                                                 cs = parentcs;
601                                                 up = 1;
602                                                 break;
603                                         }
604                                 }
605                         }
606
607                         while (cp == NULL) {
608                                 char *q;
609                                 /*
610                                  *      Find the next section.
611                                  */
612                                 for (q = name;
613                                      (*ptr != 0) && (*ptr != '.') &&
614                                              (ptr != end);
615                                      q++, ptr++) {
616                                         *q = *ptr;
617                                 }
618                                 *q = '\0';
619
620                                 /*
621                                  *      The character is a '.', find a
622                                  *      section (as the user has given
623                                  *      us a subsection to find)
624                                  */
625                                 if (*ptr == '.') {
626                                         CONF_SECTION *next;
627
628                                         ptr++;  /* skip the period */
629
630                                         /*
631                                          *      Find the sub-section.
632                                          */
633                                         next = cf_section_sub_find(cs, name);
634                                         if (next == NULL) {
635                                                 radlog(L_ERR, "config: No such section %s in variable %s", name, input);
636                                                 return NULL;
637                                         }
638                                         cs = next;
639
640                                 } else { /* no period, must be a conf-part */
641                                         /*
642                                          *      Find in the current referenced
643                                          *      section.
644                                          */
645                                         cp = cf_pair_find(cs, name);
646                                         if (cp == NULL) {
647                                                 /*
648                                                  *      It it was NOT ${..foo}
649                                                  *      then look in the
650                                                  *      top-level config items.
651                                                  */
652                                                 if (!up) cp = cf_pair_find(parentcs, name);
653                                         }
654                                         if (cp == NULL) {
655                                                 radlog(L_ERR, "config: No such configuration item %s in section %s when expanding string \"%s\"", name,
656                                                        cf_section_name1(cs),
657                                                        input);
658                                                 return NULL;
659                                         }
660                                 }
661                         } /* until cp is non-NULL */
662
663                         /*
664                          *  Substitute the value of the variable.
665                          */
666                         strcpy(p, cp->value);
667                         p += strlen(p);
668                         ptr = end + 1;
669
670                 } else if (memcmp(ptr, "$ENV{", 5) == 0) {
671                         char *env;
672
673                         ptr += 5;
674
675                         /*
676                          *      Look for trailing '}', and log a
677                          *      warning for anything that doesn't match,
678                          *      and exit with a fatal error.
679                          */
680                         end = strchr(ptr, '}');
681                         if (end == NULL) {
682                                 *p = '\0';
683                                 radlog(L_INFO, "%s[%d]: Environment variable expansion missing }",
684                                        cf, *lineno);
685                                 return NULL;
686                         }
687
688                         memcpy(name, ptr, end - ptr);
689                         name[end - ptr] = '\0';
690
691                         /*
692                          *      Get the environment variable.
693                          *      If none exists, then make it an empty string.
694                          */
695                         env = getenv(name);
696                         if (env == NULL) {
697                                 *name = '\0';
698                                 env = name;
699                         }
700
701                         strcpy(p, env);
702                         p += strlen(p);
703                         ptr = end + 1;
704
705                 } else {
706                         /*
707                          *      Copy it over verbatim.
708                          */
709                         *(p++) = *(ptr++);
710                 }
711         } /* loop over all of the input string. */
712
713         *p = '\0';
714
715         return output;
716 }
717
718
719 /*
720  *      Parses an item (not a CONF_ITEM) into the specified format,
721  *      with a default value.
722  *
723  *      Returns -1 on error, 0 for correctly parsed, and 1 if the
724  *      default value was used.  Note that the default value will be
725  *      used ONLY if the CONF_PAIR is NULL.
726  */
727 int cf_item_parse(CONF_SECTION *cs, const char *name,
728                   int type, void *data, const char *dflt)
729 {
730         int rcode = 0;
731         char **q;
732         const char *value;
733         lrad_ipaddr_t ipaddr;
734         const CONF_PAIR *cp;
735         char ipbuf[128];
736
737         cp = cf_pair_find(cs, name);
738         if (cp) {
739                 value = cp->value;
740
741         } else if (!dflt) {
742                 return 1;       /* nothing to parse, return default value */
743
744         } else {
745                 rcode = 1;
746                 value = dflt;
747         }
748
749         switch (type) {
750         case PW_TYPE_BOOLEAN:
751                 /*
752                  *      Allow yes/no and on/off
753                  */
754                 if ((strcasecmp(value, "yes") == 0) ||
755                     (strcasecmp(value, "on") == 0)) {
756                         *(int *)data = 1;
757                 } else if ((strcasecmp(value, "no") == 0) ||
758                            (strcasecmp(value, "off") == 0)) {
759                         *(int *)data = 0;
760                 } else {
761                         *(int *)data = 0;
762                         radlog(L_ERR, "Bad value \"%s\" for boolean variable %s", value, name);
763                         return -1;
764                 }
765                 DEBUG2("\t%s = %s", name, value);
766                 break;
767
768         case PW_TYPE_INTEGER:
769                 *(int *)data = strtol(value, 0, 0);
770                 DEBUG2("\t%s = %d", name, *(int *)data);
771                 break;
772
773         case PW_TYPE_STRING_PTR:
774                 q = (char **) data;
775                 if (*q != NULL) {
776                         free(*q);
777                 }
778
779                 /*
780                  *      Expand variables which haven't already been
781                  *      expanded automagically when the configuration
782                  *      file was read.
783                  */
784                 if (value == dflt) {
785                         char buffer[8192];
786
787                         int lineno = cs->item.lineno;
788
789                         /*
790                          *      FIXME: sizeof(buffer)?
791                          */
792                         value = cf_expand_variables("?",
793                                                     &lineno,
794                                                     cs, buffer, value);
795                         if (!value) return -1;
796                 }
797
798                 DEBUG2("\t%s = \"%s\"", name, value ? value : "(null)");
799                 *q = value ? strdup(value) : NULL;
800                 break;
801
802                 /*
803                  *      This is the same as PW_TYPE_STRING_PTR,
804                  *      except that we also "stat" the file, and
805                  *      cache the result.
806                  */
807         case PW_TYPE_FILENAME:
808                 q = (char **) data;
809                 if (*q != NULL) {
810                         free(*q);
811                 }
812
813                 /*
814                  *      Expand variables which haven't already been
815                  *      expanded automagically when the configuration
816                  *      file was read.
817                  */
818                 if (value == dflt) {
819                         char buffer[8192];
820
821                         int lineno = cs->item.lineno;
822
823                         /*
824                          *      FIXME: sizeof(buffer)?
825                          */
826                         value = cf_expand_variables("?",
827                                                     &lineno,
828                                                     cs, buffer, value);
829                         if (!value) return -1;
830                 }
831
832                 DEBUG2("\t%s = \"%s\"", name, value ? value : "(null)");
833                 *q = value ? strdup(value) : NULL;
834
835                 /*
836                  *      And now we "stat" the file.
837                  */
838                 if (*q) {
839                         struct stat buf;
840
841                         if (stat(*q, &buf) == 0) {
842                                 time_t *mtime;
843
844                                 mtime = rad_malloc(sizeof(*mtime));
845                                 *mtime = buf.st_mtime;
846                                 /* FIXME: error? */
847                                 cf_data_add_internal(cs, *q, mtime, free,
848                                                      PW_TYPE_FILENAME);
849                         }
850                 }
851                 break;
852
853         case PW_TYPE_IPADDR:
854                 /*
855                  *      Allow '*' as any address
856                  */
857                 if (strcmp(value, "*") == 0) {
858                         *(uint32_t *) data = htonl(INADDR_ANY);
859                         DEBUG2("\t%s = *", name);
860                         break;
861                 }
862                 if (ip_hton(value, AF_INET, &ipaddr) < 0) {
863                         radlog(L_ERR, "Can't find IP address for host %s", value);
864                         return -1;
865                 }
866                 DEBUG2("\t%s = %s IP address [%s]", name, value,
867                                ip_ntoh(&ipaddr, ipbuf, sizeof(ipbuf)));
868                 *(uint32_t *) data = ipaddr.ipaddr.ip4addr.s_addr;
869                 break;
870
871         case PW_TYPE_IPV6ADDR:
872                 if (ip_hton(value, AF_INET6, &ipaddr) < 0) {
873                         radlog(L_ERR, "Can't find IPv6 address for host %s", value);
874                         return -1;
875                 }
876                 DEBUG2("\t%s = %s IPv6 address [%s]", name, value,
877                                ip_ntoh(&ipaddr, ipbuf, sizeof(ipbuf)));
878                 memcpy(data, &ipaddr.ipaddr.ip6addr,
879                        sizeof(ipaddr.ipaddr.ip6addr));
880                 break;
881
882         default:
883                 radlog(L_ERR, "type %d not supported yet", type);
884                 return -1;
885                 break;
886         } /* switch over variable type */
887
888         return rcode;
889 }
890
891 static const char *parse_spaces = "                                                                                                                                                                                                                                                                ";
892
893 /*
894  *      Parse a configuration section into user-supplied variables.
895  */
896 int cf_section_parse(CONF_SECTION *cs, void *base,
897                      const CONF_PARSER *variables)
898 {
899         int i;
900         void *data;
901
902         if (!cs->name2) {
903                 DEBUG2("%.*s%s {", cs->depth, parse_spaces,
904                        cs->name1);
905         } else {
906                 DEBUG2("%.*s%s %s {", cs->depth, parse_spaces,
907                        cs->name1, cs->name2);
908         }
909
910         /*
911          *      Handle the known configuration parameters.
912          */
913         for (i = 0; variables[i].name != NULL; i++) {
914                 /*
915                  *      Handle subsections specially
916                  */
917                 if (variables[i].type == PW_TYPE_SUBSECTION) {
918                         const CONF_SECTION *subcs;
919                         subcs = cf_section_sub_find(cs, variables[i].name);
920
921                         /*
922                          *      If the configuration section is NOT there,
923                          *      then ignore it.
924                          *
925                          *      FIXME! This is probably wrong... we should
926                          *      probably set the items to their default values.
927                          */
928                         if (!subcs) continue;
929
930                         if (!variables[i].dflt) {
931                                 DEBUG2("Internal sanity check 1 failed in cf_section_parse");
932                                 goto error;
933                         }
934
935                         if (cf_section_parse(subcs, base,
936                                              (const CONF_PARSER *) variables[i].dflt) < 0) {
937                                 goto error;
938                         }
939                         continue;
940                 } /* else it's a CONF_PAIR */
941
942                 if (variables[i].data) {
943                         data = variables[i].data; /* prefer this. */
944                 } else if (base) {
945                         data = ((char *)base) + variables[i].offset;
946                 } else {
947                         DEBUG2("Internal sanity check 2 failed in cf_section_parse");
948                         goto error;
949                 }
950
951                 /*
952                  *      Parse the pair we found, or a default value.
953                  */
954                 if (cf_item_parse(cs, variables[i].name, variables[i].type,
955                                   data, variables[i].dflt) < 0) {
956                         goto error;
957                 }
958         } /* for all variables in the configuration section */
959
960         DEBUG2("%.*s}", cs->depth, parse_spaces);
961
962         cs->base = base;
963         cs->variables = variables;
964
965         return 0;
966
967  error:
968         DEBUG2("%.*s}", cs->depth, parse_spaces);
969         cf_section_parse_free(base, variables);
970         return -1;
971 }
972
973
974 /*
975  *      Sanity check the "if" or "elsif", presuming that the first '('
976  *      has already been eaten.
977  *
978  *      We're not really parsing it here, just checking if it's mostly
979  *      well-formed.
980  */
981 static int condition_looks_ok(const char **ptr)
982 {
983         int num_braces = 1;
984         int quote = 0;
985         const char *p = *ptr;
986
987         while (*p) {
988                 if (quote) {
989                         if (*p == quote) {
990                                 p++;
991                                 quote = 0;
992                                 continue;
993                         }
994
995                         if (*p == '\\') {
996                                 if (!p[1]) {
997                                         return 0; /* no trailing slash */
998                                 }
999                                 p += 2;
1000                                 continue;
1001                         }
1002                         p++;
1003                         continue;
1004                 }
1005
1006                 switch (*p) {
1007                 case '\\':
1008                         if (!p[1]) {
1009                                 return 0; /* no trailing slash */
1010                         }
1011                         p += 2;
1012                         continue;
1013
1014                 case '(':
1015                         num_braces++;
1016                         p++;
1017                         continue;
1018
1019                 case ')':
1020                         if (num_braces == 1) {
1021                                 const char *q = p + 1;
1022
1023                                 /*
1024                                  *      Validate that there isn't much
1025                                  *      else after the closing brace.
1026                                  */
1027                                 while ((*q == ' ') || (*q == '\t')) q++;
1028
1029                                 /*
1030                                  *      Parse error.
1031                                  */
1032                                 if (*q != '{') {
1033                                         return 0;
1034                                 }
1035
1036                                 *ptr = p + 1; /* include the trailing ')' */
1037                                 return 1;
1038                         }
1039                         num_braces--;
1040                         p++;
1041                         continue;
1042
1043                 case '"':
1044                 case '\'':
1045                 case '/':
1046                 case '`':
1047                         quote = *p;
1048                         /* FALL-THROUGH */
1049
1050                 default:
1051                         p++;
1052                         break;
1053                 }
1054         }
1055
1056         return 0;
1057 }
1058
1059
1060 /*
1061  *      Read a part of the config file.
1062  */
1063 static int cf_section_read(const char *filename, int *lineno, FILE *fp,
1064                            CONF_SECTION *current)
1065
1066 {
1067         CONF_SECTION *this, *css;
1068         CONF_PAIR *cpn;
1069         char *ptr;
1070         const char *value;
1071         char buf[8192];
1072         char buf1[8192];
1073         char buf2[8192];
1074         char buf3[8192];
1075         int t1, t2, t3;
1076         char *cbuf = buf;
1077         int len;
1078
1079         this = current;         /* add items here */
1080
1081         /*
1082          *      Read, checking for line continuations ('\\' at EOL)
1083          */
1084         for (;;) {
1085                 int eof;
1086
1087                 /*
1088                  *      Get data, and remember if we are at EOF.
1089                  */
1090                 eof = (fgets(cbuf, sizeof(buf) - (cbuf - buf), fp) == NULL);
1091                 (*lineno)++;
1092
1093                 len = strlen(cbuf);
1094
1095                 /*
1096                  *      We've filled the buffer, and there isn't
1097                  *      a CR in it.  Die!
1098                  */
1099                 if ((cbuf[len - 1] != '\n') && !feof(fp)) {
1100                         radlog(L_ERR, "%s[%d]: Line too long",
1101                                filename, *lineno);
1102                         return -1;
1103                 }
1104
1105                 /*
1106                  *  Check for continuations.
1107                  */
1108                 if (cbuf[len - 1] == '\n') len--;
1109
1110                 /*
1111                  *      Last character is '\\'.  Over-write it,
1112                  *      and read another line.
1113                  */
1114                 if ((len > 0) && (cbuf[len - 1] == '\\')) {
1115                         if (len >= (sizeof(buf) - 5)) {
1116                                 radlog(L_ERR, "%s[%d]: Line too long",
1117                                        filename, *lineno);
1118                                 return -1;
1119                         }
1120
1121                         cbuf[len - 1] = '\0';
1122                         cbuf += len - 1;
1123                         continue;
1124                 }
1125
1126                 /*
1127                  *  We're at EOF, and haven't read anything.  Stop.
1128                  */
1129                 if (eof && (cbuf == buf)) {
1130                         break;
1131                 }
1132
1133                 ptr = cbuf = buf;
1134                 t1 = gettoken(&ptr, buf1, sizeof(buf1));
1135
1136                 if ((*buf1 == '#') || (*buf1 == '\0')) {
1137                         continue;
1138                 }
1139
1140                 /*
1141                  *      The caller eats "name1 name2 {", and calls us
1142                  *      for the data inside of the section.  So if we
1143                  *      receive a closing brace, then it must mean the
1144                  *      end of the section.
1145                  */
1146                if (t1 == T_RCBRACE) {
1147                        if (this == current) {
1148                                radlog(L_ERR, "%s[%d]: Too many closing braces",
1149                                       filename, *lineno);
1150                                return -1;
1151
1152                        }
1153                        this = this->item.parent;
1154                        continue;
1155                 }
1156
1157                 /*
1158                  *      Allow for $INCLUDE files
1159                  *
1160                  *      This *SHOULD* work for any level include.
1161                  *      I really really really hate this file.  -cparker
1162                  */
1163                 if (strcasecmp(buf1, "$INCLUDE") == 0) {
1164                         t2 = getword(&ptr, buf2, sizeof(buf2));
1165
1166                         value = cf_expand_variables(filename, lineno, this, buf, buf2);
1167                         if (!value) return -1;
1168
1169 #ifdef HAVE_DIRENT_H
1170                         /*
1171                          *      $INCLUDE foo/
1172                          *
1173                          *      Include ALL non-"dot" files in the directory.
1174                          *      careful!
1175                          */
1176                         if (value[strlen(value) - 1] == '/') {
1177                                 DIR             *dir;
1178                                 struct dirent   *dp;
1179                                 struct stat stat_buf;
1180
1181                                 DEBUG2( "Config:   including files in directory: %s", value );
1182                                 dir = opendir(value);
1183                                 if (!dir) {
1184                                         radlog(L_ERR, "%s[%d]: Error reading directory %s: %s",
1185                                                filename, *lineno, value,
1186                                                strerror(errno));
1187                                         return -1;
1188                                 }
1189
1190                                 /*
1191                                  *      Read the directory, ignoring "." files.
1192                                  */
1193                                 while ((dp = readdir(dir)) != NULL) {
1194                                         const char *p;
1195
1196                                         if (dp->d_name[0] == '.') continue;
1197
1198                                         /*
1199                                          *      Check for valid characters
1200                                          */
1201                                         for (p = dp->d_name; *p != '\0'; p++) {
1202                                                 if (isalpha((int)*p) ||
1203                                                     isdigit((int)*p) ||
1204                                                     (*p == '_') ||
1205                                                     (*p == '.')) continue;
1206                                                 break;
1207                                         }
1208                                         if (*p != '\0') continue;
1209
1210                                         snprintf(buf2, sizeof(buf2), "%s%s",
1211                                                  value, dp->d_name);
1212                                         if ((stat(buf2, &stat_buf) != 0) ||
1213                                             S_ISDIR(stat_buf.st_mode)) continue;
1214                                         /*
1215                                          *      Read the file into the current
1216                                          *      configuration sectoin.
1217                                          */
1218                                         if (cf_file_include(buf2, this) < 0) {
1219                                                 closedir(dir);
1220                                                 return -1;
1221                                         }
1222                                 }
1223                                 closedir(dir);
1224                         }  else
1225 #endif
1226                         { /* it was a normal file */
1227                                 if (cf_file_include(value, this) < 0) {
1228                                         return -1;
1229                                 }
1230                         }
1231                         continue;
1232                 } /* we were in an include */
1233
1234                 /*
1235                  *      Ensure that the user can't add CONF_PAIRs
1236                  *      with 'internal' names;
1237                  */
1238                 if (buf1[0] == '_') {
1239                         radlog(L_ERR, "%s[%d]: Illegal configuration pair name \"%s\"",
1240                                         filename, *lineno, buf1);
1241                         return -1;
1242                 }
1243
1244                 /*
1245                  *      Grab the next token.
1246                  */
1247                 t2 = gettoken(&ptr, buf2, sizeof(buf2));
1248                 switch (t2) {
1249                 case T_EOL:
1250                 case T_HASH:
1251                         t2 = T_OP_EQ;
1252                         value = NULL;
1253                         goto do_set;
1254
1255                 case T_OP_ADD:
1256                 case T_OP_SUB:
1257                 case T_OP_LE:
1258                 case T_OP_GE:
1259                         if (!this || (strcmp(this->name1, "update") != 0)) {
1260                                 radlog(L_ERR, "%s[%d]: Invalid operator in assignment",
1261                                        filename, *lineno);
1262                                 return -1;
1263                         }
1264
1265                 case T_OP_EQ:
1266                 case T_OP_SET:
1267                 do_set:
1268                         t3 = getstring(&ptr, buf3, sizeof(buf3));
1269
1270                         /*
1271                          *      Handle variable substitution via ${foo}
1272                          */
1273                         if ((t3 == T_BARE_WORD) ||
1274                             (t3 == T_DOUBLE_QUOTED_STRING)) {
1275                                 value = cf_expand_variables(filename, lineno, this,
1276                                                             buf, buf3);
1277                                 if (!value) return -1;
1278                         } else if ((t3 == T_EOL) ||
1279                                    (t3 == T_HASH)) {
1280                                 value = NULL;
1281                         } else {
1282                                 value = buf3;
1283                         }
1284                         
1285                         /*
1286                          *      Add this CONF_PAIR to our CONF_SECTION
1287                          */
1288                         cpn = cf_pair_alloc(buf1, value, t2, t3, this);
1289                         cpn->item.filename = filename;
1290                         cpn->item.lineno = *lineno;
1291                         cf_item_add(this, cf_pairtoitem(cpn));
1292                         continue;
1293
1294                         /*
1295                          *      This horrible code is here to support
1296                          *      if/then/else failover in the
1297                          *      authorize, etc. sections.  It makes no
1298                          *      sense anywhere else.
1299                          */
1300                 case T_LBRACE:
1301                         if ((strcmp(buf1, "if") == 0) ||
1302                             (strcmp(buf1, "elsif") == 0)) {
1303                                 const char *end = ptr;
1304
1305                                 if (!condition_looks_ok(&end)) {
1306                                         radlog(L_ERR, "%s[%d]: Parse error in condition at: %s",
1307                                                filename, *lineno, ptr);
1308                                         return -1;
1309                                 }
1310
1311                                 if ((end - ptr) >= (sizeof(buf2) - 1)) {
1312                                         radlog(L_ERR, "%s[%d]: Statement too complicated after \"%s\"",
1313                                                filename, *lineno, buf1);
1314                                         return -1;
1315                                 }
1316                                 buf2[0] = '(';
1317                                 memcpy(buf2 + 1, ptr, end - ptr);
1318                                 buf2[end - ptr + 1] = '\0';
1319                                 ptr = end + 1;
1320                                 t2 = T_BARE_WORD;
1321                                 goto section_alloc;
1322
1323                         } else {
1324                                 radlog(L_ERR, "%s[%d]: Parse error after \"%s\"",
1325                                        filename, *lineno, buf1);
1326                                 return -1;
1327                         }
1328                         /* FALL-THROUGH */
1329
1330                         /*
1331                          *      No '=', must be a section or sub-section.
1332                          */
1333                 case T_BARE_WORD:
1334                 case T_DOUBLE_QUOTED_STRING:
1335                 case T_SINGLE_QUOTED_STRING:
1336                         t3 = gettoken(&ptr, buf3, sizeof(buf3));
1337                         if (t3 != T_LCBRACE) {
1338                                 radlog(L_ERR, "%s[%d]: Expecting section start brace '{' after \"%s %s\"",
1339                                        filename, *lineno, buf1, buf2);
1340                                 return -1;
1341                         }
1342
1343                 case T_LCBRACE:
1344                 section_alloc:
1345                         css = cf_section_alloc(buf1,
1346                                                t2 == T_LCBRACE ? NULL : buf2,
1347                                                this);
1348                         if (!css) {
1349                                 radlog(L_ERR, "%s[%d]: Failed allocating memory for section",
1350                                                 filename, *lineno);
1351                                 return -1;
1352                         }
1353                         cf_item_add(this, cf_sectiontoitem(css));
1354                         css->item.filename = filename;
1355                         css->item.lineno = *lineno;
1356
1357                         /*
1358                          *      The current section is now the child section.
1359                          */
1360                         this = css;
1361                         continue;
1362
1363                 default:
1364                         radlog(L_ERR, "%s[%d]: Parse error after \"%s\"",
1365                                filename, *lineno, buf1);
1366                         return -1;
1367                 }
1368         }
1369
1370         /*
1371          *      See if EOF was unexpected ..
1372          */
1373         if (feof(fp) && (this != current)) {
1374                 radlog(L_ERR, "%s[%d]: EOF reached without closing brace for section %s starting at line %d",
1375                        filename, *lineno,
1376                        cf_section_name1(this), cf_section_lineno(this));
1377                 return -1;
1378         }
1379
1380         return 0;
1381 }
1382
1383 /*
1384  *      Include one config file in another.
1385  */
1386 int cf_file_include(const char *filename, CONF_SECTION *cs)
1387 {
1388         FILE            *fp;
1389         int             lineno = 0;
1390         struct stat     statbuf;
1391         time_t          *mtime;
1392         CONF_DATA       *cd;
1393
1394         DEBUG2( "Config:   including file: %s", filename);
1395
1396         if (stat(filename, &statbuf) == 0) {
1397 #ifdef S_IWOTH
1398                 if ((statbuf.st_mode & S_IWOTH) != 0) {
1399                         radlog(L_ERR|L_CONS, "Configuration file %s is globally writable.  Refusing to start due to insecure configuration.",
1400                                filename);
1401                         return -1;
1402                 }
1403 #endif
1404
1405 #ifdef S_IROTH
1406                 if (0 && (statbuf.st_mode & S_IROTH) != 0) {
1407                         radlog(L_ERR|L_CONS, "Configuration file %s is globally readable.  Refusing to start due to insecure configuration.",
1408                                filename);
1409                         return -1;
1410                 }
1411 #endif
1412         }
1413
1414         fp = fopen(filename, "r");
1415         if (!fp) {
1416                 radlog(L_ERR|L_CONS, "Unable to open file \"%s\": %s",
1417                        filename, strerror(errno));
1418                 return -1;
1419         }
1420
1421         /*
1422          *      Add the filename to the section
1423          */
1424         mtime = rad_malloc(sizeof(*mtime));
1425         *mtime = statbuf.st_mtime;
1426
1427         if (cf_data_add_internal(cs, filename, mtime, free,
1428                                  PW_TYPE_FILENAME) < 0) {
1429                 radlog(L_ERR|L_CONS, "Internal error open file \"%s\"",
1430                        filename);
1431                 return -1;
1432         }
1433
1434         cd = cf_data_find_internal(cs, filename, PW_TYPE_FILENAME);
1435         if (!cd) {
1436                 radlog(L_ERR|L_CONS, "Internal error open file \"%s\"",
1437                        filename);
1438                 return -1;
1439         }
1440
1441         /*
1442          *      Read the section.  It's OK to have EOF without a
1443          *      matching close brace.
1444          */
1445         if (cf_section_read(cd->name, &lineno, fp, cs) < 0) {
1446                 fclose(fp);
1447                 return -1;
1448         }
1449
1450         fclose(fp);
1451         return 0;
1452 }
1453
1454 /*
1455  *      Bootstrap a config file.
1456  */
1457 CONF_SECTION *cf_file_read(const char *filename)
1458 {
1459         CONF_SECTION *cs;
1460
1461         cs = cf_section_alloc("main", NULL, NULL);
1462         if (!cs) return NULL;
1463
1464         if (cf_file_include(filename, cs) < 0) {
1465                 cf_section_free(&cs);
1466                 return NULL;
1467         }
1468
1469         return cs;
1470 }
1471
1472 /*
1473  * Return a CONF_PAIR within a CONF_SECTION.
1474  */
1475 CONF_PAIR *cf_pair_find(const CONF_SECTION *cs, const char *name)
1476 {
1477         CONF_ITEM       *ci;
1478         CONF_PAIR       *cp = NULL;
1479
1480         if (!cs) cs = mainconfig.config;
1481
1482         /*
1483          *      Find the name in the tree, for speed.
1484          */
1485         if (name) {
1486                 CONF_PAIR mycp;
1487
1488                 mycp.attr = name;
1489                 cp = rbtree_finddata(cs->pair_tree, &mycp);
1490         } else {
1491                 /*
1492                  *      Else find the first one that matches
1493                  */
1494                 for (ci = cs->children; ci; ci = ci->next) {
1495                         if (ci->type == CONF_ITEM_PAIR) {
1496                                 return cf_itemtopair(ci);
1497                         }
1498                 }
1499         }
1500
1501         if (cp || !cs->template) return cp;
1502
1503         return cf_pair_find(cs->template, name);
1504 }
1505
1506 /*
1507  * Return the attr of a CONF_PAIR
1508  */
1509
1510 char *cf_pair_attr(CONF_PAIR *pair)
1511 {
1512         return (pair ? pair->attr : NULL);
1513 }
1514
1515 /*
1516  * Return the value of a CONF_PAIR
1517  */
1518
1519 char *cf_pair_value(CONF_PAIR *pair)
1520 {
1521         return (pair ? pair->value : NULL);
1522 }
1523
1524 /*
1525  *      Copied here for error reporting.
1526  */
1527 extern void librad_log(const char *, ...);
1528
1529 /*
1530  * Turn a CONF_PAIR into a VALUE_PAIR
1531  * For now, ignore the "value_type" field...
1532  */
1533 VALUE_PAIR *cf_pairtovp(CONF_PAIR *pair)
1534 {
1535         DICT_ATTR *da;
1536         VALUE_PAIR *vp;
1537
1538         if (!pair) {
1539                 librad_log("Internal error");
1540                 return NULL;
1541         }
1542
1543         da = dict_attrbyname(pair->attr);
1544         if (!da) {
1545                 librad_log("Unknown attribute %s", pair->attr);
1546                 return NULL;
1547         }
1548
1549         if (!pair->value) {
1550                 librad_log("No value given for attribute %s", pair->attr);
1551                 return NULL;
1552         }
1553
1554         vp = pairalloc(da);
1555         if (!vp) {
1556                 librad_log("Out of memory");
1557                 return NULL;
1558         }
1559
1560         vp->operator = pair->operator;
1561
1562         if ((pair->value_type == T_BARE_WORD) ||
1563             (pair->value_type == T_SINGLE_QUOTED_STRING)) {
1564                 if (!pairparsevalue(vp, pair->value)) {
1565                         pairfree(&vp);
1566                         return NULL;
1567                 }
1568                 vp->flags.do_xlat = 0;
1569         } else {
1570                 vp->flags.do_xlat = 1;
1571         }
1572
1573         return vp;
1574 }
1575
1576 /*
1577  * Return the first label of a CONF_SECTION
1578  */
1579
1580 const char *cf_section_name1(const CONF_SECTION *cs)
1581 {
1582         return (cs ? cs->name1 : NULL);
1583 }
1584
1585 /*
1586  * Return the second label of a CONF_SECTION
1587  */
1588
1589 const char *cf_section_name2(const CONF_SECTION *cs)
1590 {
1591         return (cs ? cs->name2 : NULL);
1592 }
1593
1594 /*
1595  * Find a value in a CONF_SECTION
1596  */
1597 char *cf_section_value_find(const CONF_SECTION *cs, const char *attr)
1598 {
1599         CONF_PAIR       *cp;
1600
1601         cp = cf_pair_find(cs, attr);
1602
1603         return (cp ? cp->value : NULL);
1604 }
1605
1606 /*
1607  * Return the next pair after a CONF_PAIR
1608  * with a certain name (char *attr) If the requested
1609  * attr is NULL, any attr matches.
1610  */
1611
1612 CONF_PAIR *cf_pair_find_next(const CONF_SECTION *cs,
1613                              const CONF_PAIR *pair, const char *attr)
1614 {
1615         CONF_ITEM       *ci;
1616
1617         /*
1618          * If pair is NULL this must be a first time run
1619          * Find the pair with correct name
1620          */
1621
1622         if (pair == NULL){
1623                 return cf_pair_find(cs, attr);
1624         }
1625
1626         ci = cf_pairtoitem(pair)->next;
1627
1628         for (; ci; ci = ci->next) {
1629                 if (ci->type != CONF_ITEM_PAIR)
1630                         continue;
1631                 if (attr == NULL || strcmp(cf_itemtopair(ci)->attr, attr) == 0)
1632                         break;
1633         }
1634
1635         return cf_itemtopair(ci);
1636 }
1637
1638 /*
1639  * Find a CONF_SECTION, or return the root if name is NULL
1640  */
1641
1642 CONF_SECTION *cf_section_find(const char *name)
1643 {
1644         if (name)
1645                 return cf_section_sub_find(mainconfig.config, name);
1646         else
1647                 return mainconfig.config;
1648 }
1649
1650 /*
1651  * Find a sub-section in a section
1652  */
1653
1654 CONF_SECTION *cf_section_sub_find(const CONF_SECTION *cs, const char *name)
1655 {
1656         CONF_ITEM *ci;
1657
1658         /*
1659          *      Do the fast lookup if possible.
1660          */
1661         if (name && cs->section_tree) {
1662                 CONF_SECTION mycs;
1663
1664                 mycs.name1 = name;
1665                 mycs.name2 = NULL;
1666                 return rbtree_finddata(cs->section_tree, &mycs);
1667         }
1668
1669         for (ci = cs->children; ci; ci = ci->next) {
1670                 if (ci->type != CONF_ITEM_SECTION)
1671                         continue;
1672                 if (strcmp(cf_itemtosection(ci)->name1, name) == 0)
1673                         break;
1674         }
1675
1676         return cf_itemtosection(ci);
1677
1678 }
1679
1680
1681 /*
1682  *      Find a CONF_SECTION with both names.
1683  */
1684 CONF_SECTION *cf_section_sub_find_name2(const CONF_SECTION *cs,
1685                                         const char *name1, const char *name2)
1686 {
1687         CONF_ITEM    *ci;
1688
1689         if (!cs) cs = mainconfig.config;
1690
1691         if (name1 && (cs->section_tree)) {
1692                 CONF_SECTION mycs, *master_cs;
1693
1694                 mycs.name1 = name1;
1695                 mycs.name2 = name2;
1696
1697                 master_cs = rbtree_finddata(cs->section_tree, &mycs);
1698                 if (master_cs) {
1699                         return rbtree_finddata(master_cs->name2_tree, &mycs);
1700                 }
1701         }
1702
1703         /*
1704          *      Else do it the old-fashioned way.
1705          */
1706         for (ci = cs->children; ci; ci = ci->next) {
1707                 CONF_SECTION *subcs;
1708
1709                 if (ci->type != CONF_ITEM_SECTION)
1710                         continue;
1711
1712                 subcs = cf_itemtosection(ci);
1713                 if (!name1) {
1714                         if (!subcs->name2) {
1715                                 if (strcmp(subcs->name1, name2) == 0) break;
1716                         } else {
1717                                 if (strcmp(subcs->name2, name2) == 0) break;
1718                         }
1719                         continue; /* don't do the string comparisons below */
1720                 }
1721
1722                 if ((strcmp(subcs->name1, name1) == 0) &&
1723                     (subcs->name2 != NULL) &&
1724                     (strcmp(subcs->name2, name2) == 0))
1725                         break;
1726         }
1727
1728         return cf_itemtosection(ci);
1729 }
1730
1731 /*
1732  * Return the next subsection after a CONF_SECTION
1733  * with a certain name1 (char *name1). If the requested
1734  * name1 is NULL, any name1 matches.
1735  */
1736
1737 CONF_SECTION *cf_subsection_find_next(CONF_SECTION *section,
1738                                       CONF_SECTION *subsection,
1739                                       const char *name1)
1740 {
1741         CONF_ITEM       *ci;
1742
1743         /*
1744          * If subsection is NULL this must be a first time run
1745          * Find the subsection with correct name
1746          */
1747
1748         if (subsection == NULL){
1749                 ci = section->children;
1750         } else {
1751                 ci = cf_sectiontoitem(subsection)->next;
1752         }
1753
1754         for (; ci; ci = ci->next) {
1755                 if (ci->type != CONF_ITEM_SECTION)
1756                         continue;
1757                 if ((name1 == NULL) ||
1758                     (strcmp(cf_itemtosection(ci)->name1, name1) == 0))
1759                         break;
1760         }
1761
1762         return cf_itemtosection(ci);
1763 }
1764
1765 /*
1766  * Return the next item after a CONF_ITEM.
1767  */
1768
1769 CONF_ITEM *cf_item_find_next(CONF_SECTION *section, CONF_ITEM *item)
1770 {
1771         /*
1772          * If item is NULL this must be a first time run
1773          * Return the first item
1774          */
1775
1776         if (item == NULL) {
1777                 return section->children;
1778         } else {
1779                 return item->next;
1780         }
1781 }
1782
1783 int cf_section_lineno(CONF_SECTION *section)
1784 {
1785         return cf_sectiontoitem(section)->lineno;
1786 }
1787
1788 const char *cf_pair_filename(CONF_PAIR *pair)
1789 {
1790         return cf_pairtoitem(pair)->filename;
1791 }
1792
1793 const char *cf_section_filename(CONF_SECTION *section)
1794 {
1795         return cf_sectiontoitem(section)->filename;
1796 }
1797
1798 int cf_pair_lineno(CONF_PAIR *pair)
1799 {
1800         return cf_pairtoitem(pair)->lineno;
1801 }
1802
1803 int cf_item_is_section(CONF_ITEM *item)
1804 {
1805         return item->type == CONF_ITEM_SECTION;
1806 }
1807 int cf_item_is_pair(CONF_ITEM *item)
1808 {
1809         return item->type == CONF_ITEM_PAIR;
1810 }
1811
1812
1813 static CONF_DATA *cf_data_alloc(CONF_SECTION *parent, const char *name,
1814                                 void *data, void (*data_free)(void *))
1815 {
1816         CONF_DATA *cd;
1817
1818         cd = rad_malloc(sizeof(*cd));
1819         memset(cd, 0, sizeof(*cd));
1820
1821         cd->item.type = CONF_ITEM_DATA;
1822         cd->item.parent = parent;
1823         cd->name = strdup(name);
1824         cd->data = data;
1825         cd->free = data_free;
1826
1827         return cd;
1828 }
1829
1830
1831 static void *cf_data_find_internal(CONF_SECTION *cs, const char *name,
1832                                    int flag)
1833 {
1834         if (!cs || !name) return NULL;
1835
1836         /*
1837          *      Find the name in the tree, for speed.
1838          */
1839         if (cs->data_tree) {
1840                 CONF_DATA mycd;
1841
1842                 mycd.name = name;
1843                 mycd.flag = flag;
1844                 return rbtree_finddata(cs->data_tree, &mycd);
1845         }
1846
1847         return NULL;
1848 }
1849
1850 /*
1851  *      Find data from a particular section.
1852  */
1853 void *cf_data_find(CONF_SECTION *cs, const char *name)
1854 {
1855         CONF_DATA *cd = cf_data_find_internal(cs, name, 0);
1856
1857         if (cd) return cd->data;
1858         return NULL;
1859 }
1860
1861
1862 /*
1863  *      Add named data to a configuration section.
1864  */
1865 static int cf_data_add_internal(CONF_SECTION *cs, const char *name,
1866                                 void *data, void (*data_free)(void *),
1867                                 int flag)
1868 {
1869         CONF_DATA *cd;
1870
1871         if (!cs || !name) return -1;
1872
1873         /*
1874          *      Already exists.  Can't add it.
1875          */
1876         if (cf_data_find_internal(cs, name, flag) != NULL) return -1;
1877
1878         cd = cf_data_alloc(cs, name, data, data_free);
1879         if (!cd) return -1;
1880         cd->flag = flag;
1881
1882         cf_item_add(cs, cf_datatoitem(cd));
1883
1884         return 0;
1885 }
1886
1887 /*
1888  *      Add named data to a configuration section.
1889  */
1890 int cf_data_add(CONF_SECTION *cs, const char *name,
1891                 void *data, void (*data_free)(void *))
1892 {
1893         return cf_data_add_internal(cs, name, data, data_free, 0);
1894 }
1895
1896
1897 /*
1898  *      Copy CONF_DATA from src to dst
1899  */
1900 static void cf_section_copy_data(CONF_SECTION *s, CONF_SECTION *d)
1901 {
1902
1903         CONF_ITEM *cd, *next, **last;
1904
1905         /*
1906          *      Don't check if s->data_tree is NULL.  It's child
1907          *      sections may have data, even if this section doesn't.
1908          */
1909
1910         rad_assert(d->data_tree == NULL);
1911         d->data_tree = s->data_tree;
1912         s->data_tree = NULL;
1913
1914         /*
1915          *      Walk through src, moving CONF_ITEM_DATA
1916          *      to dst, by hand.
1917          */
1918         last = &(s->children);
1919         for (cd = s->children; cd != NULL; cd = next) {
1920                 next = cd->next;
1921
1922                 /*
1923                  *      Recursively copy data from child sections.
1924                  */
1925                 if (cd->type == CONF_ITEM_SECTION) {
1926                         CONF_SECTION *s1, *d1;
1927
1928                         s1 = cf_itemtosection(cd);
1929                         d1 = cf_section_sub_find_name2(d, s1->name1, s1->name2);
1930                         if (d1) {
1931                                 cf_section_copy_data(s1, d1);
1932                         }
1933                         last = &(cd->next);
1934                         continue;
1935                 }
1936
1937                 /*
1938                  *      Not conf data, remember last ptr.
1939                  */
1940                 if (cd->type != CONF_ITEM_DATA) {
1941                         last = &(cd->next);
1942                         continue;
1943                 }
1944
1945                 /*
1946                  *      Remove it from the src list
1947                  */
1948                 *last = cd->next;
1949                 cd->next = NULL;
1950
1951                 /*
1952                  *      Add it to the dst list
1953                  */
1954                 if (!d->children) {
1955                         rad_assert(d->tail == NULL);
1956                         d->children = cd;
1957                 } else {
1958                         rad_assert(d->tail != NULL);
1959                         d->tail->next = cd;
1960                 }
1961                 d->tail = cd;
1962         }
1963 }
1964
1965 /*
1966  *      For a CONF_DATA element, stat the filename, if necessary.
1967  */
1968 static int filename_stat(void *context, void *data)
1969 {
1970         struct stat buf;
1971         CONF_DATA *cd = data;
1972
1973         context = context;      /* -Wunused */
1974
1975         if (cd->flag != PW_TYPE_FILENAME) return 0;
1976
1977         if (stat(cd->name, &buf) < 0) return -1;
1978
1979         if (buf.st_mtime != *(time_t *) cd->data) return -1;
1980
1981         return 0;
1982 }
1983
1984
1985 /*
1986  *      Compare two CONF_SECTIONS.  The items MUST be in the same
1987  *      order.
1988  */
1989 static int cf_section_cmp(CONF_SECTION *a, CONF_SECTION *b)
1990 {
1991         CONF_ITEM *ca = a->children;
1992         CONF_ITEM *cb = b->children;
1993
1994         while (1) {
1995                 CONF_PAIR *pa, *pb;
1996
1997                 /*
1998                  *      Done.  Stop.
1999                  */
2000                 if (!ca && !cb) break;
2001
2002                 /*
2003                  *      Skip CONF_DATA.
2004                  */
2005                 if (ca && ca->type == CONF_ITEM_DATA) {
2006                         ca = ca->next;
2007                         continue;
2008                 }
2009                 if (cb && cb->type == CONF_ITEM_DATA) {
2010                         cb = cb->next;
2011                         continue;
2012                 }
2013
2014                 /*
2015                  *      One is smaller than the other.  Exit.
2016                  */
2017                 if (!ca || !cb) return 0;
2018
2019                 if (ca->type != cb->type) return 0;
2020
2021                 /*
2022                  *      Deal with subsections.
2023                  */
2024                 if (ca->type == CONF_ITEM_SECTION) {
2025                         CONF_SECTION *sa = cf_itemtosection(ca);
2026                         CONF_SECTION *sb = cf_itemtosection(cb);
2027
2028                         if (!cf_section_cmp(sa, sb)) return 0;
2029                         goto next;
2030                 }
2031
2032                 rad_assert(ca->type == CONF_ITEM_PAIR);
2033
2034                 pa = cf_itemtopair(ca);
2035                 pb = cf_itemtopair(cb);
2036
2037                 /*
2038                  *      Different attr and/or value, Exit.
2039                  */
2040                 if ((strcmp(pa->attr, pb->attr) != 0) ||
2041                     (strcmp(pa->value, pb->value) != 0)) return 0;
2042
2043
2044                 /*
2045                  *      And go to the next element.
2046                  */
2047         next:
2048                 ca = ca->next;
2049                 cb = cb->next;
2050         }
2051
2052         /*
2053          *      Walk over the CONF_DATA, stat'ing PW_TYPE_FILENAME.
2054          */
2055         if (a->data_tree &&
2056             (rbtree_walk(a->data_tree, InOrder, filename_stat, NULL) != 0)) {
2057                 return 0;
2058         }
2059
2060         /*
2061          *      They must be the same, say so.
2062          */
2063         return 1;
2064 }
2065
2066
2067 /*
2068  *      Migrate CONF_DATA from one section to another.
2069  */
2070 int cf_section_migrate(CONF_SECTION *dst, CONF_SECTION *src)
2071 {
2072         CONF_ITEM *ci;
2073         CONF_SECTION *s, *d;
2074
2075         for (ci = src->children; ci != NULL; ci = ci->next) {
2076                 if (ci->type != CONF_ITEM_SECTION)
2077                         continue;
2078
2079                 s = cf_itemtosection(ci);
2080                 d = cf_section_sub_find_name2(dst, s->name1, s->name2);
2081
2082                 if (!d) continue; /* not in new one, don't migrate it */
2083
2084                 /*
2085                  *      A section of the same name is in BOTH src & dst,
2086                  *      compare the CONF_PAIR's.  If they're all the same,
2087                  *      then copy the CONF_DATA from one to the other.
2088                  */
2089                 if (cf_section_cmp(s, d)) {
2090                         cf_section_copy_data(s, d);
2091                 }
2092         }
2093
2094         return 1;               /* rcode means anything? */
2095 }
2096
2097 int cf_section_template(CONF_SECTION *cs, CONF_SECTION *template)
2098 {
2099         if (!cs || !template || cs->template || template->template) return -1;
2100
2101         cs->template = template;
2102
2103         return 0;
2104 }
2105
2106
2107 /*
2108  *      This is here to make the rest of the code easier to read.  It
2109  *      ties conffile.c to log.c, but it means we don't have to
2110  *      pollute the 
2111  */
2112 void cf_log_err(CONF_ITEM *ci, const char *fmt, ...)
2113 {
2114         va_list ap;
2115         char buffer[256];
2116
2117         va_start(ap, fmt);
2118         vsnprintf(buffer, sizeof(buffer), fmt, ap);
2119         va_end(ap);
2120
2121         radlog(L_ERR, "%s[%d]: %s", ci->filename, ci->lineno, buffer);
2122 }
2123
2124
2125 #if 0
2126 /*
2127  * JMG dump_config tries to dump the config structure in a readable format
2128  *
2129 */
2130
2131 static int dump_config_section(CONF_SECTION *cs, int indent)
2132 {
2133         CONF_SECTION    *scs;
2134         CONF_PAIR       *cp;
2135         CONF_ITEM       *ci;
2136
2137         /* The DEBUG macro doesn't let me
2138          *   for(i=0;i<indent;++i) debugputchar('\t');
2139          * so I had to get creative. --Pac. */
2140
2141         for (ci = cs->children; ci; ci = ci->next) {
2142                 switch (ci->type) {
2143                 case CONF_ITEM_PAIR:
2144                         cp=cf_itemtopair(ci);
2145                         DEBUG("%.*s%s = %s",
2146                                 indent, "\t\t\t\t\t\t\t\t\t\t\t",
2147                                 cp->attr, cp->value);
2148                         break;
2149
2150                 case CONF_ITEM_SECTION:
2151                         scs=cf_itemtosection(ci);
2152                         DEBUG("%.*s%s %s%s{",
2153                                 indent, "\t\t\t\t\t\t\t\t\t\t\t",
2154                                 scs->name1,
2155                                 scs->name2 ? scs->name2 : "",
2156                                 scs->name2 ?  " " : "");
2157                         dump_config_section(scs, indent+1);
2158                         DEBUG("%.*s}",
2159                                 indent, "\t\t\t\t\t\t\t\t\t\t\t");
2160                         break;
2161
2162                 default:        /* FIXME: Do more! */
2163                         break;
2164                 }
2165         }
2166
2167         return 0;
2168 }
2169
2170 int dump_config(void)
2171 {
2172         return dump_config_section(mainconfig.config, 0);
2173 }
2174 #endif