"Fossies" - the Fresh Open Source Software Archive

Member "freeradius-server-3.0.23/src/main/conffile.c" (10 Jun 2021, 87074 Bytes) of package /linux/misc/freeradius-server-3.0.23.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "conffile.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.0.22_vs_3.0.23.

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