The conf parser can now produce an array of allocated sturcts representing the subsections.
.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, \
.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
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.
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);
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);
*/
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;
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
*
* @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;
* 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;
}
* - 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;
* | 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.
* - ``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;
* 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.
*
*/
} 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:
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:
}
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.
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;
}
}
}
+/** 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 */
* 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 */
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;
}
/*
* 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) */
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;
}
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;
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;
/*
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);
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;
*/
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))) {
*/
clients_cs = NULL;
parent_cs = cf_top_section(cs);
- rcode = cf_pair_parse(cs, "clients", FR_ITEM_POINTER(PW_TYPE_STRING, §ion_name), NULL, T_INVALID);
+ rcode = cf_pair_parse(NULL, cs, "clients", FR_ITEM_POINTER(PW_TYPE_STRING, §ion_name), NULL, T_INVALID);
if (rcode < 0) return -1; /* bad string */
if (rcode == 0) {
/*
return -1;
}
} /* else there was no "clients = " entry. */
+ talloc_const_free(section_name);
/*
* Always cache the CONF_SECTION of the server.
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.
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".
*/
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;
* 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);
* 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
* 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;
}
/*
* 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);
/*
* 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);
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);
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;
* 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.
#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;
}
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.
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;
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;
/*
* %{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)
{
/*
* 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");
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);
/*
* 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;
*/
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) {
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;
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;
}
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;
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;
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;
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);
}
*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;
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;
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;
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;
}
* 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;
}
#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 */
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)
{