]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add '-S' and overrides developer/alandekok master
authorAlan T. DeKok <aland@freeradius.org>
Mon, 20 Apr 2026 17:36:06 +0000 (13:36 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 20 Apr 2026 17:47:59 +0000 (13:47 -0400)
src/bin/radiusd.c
src/lib/server/main_config.c
src/lib/server/main_config.h

index e1503f75c5114f80c31a1cc2a054eaf08c4e1bc3..16c791fe22c81c786a077dc009f9c27c23ff7c98 100644 (file)
@@ -411,13 +411,11 @@ int main(int argc, char *argv[])
                        break;
 
                case 'S':       /* Migration support */
-#if 0
-                       if (main_config_parse_option(optarg) < 0) {
-                               fprintf(stderr, "%s: Unknown configuration option '%s'\n",
-                                       program, optarg);
+                       if (main_config_save_override(optarg) < 0) {
+                               fprintf(stderr, "%s: Failed saving configuration option '%s' - %s\n",
+                                       program, optarg, fr_strerror());
                                EXIT_WITH_FAILURE;
                        }
-#endif
                        break;
 
                case 't':       /* no child threads */
@@ -1104,6 +1102,15 @@ do { \
        main_config_exclusive_proc_done(main_config);
 
 cleanup:
+       /*
+        *      If we're told to just exit without cleaning up memory,
+        *      then do so.
+        */
+       if (config && config->talloc_skip_cleanup) {
+               fr_atexit_global_disarm_all();
+               exit(ret);
+       }
+
        /*
         *      This may not have been done earlier if we're
         *      exiting due to a startup error.
index 014aad1089d6980c665fb38edd26f72dedcba81d..fd2ea4e8de052be909987932d2bde94e887c27b7 100644 (file)
@@ -45,8 +45,6 @@ RCSID("$Id$")
 
 #include <freeradius-devel/unlang/xlat_func.h>
 
-
-
 #ifdef HAVE_SYSLOG_H
 #  include <syslog.h>
 #endif
@@ -61,6 +59,27 @@ extern fr_log_t              debug_log;
 
 fr_log_t               debug_log = { .fd = -1, .dst = L_DST_NULL };
 
+/*
+ *     Configuration file overrides
+ */
+FR_DLIST_TYPES(fr_override_list)
+typedef FR_DLIST_HEAD(fr_override_list) fr_override_list_t;
+FR_DLIST_TYPEDEFS(fr_override_list, fr_override_list_t, fr_override_entry_t)
+
+static fr_override_list_t override;
+
+typedef struct {
+       char                            *name;  //!< must not be 'const'
+       char                            *value;
+       FR_DLIST_ENTRY(fr_override_list)  entry;
+} fr_override_t;
+
+FR_DLIST_FUNCS(fr_override_list, fr_override_t, entry)
+
+#define fr_override_list_foreach(_list_head, _iter) \
+       for (fr_override_t *JOIN(_next,_iter), *_iter = fr_override_list_head(_list_head); JOIN(_next,_iter) = fr_override_list_next(_list_head, _iter), _iter != NULL; _iter = JOIN(_next,_iter))
+
+
 /**********************************************************************
  *
  *     We need to figure out where the logs go, before doing anything
@@ -148,11 +167,11 @@ static const conf_parser_t log_config[] = {
 
 static const conf_parser_t resources[] = {
        /*
-        *      Don't set a default here.  It's set in the code, below.  This means that
-        *      the config item will *not* get printed out in debug mode, so that no one knows
-        *      it exists.
+        *      Don't set defaults here.  They're set in the command line.  This means
+        *      that the config item will *not* get printed out in debug mode, so that no one knows it exists.
         */
-       { FR_CONF_OFFSET_FLAGS("talloc_memory_report", CONF_FLAG_HIDDEN, main_config_t, talloc_memory_report) },                                                /* DO NOT SET DEFAULT */
+       { FR_CONF_OFFSET_FLAGS("talloc_memory_report", CONF_FLAG_HIDDEN, main_config_t, talloc_memory_report) }, /* DO NOT SET DEFAULT */
+       { FR_CONF_OFFSET_FLAGS("talloc_skip_cleanup", CONF_FLAG_HIDDEN, main_config_t, talloc_skip_cleanup) }, /* DO NOT SET DEFAULT */
        CONF_PARSER_TERMINATOR
 };
 
@@ -997,6 +1016,8 @@ main_config_t *main_config_alloc(TALLOC_CTX *ctx)
 
        main_config = config;
 
+       fr_override_list_init(&override);
+
        return config;
 }
 
@@ -1213,6 +1234,17 @@ int main_config_init(main_config_t *config)
                } /* loop over pairs in ENV */
        } /* there's an ENV subsection */
 
