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