From: Arran Cudbard-Bell Date: Thu, 8 Jun 2017 23:09:26 +0000 (-0400) Subject: Don't assume item.parent is a CONF_SECTION X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d8b76e85aa7fd8b4f6298802e86ae00dba6fc19;p=thirdparty%2Ffreeradius-server.git Don't assume item.parent is a CONF_SECTION It could be a pair if the child is cf_data --- diff --git a/src/include/conf_file.h b/src/include/conf_file.h index ee271aa9c4e..1ac9d50ed98 100644 --- a/src/include/conf_file.h +++ b/src/include/conf_file.h @@ -41,11 +41,11 @@ extern "C" { /* * Export the minimum amount of information about these structs */ -typedef struct conf_item CONF_ITEM; //!< Generic configuration element, extended to become +typedef struct cf_item CONF_ITEM; //!< Generic configuration element, extended to become ///< a #CONF_PAIR, a #CONF_SECTION or #CONF_DATA. -typedef struct conf_pair CONF_PAIR; //!< #CONF_ITEM with an attribute, an operator and a value. -typedef struct conf_part CONF_SECTION; //!< #CONF_ITEM used to group multiple #CONF_PAIR and #CONF_SECTION, together. -typedef struct conf_data CONF_DATA; //!< #CONF_ITEM used to associate arbitrary data +typedef struct cf_pair CONF_PAIR; //!< #CONF_ITEM with an attribute, an operator and a value. +typedef struct cf_section CONF_SECTION; //!< #CONF_ITEM used to group multiple #CONF_PAIR and #CONF_SECTION, together. +typedef struct cf_data CONF_DATA; //!< #CONF_ITEM used to associate arbitrary data ///< with a #CONF_PAIR or #CONF_SECTION. /* @@ -496,7 +496,9 @@ char const *cf_section_filename(CONF_SECTION const *section); CONF_ITEM *cf_item_find_next(CONF_SECTION const *section, CONF_ITEM const *item); int cf_pair_count(CONF_SECTION const *cs); -CONF_SECTION *cf_item_parent(CONF_ITEM const *ci); +CONF_ITEM *cf_item_parent(CONF_ITEM const *ci); +CONF_SECTION *cf_section_parent(CONF_SECTION const *cs); +CONF_SECTION *cf_pair_parent(CONF_PAIR const *cp); CONF_SECTION *cf_item_root(CONF_ITEM const *ci); bool cf_item_is_section(CONF_ITEM const *item); diff --git a/src/main/conf_file.c b/src/main/conf_file.c index d1de7a2fa59..e6cfa280335 100644 --- a/src/main/conf_file.c +++ b/src/main/conf_file.c @@ -72,69 +72,75 @@ typedef enum conf_type { #endif } CONF_ITEM_TYPE; -struct conf_item { - struct conf_item *next; //!< Sibling. - struct conf_part *parent; //!< Parent. - int lineno; //!< The line number the config item began on. - char const *filename; //!< The file the config item was parsed from. - CONF_ITEM_TYPE type; //!< Whether the config item is a config_pair, conf_section or conf_data. +struct cf_item { + struct cf_item *next; //!< Sibling. + struct cf_item *parent; //!< Parent. + int lineno; //!< The line number the config item began on. + char const *filename; //!< The file the config item was parsed from. + CONF_ITEM_TYPE type; //!< Whether the config item is a config_pair, conf_section or cf_data. }; /** Configuration AVP similar to a VALUE_PAIR * */ -struct conf_pair { - CONF_ITEM item; - char const *attr; //!< Attribute name +struct cf_pair { + CONF_ITEM item; //!< Common set of fields. + + char const *attr; //!< Attribute name #ifdef WITH_CONF_WRITE - char const *orig_value; /* original value */ + char const *orig_value; /* original value */ #endif - char const *value; //!< Attribute value - FR_TOKEN op; //!< Operator e.g. =, := - FR_TOKEN lhs_type; //!< Name quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD. - FR_TOKEN rhs_type; //!< Value Quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD. - bool pass2; //!< do expansion in pass2. - bool parsed; //!< Was this item used during parsing? + char const *value; //!< Attribute value + FR_TOKEN op; //!< Operator e.g. =, := + FR_TOKEN lhs_type; //!< Name quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD. + FR_TOKEN rhs_type; //!< Value Quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD. + bool pass2; //!< do expansion in pass2. + bool parsed; //!< Was this item used during parsing? }; -/** Internal data that is associated with a configuration section +/** A section grouping multiple #CONF_PAIR * */ -struct conf_data { - CONF_ITEM item; - char const *type; //!< C type of data being stored. - char const *name; //!< Additional qualification of type. - void const *data; //!< User data. - bool free; //!< Free user data function. -}; +struct cf_section { + CONF_ITEM item; //!< Common set of fields. -struct conf_part { - CONF_ITEM item; - char const *name1; //!< First name token. Given ``foo bar {}`` would be ``foo``. - char const *name2; //!< Second name token. Given ``foo bar {}`` would be ``bar``. + char const *name1; //!< First name token. Given ``foo bar {}`` would be ``foo``. + char const *name2; //!< Second name token. Given ``foo bar {}`` would be ``bar``. + + FR_TOKEN name2_type; //!< The type of quoting around name2. - FR_TOKEN name2_type; //!< The type of quoting around name2. + int argc; //!< number of additional arguments + char const **argv; //!< additional arguments + FR_TOKEN *argv_type; - int argc; //!< number of additional arguments - char const **argv; //!< additional arguments - FR_TOKEN *argv_type; + CONF_ITEM *children; + CONF_ITEM *tail; //!< For speed. + CONF_SECTION *template; - CONF_ITEM *children; - CONF_ITEM *tail; //!< For speed. - CONF_SECTION *template; + rbtree_t *pair_tree; //!< and a partridge.. + rbtree_t *section_tree; //!< no jokes here. + rbtree_t *name2_tree; //!< for sections of the same name2 + rbtree_t *data_tree; - rbtree_t *pair_tree; //!< and a partridge.. - rbtree_t *section_tree; //!< no jokes here. - rbtree_t *name2_tree; //!< for sections of the same name2 - rbtree_t *data_tree; + void *base; + int depth; - void *base; - int depth; + CONF_PARSER const *variables; //!< the section was parsed with. +}; + +/** Internal data that is associated with a configuration section + * + */ +struct cf_data { + CONF_ITEM item; //!< Common set of fields. - CONF_PARSER const *variables; + char const *type; //!< C type of data being stored. + char const *name; //!< Additional qualification of type. + void const *data; //!< User data. + bool free; //!< Free user data function. }; -typedef enum conf_include_type { +typedef enum cf_include_type { CONF_INCLUDE_FILE, CONF_INCLUDE_DIR, CONF_INCLUDE_FROMDIR, @@ -628,7 +634,7 @@ CONF_PAIR *cf_pair_alloc(CONF_SECTION *parent, char const *attr, char const *val if (!cp) return NULL; cp->item.type = CONF_ITEM_PAIR; - cp->item.parent = parent; + cp->item.parent = cf_section_to_item(parent); cp->lhs_type = lhs_type; cp->rhs_type = rhs_type; cp->op = op; @@ -721,7 +727,7 @@ CONF_SECTION *cf_section_alloc(CONF_SECTION *parent, char const *name1, char con if (!cs) return NULL; cs->item.type = CONF_ITEM_SECTION; - cs->item.parent = parent; + cs->item.parent = cf_section_to_item(parent); cs->item.filename = ""; /* will be over-written if necessary */ cs->name1 = talloc_typed_strdup(cs, name1); @@ -1012,7 +1018,7 @@ CONF_ITEM *cf_reference_item(CONF_SECTION const *parentcs, */ while (*p == '.') { if (cs->item.parent) { - cs = cs->item.parent; + cs = cf_item_to_section(cs->item.parent); } /* @@ -1117,9 +1123,7 @@ CONF_SECTION *cf_top_section(CONF_SECTION *cs) { if (!cs) return NULL; - while (cs->item.parent != NULL) { - cs = cs->item.parent; - } + while (cs->item.parent != NULL) cs = cf_item_to_section(cs->item.parent); return cs; } @@ -1275,7 +1279,7 @@ static char const *cf_expand_variables(char const *cf, int *lineno, * section is wrong. We don't * want an infinite loop. */ - if (ci->parent == outercs) { + if (cf_item_to_section(ci->parent) == outercs) { ERROR("%s[%d]: Cannot reference different item in same section", cf, *lineno); return NULL; } @@ -2700,11 +2704,11 @@ static bool invalid_location(CONF_SECTION *this, char const *name, char const *f /* * Can only have "if" in 3 named sections. */ - this = this->item.parent; + this = cf_item_to_section(this->item.parent); while ((strcmp(this->name1, "server") != 0) && (strcmp(this->name1, "policy") != 0) && (strcmp(this->name1, "instantiate") != 0)) { - this = this->item.parent; + this = cf_item_to_section(this->item.parent); if (!this) goto invalid_location; } @@ -2924,7 +2928,7 @@ static int cf_section_read(char const *filename, int *lineno, FILE *fp, */ if (!cf_template_merge(this, this->template)) goto error; - this = this->item.parent; + this = cf_item_to_section(this->item.parent); goto check_for_more; } @@ -4057,7 +4061,7 @@ CONF_SECTION *cf_section_find_next(CONF_SECTION const *section, if (!section->item.parent) return NULL; - return cf_subsection_find_next(section->item.parent, subsection, name1); + return cf_subsection_find_next(cf_item_to_section(section->item.parent), subsection, name1); } /** Return the next item after a CONF_ITEM. @@ -4109,22 +4113,36 @@ int cf_pair_count(CONF_SECTION const *cs) return count; } -CONF_SECTION *cf_item_parent(CONF_ITEM const *ci) +CONF_ITEM *cf_item_parent(CONF_ITEM const *ci) { if (!ci) return NULL; return ci->parent; } +CONF_SECTION *cf_section_parent(CONF_SECTION const *cs) +{ + if (!cs) return NULL; + + return cf_item_to_section(cs->item.parent); +} + +CONF_SECTION *cf_pair_parent(CONF_PAIR const *cp) +{ + if (!cp) return NULL; + + return cf_item_to_section(cp->item.parent); +} + CONF_SECTION *cf_item_root(CONF_ITEM const *ci) { - CONF_SECTION *cs; + CONF_ITEM *ci_p; if (!ci) return NULL; - for (cs = ci->parent; cs->item.parent; cs = cs->item.parent); + for (ci_p = ci->parent; ci_p->parent; ci_p = ci_p->parent); - return (CONF_SECTION *)cs; + return cf_item_to_section(ci_p); } int cf_section_lineno(CONF_SECTION const *section) @@ -4159,15 +4177,15 @@ bool cf_item_is_pair(CONF_ITEM const *item) /** Allocate a new user data container * - * @param[in] parent conf section. + * @param[in] parent #CONF_PAIR, or #CONF_SECTION to hang CONF_DATA off of. * @param[in] name String identifier of the user data. * @param[in] data being added. - * @param[in] do_free function, called when the parent CONF_SECTION is being freed. + * @param[in] do_free function, called when the parent #CONF_SECTION is being freed. * @return * - CONF_DATA on success. * - NULL on error. */ -static CONF_DATA *cf_data_alloc(CONF_SECTION *parent, void const *data, char const *name, bool do_free) +static CONF_DATA *cf_data_alloc(CONF_ITEM *parent, void const *data, char const *name, bool do_free) { CONF_DATA *cd; @@ -4263,7 +4281,7 @@ int _cf_data_add(CONF_SECTION *cs, void const *data, char const *name, bool do_f return -1; } - cd = cf_data_alloc(cs, data, name, do_free); + cd = cf_data_alloc(cf_section_to_item(cs), data, name, do_free); if (!cd) { cf_log_err_cs(cs, "Failed allocating data"); return -1; diff --git a/src/main/modules.c b/src/main/modules.c index b5705373c24..6042bdd5b6a 100644 --- a/src/main/modules.c +++ b/src/main/modules.c @@ -180,7 +180,7 @@ int module_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, char c * instantiation order issues. */ inst_name = cf_pair_value(cp); - inst = module_find(cf_item_parent(cf_section_to_item(module)), inst_name); + inst = module_find(cf_section_parent(module), inst_name); if (!inst) { cf_log_err_cp(cp, "Unknown module instance \"%s\"", inst_name); @@ -196,7 +196,7 @@ int module_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, char c do { CONF_SECTION *tmp; - tmp = cf_item_parent(cf_section_to_item(parent)); + tmp = cf_section_parent(parent); if (!tmp) break; parent = tmp; @@ -258,7 +258,7 @@ fr_pool_t *module_connection_pool_init(CONF_SECTION *module, int ret; -#define parent_name(_x) cf_section_name(cf_item_parent(cf_section_to_item(_x))) +#define parent_name(_x) cf_section_name(cf_section_parent(_x)) cs_name1 = cf_section_name1(module); cs_name2 = cf_section_name2(module); diff --git a/src/main/realms.c b/src/main/realms.c index d23832f5c2d..8f7f4e5fe80 100644 --- a/src/main/realms.c +++ b/src/main/realms.c @@ -470,7 +470,7 @@ void realm_home_server_sanitize(home_server_t *home, CONF_SECTION *cs) home->src_ipaddr.af = home->ipaddr.af; } - parent = cf_item_parent(cf_section_to_item(cs)); + parent = cf_section_parent(cs); if (parent && strcmp(cf_section_name1(parent), "server") == 0) { home->parent_server = cf_section_name2(parent); } diff --git a/src/main/unlang_compile.c b/src/main/unlang_compile.c index 87a51587028..eeb4fcc299e 100644 --- a/src/main/unlang_compile.c +++ b/src/main/unlang_compile.c @@ -2425,7 +2425,7 @@ static unlang_t *compile_redundant(unlang_t *parent, unlang_compile_t *unlang_ct * For backwards compatibility. */ if (name2 && - (strcmp(cf_section_name1(cf_item_parent(cf_section_to_item(cs))), "instantiate") != 0)) { + (strcmp(cf_section_name1(cf_section_parent(cs)), "instantiate") != 0)) { cf_log_err_cs(cs, "%s sections cannot have a name", unlang_ops[mod_type].name); return NULL; } @@ -2469,7 +2469,7 @@ static unlang_t *compile_load_balance(unlang_t *parent, unlang_compile_t *unlang * Inside of the "instantiate" section, the name is a name, not a key. */ if (name2) { - if (strcmp(cf_section_name1(cf_item_parent(cf_section_to_item(cs))), "instantiate") == 0) name2 = NULL; + if (strcmp(cf_section_name1(cf_section_parent(cs)), "instantiate") == 0) name2 = NULL; } if (name2) { @@ -2743,7 +2743,7 @@ static unlang_t *compile_item(unlang_t *parent, unlang_compile_t *unlang_ctx, CO unlang_t *c; module_instance_t *this; CONF_SECTION *cs, *subcs, *modules; - CONF_SECTION *loop; + CONF_ITEM *loop; char const *realname; rlm_components_t component = unlang_ctx->component; unlang_compile_t unlang_ctx2; @@ -2894,8 +2894,8 @@ static unlang_t *compile_item(unlang_t *parent, unlang_compile_t *unlang_ctx, CO */ for (loop = cf_item_parent(ci); loop && subcs; - loop = cf_item_parent(cf_section_to_item(loop))) { - if (loop == subcs) { + loop = cf_item_parent(loop)) { + if (loop == cf_section_to_item(subcs)) { subcs = NULL; } } diff --git a/src/modules/proto_bfd/proto_bfd.c b/src/modules/proto_bfd/proto_bfd.c index 78cead9fab0..1a82ca158eb 100644 --- a/src/modules/proto_bfd/proto_bfd.c +++ b/src/modules/proto_bfd/proto_bfd.c @@ -1733,7 +1733,7 @@ static int bfd_socket_parse(CONF_SECTION *cs, rad_listen_t *this) /* * Find the sibling "bfd" section of the "listen" section. */ - server = cf_item_parent(cf_section_to_item(cs)); + server = cf_section_parent(cs); sock->unlang = cf_subsection_find(server, "bfd"); return 0; diff --git a/src/modules/proto_detail/proto_detail.c b/src/modules/proto_detail/proto_detail.c index 90c78597667..08b58f75f57 100644 --- a/src/modules/proto_detail/proto_detail.c +++ b/src/modules/proto_detail/proto_detail.c @@ -1128,7 +1128,7 @@ static int detail_parse(CONF_SECTION *cs, rad_listen_t *this) client->secret = client->shortname; client->nas_type = talloc_strdup(data, "none"); /* Part of 'data' not dynamically allocated */ - this->server_cs = cf_item_parent(cf_section_to_item(this->cs)); + this->server_cs = cf_section_parent(this->cs); client->server_cs = this->server_cs; return 0; diff --git a/src/modules/proto_dhcp/proto_dhcp.c b/src/modules/proto_dhcp/proto_dhcp.c index 6eb5dc3c855..f027831e2d7 100644 --- a/src/modules/proto_dhcp/proto_dhcp.c +++ b/src/modules/proto_dhcp/proto_dhcp.c @@ -322,7 +322,7 @@ static rlm_rcode_t dhcp_process(REQUEST *request) RDEBUG("Trying sub-section dhcp %s {...}", dv->alias); - server = cf_item_parent(cf_section_to_item(request->listener->cs)); + server = cf_section_parent(request->listener->cs); unlang = cf_subsection_find_name2(server, "dhcp", dv->alias); rcode = unlang_interpret(request, unlang, RLM_MODULE_NOOP); diff --git a/src/modules/rlm_eap/lib/base/eap_tls.c b/src/modules/rlm_eap/lib/base/eap_tls.c index 818381c56bd..7ad6f832d41 100644 --- a/src/modules/rlm_eap/lib/base/eap_tls.c +++ b/src/modules/rlm_eap/lib/base/eap_tls.c @@ -1097,7 +1097,7 @@ fr_tls_conf_t *eap_tls_conf_parse(CONF_SECTION *cs, char const *attr) CONF_SECTION *tls_cs; fr_tls_conf_t *tls_conf; - parent = cf_item_parent(cf_section_to_item(cs)); + parent = cf_section_parent(cs); cp = cf_pair_find(cs, attr); if (cp) { diff --git a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c index df6261f9e75..60fc55c717e 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c @@ -440,7 +440,7 @@ static int mod_instantiate(rlm_sql_config_t const *config, void *instance, CONF_ CONF_SECTION *cs; char const *name; - cs = cf_item_parent(cf_section_to_item(conf)); + cs = cf_section_parent(conf); name = cf_section_name2(cs); if (!name) name = cf_section_name1(cs);