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