From: Alan T. DeKok Date: Mon, 20 Apr 2026 17:36:06 +0000 (-0400) Subject: Add '-S' and overrides X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;ds=inline;p=thirdparty%2Ffreeradius-server.git Add '-S' and overrides --- diff --git a/src/bin/radiusd.c b/src/bin/radiusd.c index e1503f75c51..16c791fe22c 100644 --- a/src/bin/radiusd.c +++ b/src/bin/radiusd.c @@ -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. diff --git a/src/lib/server/main_config.c b/src/lib/server/main_config.c index 014aad1089d..fd2ea4e8de0 100644 --- a/src/lib/server/main_config.c +++ b/src/lib/server/main_config.c @@ -45,8 +45,6 @@ RCSID("$Id$") #include - - #ifdef HAVE_SYSLOG_H # include #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 diff --git a/src/lib/server/main_config.h b/src/lib/server/main_config.h index d7baba5ca00..eec8551b7dd 100644 --- a/src/lib/server/main_config.h +++ b/src/lib/server/main_config.h @@ -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);