]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Fix PW_TYPE_SUBSECTION | PW_TYPE_MULTI
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 12 Apr 2017 22:42:22 +0000 (18:42 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 12 Apr 2017 22:45:55 +0000 (18:45 -0400)
The conf parser can now produce an array of allocated sturcts representing the subsections.

24 files changed:
src/include/conf_file.h
src/main/client.c
src/main/command.c
src/main/conf_file.c
src/main/connection.c
src/main/dl.c
src/main/listen.c
src/main/mainconfig.c
src/main/modules.c
src/main/radmin.c
src/main/radwho.c
src/main/realms.c
src/main/threads.c
src/main/tls/conf.c
src/main/unit_test_module.c
src/modules/proto_bfd/proto_bfd.c
src/modules/proto_detail/proto_detail.c
src/modules/proto_dhcp/proto_dhcp.c
src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c
src/modules/rlm_ldap/rlm_ldap.c
src/modules/rlm_redis_ippool/rlm_redis_ippool_tool.c
src/modules/rlm_rest/rlm_rest.c
src/modules/rlm_test/rlm_test.c
src/modules/rlm_yubikey/rlm_yubikey.c

index b3ecb6e751415c6b433566a74422c4c3f8597770..8338d5b4ea8ccb8936d859482dd33361258d7491 100644 (file)
@@ -204,12 +204,29 @@ _Generic((_ct), \
        .name = _n, \
        .type = _t, \
        .data = FR_CONF_TYPE_CHECK((_t), (_p), _p)
+
 #  define FR_CONF_IS_SET_POINTER(_n, _t, _p) \
        .name = _n, \
        .type = (_t) | PW_TYPE_IS_SET, \
        .data = FR_CONF_TYPE_CHECK((_t), (_p), _p), \
        .is_set_ptr = _p ## _is_set
 #  define FR_ITEM_POINTER(_t, _p) _t, FR_CONF_TYPE_CHECK((_t), (_p), _p)
+
+/** A CONF_PARSER multi-subsection
+ *
+ * Parse multiple instance of a subsection.
+ *
+ * @param _n   name of subsection to search for.
+ * @param _s   instance data struct.
+ * @param _f   field in instance data struct.
+ * @param _sub CONF_PARSER array to use to parse subsection data.
+ */
+#  define FR_CONF_SUBSECTION_MULTI(_n, _s, _f, _sub) \
+       .name = _n, \
+       .type = PW_TYPE_SUBSECTION | PW_TYPE_MULTI, \
+       .offset = FR_CONF_TYPE_CHECK(PW_TYPE_SUBSECTION | PW_TYPE_MULTI, &(((_s *)NULL)->_f), offsetof(_s, _f)), \
+       .subcs = _sub, \
+       .subcs_size = sizeof(**(((_s *)0)->_f))
 #else
 #  define FR_CONF_OFFSET(_n, _t, _s, _f) \
        .name = _n, \
@@ -230,8 +247,25 @@ _Generic((_ct), \
        .data = _p, \
        .is_set_ptr = _p ## _is_set
 #  define FR_ITEM_POINTER(_t, _p) _t, _p
+
+/** A CONF_PARSER multi-subsection
+ *
+ * Parse multiple instance of a subsection.
+ *
+ * @param _n   name of subsection to search for.
+ * @param _s   instance data struct.
+ * @param _f   field in instance data struct.
+ * @param _sub CONF_PARSER array to use to parse subsection data.
+ */
+#  define FR_CONF_SUBSECTION_MULTI(_n, _s, _f, _sub) \
+       .name = _n, \
+       .type = PW_TYPE_SUBSECTION | PW_TYPE_MULTI, \
+       .offset = offsetof(_s, _f), \
+       .subcs = _sub, \
+       .subcs_size = sizeof(**(((_s *)0)->_f))
 #endif
 
+
 #define FR_CONF_DEPRECATED(_n, _t, _p, _f) \
        .name = _n, \
        .type = (_t) | PW_TYPE_DEPRECATED
@@ -372,9 +406,13 @@ typedef struct CONF_PARSER {
        union {
                char const      *dflt;          //!< Default as it would appear in radiusd.conf.
 
-               void const      *subcs;         //!< When type is set to #PW_TYPE_SUBSECTION, should be a pointer
-                                               //!< to the start of another array of #CONF_PARSER structs, forming
-                                               //!< the subsection.
+               struct {
+                       struct CONF_PARSER const *subcs;        //!< When type is set to #PW_TYPE_SUBSECTION, should
+                                                       //!< be a pointer to the start of another array of
+                                                       //!< #CONF_PARSER structs, forming the subsection.
+                       size_t          subcs_size;     //!< If non-zero, allocate structs of this size to hold
+                                                       //!< the parsed data.
+               };
        };
 
        FR_TOKEN        quote;                  //!< Quoting around the default value.  Only used for templates.
@@ -397,10 +435,10 @@ CONF_SECTION      *cf_section_dup(CONF_SECTION *parent, CONF_SECTION const *cs,
                                char const *name1, char const *name2, bool copy_meta);
 void           cf_section_add(CONF_SECTION *parent, CONF_SECTION *cs);
 int            cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value);
-int            cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *data,
+int            cf_pair_parse(TALLOC_CTX *ctx, CONF_SECTION *cs, char const *name, unsigned int type, void *data,
                              char const *dflt, FR_TOKEN dflt_quote);
-int            cf_section_parse(CONF_SECTION *cs, void *base, CONF_PARSER const *variables);
-int            cf_section_parse_pass2(CONF_SECTION *cs, void *base, CONF_PARSER const *variables);
+int            cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs, CONF_PARSER const *variables);
+int            cf_section_parse_pass2(void *base, CONF_SECTION *cs, CONF_PARSER const *variables);
 const CONF_PARSER *cf_section_parse_table(CONF_SECTION *cs);
 int            cf_file_read(CONF_SECTION *cs, char const *file);
 void           cf_file_free(CONF_SECTION *cs);
index b01bec7dd8d1ec54a9f4c59f547718cb684f2488..e082570060c023898ae485a69fa1d100221ee022 100644 (file)
@@ -885,7 +885,7 @@ RADCLIENT *client_afrom_cs(TALLOC_CTX *ctx, CONF_SECTION *cs, CONF_SECTION *serv
        c->cs = cs;
 
        memset(&cl_ipaddr, 0, sizeof(cl_ipaddr));
-       if (cf_section_parse(cs, c, client_config) < 0) {
+       if (cf_section_parse(c, c, cs, client_config) < 0) {
                cf_log_err_cs(cs, "Error parsing client section");
        error:
                client_free(c);
index 2a10e5b34d3dc0c97270e61862604e217bce1f86..7dd2006b36d56ef1b2f609cea629d5282acf1f68 100644 (file)
@@ -2541,7 +2541,7 @@ static int command_set_module_config(rad_listen_t *listener, int argc, char *arg
         */
        cf_pair_replace(instance->cs, cp, argv[2]);
 
-       rcode = cf_pair_parse(instance->cs, argv[1], variables[i].type, data, argv[2], T_DOUBLE_QUOTED_STRING);
+       rcode = cf_pair_parse(NULL, instance->cs, argv[1], variables[i].type, data, argv[2], T_DOUBLE_QUOTED_STRING);
        if (rcode < 0) {
                cprintf_error(listener, "Failed to parse value\n");
                return 0;
@@ -3174,7 +3174,7 @@ static int command_socket_parse_unix(CONF_SECTION *cs, rad_listen_t *this)
        sock = this->data;
        talloc_set_destructor(sock, _command_socket_free);
 
-       if (cf_section_parse(cs, sock, command_config) < 0) return -1;
+       if (cf_section_parse(sock, sock, cs, command_config) < 0) return -1;
 
        /*
         *      Can't get uid or gid of connecting user, so can't do
index 9ef75af12bbe79c44f06c41e5e6582d7668183f0..d49228f4445a6e4eb006bd77bfa87f49736e271e 100644 (file)
@@ -1430,14 +1430,14 @@ static inline int fr_item_validate_ipaddr(CONF_SECTION *cs, char const *name, PW
  *
  * @note Despite the name, this is really the second phase of #cf_pair_parse.
  *
- * @param cs CONF_SECTION to fixup.
- * @param base start of structure to write #vp_tmpl_t s to.
- * @param variables Array of CONF_PARSER structs to process.
+ * @param[out] base start of structure to write #vp_tmpl_t s to.
+ * @param[in] cs CONF_SECTION to fixup.
+ * @param[in] variables Array of CONF_PARSER structs to process.
  * @return
  *     - 0 on success.
  *     - -1 on failure (parse errors etc...).
  */
-int cf_section_parse_pass2(CONF_SECTION *cs, void *base, CONF_PARSER const variables[])
+int cf_section_parse_pass2(void *base, CONF_SECTION *cs, CONF_PARSER const variables[])
 {
 
        int i;
@@ -1464,10 +1464,38 @@ int cf_section_parse_pass2(CONF_SECTION *cs, void *base, CONF_PARSER const varia
                 *      It's a section, recurse!
                 */
                if (type == PW_TYPE_SUBSECTION) {
-                       CONF_SECTION *subcs = cf_subsection_find(cs, name);
+                       uint8_t         *subcs_base;
+                       CONF_SECTION    *subcs = cf_subsection_find(cs, name);
 
-                       if (cf_section_parse_pass2(subcs, (uint8_t *)base + variables[i].offset,
+                       /*
+                        *      Select base by whether this is a nested struct,
+                        *      or a pointer to another struct.
+                        */
+                       if (!base) {
+                               subcs_base = NULL;
+                       } else if (type & PW_TYPE_MULTI) {
+                               size_t j, len;
+                               uint8_t **array;
+
+                               array = (uint8_t **)((uint8_t *)base) + variables[i].offset;
+                               len = talloc_array_length(array);
+
+                               for (j = 0; j < len; j++) {
+                                       if (cf_section_parse_pass2(array[j], subcs,
+                                                                  (CONF_PARSER const *)variables[i].dflt) < 0) {
+                                               return -1;
+                                       }
+                               }
+                               continue;
+                       } else if (variables[i].subcs_size) {
+                               subcs_base = (*(uint8_t **)((uint8_t *)base) + variables[i].offset);
+                       } else {
+                               subcs_base = (uint8_t *)base + variables[i].offset;
+                       }
+
+                       if (cf_section_parse_pass2(subcs_base, subcs,
                                                   (CONF_PARSER const *)variables[i].dflt) < 0) return -1;
+
                        continue;
                }
 
@@ -1633,7 +1661,7 @@ int cf_section_parse_pass2(CONF_SECTION *cs, void *base, CONF_PARSER const varia
  *     - 0 on success.
  *     - -1 on failure.
  */
-static int cf_pair_parse_value(void *out, TALLOC_CTX *ctx, CONF_SECTION *cs, CONF_PAIR *cp, unsigned int type)
+static int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, CONF_SECTION *cs, CONF_PAIR *cp, unsigned int type)
 {
        int             rcode = 0;
        bool            attribute, required, secret, file_input, cant_be_empty, tmpl, file_exists;
@@ -2026,10 +2054,12 @@ static int cf_pair_default(CONF_PAIR **out, CONF_SECTION *cs, char const *name,
  * | PW_TYPE_COMBO_IP_PREFIX | ``fr_ipaddr_t``    | No                     |
  * | PW_TYPE_TIMEVAL         | ``struct timeval`` | No                     |
  *
- * @param cs to search for matching #CONF_PAIR in.
- * @param name of #CONF_PAIR to search for.
- * @param type Data type to parse #CONF_PAIR value as.
- *     Should be one of the following ``data`` types, and one or more of the following ``flag`` types or'd together:
+ * @param[in] ctx      To allocate arrays and values in.
+ * @param[in] cs       to search for matching #CONF_PAIR in.
+ * @param[in] name     of #CONF_PAIR to search for.
+ * @param[in] type     Data type to parse #CONF_PAIR value as.
+ *                     Should be one of the following ``data`` types,
+ *                     and one or more of the following ``flag`` types or'd together:
  *     - ``data`` #PW_TYPE_TMPL                - @copybrief PW_TYPE_TMPL
  *                                               Feeds the value into #tmpl_afrom_str. Value can be
  *                                               obtained when processing requests, with #tmpl_expand or #tmpl_aexpand.
@@ -2055,17 +2085,18 @@ static int cf_pair_default(CONF_PAIR **out, CONF_SECTION *cs, char const *name,
  *     - ``flag`` #PW_TYPE_FILE_INPUT          - @copybrief PW_TYPE_FILE_INPUT
  *     - ``flag`` #PW_TYPE_NOT_EMPTY           - @copybrief PW_TYPE_NOT_EMPTY
  *     - ``flag`` #PW_TYPE_MULTI               - @copybrief PW_TYPE_MULTI
 *    - ``flag`` #PW_TYPE_IS_SET              - @copybrief PW_TYPE_IS_SET
- * @param data Pointer to a global variable, or pointer to a field in the struct being populated with values.
- * @param dflt value to use, if no #CONF_PAIR is found.
- * @param dflt_quote around the dflt value.
    - ``flag`` #PW_TYPE_IS_SET              - @copybrief PW_TYPE_IS_SET
+ * @param[out] out     Pointer to a global variable, or pointer to a field in the struct being populated with values.
+ * @param[in] dflt             value to use, if no #CONF_PAIR is found.
+ * @param[in] dflt_quote       around the dflt value.
  * @return
  *     - 1 if default value was used, or if there was no CONF_PAIR or dflt.
  *     - 0 on success.
  *     - -1 on error.
  *     - -2 if deprecated.
  */
-int cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *data,
+int cf_pair_parse(TALLOC_CTX *ctx, CONF_SECTION *cs,
+                 char const *name, unsigned int type, void *out,
                  char const *dflt, FR_TOKEN dflt_quote)
 {
        bool            multi, required, deprecated;
@@ -2126,7 +2157,7 @@ int cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *d
                 *      Tmpl is outside normal range
                 */
                if (type & PW_TYPE_TMPL) {
-                       array = (void **)talloc_zero_array(cs, vp_tmpl_t *, count);
+                       array = (void **)talloc_zero_array(ctx, vp_tmpl_t *, count);
                /*
                 *      Allocate an array of values.
                 *
@@ -2135,27 +2166,27 @@ int cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *d
                 */
                } else switch (PW_BASE_TYPE(type)) {
                case PW_TYPE_BOOLEAN:
-                       array = (void **)talloc_zero_array(cs, bool, count);
+                       array = (void **)talloc_zero_array(ctx, bool, count);
                        break;
 
                case PW_TYPE_INTEGER:
-                       array = (void **)talloc_zero_array(cs, uint32_t, count);
+                       array = (void **)talloc_zero_array(ctx, uint32_t, count);
                        break;
 
                case PW_TYPE_SHORT:
-                       array = (void **)talloc_zero_array(cs, uint16_t, count);
+                       array = (void **)talloc_zero_array(ctx, uint16_t, count);
                        break;
 
                case PW_TYPE_INTEGER64:
-                       array = (void **)talloc_zero_array(cs, uint64_t, count);
+                       array = (void **)talloc_zero_array(ctx, uint64_t, count);
                        break;
 
                case PW_TYPE_SIGNED:
-                       array = (void **)talloc_zero_array(cs, int32_t, count);
+                       array = (void **)talloc_zero_array(ctx, int32_t, count);
                        break;
 
                case PW_TYPE_STRING:
-                       array = (void **)talloc_zero_array(cs, char *, count);
+                       array = (void **)talloc_zero_array(ctx, char *, count);
                        break;
 
                case PW_TYPE_IPV4_ADDR:
@@ -2164,11 +2195,11 @@ int cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *d
                case PW_TYPE_IPV6_PREFIX:
                case PW_TYPE_COMBO_IP_ADDR:
                case PW_TYPE_COMBO_IP_PREFIX:
-                       array = (void **)talloc_zero_array(cs, fr_ipaddr_t, count);
+                       array = (void **)talloc_zero_array(ctx, fr_ipaddr_t, count);
                        break;
 
                case PW_TYPE_TIMEVAL:
-                       array = (void **)talloc_zero_array(cs, struct timeval, count);
+                       array = (void **)talloc_zero_array(ctx, struct timeval, count);
                        break;
 
                default:
@@ -2177,14 +2208,14 @@ int cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *d
                }
 
                for (i = 0; i < count; i++, cp = cf_pair_find_next(cs, cp, name)) {
-                       if (cf_pair_parse_value(&array[i], array, cs, cp, type) < 0) {
+                       if (cf_pair_parse_value(array, &array[i], cs, cp, type) < 0) {
                                talloc_free(array);
                                talloc_free(dflt_cp);
                                return -1;
                        }
                }
 
-               *(void **)data = array;
+               *(void **)out = array;
        /*
         *      Single valued config item gets written to
         *      the data pointer directly.
@@ -2212,7 +2243,7 @@ int cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *d
 
                if (deprecated) goto deprecated;
 
-               if (cf_pair_parse_value(data, cs, cs, cp, type) < 0) {
+               if (cf_pair_parse_value(ctx, out, cs, cp, type) < 0) {
                        talloc_free(dflt_cp);
                        return -1;
                }
@@ -2321,23 +2352,133 @@ static void cf_section_parse_warn(CONF_SECTION *cs)
        }
 }
 
+/** Parse a subsection
+ *
+ * @note Turns out using nested structures (instead of pointers) for subsections, was actually
+ *     a pretty bad design decision, and will need to be fixed at some future point.
+ *     For now we have a horrible hack where only multi-subsections get an array of structures
+ *     of the appropriate size.
+ *
+ * @param[in] ctx              to allocate any additional structures under.
+ * @param[out] out             pointer to a struct/pointer to fill with data.
+ * @param[in] cs               to parse.
+ * @param[in] name             of subsection to parse.
+ * @param[in] type             flags.
+ * @param[in] subcs_vars       CONF_PARSER definitions for the subsection.
+ * @param[in] subcs_size       size of subsection structures to allocate.
+ * @return
+ *     - 0 on success.
+ *     - -1 on general error.
+ *     - -2 if a deprecated #CONF_ITEM was found.
+ */
+static int cf_subsection_parse(TALLOC_CTX *ctx, void *out, CONF_SECTION *cs,
+                              char const *name, PW_TYPE type, CONF_PARSER const *subcs_vars, size_t subcs_size)
+{
+       CONF_SECTION *subcs;
+       int count, i, ret;
+       uint8_t **array;
+
+       rad_assert(type & PW_TYPE_SUBSECTION);
+
+       subcs = cf_subsection_find(cs, name);
+       if (!subcs) return 0;
+
+       /*
+        *      Handle the single subsection case (which is simple)
+        */
+       if (!(type & PW_TYPE_MULTI)) {
+               uint8_t *buff;
+
+               /*
+                *      FIXME: We shouldn't allow nested structures like this.
+                *      Each subsection struct should be allocated separately so
+                *      we have a clean talloc hierarchy.
+                */
+               if (!subcs_size) return cf_section_parse(ctx, out, subcs, subcs_vars);
+
+               buff = talloc_array(ctx, uint8_t, subcs_size);
+               if (!buff) {
+                       ERROR("Failed allocating memory for subsection");
+                       return -1;
+               }
+
+               ret = cf_section_parse(buff, buff, subcs, subcs_vars);
+               if (ret < 0) {
+                       talloc_free(buff);
+                       return -1;
+               }
+
+               *((uint8_t **)out) = buff;
+       }
+
+       rad_assert(subcs_size);
+
+       /*
+        *      Handle the multi subsection case (which is harder)
+        */
+       for (subcs = cf_subsection_find(cs, name), count = 0;
+            subcs;
+            subcs = cf_subsection_find_next(cs, subcs, name), count++);
+
+       /*
+        *      Allocate an array to hold the subsections
+        */
+       array = talloc_array(ctx, uint8_t *, count);
+       if (!array) {
+               ERROR("Failed allocating array to hold subsection structures");
+               return -1;
+       }
+
+       /*
+        *      Start parsing...
+        *
+        *      Note, we allocate each subsection structure individually
+        *      so that they can be used as talloc contexts and we can
+        *      keep the talloc hierarchy clean.
+        */
+       for (subcs = cf_subsection_find(cs, name), i = 0;
+            subcs;
+            subcs = cf_subsection_find_next(cs, subcs, name), i++) {
+               uint8_t *buff;
+
+               buff = talloc_zero_array(array, uint8_t, subcs_size);
+               if (!buff) {
+                       ERROR("Failed allocating memory for subsection");
+                       talloc_free(array);
+                       return -1;
+               }
+               array[i] = buff;
+
+               ret = cf_section_parse(buff, buff, subcs, subcs_vars);
+               if (ret < 0) {
+                       talloc_free(array);
+                       return ret;
+               }
+       }
+
+       *((uint8_t ***)out) = array;
+
+       return 0;
+}
+
 /** Parse a configuration section into user-supplied variables
  *
- * @param cs to parse.
- * @param base pointer to a struct to fill with data.  Any buffers will also be talloced
- *     using this parent as a pointer.
- * @param variables mappings between struct fields and #CONF_ITEM s.
+ * @param[in] ctx              to allocate any strings, or additional structures in.
+ *                             Usually the same as base, unless base is a nested struct.
+ * @param[out] base            pointer to a struct to fill with data.
+ * @param[in] cs               to parse.
+ * @param[in] variables        mappings between struct fields and #CONF_ITEM s.
  * @return
  *     - 0 on success.
  *     - -1 on general error.
  *     - -2 if a deprecated #CONF_ITEM was found.
  */
-int cf_section_parse(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
+int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs, CONF_PARSER const *variables)
 {
-       int ret = 0;
-       int i;
-       void *data;
-       bool *is_set = NULL;
+       int     ret = 0;
+       int     i;
+       void    *data;
+       bool    *is_set = NULL;
 
        cs->variables = variables; /* this doesn't hurt anything */
 
@@ -2357,22 +2498,9 @@ int cf_section_parse(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
                 *      Handle subsections specially
                 */
                if (PW_BASE_TYPE(variables[i].type) == PW_TYPE_SUBSECTION) {
-                       CONF_SECTION *subcs;
-
-                       for (subcs = cf_subsection_find(cs, variables[i].name);
-                       /*
-                        *      Default in this case is overloaded to mean a pointer
-                        *      to the CONF_PARSER struct for the subsection.
-                        */
-                       if (!variables[i].dflt || !subcs) {
-                               ERROR("Internal sanity check 1 failed in cf_section_parse %s", variables[i].name);
-                               ret = -1;
-                               goto finish;
-                       }
-
-                       ret = cf_section_parse(subcs, (uint8_t *)base + variables[i].offset,
-                                              (CONF_PARSER const *) variables[i].dflt);
-                       if (ret < 0) goto finish;
+                       if (cf_subsection_parse(ctx, (uint8_t *)base + variables[i].offset, cs,
+                                               variables[i].name, variables[i].type,
+                                               variables[i].subcs, variables[i].subcs_size) < 0) goto finish;
                        continue;
                } /* else it's a CONF_PAIR */
 
@@ -2380,8 +2508,7 @@ int cf_section_parse(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
                        data = variables[i].data; /* prefer this. */
                } else if (base) {
                        data = ((uint8_t *)base) + variables[i].offset;
-               } else {
-                       ERROR("Internal sanity check 2 failed in cf_section_parse");
+               } else if (!rad_cond_assert(0)) {
                        ret = -1;
                        goto finish;
                }
@@ -2398,7 +2525,7 @@ int cf_section_parse(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
                /*
                 *      Parse the pair we found, or a default value.
                 */
-               ret = cf_pair_parse(cs, variables[i].name, variables[i].type, data,
+               ret = cf_pair_parse(ctx, cs, variables[i].name, variables[i].type, data,
                                    variables[i].dflt, variables[i].quote);
                switch (ret) {
                case 1:         /* Used default (or not present) */
index 1a1b02baf0843c6420ff75db8e5a96c8b10cf7a1..338cd4b6872a4743d37e252b74930a607e2c126a 100644 (file)
@@ -1046,7 +1046,7 @@ fr_connection_pool_t *fr_connection_pool_init(TALLOC_CTX *ctx,
 
                memcpy(&mutable, &cs, sizeof(mutable));
 
-               if (cf_section_parse(mutable, pool, connection_config) < 0) {
+               if (cf_section_parse(pool, pool, mutable, connection_config) < 0) {
                        ERROR("Configuration parsing failed: %s", fr_strerror());
                        goto error;
                }
index c47eab9ba429c5969730d5a2f81898a5c2a92827..f42ae4c4bf7649364c8c96a0d79dd1083487b484 100644 (file)
@@ -402,7 +402,7 @@ int dl_module_instance_data_alloc(void **data, TALLOC_CTX *ctx, dl_module_t cons
        MEM(*data = talloc_zero_array(ctx, uint8_t, module->common->inst_size));
 
        talloc_set_name(*data, "%s_t", module->name ? module->name : "config");
-       if (module->common->config && (cf_section_parse(cs, *data, module->common->config) < 0)) {
+       if (module->common->config && (cf_section_parse(*data, *data, cs, module->common->config) < 0)) {
                cf_log_err_cs(cs, "Invalid configuration for module \"%s\"", module->name);
                talloc_free(*data);
                return -1;
index 702e9eda4dae200c609b8da4bd7097c473ade49a..1a6e436b2fd292f6178421a71cc5a31d2581cb1b 100644 (file)
@@ -1308,12 +1308,12 @@ int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
        memset(&ipaddr, 0, sizeof(ipaddr));
        ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
 
-       rcode = cf_pair_parse(cs, "ipaddr", FR_ITEM_POINTER(PW_TYPE_COMBO_IP_ADDR, &ipaddr), NULL, T_INVALID);
+       rcode = cf_pair_parse(NULL, cs, "ipaddr", FR_ITEM_POINTER(PW_TYPE_COMBO_IP_ADDR, &ipaddr), NULL, T_INVALID);
        if (rcode < 0) return -1;
-       if (rcode != 0) rcode = cf_pair_parse(cs, "ipv4addr",
+       if (rcode != 0) rcode = cf_pair_parse(NULL, cs, "ipv4addr",
                                              FR_ITEM_POINTER(PW_TYPE_IPV4_ADDR, &ipaddr), NULL, T_INVALID);
        if (rcode < 0) return -1;
-       if (rcode != 0) rcode = cf_pair_parse(cs, "ipv6addr",
+       if (rcode != 0) rcode = cf_pair_parse(NULL, cs, "ipv6addr",
                                              FR_ITEM_POINTER(PW_TYPE_IPV6_ADDR, &ipaddr), NULL, T_INVALID);
        if (rcode < 0) return -1;
        /*
@@ -1326,10 +1326,10 @@ int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
                ipaddr.ipaddr.ip6addr = in6addr_any;    /* in6addr_any binds to all addresses */
        }
 
-       rcode = cf_pair_parse(cs, "port", FR_ITEM_POINTER(PW_TYPE_SHORT, &sock->my_port), "0", T_BARE_WORD);
+       rcode = cf_pair_parse(NULL, cs, "port", FR_ITEM_POINTER(PW_TYPE_SHORT, &sock->my_port), "0", T_BARE_WORD);
        if (rcode < 0) return -1;
 
-       rcode = cf_pair_parse(cs, "recv_buff", FR_ITEM_POINTER(PW_TYPE_INTEGER, &recv_buff), "0", T_BARE_WORD);
+       rcode = cf_pair_parse(NULL, cs, "recv_buff", FR_ITEM_POINTER(PW_TYPE_INTEGER, &recv_buff), "0", T_BARE_WORD);
        if (rcode < 0) return -1;
        if (recv_buff) {
                FR_INTEGER_BOUND_CHECK("recv_buff", recv_buff, >=, 32);
@@ -1349,7 +1349,7 @@ int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
                CONF_SECTION *tls;
 #  endif
 
-               rcode = cf_pair_parse(cs, "proto", FR_ITEM_POINTER(PW_TYPE_STRING, &proto),
+               rcode = cf_pair_parse(NULL, cs, "proto", FR_ITEM_POINTER(PW_TYPE_STRING, &proto),
                                      "udp", T_DOUBLE_QUOTED_STRING);
                if (rcode < 0) return -1;
 
@@ -1407,15 +1407,13 @@ int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
         */
        subcs = cf_subsection_find(cs, "performance");
        if (subcs) {
-               rcode = cf_section_parse(subcs, this,
-                                        performance_config);
+               rcode = cf_section_parse(this, this, subcs, performance_config);
                if (rcode < 0) return -1;
        }
 
        subcs = cf_subsection_find(cs, "limit");
        if (subcs) {
-               rcode = cf_section_parse(subcs, sock,
-                                        limit_config);
+               rcode = cf_section_parse(sock, sock, subcs, limit_config);
                if (rcode < 0) return -1;
 
                if (sock->max_rate && ((sock->max_rate < 10) || (sock->max_rate > 1000000))) {
@@ -1543,7 +1541,7 @@ int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
         */
        clients_cs = NULL;
        parent_cs = cf_top_section(cs);
-       rcode = cf_pair_parse(cs, "clients", FR_ITEM_POINTER(PW_TYPE_STRING, &section_name), NULL, T_INVALID);
+       rcode = cf_pair_parse(NULL, cs, "clients", FR_ITEM_POINTER(PW_TYPE_STRING, &section_name), NULL, T_INVALID);
        if (rcode < 0) return -1; /* bad string */
        if (rcode == 0) {
                /*
@@ -1556,6 +1554,7 @@ int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
                        return -1;
                }
        } /* else there was no "clients = " entry. */
+       talloc_const_free(section_name);
 
        /*
         *      Always cache the CONF_SECTION of the server.
@@ -3094,8 +3093,7 @@ static rad_listen_t *listen_parse(listen_config_t *lc)
        cf_log_info(cs, "listen {");
 
        listen_type = NULL;
-       rcode = cf_pair_parse(cs, "type", FR_ITEM_POINTER(PW_TYPE_STRING, &listen_type), "", T_DOUBLE_QUOTED_STRING);
-       if (rcode < 0) return NULL;
+
 
        /*
         *      Allocate a listener.
@@ -3105,6 +3103,13 @@ static rad_listen_t *listen_parse(listen_config_t *lc)
        this->fd = -1;
        this->cs = cs;
 
+       rcode = cf_pair_parse(this, cs, "type", FR_ITEM_POINTER(PW_TYPE_STRING, &listen_type),
+                             "", T_DOUBLE_QUOTED_STRING);
+       if (rcode < 0) {
+               talloc_free(this);
+               return NULL;
+       }
+
 #ifdef WITH_TCP
        /*
         *      Special-case '+' for "auth+acct".
index a5548397ba241d5b8d1151970fa50a2fabd34256..7296be15fd37add5dbda207743b89e1747ee09e4 100644 (file)
@@ -436,7 +436,7 @@ static int switch_users(CONF_SECTION *cs)
         */
        if (rad_debug_lvl && (getuid() != 0)) return 1;
 
-       if (cf_section_parse(cs, NULL, bootstrap_config) < 0) {
+       if (cf_section_parse(NULL, NULL, cs, bootstrap_config) < 0) {
                fprintf(stderr, "%s: Error: Failed to parse user/group information.\n",
                        main_config.name);
                return 0;
@@ -800,7 +800,7 @@ do {\
         *      set it now.
         */
        if (default_log.dst == L_DST_NULL) {
-               if (cf_section_parse(cs, NULL, startup_server_config) < 0) {
+               if (cf_section_parse(NULL, NULL, cs, startup_server_config) < 0) {
                        fprintf(stderr, "%s: Error: Failed to parse log{} section.\n",
                                main_config.name);
                        cf_file_free(cs);
@@ -879,7 +879,7 @@ do {\
         *      This allows us to figure out where, relative to
         *      radiusd.conf, the other configuration files exist.
         */
-       if (cf_section_parse(cs, NULL, server_config) < 0) return -1;
+       if (cf_section_parse(NULL, NULL, cs, server_config) < 0) return -1;
 
        /*
         *      We ignore colourization of output until after the
index ecb364b3f3b5305f2b7d5723748e824bb42f0d81..5f679122630b94a59827d84fb7a58d68bddd6121 100644 (file)
@@ -657,8 +657,7 @@ static int _module_instantiate(void *instance, UNUSED void *ctx)
         *      are defined, go compile the config items marked as XLAT.
         */
        if (inst->module->config &&
-           (cf_section_parse_pass2(inst->cs, inst->data,
-                                   inst->module->config) < 0)) {
+           (cf_section_parse_pass2(inst->data, inst->cs, inst->module->config) < 0)) {
                return -1;
        }
 
index 531be2b97afff4fa85231b4b3a7cebcc33efdce3..193554bcd3c3fc2f6d6894d69b967ce49ab5e6d1 100644 (file)
@@ -570,7 +570,7 @@ int main(int argc, char **argv)
                        /*
                         *      Now find the socket name (sigh)
                         */
-                       rcode = cf_pair_parse(subcs, "socket",
+                       rcode = cf_pair_parse(NULL, subcs, "socket",
                                              FR_ITEM_POINTER(PW_TYPE_STRING, &file), NULL, T_DOUBLE_QUOTED_STRING);
                        if (rcode < 0) {
                                fprintf(stderr, "%s: Failed parsing listen section 'socket'\n", progname);
@@ -590,7 +590,7 @@ int main(int argc, char **argv)
                        /*
                         *      Check UID and GID.
                         */
-                       rcode = cf_pair_parse(subcs, "uid",
+                       rcode = cf_pair_parse(NULL, subcs, "uid",
                                              FR_ITEM_POINTER(PW_TYPE_STRING, &uid_name), NULL, T_DOUBLE_QUOTED_STRING);
                        if (rcode < 0) {
                                fprintf(stderr, "%s: Failed parsing listen section 'uid'\n", progname);
@@ -607,7 +607,7 @@ int main(int argc, char **argv)
 
                        if (uid != pwd->pw_uid) continue;
 
-                       rcode = cf_pair_parse(subcs, "gid",
+                       rcode = cf_pair_parse(NULL, subcs, "gid",
                                              FR_ITEM_POINTER(PW_TYPE_STRING, &gid_name), NULL, T_DOUBLE_QUOTED_STRING);
                        if (rcode < 0) {
                                fprintf(stderr, "%s: Failed parsing listen section 'gid'\n", progname);
index 4afd0effa8c81e96ecfd1cf45a95e53d99877645..0a8a22ca695fa549b5f3ab0fc5b7c3113c7f3aa5 100644 (file)
@@ -345,7 +345,7 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       cf_section_parse(cs, NULL, module_config);
+       cf_section_parse(maincs, NULL, cs, module_config);
 
        /* Assign the correct path for the radutmp file */
        radutmp_file = radutmpconfig.radutmp_fn;
index c3cca5764703ba69bba21e6c67560cce0bccc30c..88f5004c66a1602fa3f79ea15d615c552a49d2af 100644 (file)
@@ -623,7 +623,7 @@ home_server_t *home_server_afrom_cs(TALLOC_CTX *ctx, realm_config_t *rc, CONF_SE
         *      Parse the configuration into the home server
         *      struct.
         */
-       if (cf_section_parse(cs, home, home_server_config) < 0) goto error;
+       if (cf_section_parse(home, home, cs, home_server_config) < 0) goto error;
 
        /*
         *      It has an IP address, it must be a remote server.
@@ -2135,7 +2135,7 @@ int realms_init(CONF_SECTION *config)
 #ifdef WITH_PROXY
        cs = cf_subsection_find_next(config, NULL, "proxy");
        if (cs) {
-               if (cf_section_parse(cs, rc, proxy_config) < 0) {
+               if (cf_section_parse(rc, rc, cs, proxy_config) < 0) {
                        ERROR("Failed parsing proxy section");
                        goto error;
                }
index 0f5cd641d208bd374ffc4273fb4445d0e51b5709..21ef1cb16d6992d6538b4d2a3faa01da3cf75e4e 100644 (file)
@@ -785,7 +785,7 @@ int thread_pool_bootstrap(CONF_SECTION *cs, bool *spawn_workers)
                return 0;
        }
 
-       if (cf_section_parse(pool_cf, NULL, thread_config) < 0) return -1;
+       if (cf_section_parse(NULL, NULL, pool_cf, thread_config) < 0) return -1;
 
        /*
         *      Catch corner cases.
index afa26980eba1b690c99227fd3702a6cd36ae2a6c..02fcf4810f37978872717d378940de06c56a925a 100644 (file)
@@ -318,7 +318,7 @@ fr_tls_conf_t *tls_conf_parse_server(CONF_SECTION *cs)
 
        conf = conf_alloc(cs);
 
-       if (cf_section_parse(cs, conf, tls_server_config) < 0) {
+       if (cf_section_parse(conf, conf, cs, tls_server_config) < 0) {
        error:
                talloc_free(conf);
                return NULL;
@@ -450,7 +450,7 @@ fr_tls_conf_t *tls_conf_parse_client(CONF_SECTION *cs)
 
        conf = conf_alloc(cs);
 
-       if (cf_section_parse(cs, conf, tls_client_config) < 0) {
+       if (cf_section_parse(conf, conf, cs, tls_client_config) < 0) {
        error:
                talloc_free(conf);
                return NULL;
index ddd4a24ccc0bfb12e54eb8da873cd0fcf176bce5..b12ec9940c0c86bb308db7cf0b1bdebb86f4affa 100644 (file)
@@ -446,7 +446,7 @@ static void print_packet(FILE *fp, RADIUS_PACKET *packet)
 /*
  *     %{poke:sql.foo=bar}
  */
-static ssize_t xlat_poke(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
+static ssize_t xlat_poke(TALLOC_CTX *ctx, char **out, size_t outlen,
                         UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
                         REQUEST *request, char const *fmt)
 {
@@ -544,7 +544,7 @@ static ssize_t xlat_poke(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
                /*
                 *      Parse the pair we found, or a default value.
                 */
-               ret = cf_pair_parse(instance->cs, variables[i].name, variables[i].type,
+               ret = cf_pair_parse(ctx, instance->cs, variables[i].name, variables[i].type,
                                    data, variables[i].dflt, variables[i].quote);
                if (ret < 0) {
                        DEBUG2("Failed inserting new value into module instance data");
index 52175cff4eda1656f1afb02373de2dd5e9c6c233..1c6c12454a49ef91ea8bece23d137ab7bb68c6b1 100644 (file)
@@ -425,7 +425,7 @@ static ssize_t bfd_parse_secret(CONF_SECTION *cs, uint8_t secret[BFD_MAX_SECRET_
        size_t len;
        char const *value = NULL;
 
-       rcode = cf_pair_parse(cs, "secret", FR_ITEM_POINTER(PW_TYPE_STRING, &value), NULL, T_INVALID);
+       rcode = cf_pair_parse(NULL, cs, "secret", FR_ITEM_POINTER(PW_TYPE_STRING, &value), NULL, T_INVALID);
        if (rcode != 0) return 0;
 
        len = strlen(value);
@@ -495,26 +495,26 @@ static bfd_state_t *bfd_new_session(bfd_socket_t *sock, int sockfd,
        /*
         *      Allow over-riding of variables per session.
         */
-       rcode = cf_pair_parse(cs, "demand", FR_ITEM_POINTER(PW_TYPE_BOOLEAN, &flag), NULL, T_INVALID);
+       rcode = cf_pair_parse(NULL, cs, "demand", FR_ITEM_POINTER(PW_TYPE_BOOLEAN, &flag), NULL, T_INVALID);
        if (rcode == 0) {
                session->demand_mode = flag;
        }
 
-       rcode = cf_pair_parse(cs, "min_transmit_interval", FR_ITEM_POINTER(PW_TYPE_INTEGER, &number), NULL, T_INVALID);
+       rcode = cf_pair_parse(NULL, cs, "min_transmit_interval", FR_ITEM_POINTER(PW_TYPE_INTEGER, &number), NULL, T_INVALID);
        if (rcode == 0) {
                if (number < 100) number = 100;
                if (number > 10000) number = 10000;
 
                session->desired_min_tx_interval = number * 1000;
        }
-       rcode = cf_pair_parse(cs, "min_receive_interval", FR_ITEM_POINTER(PW_TYPE_INTEGER, &number), NULL, T_INVALID);
+       rcode = cf_pair_parse(NULL, cs, "min_receive_interval", FR_ITEM_POINTER(PW_TYPE_INTEGER, &number), NULL, T_INVALID);
        if (rcode == 0) {
                if (number < 100) number = 100;
                if (number > 10000) number = 10000;
 
                session->required_min_rx_interval = number * 1000;
        }
-       rcode = cf_pair_parse(cs, "max_timeouts", FR_ITEM_POINTER(PW_TYPE_INTEGER, &number), NULL, T_INVALID);
+       rcode = cf_pair_parse(NULL, cs, "max_timeouts", FR_ITEM_POINTER(PW_TYPE_INTEGER, &number), NULL, T_INVALID);
        if (rcode == 0) {
                if (number == 0) number = 1;
                if (number > 10) number = 10;
@@ -1544,14 +1544,14 @@ static int bfd_parse_ip_port(CONF_SECTION *cs, fr_ipaddr_t *ipaddr, uint16_t *po
         */
        memset(ipaddr, 0, sizeof(*ipaddr));
        ipaddr->ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
-       rcode = cf_pair_parse(cs, "ipaddr", FR_ITEM_POINTER(PW_TYPE_IPV4_ADDR, ipaddr), NULL, T_INVALID);
+       rcode = cf_pair_parse(NULL, cs, "ipaddr", FR_ITEM_POINTER(PW_TYPE_IPV4_ADDR, ipaddr), NULL, T_INVALID);
        if (rcode < 0) return -1;
 
        if (rcode == 0) { /* successfully parsed IPv4 */
                ipaddr->af = AF_INET;
 
        } else {        /* maybe IPv6? */
-               rcode = cf_pair_parse(cs, "ipv6addr", FR_ITEM_POINTER(PW_TYPE_IPV6_ADDR, ipaddr), NULL, T_INVALID);
+               rcode = cf_pair_parse(NULL, cs, "ipv6addr", FR_ITEM_POINTER(PW_TYPE_IPV6_ADDR, ipaddr), NULL, T_INVALID);
                if (rcode < 0) return -1;
 
                if (rcode == 1) {
@@ -1562,7 +1562,7 @@ static int bfd_parse_ip_port(CONF_SECTION *cs, fr_ipaddr_t *ipaddr, uint16_t *po
                ipaddr->af = AF_INET6;
        }
 
-       rcode = cf_pair_parse(cs, "port", FR_ITEM_POINTER(PW_TYPE_SHORT, port), "0", T_INVALID);
+       rcode = cf_pair_parse(NULL, cs, "port", FR_ITEM_POINTER(PW_TYPE_SHORT, port), "0", T_INVALID);
        if (rcode < 0) return -1;
 
        return 0;
@@ -1667,15 +1667,15 @@ static int bfd_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
        sock->my_ipaddr = ipaddr;
        sock->my_port = listen_port;
 
-       cf_pair_parse(cs, "interface", FR_ITEM_POINTER(PW_TYPE_STRING, &sock->interface), NULL, T_INVALID);
+       cf_pair_parse(sock, cs, "interface", FR_ITEM_POINTER(PW_TYPE_STRING, &sock->interface), NULL, T_INVALID);
 
-       cf_pair_parse(cs, "min_receive_interval", FR_ITEM_POINTER(PW_TYPE_INTEGER, &sock->min_rx_interval), "1000", T_BARE_WORD);
-       cf_pair_parse(cs, "max_timeouts", FR_ITEM_POINTER(PW_TYPE_INTEGER, &sock->max_timeouts), "3", T_BARE_WORD);
-       cf_pair_parse(cs, "demand", FR_ITEM_POINTER(PW_TYPE_BOOLEAN, &sock->demand), "no", T_DOUBLE_QUOTED_STRING);
-       cf_pair_parse(cs, "auth_type", FR_ITEM_POINTER(PW_TYPE_STRING, &auth_type_str), NULL, T_INVALID);
+       cf_pair_parse(sock, cs, "min_receive_interval", FR_ITEM_POINTER(PW_TYPE_INTEGER, &sock->min_rx_interval), "1000", T_BARE_WORD);
+       cf_pair_parse(sock, cs, "max_timeouts", FR_ITEM_POINTER(PW_TYPE_INTEGER, &sock->max_timeouts), "3", T_BARE_WORD);
+       cf_pair_parse(sock, cs, "demand", FR_ITEM_POINTER(PW_TYPE_BOOLEAN, &sock->demand), "no", T_DOUBLE_QUOTED_STRING);
+       cf_pair_parse(NULL, cs, "auth_type", FR_ITEM_POINTER(PW_TYPE_STRING, &auth_type_str), NULL, T_INVALID);
 
        if (!this->server) {
-               cf_pair_parse(cs, "server", FR_ITEM_POINTER(PW_TYPE_STRING, &sock->server), NULL, T_INVALID);
+               cf_pair_parse(sock, cs, "server", FR_ITEM_POINTER(PW_TYPE_STRING, &sock->server), NULL, T_INVALID);
        } else {
                sock->server = this->server;
        }
index e22f9f4ab8790b3d60cea45e707df1529d5b401f..773dab4938d7b31b55f72c93f33916ee9631f3e8 100644 (file)
@@ -1037,7 +1037,7 @@ static int detail_parse(CONF_SECTION *cs, rad_listen_t *this)
 
        data = this->data;
 
-       rcode = cf_section_parse(cs, data, detail_config);
+       rcode = cf_section_parse(data, data, cs, detail_config);
        if (rcode < 0) {
                cf_log_err_cs(cs, "Failed parsing listen section");
                return -1;
index e613e3fff6ee619280f311ba6d260fe599663880..26a9389be36d0b663760cf2d63ae1c0bb0660574 100644 (file)
@@ -735,13 +735,15 @@ static int dhcp_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
        sock->suppress_responses = false;
        cp = cf_pair_find(cs, "suppress_responses");
        if (cp) {
-               rcode = cf_pair_parse(cs, "suppress_responses", FR_ITEM_POINTER(PW_TYPE_BOOLEAN, &sock->suppress_responses), NULL, T_INVALID);
+               rcode = cf_pair_parse(sock, cs, "suppress_responses",
+                                     FR_ITEM_POINTER(PW_TYPE_BOOLEAN, &sock->suppress_responses), NULL, T_INVALID);
                if (rcode < 0) return -1;
        }
 
        cp = cf_pair_find(cs, "src_interface");
        if (cp) {
-               rcode = cf_pair_parse(cs, "src_interface", FR_ITEM_POINTER(PW_TYPE_STRING, &sock->src_interface), NULL, T_INVALID);
+               rcode = cf_pair_parse(sock, cs, "src_interface",
+                                     FR_ITEM_POINTER(PW_TYPE_STRING, &sock->src_interface), NULL, T_INVALID);
                if (rcode < 0) return -1;
        } else {
                sock->src_interface = sock->lsock.interface;
@@ -758,7 +760,8 @@ static int dhcp_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
        if (cp) {
                memset(&sock->src_ipaddr, 0, sizeof(sock->src_ipaddr));
                sock->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
-               rcode = cf_pair_parse(cs, "src_ipaddr", FR_ITEM_POINTER(PW_TYPE_IPV4_ADDR, &sock->src_ipaddr), NULL, T_INVALID);
+               rcode = cf_pair_parse(sock, cs, "src_ipaddr",
+                                     FR_ITEM_POINTER(PW_TYPE_IPV4_ADDR, &sock->src_ipaddr), NULL, T_INVALID);
                if (rcode < 0) return -1;
 
                sock->src_ipaddr.af = AF_INET;
index e1840eb2826f974d0b1e07650ea74f002815a6b0..f05ad2eeeaf869e606237f148119e24c3e6fd852 100644 (file)
@@ -56,7 +56,7 @@ static int mod_instantiate(rlm_cache_config_t const *config, void *instance, CON
 
        buffer[0] = '\0';
 
-       if (cf_section_parse(conf, driver, driver_config) < 0) return -1;
+       if (cf_section_parse(driver, driver, conf, driver_config) < 0) return -1;
 
        snprintf(buffer, sizeof(buffer), "rlm_cache (%s)", config->name);
 
index 295e0b79aa31e4589e9ba3b07a8cbf32eaee90ef..ec4de60c4541b660e7e5d1138daa4fe2b6634340 100644 (file)
@@ -1398,7 +1398,7 @@ static int parse_sub_section(rlm_ldap_t *inst, CONF_SECTION *parent, ldap_acct_s
        }
 
        *config = talloc_zero(inst, ldap_acct_section_t);
-       if (cf_section_parse(cs, *config, acct_section_config) < 0) {
+       if (cf_section_parse(*config, *config, cs, acct_section_config) < 0) {
                ERROR("rlm_ldap (%s) - Failed parsing configuration for section %s", inst->name, name);
 
                return -1;
index 8588bebc9be6600e1c96f2a3860645714ca010ba..981eb905f030bd875e841d3a16b1fbea4cab1750 100644 (file)
@@ -1151,7 +1151,7 @@ static int driver_init(TALLOC_CTX *ctx, CONF_SECTION *conf, void **instance)
        this = talloc_zero(ctx, redis_driver_conf_t);
        if (!this) return -1;
 
-       ret = cf_section_parse(conf, &this->conf, redis_config);
+       ret = cf_section_parse(this, &this->conf, conf, redis_config);
        if (ret < 0) {
                talloc_free(this);
                return -1;
index d0e91e66f7f1d5282a518fad965741e802eb4023..b6b54c0a0f1fc922ad2b46eab216350eaa19377c 100644 (file)
@@ -751,7 +751,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, void *thread,
        return unlang_yield(request, mod_post_auth_result, NULL, handle);
 }
 
-static int parse_sub_section(CONF_SECTION *parent, CONF_PARSER const *config_items,
+static int parse_sub_section(rlm_rest_t *inst, CONF_SECTION *parent, CONF_PARSER const *config_items,
                             rlm_rest_section_t *config, char const *name)
 {
        CONF_SECTION *cs;
@@ -762,7 +762,7 @@ static int parse_sub_section(CONF_SECTION *parent, CONF_PARSER const *config_ite
                return 0;
        }
 
-       if (cf_section_parse(cs, config, config_items) < 0) {
+       if (cf_section_parse(inst, config, cs, config_items) < 0) {
                config->name = NULL;
                return -1;
        }
@@ -960,18 +960,18 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
         *      Parse sub-section configs.
         */
        if (
-               (parse_sub_section(conf, xlat_config, &inst->xlat, "xlat") < 0) ||
-               (parse_sub_section(conf, section_config, &inst->authorize,
+               (parse_sub_section(inst, conf, xlat_config, &inst->xlat, "xlat") < 0) ||
+               (parse_sub_section(inst, conf, section_config, &inst->authorize,
                                   section_type_value[MOD_AUTHORIZE].section) < 0) ||
-               (parse_sub_section(conf, section_config, &inst->authenticate,
+               (parse_sub_section(inst, conf, section_config, &inst->authenticate,
                                   section_type_value[MOD_AUTHENTICATE].section) < 0) ||
-               (parse_sub_section(conf, section_config, &inst->accounting,
+               (parse_sub_section(inst, conf, section_config, &inst->accounting,
                                   section_type_value[MOD_ACCOUNTING].section) < 0) ||
 
 /* @todo add behaviour for checksimul */
 /*             (parse_sub_section(conf, section_config, &inst->checksimul,
                                   section_type_value[MOD_SESSION].section) < 0) || */
-               (parse_sub_section(conf, section_config, &inst->post_auth,
+               (parse_sub_section(inst, conf, section_config, &inst->post_auth,
                                   section_type_value[MOD_POST_AUTH].section) < 0))
        {
                return -1;
index 0eb6a16ab7a34721e07b35a1981503025bfeac39..f18ad86e35ed7861f079101302e03f662676f161 100644 (file)
@@ -332,11 +332,6 @@ static rlm_rcode_t CC_HINT(nonnull) mod_checksimul(UNUSED void *instance, void *
 }
 #endif
 
-
-/*
- *     Only free memory we allocated.  The strings allocated via
- *     cf_section_parse() do not need to be freed.
- */
 static int mod_detach(UNUSED void *instance)
 {
        /* free things here */
index ccfa809cd734f5eea1da03dba94f5d32e706e99d..773bf2447b2c3671f003a5f82db99715333a3632 100644 (file)
@@ -174,10 +174,6 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
        return 0;
 }
 
-/*
- *     Only free memory we allocated.  The strings allocated via
- *     cf_section_parse() do not need to be freed.
- */
 #ifdef HAVE_YKCLIENT
 static int mod_detach(void *instance)
 {