From: Alan T. DeKok Date: Thu, 9 Jan 2020 14:56:08 +0000 (-0500) Subject: use app->dict instead of more complex logic X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=652060eceadfee87d789c8d83029d91bf3c09fa1;p=thirdparty%2Ffreeradius-server.git use app->dict instead of more complex logic remove namespace_on_read(), and add check for dictionary to listen_on_read(). Also update the virtual_servers_instantiate() to look in the vns_tree only if a dictionary was not previously defined. --- diff --git a/src/lib/server/virtual_servers.c b/src/lib/server/virtual_servers.c index f8f18960653..72bc00f9284 100644 --- a/src/lib/server/virtual_servers.c +++ b/src/lib/server/virtual_servers.c @@ -97,8 +97,6 @@ static rbtree_t *server_section_name_tree = NULL; static int server_section_name_cmp(void const *one, void const *two); static int virtual_server_section_register(virtual_server_compile_t const *entry); -static int namespace_on_read(UNUSED TALLOC_CTX *ctx, UNUSED void *out, UNUSED void *parent, - CONF_ITEM *ci, UNUSED CONF_PARSER const *rule); static int listen_on_read(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, CONF_PARSER const *rule); static int server_on_read(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED CONF_PARSER const *rule); @@ -137,8 +135,7 @@ static const CONF_PARSER server_config[] = { }; static const CONF_PARSER namespace_config[] = { - { FR_CONF_OFFSET("namespace", FR_TYPE_STRING | FR_TYPE_ON_READ, fr_virtual_server_t, namespace), - .func = namespace_on_read }, + { FR_CONF_OFFSET("namespace", FR_TYPE_STRING, fr_virtual_server_t, namespace), }, CONF_PARSER_TERMINATOR }; @@ -156,6 +153,28 @@ const CONF_PARSER virtual_servers_config[] = { CONF_PARSER_TERMINATOR }; + +/** Decrement references on dictionaries as the config sections are freed + * + */ +static int _virtual_server_dict_free(fr_dict_t **dict) +{ + fr_dict_free(dict); + return 0; +} + + +static void virtual_server_dict_set(CONF_SECTION *server_cs, fr_dict_t const *dict, bool do_free) +{ + fr_dict_t **dict_p; + + dict_p = talloc_zero(NULL, fr_dict_t *); + memcpy(dict_p, &dict, sizeof(dict)); /* const issues */ + if (do_free) talloc_set_destructor(dict_p, _virtual_server_dict_free); + + cf_data_add(server_cs, dict_p, "dictionary", true); +} + /** dl_open a proto_* module * * @param[in] ctx to allocate data in. @@ -174,6 +193,7 @@ static int listen_on_read(UNUSED TALLOC_CTX *ctx, UNUSED void *out, UNUSED void CONF_SECTION *server_cs = cf_item_to_section(cf_parent(ci)); CONF_PAIR *namespace = cf_pair_find(server_cs, "namespace"); dl_module_t const *module; + fr_app_t const *app; if (!namespace) { cf_log_err(listen_cs, "No 'namespace' set for virtual server"); @@ -191,90 +211,12 @@ static int listen_on_read(UNUSED TALLOC_CTX *ctx, UNUSED void *out, UNUSED void } cf_data_add(listen_cs, module, "proto module", true); - return 0; -} + app = (fr_app_t const *) module->common; + if (app->dict) virtual_server_dict_set(server_cs, *app->dict, false); -/** Decrement references on dictionaries as the config sections are freed - * - */ -static int _virtual_server_dict_free(fr_dict_t **dict) -{ - fr_dict_free(dict); return 0; } -/** Load a dictionary for a virtual server and - * - * @param[in] server_cs to set the namespace for. - * @param[in] proto_dict to load. - * @param[in] proto_dir Path override for dictionary. - */ -static int virtual_server_namespace_set(CONF_SECTION *server_cs, - char const *proto_dict, char const *proto_dir) -{ - fr_dict_t **dict_p; - fr_dict_t *dict = NULL; - - if (fr_dict_protocol_afrom_file(&dict, proto_dict, proto_dir) < 0) return -1; - - dict_p = talloc_zero(NULL, fr_dict_t *); - *dict_p = dict; - talloc_set_destructor(dict_p, _virtual_server_dict_free); - - cf_data_add(server_cs, dict_p, "dictionary", true); - - return 0; -} - -/** Load a protocol dictionary matching the specified namespace - * - * @param[in] ctx to allocate data in. - * @param[out] out always NULL - * @param[in] parent Base structure address. - * @param[in] ci #CONF_SECTION containing the namespace pair. - * @param[in] rule unused. - * @return - * - 0 on success. - * - -1 on failure. - */ -static int namespace_on_read(UNUSED TALLOC_CTX *ctx, UNUSED void *out, UNUSED void *parent, - CONF_ITEM *ci, UNUSED CONF_PARSER const *rule) -{ - rbtree_t *vns_tree = cf_data_value(cf_data_find(virtual_server_root, rbtree_t, "vns_tree")); - CONF_PAIR *namespace_cp = cf_item_to_pair(ci); - char const *namespace_str = cf_pair_value(namespace_cp); - char const *proto_dict = namespace_str; - char const *proto_dir = NULL; - CONF_SECTION *server_cs = cf_item_to_section(cf_parent(ci)); - - if (DEBUG_ENABLED4) cf_log_debug(ci, "Initialising namespace \"%s\"", namespace_str); - - /* - * Doesn't currently work, because namespace - * *REALLY REALLY* shouldn't be processed on_read, - * because it doesn't give modules a chance to - * run their bootstrap methods. - */ - if (vns_tree) { - fr_virtual_namespace_t *found; - - found = rbtree_finddata(vns_tree, - &(fr_virtual_namespace_t){ .namespace = cf_section_name2(server_cs) }); - if (found) { - proto_dict = found->proto_dict; - proto_dir = found->proto_dir; - } - } - - if (virtual_server_namespace_set(server_cs, proto_dict, proto_dir) < 0) { - if (strncmp(proto_dict, "eap-", 4) == 0) return 0; - - cf_log_perr(ci, "Failed initialising namespace \"%s\" - %s", namespace_str, fr_strerror()); - return 0; /* Ignore for now */ - } - - return 0; -} /** Callback to set up listen_on_read * @@ -569,7 +511,6 @@ int virtual_servers_instantiate(void) size_t j, listen_cnt; CONF_ITEM *ci = NULL; CONF_SECTION *server_cs = virtual_servers[i]->server_cs; - fr_virtual_namespace_t *found; CONF_PAIR *ns; listener = virtual_servers[i]->listener; @@ -583,32 +524,26 @@ int virtual_servers_instantiate(void) return -1; } - found = rbtree_finddata(vns_tree, &(fr_virtual_namespace_t){ .namespace = cf_pair_value(ns) }); - if (found) { - /* - * Stupid hack because of the on_read - * namespace stuff. - */ - if (virtual_server_namespace_set(server_cs, - found->proto_dict, - found-> proto_dir) < 0) { - cf_log_perr(ci, "Failed loading dictionary for virtual namespace \"%s\" - %s", - cf_pair_value(ns), fr_strerror()); - return -1; - } - if ((found->func(server_cs) < 0)) return -1; + /* + * If the dictionary was already loaded, e.g. by + * listen_on_read(), then don't do anything else. + */ + if (!cf_data_find(server_cs, fr_dict_t *, "dictionary")) { + fr_virtual_namespace_t *found; - } else { - /* - * If it's not a virtual namespace, check a - * dictionary was loaded in a previous phase. - */ - if (!cf_data_find(server_cs, fr_dict_t *, "dictionary")) { - if (!cf_section_find(server_cs, "listen", CF_IDENT_ANY)) { - cf_log_err(ns, "Failed resolving namespace. Verify that modules " - "referencing this server are enabled"); - return -1; - } + found = rbtree_finddata(vns_tree, &(fr_virtual_namespace_t){ .namespace = cf_pair_value(ns) }); + if (found) { + fr_dict_t *dict; + + if (fr_dict_protocol_afrom_file(&dict, found->proto_dict, found->proto_dir) < 0) return -1; + virtual_server_dict_set(server_cs, dict, true); + + if ((found->func(server_cs) < 0)) return -1; + + } else if (!listener) { + cf_log_err(ns, "Failed resolving namespace. Verify that modules " + "referencing this server are enabled"); + return -1; } }