100 |
#define CMD_MEMINFO 4 /* Dump memory usage statistics */ |
#define CMD_MEMINFO 4 /* Dump memory usage statistics */ |
101 |
#define CMD_DUMPDB 5 /* Dump authentication database */ |
#define CMD_DUMPDB 5 /* Dump authentication database */ |
102 |
#define CMD_SHUTDOWN 6 /* Stop immediately */ |
#define CMD_SHUTDOWN 6 /* Stop immediately */ |
103 |
|
#define CMD_SUSPEND 7 /* Suspend service */ |
104 |
|
#define CMD_CONTINUE 8 /* Continue after suspend */ |
105 |
|
|
106 |
int daemon_command = CMD_NONE; |
int daemon_command = CMD_NONE; |
107 |
|
|
289 |
return svp ? ntohs(svp->s_port) : defval; |
return svp ? ntohs(svp->s_port) : defval; |
290 |
} |
} |
291 |
|
|
292 |
|
static void |
293 |
|
radiusd_preconfig_hook(void *a ARG_UNUSED, void *b ARG_UNUSED) |
294 |
|
{ |
295 |
|
/* Flush any pending requests and empty the request queue */ |
296 |
|
radiusd_flush_queue(); |
297 |
|
request_init_queue(); |
298 |
|
|
299 |
|
/* Terminate all subprocesses */ |
300 |
|
rpp_kill(-1, SIGTERM); |
301 |
|
radiusd_cleanup(); |
302 |
|
} |
303 |
|
|
304 |
|
static void |
305 |
|
radiusd_postconfig_hook(void *a ARG_UNUSED, void *b ARG_UNUSED) |
306 |
|
{ |
307 |
|
/*FIXME: Emit the warning: |
308 |
|
radlog(L_ALERT, |
309 |
|
_("Radiusd is not listening on any port. |
310 |
|
Trying to continue anyway...")); |
311 |
|
|
312 |
|
If necessary..*/ |
313 |
|
} |
314 |
|
|
315 |
void |
void |
316 |
radiusd_setup() |
radiusd_setup() |
317 |
{ |
{ |
329 |
|
|
330 |
/* Register radiusd hooks first. This ensures they will be |
/* Register radiusd hooks first. This ensures they will be |
331 |
executed after all other hooks */ |
executed after all other hooks */ |
332 |
#ifdef FIXME |
radiusd_set_preconfig_hook(radiusd_preconfig_hook, NULL, 0); |
333 |
register_before_config_hook(radiusd_before_config_hook, NULL); |
radiusd_set_postconfig_hook(radiusd_postconfig_hook, NULL, 0); |
|
register_after_config_hook(radiusd_after_config_hook, NULL); |
|
|
#endif |
|
334 |
|
|
335 |
snmp_init(0, 0, (snmp_alloc_t)emalloc, (snmp_free_t)efree); |
snmp_init(0, 0, (snmp_alloc_t)emalloc, (snmp_free_t)efree); |
|
#ifdef USE_SNMP |
|
|
snmpserv_init(&saved_status); |
|
|
#endif |
|
336 |
} |
} |
337 |
|
|
338 |
void |
void |
358 |
radiusd_signal_init(sig_handler); |
radiusd_signal_init(sig_handler); |
359 |
radiusd_reconfigure(); |
radiusd_reconfigure(); |
360 |
radpath_init(); |
radpath_init(); |
361 |
stat_init(); |
#ifdef USE_SNMP |
362 |
|
snmpserv_init(&saved_status); |
363 |
|
#endif |
364 |
radlog(L_INFO, _("Ready")); |
radlog(L_INFO, _("Ready")); |
365 |
} |
} |
366 |
|
|
515 |
/*NOTREACHED*/ |
/*NOTREACHED*/ |
516 |
} |
} |
517 |
|
|
518 |
|
static int |
519 |
|
snmp_request_to_command() |
520 |
|
{ |
521 |
|
if (server_stat && server_stat->auth.status != saved_status) { |
522 |
|
saved_status = server_stat->auth.status; |
523 |
|
switch (server_stat->auth.status) { |
524 |
|
case serv_reset: |
525 |
|
return CMD_RESTART; |
526 |
|
|
527 |
|
case serv_init: |
528 |
|
return CMD_RELOAD; |
529 |
|
|
530 |
|
case serv_running: |
531 |
|
return CMD_CONTINUE; |
532 |
|
|
533 |
|
case serv_suspended: |
534 |
|
return CMD_SUSPEND; |
535 |
|
|
536 |
|
case serv_shutdown: |
537 |
|
return CMD_SHUTDOWN; |
538 |
|
} |
539 |
|
} |
540 |
|
return CMD_NONE; |
541 |
|
} |
542 |
|
|
543 |
|
void |
544 |
|
radiusd_suspend() |
545 |
|
{ |
546 |
|
if (suspend_flag == 0) { |
547 |
|
radlog(L_NOTICE, _("RADIUSD SUSPENDED")); |
548 |
|
suspend_flag = 1; |
549 |
|
} |
550 |
|
} |
551 |
|
|
552 |
|
void |
553 |
|
radiusd_continue() |
554 |
|
{ |
555 |
|
if (suspend_flag) { |
556 |
|
suspend_flag = 0; |
557 |
|
#ifdef USE_SNMP |
558 |
|
server_stat->auth.status = serv_running; |
559 |
|
server_stat->acct.status = serv_running; |
560 |
|
#endif |
561 |
|
} |
562 |
|
} |
563 |
|
|
564 |
static void |
static void |
565 |
check_reload() |
check_reload() |
566 |
{ |
{ |
567 |
|
if (daemon_command == CMD_NONE) |
568 |
|
daemon_command = snmp_request_to_command(); |
569 |
|
|
570 |
switch (daemon_command) { |
switch (daemon_command) { |
571 |
case CMD_CLEANUP: |
case CMD_CLEANUP: |
572 |
radiusd_cleanup(); |
radiusd_cleanup(); |
590 |
RADIUS_DUMPDB_NAME); |
RADIUS_DUMPDB_NAME); |
591 |
dump_users_db(); |
dump_users_db(); |
592 |
break; |
break; |
593 |
|
|
594 |
|
case CMD_SUSPEND: |
595 |
|
radiusd_suspend(); |
596 |
|
break; |
597 |
|
|
598 |
|
case CMD_CONTINUE: |
599 |
|
radiusd_continue(); |
600 |
|
break; |
601 |
|
|
602 |
case CMD_SHUTDOWN: |
case CMD_SHUTDOWN: |
603 |
radiusd_exit(); |
radiusd_exit(); |
604 |
|
break; |
|
default: |
|
|
//check_snmp_request(); |
|
|
break; |
|
605 |
} |
} |
606 |
daemon_command = CMD_NONE; |
daemon_command = CMD_NONE; |
607 |
} |
} |
714 |
} |
} |
715 |
} |
} |
716 |
|
|
717 |
|
|
718 |
|
/* ************************ Coniguration Functions ************************* */ |
719 |
|
|
720 |
|
struct hook_rec { |
721 |
|
void (*function)(void *func_data, void *call_data); |
722 |
|
void *data; |
723 |
|
int once; /* Run once and remove */ |
724 |
|
}; |
725 |
|
|
726 |
|
static LIST /* of struct hook_rec */ *preconfig; |
727 |
|
static LIST /* of struct hook_rec */ *postconfig; |
728 |
|
|
729 |
|
void |
730 |
|
radiusd_set_preconfig_hook(void (*f)(void *, void *), void *p, int once) |
731 |
|
{ |
732 |
|
struct hook_rec *hp = emalloc(sizeof(*hp)); |
733 |
|
hp->function = f; |
734 |
|
hp->data = p; |
735 |
|
hp->once = once; |
736 |
|
if (!preconfig) |
737 |
|
preconfig = list_create(); |
738 |
|
list_prepend(preconfig, hp); |
739 |
|
} |
740 |
|
|
741 |
|
void |
742 |
|
radiusd_set_postconfig_hook(void (*f)(void *, void *), void *p, int once) |
743 |
|
{ |
744 |
|
struct hook_rec *hp = emalloc(sizeof(*hp)); |
745 |
|
hp->function = f; |
746 |
|
hp->data = p; |
747 |
|
hp->once = once; |
748 |
|
if (!postconfig) |
749 |
|
postconfig = list_create(); |
750 |
|
list_prepend(postconfig, hp); |
751 |
|
} |
752 |
|
|
753 |
|
struct hook_runtime_closure { |
754 |
|
LIST *list; |
755 |
|
void *call_data; |
756 |
|
}; |
757 |
|
|
758 |
|
static int |
759 |
|
_hook_call(void *item, void *data) |
760 |
|
{ |
761 |
|
struct hook_rec *hp = item; |
762 |
|
struct hook_runtime_closure *clos = data; |
763 |
|
hp->function(hp->data, clos->call_data); |
764 |
|
if (hp->once) { |
765 |
|
list_remove(clos->list, hp, NULL); |
766 |
|
efree(hp); |
767 |
|
} |
768 |
|
return 0; |
769 |
|
} |
770 |
|
|
771 |
|
void |
772 |
|
radiusd_run_preconfig_hooks(void *data) |
773 |
|
{ |
774 |
|
struct hook_runtime_closure clos; |
775 |
|
clos.list = preconfig; |
776 |
|
clos.call_data = data; |
777 |
|
list_iterate(clos.list, _hook_call, &clos); |
778 |
|
} |
779 |
|
|
780 |
|
void |
781 |
|
radiusd_run_postconfig_hooks(void *data) |
782 |
|
{ |
783 |
|
struct hook_runtime_closure clos; |
784 |
|
clos.list = postconfig; |
785 |
|
clos.call_data = data; |
786 |
|
list_iterate(clos.list, _hook_call, &clos); |
787 |
|
} |
788 |
|
|
789 |
void |
void |
790 |
radiusd_reconfigure() |
radiusd_reconfigure() |
791 |
{ |
{ |
792 |
int rc = 0; |
int rc = 0; |
793 |
char *filename; |
char *filename; |
794 |
|
|
795 |
/* Flush any pending requests and empty the request queue */ |
radiusd_run_preconfig_hooks(NULL); |
|
radiusd_flush_queue(); |
|
|
request_init_queue(); |
|
|
|
|
|
/* Terminate all subprocesses */ |
|
|
rpp_kill(-1, SIGTERM); |
|
|
radiusd_cleanup(); |
|
796 |
|
|
797 |
radlog(L_INFO, _("Loading configuration files.")); |
radlog(L_INFO, _("Loading configuration files.")); |
798 |
/* Read main configuration file */ |
/* Read main configuration file */ |
807 |
radlog(L_CRIT, _("Errors reading config file - EXITING")); |
radlog(L_CRIT, _("Errors reading config file - EXITING")); |
808 |
exit(1); |
exit(1); |
809 |
} |
} |
810 |
|
|
811 |
|
radiusd_run_postconfig_hooks(NULL); |
812 |
} |
} |
813 |
|
|
814 |
|
|
1081 |
} |
} |
1082 |
|
|
1083 |
int |
int |
1084 |
udp_open(int type, UINT4 ipaddr, int port) |
udp_open(int type, UINT4 ipaddr, int port, int nonblock) |
1085 |
{ |
{ |
1086 |
int fd; |
int fd; |
1087 |
struct sockaddr_in s; |
struct sockaddr_in s; |
1101 |
} |
} |
1102 |
|
|
1103 |
fd = socket(PF_INET, SOCK_DGRAM, 0); |
fd = socket(PF_INET, SOCK_DGRAM, 0); |
1104 |
|
if (nonblock) |
1105 |
|
set_nonblocking(fd); |
1106 |
if (fd < 0) { |
if (fd < 0) { |
1107 |
radlog(L_CRIT|L_PERROR, "%s socket", |
radlog(L_CRIT|L_PERROR, "%s socket", |
1108 |
request_class[type].name); |
request_class[type].name); |
1144 |
if (udp_open(R_AUTH, |
if (udp_open(R_AUTH, |
1145 |
argv[i].v.host.ipaddr, |
argv[i].v.host.ipaddr, |
1146 |
argv[i].v.host.port > 0 ? |
argv[i].v.host.port > 0 ? |
1147 |
argv[i].v.host.port : auth_port)) |
argv[i].v.host.port : auth_port, |
1148 |
|
0)) |
1149 |
errcnt++; |
errcnt++; |
1150 |
} |
} |
1151 |
if (errcnt == 0) |
if (errcnt == 0) |
1159 |
if (!finish) |
if (!finish) |
1160 |
_opened_auth_sockets = 0; |
_opened_auth_sockets = 0; |
1161 |
else if (radius_mode == MODE_DAEMON && !_opened_auth_sockets) |
else if (radius_mode == MODE_DAEMON && !_opened_auth_sockets) |
1162 |
udp_open(R_AUTH, INADDR_ANY, auth_port); |
udp_open(R_AUTH, INADDR_ANY, auth_port, 0); |
1163 |
return 0; |
return 0; |
1164 |
} |
} |
1165 |
|
|
1180 |
udp_open(R_ACCT, |
udp_open(R_ACCT, |
1181 |
argv[i].v.host.ipaddr, |
argv[i].v.host.ipaddr, |
1182 |
argv[i].v.host.port > 0 ? |
argv[i].v.host.port > 0 ? |
1183 |
argv[i].v.host.port : acct_port); |
argv[i].v.host.port : acct_port, |
1184 |
|
0); |
1185 |
} |
} |
1186 |
_opened_acct_sockets++; |
_opened_acct_sockets++; |
1187 |
return 0; |
return 0; |
1193 |
if (!finish) |
if (!finish) |
1194 |
_opened_acct_sockets = 0; |
_opened_acct_sockets = 0; |
1195 |
else if (radius_mode == MODE_DAEMON && !_opened_acct_sockets) |
else if (radius_mode == MODE_DAEMON && !_opened_acct_sockets) |
1196 |
udp_open(R_ACCT, INADDR_ANY, acct_port); |
udp_open(R_ACCT, INADDR_ANY, acct_port, 0); |
1197 |
return 0; |
return 0; |
1198 |
} |
} |
1199 |
|
|