+       /*
+        *      Now that we've read the configuration files, override the values.
+        */
+       fr_override_list_foreach(&override, ov) {
+               if (cf_pair_replace_or_add(cs, ov->name, ov->value) < 0) {
+                       fprintf(stderr, "%s: Error: Cannot update configuration item '%s' - %s.\n",
+                               config->name, ov->name, fr_strerror());
+                       goto failure;
+               }
+       }
+
        /*
         *      Parse log section of main config.
         */
@@ -1450,11 +1482,6 @@ void main_config_hup(main_config_t *config)
        INFO("HUP - NYI in version 4"); /* Not yet implemented in v4 */
 }
 
-#if 0
-static fr_table_num_ordered_t config_arg_table[] = {
-};
-static size_t config_arg_table_len = NUM_ELEMENTS(config_arg_table);
-
 /*
  *     Migration function that allows for command-line over-ride of
  *     data structures which need to be initialized before the
@@ -1462,50 +1489,30 @@ static size_t config_arg_table_len = NUM_ELEMENTS(config_arg_table);
  *
  *     This should really only be temporary, until we get rid of flat vs nested.
  */
-int main_config_parse_option(char const *value)
+int main_config_save_override(char const *str)
 {
-       fr_value_box_t box;
-       size_t offset;
-       char const *p;
-       bool *out;
+       char *p;
+       fr_override_t *ov;
 
-       p = strchr(value, '=');
-       if (!p) return -1;
+       MEM(ov = talloc_zero(main_config, fr_override_t));
 
-       offset = fr_table_value_by_substr(config_arg_table, value, p - value, 0);
-       if (offset) {
-               out = (bool *) (((uintptr_t) main_config) + offset);
+       MEM(ov->name = talloc_strdup(ov, str));
 
-       } else {
+       p = strchr(ov->name, '=');
+       if (!p) {
+               talloc_free(ov);
+               fr_strerror_const("Missing '='");
                return -1;
        }
 
-       p += 1;
-
-       fr_value_box_init(&box, FR_TYPE_BOOL, NULL, false);
-       if (fr_value_box_from_str(NULL, &box, FR_TYPE_BOOL, NULL,
-                                 p, strlen(p), NULL) < 0) {
-               fr_perror("Invalid boolean \"%s\"", p);
-               fr_exit(1);
+       *p++ = '\0';
+       if (!*p) {
+               talloc_free(ov);
+               fr_strerror_const("Missing value after '='");
+               return -1;
        }
+       ov->value = p;
 
-       *out = box.vb_bool;
-
+       fr_override_list_insert_tail(&override, ov);
        return 0;
 }
-
-/*
- *     Allow other pieces of the code to examine the migration options.
- */
-bool main_config_migrate_option_get(char const *name)
-{
-       size_t offset;
-
-       if (!main_config) return false;
-
-       offset = fr_table_value_by_substr(config_arg_table, name, strlen(name), 0);
-       if (!offset) return false;
-
-       return *(bool *) (((uintptr_t) main_config) + offset);
-}
-#endif
index d7baba5ca0056135de1955fc9d72d64c1a0f6b4c..eec8551b7dd7de96cc12184b25f6068af73de5ac 100644 (file)
@@ -58,16 +58,15 @@ struct main_config_s {
        bool            spawn_workers;                  //!< Should the server spawn threads.
        char const      *pid_file;                      //!< Path to write out PID file.
 
-       fr_worker_config_t      worker;                 //!< Worker thread configuration.
-
-       bool            drop_requests;                  //!< Administratively disable request processing.
-       bool            suppress_secrets;               //!< suppress secrets (or not)
+       bool            write_pid;                      //!< write the PID file
 
        char const      *log_dir;
        char const      *local_state_dir;
 
-       bool            reverse_lookups;
-       bool            hostname_lookups;
+       bool            reverse_lookups;                //!< do IP -> host lookups.  Don't set this!
+       bool            hostname_lookups;               //!< do hostname -> IP lookups
+       bool            drop_requests;                  //!< Administratively disable request processing.
+       bool            suppress_secrets;               //!< suppress secrets (or not)
 
        char const      *radacct_dir;
        char const      *lib_dir;
@@ -78,7 +77,6 @@ struct main_config_s {
        char const      *prefix;
 
        char const      *log_dest;
-
        char const      *log_file;
        bool            do_colourise;
        bool            log_line_number;                //!< Log src file/line the message was generated on.
@@ -90,8 +88,7 @@ struct main_config_s {
        int32_t         syslog_facility;
 
        char const      *dict_dir;                      //!< Where to load dictionaries from.
-
-       bool            write_pid;                      //!< write the PID file
+       fr_dict_t       *dict;                          //!< Main dictionary.
 
 #ifdef HAVE_SETUID
        uid_t           server_uid;                     //!< UID we're running as.
@@ -105,6 +102,9 @@ struct main_config_s {
        char const      *chdir;                         //!< where to chdir() to when we start.
        bool            chdir_is_set;
 
+       /*
+        *      OpenSSL configuration
+        */
 #ifdef ENABLE_OPENSSL_VERSION_CHECK
        char const      *allow_vulnerable_openssl;      //!< The CVE number of the last security issue acknowledged.
 #endif
@@ -120,51 +120,53 @@ struct main_config_s {
                                                        ///< in the async ctx pool.
 #endif
 
-       fr_dict_t       *dict;                          //!< Main dictionary.
-
-
        /*
         *      Debugging options
         */
+       uint32_t        debug_level;                    //!< The base log level for the server.
+
+       bool            talloc_memory_report;           //!< Print a memory report on what's left unfreed.
+                                                       //!< Can only be used when the server is running in single
+                                                       //!< threaded mode.
+
+       bool            talloc_skip_cleanup;            //!< skip talloc cleanups at exit
+
        bool            allow_core_dumps;               //!< Whether the server is allowed to drop a core when
                                                        //!< receiving a fatal signal.
 
        char const      *panic_action;                  //!< Command to execute if the server receives a fatal
                                                        //!< signal.
 
-       uint32_t        debug_level;                    //!< The base log level for the server.
-
-       bool            talloc_memory_report;           //!< Print a memory report on what's left unfreed.
-                                                       //!< Can only be used when the server is running in single
-                                                       //!< threaded mode.
 
+       /*
+        *      Multiple processing sharing configs
+        */
        bool            allow_multiple_procs;           //!< Allow multiple instances of radiusd to run with the
                                                        ///< same config file.
 
        int             multi_proc_sem_id;              //!< Semaphore we use to prevent multiple processes running.
        char            *multi_proc_sem_path;           //!< Semaphore path.
 
+       /*
+        *      Internal scheduler configuration
+        */
        uint32_t        max_networks;                   //!< for the scheduler
        uint32_t        max_workers;                    //!< for the scheduler
        fr_time_delta_t stats_interval;                 //!< for the scheduler
 
+       fr_worker_config_t      worker;                 //!< Worker thread configuration.
+
 #ifndef NDEBUG
        uint32_t        ins_max;                        //!< max instruction count
        bool            ins_countup;                    //!< count up to "max"
 #endif
-
-       /*
-        *      Migration tools
-        */
 };
 
 void                   main_config_name_set_default(main_config_t *config, char const *name, bool overwrite_config);
 void                   main_config_confdir_set(main_config_t *config, char const *path);
 void                   main_config_dict_dir_set(main_config_t *config, char const *path);
 
-int                    main_config_parse_option(char const *value); /* flat / nested migration */
-
-bool                   main_config_migrate_option_get(char const *name);
+int                    main_config_save_override(char const *value);
 
 void                   main_config_exclusive_proc_done(main_config_t  const *config);
 int                    main_config_exclusive_proc_child(main_config_t const *config);