*/
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(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);
+int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs);
+int cf_section_parse_pass2(void *base, CONF_SECTION *cs);
CONF_PARSER const *cf_section_parse_table(CONF_SECTION *cs);
+
+/*
+ * Runtime parse rules
+ */
+#define cf_section_rule_push(_cs, _rule) _cf_section_rule_push(_cs, _rule, __FILE__, __LINE__)
+int _cf_section_rule_push(CONF_SECTION *cs, CONF_PARSER const *rule, char const *filename, int lineno);
+#define cf_section_rules_push(_cs, _rule) _cf_section_rules_push(_cs, _rule, __FILE__, __LINE__)
+int _cf_section_rules_push(CONF_SECTION *cs, CONF_PARSER const *rules, char const *filename, int lineno);
+
#ifdef __cplusplus
}
#endif
#define cf_data_find(_cf, _type, _name) _cf_data_find(CF_TO_ITEM(_cf), #_type, _name)
CONF_DATA const *_cf_data_find(CONF_ITEM const *ci, char const *type, char const *name);
-#define cf_data_find_next(_cf, _prev, _type, _name) _cf_data_find(CF_TO_ITEM(_cf), CF_TO_ITEM(_prev), #_type, _name)
+#define cf_data_find_next(_cf, _prev, _type, _name) _cf_data_find_next(CF_TO_ITEM(_cf), CF_TO_ITEM(_prev), #_type, _name)
CONF_DATA const *_cf_data_find_next(CONF_ITEM const *ci, CONF_ITEM const *prev, char const *type, char const *name);
void *cf_data_value(CONF_DATA const *cd);
-#define cf_data_add(_cf, _data, _name, _free) _cf_data_add(CF_TO_ITEM(_cf), _data, _name, _free)
-CONF_DATA const *_cf_data_add(CONF_ITEM *ci, void const *data, char const *name, bool free);
+#define cf_data_add(_cf, _data, _name, _free) _cf_data_add(CF_TO_ITEM(_cf), _data, _name, _free, __FILE__, __LINE__)
+CONF_DATA const *_cf_data_add(CONF_ITEM *ci, void const *data, char const *name, bool free, char const *filename, int lineno);
-#define cf_data_add_static(_cf, _data, _type, _name) _cf_data_add(CF_TO_ITEM(_cf), _data, #_type, _name)
-CONF_DATA const *_cf_data_add_static(CONF_ITEM *ci, void const *data, char const *type, char const *name);
+#define cf_data_add_static(_cf, _data, _type, _name) _cf_data_add_static(CF_TO_ITEM(_cf), _data, #_type, _name, __FILE__, __LINE__)
+CONF_DATA const *_cf_data_add_static(CONF_ITEM *ci, void const *data, char const *type, char const *name, char const *filename, int lineno);
#define cf_data_remove(_cf, _cd) _cf_data_remove(CF_TO_ITEM(_cf), _cd);
void *_cf_data_remove(CONF_ITEM *ci, CONF_DATA const *_cd);
*
* @param cs The parent subsection.
* @param base pointer or variable.
- * @param variables that may have defaults in this config section.
+ * @param rule that may have defaults in this config section.
+ * @return
+ * - 0 on success.
+ * - -1 on failure.
*/
-static int cf_section_parse_init(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
+static int cf_section_parse_init(CONF_SECTION *cs, void *base, CONF_PARSER const *rule)
{
- int i;
-
- for (i = 0; variables[i].name != NULL; i++) {
- if ((FR_BASE_TYPE(variables[i].type) == FR_TYPE_SUBSECTION)) {
- CONF_SECTION *subcs;
+ if ((FR_BASE_TYPE(rule->type) == FR_TYPE_SUBSECTION)) {
+ CONF_SECTION *subcs;
- if (!variables[i].dflt) continue;
-
- subcs = cf_section_find(cs, variables[i].name, NULL);
- if (!subcs && (variables[i].type & FR_TYPE_REQUIRED)) {
- cf_log_err(cs, "Missing %s {} subsection", variables[i].name);
- return -1;
- }
+ if (!rule->dflt) return 0;
- /*
- * Set the is_set field for the subsection.
- */
- if (variables[i].type & FR_TYPE_IS_SET) {
- bool *is_set;
+ subcs = cf_section_find(cs, rule->name, NULL);
+ if (!subcs && (rule->type & FR_TYPE_REQUIRED)) {
+ cf_log_err(cs, "Missing %s {} subsection", rule->name);
+ return -1;
+ }
- is_set = variables[i].data ? variables[i].is_set_ptr :
- ((uint8_t *)base) + variables[i].is_set_offset;
- if (is_set) *is_set = !!subcs;
- }
+ /*
+ * Set the is_set field for the subsection.
+ */
+ if (rule->type & FR_TYPE_IS_SET) {
+ bool *is_set;
- /*
- * If there's no subsection in the
- * config, BUT the CONF_PARSER wants one,
- * then create an empty one. This is so
- * that we can track the strings,
- * etc. allocated in the subsection.
- */
- if (!subcs) {
- subcs = cf_section_alloc(cs, variables[i].name, NULL);
- if (!subcs) return -1;
+ is_set = rule->data ? rule->is_set_ptr : ((uint8_t *)base) + rule->is_set_offset;
+ if (is_set) *is_set = !!subcs;
+ }
- cf_item_add(cs, &(subcs->item));
- }
+ /*
+ * If there's no subsection in the
+ * config, BUT the CONF_PARSER wants one,
+ * then create an empty one. This is so
+ * that we can track the strings,
+ * etc. allocated in the subsection.
+ */
+ if (!subcs) {
+ subcs = cf_section_alloc(cs, rule->name, NULL);
+ if (!subcs) return -1;
- continue;
+ cf_item_add(cs, &(subcs->item));
}
- if ((FR_BASE_TYPE(variables[i].type) != FR_TYPE_STRING) &&
- (variables[i].type != FR_TYPE_FILE_INPUT) &&
- (variables[i].type != FR_TYPE_FILE_OUTPUT)) {
- continue;
- }
+ return 0;
+ }
- if (variables[i].data) {
- *(char **) variables[i].data = NULL;
- } else if (base) {
- *(char **) (((char *)base) + variables[i].offset) = NULL;
- } else {
- continue;
- }
- } /* for all variables in the configuration section */
+ if ((FR_BASE_TYPE(rule->type) != FR_TYPE_STRING) &&
+ (rule->type != FR_TYPE_FILE_INPUT) &&
+ (rule->type != FR_TYPE_FILE_OUTPUT)) {
+ return 0;
+ }
+
+ if (rule->data) {
+ *(char **) rule->data = NULL;
+ } else if (base) {
+ *(char **) (((char *)base) + rule->offset) = NULL;
+ } else {
+ return 0;
+ }
return 0;
}
* @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] rules to push for subsections.
* @param[in] subcs_size size of subsection structures to allocate.
* @return
* - 0 on success.
* - -2 if a deprecated #CONF_ITEM was found.
*/
static int cf_subsection_parse(TALLOC_CTX *ctx, void *out, CONF_SECTION *cs,
- char const *name, fr_type_t type, CONF_PARSER const *subcs_vars, size_t subcs_size)
+ char const *name, fr_type_t type,
+ CONF_PARSER const *rules, size_t subcs_size)
{
- CONF_SECTION *subcs;
- int count, i, ret;
+ CONF_SECTION *subcs = NULL;
+ int count = 0, i, ret;
uint8_t **array;
rad_assert(type & FR_TYPE_SUBSECTION);
if (!(type & FR_TYPE_MULTI)) {
uint8_t *buff;
+ if (cf_section_rules_push(subcs, rules) < 0) return -1;
+
/*
* 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);
+ if (!subcs_size) return cf_section_parse(ctx, out, subcs);
MEM(buff = talloc_array(ctx, uint8_t, subcs_size));
- ret = cf_section_parse(buff, buff, subcs, subcs_vars);
+
+ ret = cf_section_parse(buff, buff, subcs);
if (ret < 0) {
talloc_free(buff);
- return -1;
+ return ret;
}
*((uint8_t **)out) = buff;
/*
* Handle the multi subsection case (which is harder)
*/
- for (subcs = cf_section_find(cs, name, NULL), count = 0;
- subcs;
- subcs = cf_section_find_next(cs, subcs, name, NULL), count++);
+ while ((subcs = cf_section_find_next(cs, subcs, name, NULL))) count++;
/*
* Allocate an array to hold the subsections
MEM(buff = talloc_zero_array(array, uint8_t, subcs_size));
array[i] = buff;
- ret = cf_section_parse(buff, buff, subcs, subcs_vars);
+ if (cf_section_rules_push(subcs, rules) < 0) {
+ talloc_free(array);
+ return ret;
+ }
+
+ ret = cf_section_parse(buff, buff, subcs);
if (ret < 0) {
talloc_free(array);
return ret;
* 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(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs, CONF_PARSER const *variables)
+int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
{
int ret = 0;
- int i;
void *data;
bool *is_set = NULL;
-
- /*
- * Hack for partially parsed sections.
- */
- if (!variables) {
- cf_log_info(cs, "%.*s}", cs->depth, parse_spaces);
- return 0;
- }
-
- cs->variables = variables; /* this doesn't hurt anything */
+ CONF_DATA const *rule_cd = NULL;
if (!cs->name2) {
cf_log_info(cs, "%.*s%s {", cs->depth, parse_spaces, cs->name1);
cf_log_info(cs, "%.*s%s %s {", cs->depth, parse_spaces, cs->name1, cs->name2);
}
- /*
- * Pre-allocate the config structure to hold default values
- */
- if (cf_section_parse_init(cs, base, variables) < 0) return -1;
+ while ((rule_cd = cf_data_find_next(cs, rule_cd, CONF_PARSER, CF_IDENT_ANY))) {
+ CONF_PARSER *rule;
+
+ rule = cf_data_value(rule_cd);
+
+ /*
+ * Pre-allocate the config structure to hold default values
+ */
+ if (cf_section_parse_init(cs, base, rule) < 0) return -1;
- /*
- * Handle the known configuration parameters.
- */
- for (i = 0; variables[i].name != NULL; i++) {
/*
* Handle subsections specially
*/
- if (FR_BASE_TYPE(variables[i].type) == FR_TYPE_SUBSECTION) {
- 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;
+ if (FR_BASE_TYPE(rule->type) == FR_TYPE_SUBSECTION) {
+ if (cf_subsection_parse(ctx, (uint8_t *)base + rule->offset, cs,
+ rule->name, rule->type,
+ rule->subcs, rule->subcs_size) < 0) goto finish;
continue;
} /* else it's a CONF_PAIR */
- if (variables[i].data) {
- data = variables[i].data; /* prefer this. */
+ if (rule->data) {
+ data = rule->data; /* prefer this. */
} else if (base) {
- data = ((uint8_t *)base) + variables[i].offset;
+ data = ((uint8_t *)base) + rule->offset;
} else if (!rad_cond_assert(0)) {
ret = -1;
goto finish;
* Get pointer to where we need to write out
* whether the pointer was set.
*/
- if (variables[i].type & FR_TYPE_IS_SET) {
- is_set = variables[i].data ? variables[i].is_set_ptr :
- ((uint8_t *)base) + variables[i].is_set_offset;
+ if (rule->type & FR_TYPE_IS_SET) {
+ is_set = rule->data ? rule->is_set_ptr : ((uint8_t *)base) + rule->is_set_offset;
}
/*
* Parse the pair we found, or a default value.
*/
- ret = cf_pair_parse(ctx, cs, variables[i].name, variables[i].type, data,
- variables[i].dflt, variables[i].quote);
+ ret = cf_pair_parse(ctx, cs, rule->name, rule->type, data, rule->dflt, rule->quote);
switch (ret) {
case 1: /* Used default (or not present) */
if (is_set) *is_set = false;
goto finish;
case -2: /* Deprecated CONF ITEM */
- if ((variables[i + 1].offset && (variables[i + 1].offset == variables[i].offset)) ||
- (variables[i + 1].data && (variables[i + 1].data == variables[i].data))) {
- cf_log_err(&(cs->item), "Replace \"%s\" with \"%s\"", variables[i].name,
- variables[i + 1].name);
+ if (((rule + 1)->offset && ((rule + 1)->offset == rule->offset)) ||
+ ((rule + 1)->data && ((rule + 1)->data == rule->data))) {
+ cf_log_err(&(cs->item), "Replace \"%s\" with \"%s\"", rule->name,
+ (rule + 1)->name);
}
goto finish;
}
- } /* for all variables in the configuration section */
-
- /*
- * Ensure we have a proper terminator, type so we catch
- * missing terminators reliably
- */
- rad_cond_assert(variables[i].type == conf_term.type);
+ }
cs->base = base;
- /*
- * Hack for partially parsed sections. We don't print
- * out the final "}", that will be printed out when the
- * caller re-calls us with 'variable=NULL'. And, we don't warn about unused
- */
- if (variables[i].offset == 1) return ret;
-
/*
* Warn about items in the configuration which weren't
* checked during parsing.
}
/** Fixup xlat expansions and attributes
- *
- * @note Despite the name, this is really the second phase of #cf_pair_parse.
*
* @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(void *base, CONF_SECTION *cs, CONF_PARSER const variables[])
+int cf_section_parse_pass2(void *base, CONF_SECTION *cs)
{
+ CONF_DATA const *rule_cd = NULL;
- int i;
-
- /*
- * Handle the known configuration parameters.
- */
- for (i = 0; variables[i].name != NULL; i++) {
+ while ((rule_cd = cf_data_find_next(cs, rule_cd, CONF_PARSER, CF_IDENT_ANY))) {
bool attribute, multi, is_tmpl, is_xlat;
CONF_PAIR *cp;
+ CONF_PARSER *rule;
void *data;
- char const *name = variables[i].name;
- int type = variables[i].type;
+ char const *name;
+ int type;
+
+ rule = cf_data_value(rule_cd);
+ name = rule->name;
+ type = rule->type;
is_tmpl = (type & FR_TYPE_TMPL);
is_xlat = (type & FR_TYPE_XLAT);
attribute = (type & FR_TYPE_ATTRIBUTE);
size_t j, len;
uint8_t **array;
- array = (uint8_t **)((uint8_t *)base) + variables[i].offset;
+ array = (uint8_t **)((uint8_t *)base) + rule->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) {
+ if (cf_section_parse_pass2(array[j], subcs) < 0) {
return -1;
}
}
continue;
- } else if (variables[i].subcs_size) {
- subcs_base = (*(uint8_t **)((uint8_t *)base) + variables[i].offset);
+ } else if (rule->subcs_size) {
+ subcs_base = (*(uint8_t **)((uint8_t *)base) + rule->offset);
} else {
- subcs_base = (uint8_t *)base + variables[i].offset;
+ subcs_base = (uint8_t *)base + rule->offset;
}
- if (cf_section_parse_pass2(subcs_base, subcs,
- (CONF_PARSER const *)variables[i].dflt) < 0) return -1;
+ if (cf_section_parse_pass2(subcs_base, subcs) < 0) return -1;
continue;
}
/*
* Figure out which data we need to fix.
*/
- data = variables[i].data; /* prefer this. */
- if (!data && base) data = ((char *)base) + variables[i].offset;
+ data = rule->data; /* prefer this. */
+ if (!data && base) data = ((char *)base) + rule->offset;
if (!data) continue;
/*
* Ignore %{... in shared secrets.
* They're never dynamically expanded.
*/
- if ((variables[i].type & FR_TYPE_SECRET) != 0) continue;
+ if ((rule->type & FR_TYPE_SECRET) != 0) continue;
if (strstr(cp->value, "%{") != NULL) {
cf_log_err(&cp->item, "Found dynamic expansion in string which "
TALLOC_FREE(*out);
*(vp_tmpl_t **)out = vpt;
}
- } /* for all variables in the configuration section */
+ }
return 0;
}
+/*
+ * Fixme? Swapout with an iterative API.
+ */
const CONF_PARSER *cf_section_parse_table(CONF_SECTION *cs)
{
if (!cs) return NULL;
return cs->variables;
}
+
+/** Add a single rule to a #CONF_SECTION
+ *
+ * @param[in] cs to add rules to.
+ * @param[in] rule to add.
+ * @return
+ * - 0 on success.
+ * - -1 if the rules added conflict.
+ */
+int _cf_section_rule_push(CONF_SECTION *cs, CONF_PARSER const *rule, char const *filename, int lineno)
+{
+ if (DEBUG_ENABLED4) {
+ cf_log_debug(cs, "Pushed parse rule to %s: %s %s",
+ cf_section_name1(cs),
+ rule->name, FR_BASE_TYPE(rule->type) & FR_TYPE_SUBSECTION ? "{}": "");
+ }
+
+ /*
+ * Qualifying with name prevents duplicate rules being added
+ *
+ * Fixme maybe?.. Can't have a section and pair with the same name.
+ */
+ if (!_cf_data_add_static(CF_TO_ITEM(cs), rule, "CONF_PARSER", rule->name, filename, lineno)) {
+ cf_debug(cs);
+ return -1;
+ }
+
+ return 0;
+}
+
+/** Add an array of parse rules to a #CONF_SECTION
+ *
+ * @param[in] cs to add rules to.
+ * @param[in] rules to add. Last element should have NULL name field.
+ * @return
+ * - 0 on success.
+ * - -1 on failure.
+ */
+int _cf_section_rules_push(CONF_SECTION *cs, CONF_PARSER const *rules, char const *filename, int lineno)
+{
+ CONF_PARSER const *rule_p;
+
+ for (rule_p = rules; rule_p->name; rule_p++) {
+ if (rule_p->type & FR_TYPE_DEPRECATED) continue; /* Skip deprecated */
+ if (_cf_section_rule_push(cs, rule_p, filename, lineno) < 0) return -1;
+ }
+
+ /*
+ * Ensure we have a proper terminator, type so we catch
+ * missing terminators reliably
+ */
+ rad_cond_assert(rule_p->type == conf_term.type);
+
+ return 0;
+}
* @param[in] data to add.
* @param[in] name String identifier of the user data.
* @param[in] do_free Function to free user data when the CONF_SECTION is freed.
+ * @param[in] filename Source file the #CONF_DATA was added in.
+ * @param[in] lineno the #CONF_DATA was added at.
* @return
* - #CONF_DATA - opaque handle to the stored data - on success.
* - NULL error.
*/
-CONF_DATA const *_cf_data_add(CONF_ITEM *ci, void const *data, char const *name, bool do_free)
+CONF_DATA const *_cf_data_add(CONF_ITEM *ci, void const *data, char const *name, bool do_free,
+ char const *filename, int lineno)
{
CONF_DATA *cd;
+ CONF_DATA const *found;
char const *type = NULL;
if (!ci) return NULL;
/*
* Already exists. Can't add it.
*/
- if (_cf_data_find(ci, type, name)) {
- cf_log_err(ci, "Data of type %s with name %s already exists", type, name);
+ found = _cf_data_find(ci, type, name);
+ if (found) {
+ cf_log_err(ci, "Data of type %s with name \"%s\" already exists. Existing data added %s[%i]", type,
+ name, found->item.filename, found->item.lineno);
return NULL;
}
return NULL;
}
cd->is_talloced = true;
+ cd->item.filename = filename;
+ cd->item.lineno = lineno;
cf_item_add(ci, cd);
* @param[in] data to add.
* @param[in] type identifier of the user data.
* @param[in] name String identifier of the user data.
+ * @param[in] filename Source file the #CONF_DATA was added in.
+ * @param[in] lineno the #CONF_DATA was added at.
* - #CONF_DATA - opaque handle to the stored data - on success.
* - NULL error.
*/
-CONF_DATA const *_cf_data_add_static(CONF_ITEM *ci, void const *data, char const *type, char const *name)
+CONF_DATA const *_cf_data_add_static(CONF_ITEM *ci, void const *data, char const *type, char const *name,
+ char const *filename, int lineno)
{
CONF_DATA *cd;
+ CONF_DATA const *found;
/*
* Already exists. Can't add it.
*/
- if (_cf_data_find(ci, type, name)) {
- cf_log_err(ci, "Data of type %s with name %s already exists", type, name);
+ found = _cf_data_find(ci, type, name);
+ if (found) {
+ cf_log_err(ci, "Data of type %s with name \"%s\" already exists. Existing data added %s[%i]", type,
+ name, found->item.filename, found->item.lineno);
return NULL;
}
return NULL;
}
cd->is_talloced = false;
+ cd->item.filename = filename;
+ cd->item.lineno = lineno;
cf_item_add(ci, cd);
msg = talloc_vasprintf(NULL, fmt, ap);
va_end(ap);
- if (!ci || !ci->filename || !DEBUG_ENABLED3) {
+ if (!ci || !ci->filename || !DEBUG_ENABLED4) {
INFO("%s", msg);
} else {
INFO("%s[%d]: %s", ci->filename, ci->lineno, msg);
c->cs = cs;
memset(&cl_ipaddr, 0, sizeof(cl_ipaddr));
- if (cf_section_parse(c, c, cs, client_config) < 0) {
+ if (cf_section_rules_push(cs, client_config) < 0) return NULL;
+
+ if (cf_section_parse(c, c, cs) < 0) {
cf_log_err(cs, "Error parsing client section");
error:
client_free(c);
sock = this->data;
talloc_set_destructor(sock, _command_socket_free);
- if (cf_section_parse(sock, sock, cs, command_config) < 0) return -1;
+ if (cf_section_rules_push(cs, command_config) < 0) return -1;
+ if (cf_section_parse(sock, sock, cs) < 0) return -1;
/*
* Can't get uid or gid of connecting user, so can't do
} else {
talloc_set_name(*data, "%s", module->common->inst_type);
}
- if (module->common->config && (cf_section_parse(*data, *data, cs, module->common->config) < 0)) {
- cf_log_err(cs, "Invalid configuration for module \"%s\"", module->name);
- talloc_free(*data);
- return -1;
+
+ if (module->common->config) {
+ if ((cf_section_rules_push(cs, module->common->config)) < 0 ||
+ (cf_section_parse(*data, *data, cs) < 0)) {
+ cf_log_err(cs, "Invalid configuration for module \"%s\"", module->name);
+ talloc_free(*data);
+ return -1;
+ }
}
/*
*/
subcs = cf_section_find(cs, "performance", NULL);
if (subcs) {
- rcode = cf_section_parse(this, this, subcs, performance_config);
+ if (cf_section_rules_push(subcs, performance_config) < 0) return -1;
+ rcode = cf_section_parse(this, this, subcs);
if (rcode < 0) return -1;
}
subcs = cf_section_find(cs, "limit", NULL);
if (subcs) {
- rcode = cf_section_parse(sock, sock, subcs, limit_config);
+ if (cf_section_rules_push(subcs, limit_config) < 0) return -1;
+
+ rcode = cf_section_parse(sock, sock, subcs);
if (rcode < 0) return -1;
if (sock->max_rate && ((sock->max_rate < 10) || (sock->max_rate > 1000000))) {
*/
if (rad_debug_lvl && (getuid() != 0)) return 1;
- if (cf_section_parse(NULL, NULL, cs, bootstrap_config) < 0) {
+ if (cf_section_rules_push(cs, bootstrap_config) < 0) {
+ fprintf(stderr, "%s: Error: Failed pushing parse rules for user/group information.\n",
+ main_config.name);
+ return 0;
+ }
+
+ if (cf_section_parse(NULL, NULL, cs) < 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(NULL, NULL, cs, startup_server_config) < 0) {
+ if (cf_section_rules_push(cs, startup_server_config) < 0) {
+ fprintf(stderr, "%s: Error: Failed pushing rules for log {} section.\n",
+ main_config.name);
+ cf_file_free(cs);
+ return -1;
+ }
+
+ if (cf_section_parse(NULL, NULL, cs) < 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(NULL, NULL, cs, server_config) < 0) return -1;
+ if (cf_section_rules_push(cs, server_config) < 0) return -1;
+ if (cf_section_parse(NULL, NULL, cs) < 0) return -1;
/*
* We ignore colourization of output until after the
* Now that ALL modules are instantiated, and ALL xlats
* are defined, go compile the config items marked as XLAT.
*/
- if (inst->module->config &&
- (cf_section_parse_pass2(inst->data, inst->cs, inst->module->config) < 0)) {
- return -1;
- }
+ if (inst->module->config && (cf_section_parse_pass2(inst->data, inst->cs) < 0)) return -1;
/*
* Call the instantiate method, if any.
memcpy(&mutable, &cs, sizeof(mutable));
- if (cf_section_parse(pool, pool, mutable, pool_config) < 0) {
+ if (cf_section_rules_push(mutable, pool_config) < 0) goto error;
+ if (cf_section_parse(pool, pool, mutable) < 0) {
PERROR("Configuration parsing failed");
goto error;
}
exit(1);
}
- cf_section_parse(maincs, NULL, cs, module_config);
+ if (cf_section_rules_push(cs, module_config) < 0) exit(1);
+ cf_section_parse(maincs, NULL, cs);
/* 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(home, home, cs, home_server_config) < 0) goto error;
+ if (cf_section_rules_push(cs, home_server_config) < 0) goto error;
+ if (cf_section_parse(home, home, cs) < 0) goto error;
/*
* It has an IP address, it must be a remote server.
#ifdef WITH_PROXY
cs = cf_section_find(config, "proxy", NULL);
if (cs) {
- if (cf_section_parse(rc, rc, cs, proxy_config) < 0) {
+ if (cf_section_rules_push(cs, proxy_config) < 0) goto error;
+ if (cf_section_parse(rc, rc, cs) < 0) {
ERROR("Failed parsing proxy section");
goto error;
}
return 0;
}
- if (cf_section_parse(NULL, NULL, pool_cf, thread_config) < 0) return -1;
+ if (cf_section_rules_push(pool_cf, thread_config) < 0) return -1;
+ if (cf_section_parse(NULL, NULL, pool_cf) < 0) return -1;
/*
* Catch corner cases.
return conf;
}
+ if (cf_section_rules_push(cs, tls_server_config) < 0) return NULL;
+
conf = tls_conf_alloc(cs);
- if ((cf_section_parse(conf, conf, cs, tls_server_config) < 0) ||
- (cf_section_parse_pass2(conf, cs, tls_server_config) < 0)) {
+ if ((cf_section_parse(conf, conf, cs) < 0) ||
+ (cf_section_parse_pass2(conf, cs) < 0)) {
error:
talloc_free(conf);
return NULL;
return conf;
}
+ if (cf_section_rules_push(cs, tls_client_config) < 0) return NULL;
+
conf = tls_conf_alloc(cs);
- if ((cf_section_parse(conf, conf, cs, tls_client_config) < 0) ||
- (cf_section_parse_pass2(conf, cs, tls_client_config) < 0)) {
+ if ((cf_section_parse(conf, conf, cs) < 0) ||
+ (cf_section_parse_pass2(conf, cs) < 0)) {
error:
talloc_free(conf);
return NULL;
data = this->data;
- rcode = cf_section_parse(data, data, cs, detail_config);
+ if (cf_section_rules_push(cs, detail_config) < 0) return -1;
+
+ rcode = cf_section_parse(data, data, cs);
if (rcode < 0) {
cf_log_err(cs, "Failed parsing listen section");
return -1;
return -1;
}
- ret = cf_section_parse(inst, inst, cs, module_config);
+ if (cf_section_rules_push(cs, module_config) < 0) return -1;
+ ret = cf_section_parse(inst, inst, cs);
if (ret < 0) return ret;
talloc_set_type(inst, proto_ldap_inst_t);
pr_config_t config;
proto_radius_ctx_t *ctx;
- if ((cf_section_parse(cs, &config, cs, mod_config) < 0) ||
- (cf_section_parse_pass2(&config, cs, mod_config) < 0)) {
+ if (cf_section_rules_push(cs, mod_config) < 0) return -1;
+
+ if ((cf_section_parse(cs, &config, cs) < 0) || (cf_section_parse_pass2(&config, cs) < 0)) {
cf_log_err(cs, "Failed parsing listen { ...}");
return -1;
}
return -1;
}
- /*
- * Print out the final "}" for debugging.
- */
- (void) cf_section_parse(cs, &config, cs, NULL);
-
return 0;
}
buffer[0] = '\0';
- if (cf_section_parse(driver, driver, conf, driver_config) < 0) return -1;
+ if (cf_section_rules_push(conf, driver_config) < 0) return -1;
+ if (cf_section_parse(driver, driver, conf) < 0) return -1;
snprintf(buffer, sizeof(buffer), "rlm_cache (%s)", config->name);
return 0;
}
+ if (cf_section_rules_push(cs, acct_section_config) < 0) return -1;
+
*config = talloc_zero(inst, ldap_acct_section_t);
- if (cf_section_parse(*config, *config, cs, acct_section_config) < 0) {
+ if (cf_section_parse(*config, *config, cs) < 0) {
PERROR("rlm_ldap (%s) - Failed parsing configuration for section %s", inst->name, name);
return -1;
/** linelog module instance
*/
typedef struct linelog_instance_t {
- char const *name; //!< Module instance name.
- fr_pool_t *pool; //!< Connection pool instance.
+ char const *name; //!< Module instance name.
+ fr_pool_t *pool; //!< Connection pool instance.
- char const *delimiter; //!< Line termination string (usually \n).
- size_t delimiter_len; //!< Length of line termination string.
+ char const *delimiter; //!< Line termination string (usually \n).
+ size_t delimiter_len; //!< Length of line termination string.
- vp_tmpl_t *log_src; //!< Source of log messages.
+ vp_tmpl_t *log_src; //!< Source of log messages.
- vp_tmpl_t *log_ref; //!< Path to a #CONF_PAIR (to use as the source of
- ///< log messages).
+ vp_tmpl_t *log_ref; //!< Path to a #CONF_PAIR (to use as the source of
+ ///< log messages).
linefr_log_dst_t log_dst; //!< Logging destination.
- char const *log_dst_str; //!< Logging destination string.
+ char const *log_dst_str; //!< Logging destination string.
struct {
char const *facility; //!< Syslog facility string.
*instance = NULL;
+ if (cf_section_rules_push(conf, redis_config) < 0) return -1;
+
this = talloc_zero(ctx, redis_driver_conf_t);
if (!this) return -1;
- ret = cf_section_parse(this, &this->conf, conf, redis_config);
+ ret = cf_section_parse(this, &this->conf, conf);
if (ret < 0) {
talloc_free(this);
return -1;
return 0;
}
- if (cf_section_parse(inst, config, cs, config_items) < 0) {
+ if (cf_section_rules_push(cs, config_items) < 0) return -1;
+ if (cf_section_parse(inst, config, cs) < 0) {
config->name = NULL;
return -1;
}