struct main_config_t mainconfig;
char *request_log_file = NULL;
-char *debug_log_file = NULL;
char *debug_condition = NULL;
+typedef struct cached_config_t {
+ struct cached_config_t *next;
+ time_t created;
+ CONF_SECTION *cs;
+} cached_config_t;
+
+static cached_config_t *cs_cache = NULL;
+
/*
* Temporary local variables for parsing the configuration
* file.
*/
-#ifndef __MINGW32__
+#ifdef HAVE_SETUID
+/*
+ * Systems that have set/getresuid also have setuid.
+ */
uid_t server_uid;
static gid_t server_gid;
static const char *uid_name = NULL;
{ "destination", PW_TYPE_STRING_PTR, 0, &radlog_dest, "files" },
{ "syslog_facility", PW_TYPE_STRING_PTR, 0, &syslog_facility, Stringify(0) },
- { "file", PW_TYPE_STRING_PTR, -1, &mainconfig.log_file, "${logdir}/radius.log" },
- { "requests", PW_TYPE_STRING_PTR, -1, &request_log_file, NULL },
- { "debug_file", PW_TYPE_STRING_PTR, -1, &debug_log_file, NULL },
+ { "file", PW_TYPE_STRING_PTR, 0, &mainconfig.log_file, "${logdir}/radius.log" },
+ { "requests", PW_TYPE_STRING_PTR, 0, &request_log_file, NULL },
{ NULL, -1, 0, NULL, NULL }
};
static const CONF_PARSER serverdest_config[] = {
{ "log", PW_TYPE_SUBSECTION, 0, NULL, (const void *) logdest_config },
- { "log_file", PW_TYPE_STRING_PTR, -1, &mainconfig.log_file, NULL },
- { "log_destination", PW_TYPE_STRING_PTR, -1, &radlog_dest, NULL },
+ { "log_file", PW_TYPE_STRING_PTR, 0, &mainconfig.log_file, NULL },
+ { "log_destination", PW_TYPE_STRING_PTR, 0, &radlog_dest, NULL },
{ NULL, -1, 0, NULL, NULL }
};
static const CONF_PARSER log_config_nodest[] = {
{ "stripped_names", PW_TYPE_BOOLEAN, 0, &log_stripped_names,"no" },
- { "auth", PW_TYPE_BOOLEAN, -1, &mainconfig.log_auth, "no" },
+ { "auth", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth, "no" },
{ "auth_badpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_badpass, "no" },
{ "auth_goodpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_goodpass, "no" },
+ { "msg_badpass", PW_TYPE_STRING_PTR, 0, &mainconfig.auth_badpass_msg, NULL},
+ { "msg_goodpass", PW_TYPE_STRING_PTR, 0, &mainconfig.auth_goodpass_msg, NULL},
{ NULL, -1, 0, NULL, NULL }
};
* DON'T exist in radiusd.conf, then the previously parsed
* values for "log { foo = bar}" will be used.
*/
- { "log_auth", PW_TYPE_BOOLEAN, -1, &mainconfig.log_auth, NULL },
+ { "log_auth", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth, NULL },
{ "log_auth_badpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_badpass, NULL },
{ "log_auth_goodpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_goodpass, NULL },
{ "log_stripped_names", PW_TYPE_BOOLEAN, 0, &log_stripped_names, NULL },
}
-#ifndef __MINGW32__
+#ifdef HAVE_SETUID
int did_setuid = FALSE;
#if defined(HAVE_SETRESUID) && defined (HAVE_GETRESUID)
int read_mainconfig(int reload)
{
const char *p = NULL;
- static int old_debug_level = -1;
CONF_PAIR *cp;
CONF_SECTION *cs;
struct stat statbuf;
+ cached_config_t *cc;
char buffer[1024];
+ if (reload != 0) {
+ radlog(L_ERR, "Reload is not implemented");
+ return -1;
+ }
+
if (stat(radius_dir, &statbuf) < 0) {
radlog(L_ERR, "Errors reading %s: %s",
radius_dir, strerror(errno));
}
#endif
- if (!reload) {
- radlog(L_INFO, "Starting - reading configuration files ...");
- } else {
- radlog(L_INFO, "Reloading - reading configuration files...");
- }
+ radlog(L_INFO, "Starting - reading configuration files ...");
/* Read the configuration file */
snprintf(buffer, sizeof(buffer), "%.200s/%.50s.conf",
}
}
-#ifndef __MINGW32__
+#ifdef HAVE_SETUID
/*
- * We should really switch users earlier in the process.
+ * Switch users as early as possible.
*/
if (!switch_users(cs)) exit(1);
#endif
cf_section_free(&mainconfig.config);
mainconfig.config = cs;
- if (!clients_parse_section(cs)) {
+ DEBUG2("%s: #### Loading Realms and Home Servers ####", mainconfig.name);
+ if (!realms_init(cs)) {
return -1;
}
- DEBUG2("%s: #### Loading Realms and Home Servers ####", mainconfig.name);
-
- if (!realms_init(cs)) {
+ DEBUG2("%s: #### Loading Clients ####", mainconfig.name);
+ if (!clients_parse_section(cs)) {
return -1;
}
xlat_register("client", xlat_client, NULL);
/*
- * Reload: change debug flag if it's changed in the
- * configuration file.
+ * Starting the server, WITHOUT "-x" on the
+ * command-line: use whatever is in the config
+ * file.
*/
- if (reload) {
- if (mainconfig.debug_level != old_debug_level) {
- debug_flag = mainconfig.debug_level;
- }
-
- } else if (debug_flag == 0) {
-
- /*
- * Starting the server, WITHOUT "-x" on the
- * command-line: use whatever's in the config
- * file.
- */
+ if (debug_flag == 0) {
debug_flag = mainconfig.debug_level;
}
fr_debug_flag = debug_flag;
- old_debug_level = mainconfig.debug_level;
/*
* Go update our behaviour, based on the configuration
/* Reload the modules. */
if (setup_modules(reload, mainconfig.config) < 0) {
- radlog(L_ERR, "Errors initializing modules");
return -1;
}
}
}
+ cc = rad_malloc(sizeof(*cc));
+ memset(cc, 0, sizeof(*cc));
+
+ cc->cs = cs;
+ rad_assert(cs_cache == NULL);
+ cs_cache = cc;
+
return 0;
}
*/
int free_mainconfig(void)
{
+ cached_config_t *cc, *next;
+
+ virtual_servers_free(0);
+
+ /*
+ * Free all of the cached configurations.
+ */
+ for (cc = cs_cache; cc != NULL; cc = next) {
+ next = cc->next;
+ cf_section_free(&cc->cs);
+ free(cc);
+ }
+
/*
* Clean up the configuration data
* structures.
*/
- cf_section_free(&mainconfig.config);
realms_free();
listen_free(&mainconfig.listen);
dict_free();
return 0;
}
+
+void hup_mainconfig(void)
+{
+ cached_config_t *cc;
+ CONF_SECTION *cs;
+ char buffer[1024];
+
+ /* Read the configuration file */
+ snprintf(buffer, sizeof(buffer), "%.200s/%.50s.conf",
+ radius_dir, mainconfig.name);
+ if ((cs = cf_file_read(buffer)) == NULL) {
+ radlog(L_ERR, "Failed to re-read %s", buffer);
+ return;
+ }
+
+ cc = rad_malloc(sizeof(*cc));
+ memset(cc, 0, sizeof(*cc));
+
+ /*
+ * Save the current configuration. Note that we do NOT
+ * free older ones. We should probably do so at some
+ * point. Doing so will require us to mark which modules
+ * are still in use, and which aren't. Modules that
+ * can't be HUPed always use the original configuration.
+ * Modules that can be HUPed use one of the newer
+ * configurations.
+ */
+ cc->created = time(NULL);
+ cc->cs = cs;
+ cc->next = cs_cache;
+ cs_cache = cc;
+
+ /*
+ * Prefer the new module configuration.
+ */
+ module_hup(cf_section_sub_find(cs, "modules"));
+
+ /*
+ * Load new servers BEFORE freeing old ones.
+ */
+ virtual_servers_load(cs);
+
+ virtual_servers_free(cc->created - mainconfig.max_request_time * 4);
+}