'mainfconfig' data structure, so everyone can see them.
Moved the signal handling code to be a bit better (yet again)
When receiving a SIGTERM, (or any other fatal signal), try
our best to clean up and exit.
#include "radpaths.h"
#include "conf.h"
#include "missing.h"
+#include "conffile.h"
#include <stdarg.h>
char *nospace_time;
char *log_file;
char *checkrad;
+ CONF_SECTION *config;
+ RADCLIENT *clients;
+ REALM *realms;
} MAIN_CONFIG_T;
#define DEBUG if(debug_flag)log_debug
RADCLIENT *client_find(uint32_t ipno);
const char *client_name(uint32_t ipno);
void client_walk(void);
+void clients_free(RADCLIENT *cl);
/* files.c */
REALM *realm_find(const char *, int);
REALM *realm_findbyaddr(uint32_t ipno, int port);
+void realm_free(REALM *cl);
void realm_disable(uint32_t ipno, int port);
int pairlist_read(const char *file, PAIR_LIST **list, int complain);
void pairlist_free(PAIR_LIST **);
#include "radiusd.h"
#include "conffile.h"
-RADCLIENT *clients = NULL;
-
/*
* Free a RADCLIENT list.
*/
-static void clients_free(RADCLIENT *cl)
+void clients_free(RADCLIENT *cl)
{
RADCLIENT *next;
int lineno = 0;
char *p;
- clients_free(clients);
- clients = NULL;
+ clients_free(mainconfig.clients);
+ mainconfig.clients = NULL;
if ((fp = fopen(file, "r")) == NULL) {
/* The clients file is no longer required. All configuration
strNcpy(c->longname, hostnm, sizeof(c->longname));
}
- c->next = clients;
- clients = c;
+ c->next = mainconfig.clients;
+ mainconfig.clients = c;
}
fclose(fp);
RADCLIENT *cl;
RADCLIENT *match = NULL;
- for (cl = clients; cl; cl = cl->next) {
+ for (cl = mainconfig.clients; cl; cl = cl->next) {
if ((ipaddr & cl->netmask) == cl->ipaddr) {
if ((!match) ||
(ntohl(cl->netmask) > ntohl(match->netmask))) {
RADCLIENT *cl;
char host_ipaddr[16];
- for (cl = clients; cl != NULL; cl = cl->next)
+ for (cl = mainconfig.clients; cl != NULL; cl = cl->next)
radlog(L_ERR, "client: client_walk: %s\n",
ip_ntoa(host_ipaddr, cl->ipaddr));
}
struct conf_item *children;
};
-CONF_SECTION *config = NULL;
-
/*
* Yucky hacks.
*/
-extern RADCLIENT *clients;
-extern REALM *realms;
extern int max_proxies;
static int generate_realms(const char *filename);
* Free the old configuration data, and replace it
* with the new one.
*/
- cf_section_free(&config);
- config = cs;
+ cf_section_free(&mainconfig.config);
+ mainconfig.config = cs;
/*
* And parse the directory configuration values.
char *s, *t, *authhost, *accthost;
tail = &my_realms;
- for (cs = cf_subsection_find_next(config, NULL, "realm"); cs != NULL;
- cs = cf_subsection_find_next(config, cs, "realm")) {
+ for (cs = cf_subsection_find_next(mainconfig.config, NULL, "realm"); cs != NULL;
+ cs = cf_subsection_find_next(mainconfig.config, cs, "realm")) {
if (!cs->name2) {
radlog(L_CONS|L_ERR, "%s[%d]: Missing realm name", filename, cs->item.lineno);
return -1;
* And make these realms preferred over the ones
* in the 'realms' file.
*/
- *tail = realms;
- realms = my_realms;
+ *tail = mainconfig.realms;
+ mainconfig.realms = my_realms;
- /*Setup node and total info for multi-listed realms*/
- for (c = realms; c; c = c->next) {
- if(c->chose == 1) {
- continue;
- }
- else {
- int i = 0, b = 0;
- REALM *rptr, *r_array[max_proxies];
- for(rptr = c; rptr; rptr = rptr->next) {
- /*if realm matches*/
- if(strcasecmp(rptr->realm, c->realm) == 0) {
- i++;
- r_array[i] = rptr;
- rptr->chose = 1;
- rptr->node = i;
- }
- }
- if (i > 1) {
- for(b = 1; b <= i; b++) {
- rptr = r_array[b];
- rptr->total = i;
- }
- }
- else {
- c->total = 0;
- }
- }
- }
-
- /*Set chose flag back to default (0) on all realms*/
- for (c = realms; c; c = c->next) {
- c->chose = 0;
- }
-
return 0;
}
char *hostnm, *secret, *shortnm, *netmask;
char *nastype, *login, *password;
- for (cs = cf_subsection_find_next(config, NULL, "client"); cs != NULL;
- cs = cf_subsection_find_next(config, cs, "client")) {
+ for (cs = cf_subsection_find_next(mainconfig.config, NULL, "client"); cs != NULL;
+ cs = cf_subsection_find_next(mainconfig.config, cs, "client")) {
if (!cs->name2) {
radlog(L_CONS|L_ERR, "%s[%d]: Missing client name", filename, cs->item.lineno);
return -1;
if(password != NULL)
strcpy(c->password, password);
- c->next = clients;
- clients = c;
+ c->next =mainconfig. clients;
+ mainconfig.clients = c;
}
return 0;
CONF_ITEM *ci;
if (section == NULL) {
- section = config;
+ section = mainconfig.config;
}
for (ci = section->children; ci; ci = ci->next) {
CONF_SECTION *cf_section_find(const char *name)
{
if (name)
- return cf_section_sub_find(config, name);
+ return cf_section_sub_find(mainconfig.config, name);
else
- return config;
+ return mainconfig.config;
}
/*
}
+#if 0
/*
* JMG dump_config tries to dump the config structure in a readable format
*
int dump_config(void)
{
- return dump_config_section(config, 0);
+ return dump_config_section(mainconfig.config, 0);
}
+#endif
extern int proxy_dead_time;
int maximum_proxies;
-REALM *realms = NULL;
-
/*
* Free a PAIR_LIST
*/
/*
* Free a REALM list.
*/
-static void realm_free(REALM *cl)
+void realm_free(REALM *cl)
{
REALM *next;
int lineno = 0;
REALM *c, **tail;
- realm_free(realms);
- realms = NULL;
- tail = &realms;
+ realm_free(mainconfig.realms);
+ mainconfig.realms = NULL;
+ tail = &mainconfig.realms;
if ((fp = fopen(file, "r")) == NULL) {
/* The realms file is not mandatory. If it exists it will
time_t now;
now = time(NULL);
- for(cl = realms; cl; cl = cl->next)
+ for(cl = mainconfig.realms; cl; cl = cl->next)
if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
cl->active = FALSE;
cl->wakeup = now + proxy_dead_time;
realm = "NULL";
}
- for (cl = realms; cl; cl = cl->next) {
+ for (cl = mainconfig.realms; cl; cl = cl->next) {
/*
* Wake up any sleeping realm.
*/
if(cl->total > 1 && cl->ldflag == 1) {
/*Get all of the realms from initial list*/
for(i = 1; i <= cl->total; i++) {
- for(realmptr = realms; realmptr;
+ for(realmptr = mainconfig.realms; realmptr;
realmptr = realmptr->next) {
if((strcasecmp(realmptr->realm,
cl->realm)) == 0 &&
* If we get a packet from an end server, then we mark it
* as active, and return the realm.
*/
- for(cl = realms; cl != NULL; cl = cl->next)
+ for(cl = mainconfig.realms; cl != NULL; cl = cl->next)
if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
cl->active = TRUE;
return cl;
REALM *next, *rptr;
if(max_config > 0) {
maximum_proxies = max_config;
- for(rptr=realms; rptr; rptr = rptr->next) {
+ for(rptr=mainconfig.realms; rptr; rptr = rptr->next) {
if(rptr->total > max_config || rptr->total >= 1) {
- for(next = realms; next; next = next->next) {
+ for(next = mainconfig.realms; next; next = next->next) {
if(next->ldflag != 0 &&
next->ldflag != 1) {
radlog(L_ERR,
spawn_flag = TRUE;
radius_dir = strdup(RADIUS_DIR);
- signal(SIGHUP, sig_hup);
- signal(SIGPIPE, SIG_IGN);
-signal(SIGINT, sig_fatal);
- signal(SIGQUIT, sig_fatal);
- signal(SIGTERM, sig_fatal);
-
- /* this is right for threads, too, right?
- * (Threads shouldn't get signals (from us) -- just be pthread_cancel()led.)
+ /*
+ * Ensure that the configuration is initialized.
*/
- signal(SIGCHLD, sig_cleanup);
+ memset(&mainconfig, 0, sizeof(mainconfig));
/* Process the options. */
while ((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:p:sSvxXyz")) != EOF) {
buffer, auth_port, acct_port);
}
+ /*
+ * Now that we've set everything up, we can install the signal
+ * handlers. Before this, if we get any signal, we don't know
+ * what to do, so we might as well do the default, and die.
+ */
+ signal(SIGHUP, sig_hup);
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGTERM, sig_fatal);
+
+ /*
+ * If we're debugging, then a CTRL-C will cause the
+ * server to die immediately. Use SIGTERM to shut down
+ * the server cleanly in that case.
+ */
+ if (debug_flag == 0) {
+ signal(SIGINT, sig_fatal);
+ signal(SIGQUIT, sig_fatal);
+ }
+
+ /* this is right for threads, too, right?
+ * (Threads shouldn't get signals (from us) -- just be pthread_cancel()led.)
+ */
+ signal(SIGCHLD, sig_cleanup);
+
radlog(L_INFO, "Ready to process requests.");
start_time = time(NULL);
* Receive user requests
*/
for (;;) {
+ /*
+ * If we've been told to exit, then do so,
+ * even if we have data waiting.
+ */
+ if (do_exit) {
+ DEBUG("Exiting...");
+
+ /*
+ * Ignore the TERM signal: we're about
+ * to die.
+ */
+ signal(SIGTERM, SIG_IGN);
+
+ /*
+ * Send a TERM signal to all associated
+ * processes (including us, which gets
+ * ignored.)
+ */
+ kill(-radius_pid, SIGTERM);
+
+ /*
+ * FIXME: Kill child threads, and
+ * clean up?
+ */
+
+ /*
+ * Detach any modules.
+ */
+ detach_modules();
+
+ /*
+ * FIXME: clean up any active REQUEST
+ * handles.
+ */
+
+ /*
+ * Clean up the configuration data
+ * structures.
+ */
+ cf_section_free(&mainconfig.config);
+ realm_free(mainconfig.realms);
+ clients_free(mainconfig.clients);
+
+ /*
+ * SIGTERM gets do_exit=0,
+ * and we want to exit cleanly.
+ *
+ * Other signals make us exit
+ * with an error status.
+ */
+ exit(do_exit - 1);
+ }
+
if (need_reload) {
if (reread_config(TRUE) < 0) {
exit(1);
#endif
status = select(max_fd + 1, &readfds, NULL, NULL, tv);
-
- /*
- * If we've been told to exit, then do so,
- * even if we have data waiting.
- */
- if (do_exit) {
- DEBUG("Exiting...");
- detach_modules();
-
- /*
- * SIGTERM gets do_exit=0,
- * and we want to exit cleanly.
- *
- * Other signals make us exit
- * with an error status.
- */
- exit(do_exit - 1);
- }
-
if (status == -1) {
/*
- * On interrupts, we clean up the
- * request list.
+ * On interrupts, we clean up the request
+ * list. We then continue with the loop,
+ * so that if we're supposed to exit,
+ * then the code at the start of the loop
+ * catches that, and exits.
*/
if (errno == EINTR) {
tv = rad_clean_list(time(NULL));
/*
- * We got a fatal signal. Clean up and exit.
+ * We got a fatal signal.
*/
static void sig_fatal(int sig)
{
- const char *me = "MASTER: ";
-
- /*
- * FIXME: Handle child threads, too...
- */
- if (radius_pid != getpid()) {
- me = "CHILD: ";
- }
-
switch(sig) {
case SIGTERM:
- radlog(L_INFO, "%sexit.", me);
do_exit = 1;
break;
default:
- radlog(L_ERR, "%sexit on signal (%d)", me, sig);
do_exit = 2;
break;
}
-
- /*
- * We're running as a daemon, we're the MASTER daemon,
- * and we got a fatal signal. Tear the rest of the
- * daemons down, as something absolutely horrible happened.
- */
- if ((debug_flag == 0) && (dont_fork == 0)
-#ifndef HAVE_PTHREAD_H
- && (radius_pid == getpid())
-#endif
- ) {
- /*
- * Kill all of the processes in the current
- * process group.
- */
- kill(-radius_pid, SIGTERM);
- }
}