]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
more work towards ON_LOAD autoload of dictionaries
authorAlan T. DeKok <aland@freeradius.org>
Mon, 7 May 2018 15:16:17 +0000 (11:16 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 7 May 2018 15:17:43 +0000 (11:17 -0400)
fr_dict_autoload_t likely needs to have base_dir removed,
and instead passed in as a function parameter.  That should
then work.

src/main/mainconfig.c
src/main/virtual_servers.c

index b0e53fc2910faac8f15d61b014538f083080124a..ecda8d760c5ffeb34c9242894f9bdb473bc793c3 100644 (file)
@@ -259,6 +259,8 @@ static const CONF_PARSER switch_users_config[] = {
 
 
 #if 0
+extern const CONF_PARSER virtual_servers_on_read_config[];
+
 /** Callback to automatically load dictionaries required by modules
  *
  * @param[in] module   being loaded.
@@ -726,30 +728,22 @@ int main_config_init(void)
         */
        main_config.talloc_pool_size = 8 * 1024; /* default */
 
+#if 0
        /*
-        *      @todo - the proto_FOO modules are loaded via the
-        *      CONF_SECTION parser callbacks.  Which means that the
-        *      fr_dict_autoload() and fr_dict_attr_autoload()
-        *      functions need to be call from here, before the
-        *      configuration is parsed.  Right now, those rules are
-        *      added in modules_bootstrap().  At that point, the
-        *      proto_FOO modules have already been loaded.  So any
-        *      autoload they have is ignored.
+        *      @todo - not quite done yet... these dictionaries have
+        *      to be loaded from radius_dir.  But the
+        *      fr_dict_autoload_t has a base_dir pointer
+        *      there... it's probably best to pass radius_dir into
+        *      fr_dict_autoload() and have it use that instead.
         *
-        *      Except that we ALSO need to load raddb/dictionary,
-        *      ideally BEFORE instantiating the modules, but AFTER
-        *      loading the various proto_FOO.
+        *      Once that's done, the proto_foo dictionaries SHOULD be
+        *      autoloaded, AND loaded before the configuration files
+        *      are read.
         *
-        *      This likely means moving the DICT_READ_OPTIONAL stuff
-        *      to after the "parsing main configuration" stage.
-        */
-
-       /*
-        *      Read the distribution dictionaries first, then
-        *      the ones in raddb.
+        *      And then all of the modules have to be updated to use
+        *      their local dict pointer, instead of NULL.
         */
-#if 0
-       (void) dl_init();
+       if (cf_section_rules_push(cs, virtual_servers_on_read_config) < 0) return -1;
 
        /*
         *      Register dictionary autoload callbacks
@@ -757,14 +751,17 @@ int main_config_init(void)
        dl_symbol_init_cb_register(DL_DICT_PRIORITY, "dict", _module_dict_autoload, NULL);
        dl_symbol_free_cb_register(DL_DICT_PRIORITY, "dict", _module_dict_autofree, NULL);
        dl_symbol_init_cb_register(DL_DICT_ATTR_PRIORITY, "dict_attr", _module_dict_attr_autoload, NULL);
-#else
+#endif
 
+       /*
+        *      Read the distribution dictionaries first, then
+        *      the ones in raddb.
+        */
        DEBUG2("Including dictionary file \"%s/%s\"", main_config.dictionary_dir, FR_DICTIONARY_FILE);
        if (fr_dict_from_file(NULL, &main_config.dict, main_config.dictionary_dir, FR_DICTIONARY_FILE, "radius") != 0) {
                fr_log_perror(&default_log, L_ERR, "Failed to initialize the dictionaries");
                return -1;
        }
-#endif
 
 #define DICT_READ_OPTIONAL(_d, _n) \
 do {\
index fc29664f58724fa271c9e30a92f6565c288cb794..762c52f91b6a5c6e7809b3bc360b9c417dd4c1b0 100644 (file)
@@ -97,9 +97,34 @@ static fr_virtual_server_t **virtual_servers;
  */
 static CONF_SECTION *virtual_server_root;
 
+static int listen_on_read(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, CONF_PARSER const *rule);
+static int server_on_read(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED CONF_PARSER const *rule);
+
 static int listen_parse(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, CONF_PARSER const *rule);
 static int server_parse(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED CONF_PARSER const *rule);
 
+static const CONF_PARSER listen_on_read_config[] = {
+       { FR_CONF_OFFSET("listen", FR_TYPE_SUBSECTION | FR_TYPE_MULTI | FR_TYPE_OK_MISSING | FR_TYPE_ON_READ,
+                        fr_virtual_server_t, listener), \
+                        .subcs_size = sizeof(fr_virtual_listen_t), .subcs_type = "fr_virtual_listen_t",
+                        .func = listen_on_read },
+
+       CONF_PARSER_TERMINATOR
+};
+
+const CONF_PARSER virtual_servers_on_read_config[] = {
+       /*
+        *      Not really ok if it's missing but we want to
+        *      let logic elsewhere handle the issue.
+        */
+       { FR_CONF_POINTER("server", FR_TYPE_SUBSECTION | FR_TYPE_MULTI | FR_TYPE_OK_MISSING | FR_TYPE_ON_READ, &virtual_servers), \
+                         .subcs_size = sizeof(fr_virtual_server_t), .subcs_type = "fr_virtual_server_t",
+                         .subcs = (void const *) listen_on_read_config, .ident2 = CF_IDENT_ANY,
+                         .func = server_on_read },
+
+       CONF_PARSER_TERMINATOR
+};
+
 static const CONF_PARSER server_config[] = {
        { FR_CONF_OFFSET("namespace", FR_TYPE_STRING, fr_virtual_server_t, namespace) },
 
@@ -124,6 +149,59 @@ const CONF_PARSER virtual_servers_config[] = {
        CONF_PARSER_TERMINATOR
 };
 
+
+/** dl_open a proto_* module
+ *
+ * @param[in] ctx      to allocate data in.
+ * @param[out] out     always NULL
+ * @param[in] ci       #CONF_SECTION containing the listen section.
+ * @param[in] rule     unused.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+static int listen_on_read(UNUSED TALLOC_CTX *ctx, UNUSED void *out, CONF_ITEM *ci, UNUSED CONF_PARSER const *rule)
+{
+       CONF_SECTION            *listen_cs = cf_item_to_section(ci);
+       CONF_SECTION            *server_cs = cf_item_to_section(cf_parent(ci));
+       CONF_PAIR               *namespace = cf_pair_find(server_cs, "namespace");
+
+       if (DEBUG_ENABLED4) cf_log_debug(ci, "Loading proto_%s", cf_pair_value(namespace));
+
+       if (!dl_module(listen_cs, NULL, cf_pair_value(namespace), DL_TYPE_PROTO)) {
+               cf_log_err(listen_cs, "Failed loading proto_%s module", cf_pair_value(namespace));
+               return -1;
+       }
+
+       return 0;
+}
+
+/** Callback to set up listen_on_read
+ *
+ * @param[in] ctx      to allocate data in.
+ * @param[out] out     Where to our listen configuration.  Is a #fr_virtual_server_t structure.
+ * @param[in] ci       #CONF_SECTION containing the listen section.
+ * @param[in] rule     unused.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+static int server_on_read(UNUSED TALLOC_CTX *ctx, UNUSED void *out, CONF_ITEM *ci, UNUSED CONF_PARSER const *rule)
+{
+       CONF_SECTION            *server_cs = cf_item_to_section(ci);
+       CONF_PAIR               *namespace;
+
+       namespace = cf_pair_find(server_cs, "namespace");
+       if (!namespace) {
+               cf_log_err(server_cs, "virtual server %s MUST contain a 'namespace' option",
+                          cf_section_name2(server_cs));
+               return -1;
+       }
+
+       return 0;
+}
+
+
 /** dl_open a proto_* module
  *
  * @param[in] ctx      to allocate data in.