2 * radiusd.c Main loop of the radius server.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2000,2001 The FreeRADIUS server project
21 * Copyright 1999,2000 Miquel van Smoorenburg <miquels@cistron.nl>
22 * Copyright 2000 Alan DeKok <aland@ox.org>
23 * Copyright 2000 Alan Curry <pacman-radius@cqc.com>
24 * Copyright 2000 Jeff Carneal <jeff@apex.net>
25 * Copyright 2000 Chad Miller <cmiller@surfsouth.com>
28 /* don't look here for the version, run radiusd -v or look in version.c */
29 static const char rcsid[] =
33 #include "libradius.h"
35 #include <sys/socket.h>
39 # include <netinet/in.h>
59 # include <sys/select.h>
67 # include <sys/wait.h>
70 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
73 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
81 #include "request_list.h"
84 # include "radius_snmp.h"
87 #include <sys/resource.h>
95 const char *progname = NULL;
96 const char *radius_dir = NULL;
97 const char *radacct_dir = NULL;
98 const char *radlog_dir = NULL;
99 const char *radlib_dir = NULL;
101 int log_stripped_names;
104 uint32_t myip = INADDR_ANY;
105 int log_auth_detail = FALSE;
109 int proxy_retry_delay = RETRY_DELAY;
110 int proxy_retry_count = RETRY_COUNT;
111 int proxy_synchronous = TRUE;
112 int need_reload = FALSE;
113 struct main_config_t mainconfig;
114 const char *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
116 static int got_child = FALSE;
120 static pid_t radius_pid;
121 static int request_num_counter = 0; /* per-request unique ID */
124 * Configuration items.
126 static int allow_core_dumps = FALSE;
127 static int max_request_time = MAX_REQUEST_TIME;
128 static int kill_unresponsive_children = FALSE;
129 static int cleanup_delay = CLEANUP_DELAY;
130 static int max_requests = MAX_REQUESTS;
131 static int dont_fork = FALSE;
132 static const char *pid_file = NULL;
133 static uid_t server_uid;
134 static gid_t server_gid;
135 static const char *uid_name = NULL;
136 static const char *gid_name = NULL;
137 static int proxy_requests = TRUE;
138 static int needs_child_cleanup = 0;
139 int spawn_flag = TRUE;
141 static void usage(void);
143 static void sig_fatal (int);
144 static void sig_hup (int);
146 static int switch_users(void);
147 static void rad_reject(REQUEST *request);
148 static struct timeval *rad_clean_list(time_t curtime);
149 static REQUEST *rad_check_list(REQUEST *);
150 static REQUEST *proxy_check_list(REQUEST *request);
151 static int refresh_request(REQUEST *request, void *data);
152 #ifndef WITH_THREAD_POOL
153 static int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
155 extern int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
159 * Map the proxy server configuration parameters to variables.
161 static CONF_PARSER proxy_config[] = {
162 { "retry_delay", PW_TYPE_INTEGER, 0, &proxy_retry_delay, Stringify(RETRY_DELAY) },
163 { "retry_count", PW_TYPE_INTEGER, 0, &proxy_retry_count, Stringify(RETRY_COUNT) },
164 { "synchronous", PW_TYPE_BOOLEAN, 0, &proxy_synchronous, "yes" },
165 { NULL, -1, 0, NULL, NULL }
169 * A mapping of configuration file names to internal variables
171 static CONF_PARSER server_config[] = {
172 { "max_request_time", PW_TYPE_INTEGER, 0, &max_request_time, Stringify(MAX_REQUEST_TIME) },
173 { "cleanup_delay", PW_TYPE_INTEGER, 0, &cleanup_delay, Stringify(CLEANUP_DELAY) },
174 { "max_requests", PW_TYPE_INTEGER, 0, &max_requests, Stringify(MAX_REQUESTS) },
175 { "delete_blocked_requests", PW_TYPE_INTEGER, 0, &kill_unresponsive_children, Stringify(FALSE) },
176 { "port", PW_TYPE_INTEGER, 0, &auth_port, Stringify(PW_AUTH_UDP_PORT) },
177 { "allow_core_dumps", PW_TYPE_BOOLEAN, 0, &allow_core_dumps, "no" },
178 { "log_stripped_names", PW_TYPE_BOOLEAN, 0, &log_stripped_names,"no" },
179 { "log_auth", PW_TYPE_BOOLEAN, -1, &mainconfig.log_auth, "no" },
180 { "log_auth_badpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_badpass, "no" },
181 { "log_auth_goodpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_goodpass, "no" },
182 { "pidfile", PW_TYPE_STRING_PTR, 0, &pid_file, "${run_dir}/radiusd.pid"},
183 { "bind_address", PW_TYPE_IPADDR, 0, &myip, "*" },
184 { "user", PW_TYPE_STRING_PTR, 0, &uid_name, "nobody"},
185 { "group", PW_TYPE_STRING_PTR, 0, &gid_name, "nobody"},
186 { "usercollide", PW_TYPE_BOOLEAN, 0, &mainconfig.do_usercollide, "no" },
187 { "lower_user", PW_TYPE_STRING_PTR, 0, &mainconfig.do_lower_user, "no" },
188 { "lower_pass", PW_TYPE_STRING_PTR, 0, &mainconfig.do_lower_pass, "no" },
189 { "nospace_user", PW_TYPE_STRING_PTR, 0, &mainconfig.do_nospace_user, "no" },
190 { "nospace_pass", PW_TYPE_STRING_PTR, 0, &mainconfig.do_nospace_pass, "no" },
191 { "proxy_requests", PW_TYPE_BOOLEAN, 0, &proxy_requests, "yes" },
192 { "proxy", PW_TYPE_SUBSECTION, 0, proxy_config, NULL },
193 { NULL, -1, 0, NULL, NULL }
197 static int switch_users() {
200 * Set the UID and GID, but only if we're NOT running
206 if (gid_name != NULL) {
209 gr = getgrnam(gid_name);
211 if (errno == ENOMEM) {
212 radlog(L_ERR|L_CONS, "Cannot switch to Group %s: out of memory", gid_name);
214 radlog(L_ERR|L_CONS, "Cannot switch group; %s doesn't exist", gid_name);
218 server_gid = gr->gr_gid;
219 if (setgid(server_gid) < 0) {
220 radlog(L_ERR|L_CONS, "Failed setting Group to %s: %s", gid_name, strerror(errno));
226 if (uid_name != NULL) {
229 pw = getpwnam(uid_name);
231 if (errno == ENOMEM) {
232 radlog(L_ERR|L_CONS, "Cannot switch to User %s: out of memory", uid_name);
234 radlog(L_ERR|L_CONS, "Cannot switch user; %s doesn't exist", uid_name);
238 server_uid = pw->pw_uid;
239 if (setuid(server_uid) < 0) {
240 radlog(L_ERR|L_CONS, "Failed setting User to %s: %s", uid_name, strerror(errno));
252 static int reread_config(int reload)
256 struct rlimit core_limits;
259 radlog(L_INFO, "Starting - reading configuration files ...");
260 } else if (pid == radius_pid) {
261 radlog(L_INFO, "Reloading configuration files.");
264 /* First read radiusd.conf */
265 DEBUG2("reread_config: reading radiusd.conf");
266 if (read_radius_conf_file() < 0) {
267 radlog(L_ERR|L_CONS, "Errors reading radiusd.conf");
271 /* And parse the server's configuration values. */
272 cs = cf_section_find(NULL);
274 radlog(L_ERR|L_CONS, "No configuration information in radiusd.conf!");
277 cf_section_parse(cs, NULL, server_config);
279 /* Reload the modules. */
280 DEBUG2("read_config_files: entering modules setup");
281 if (setup_modules() < 0) {
282 radlog(L_ERR|L_CONS, "Errors setting up modules");
287 * Go update our behaviour, based on the configuration
291 /* Get the current maximum for core files. */
292 if (getrlimit(RLIMIT_CORE, &core_limits) < 0) {
293 radlog(L_ERR|L_CONS, "Failed to get current core limit: %s", strerror(errno));
297 if (allow_core_dumps) {
298 if (setrlimit(RLIMIT_CORE, &core_limits) < 0) {
299 radlog(L_ERR|L_CONS, "Cannot update core dump limit: %s",
304 * If we're running as a daemon, and core
305 * dumps are enabled, log that information.
307 } else if ((core_limits.rlim_cur != 0) && !debug_flag)
308 radlog(L_INFO, "Core dumps are enabled.");
310 } else if (!debug_flag) {
312 * Not debugging. Set the core size to zero, to
313 * prevent security breaches. i.e. People
314 * reading passwords from the 'core' file.
316 struct rlimit limits;
319 limits.rlim_max = core_limits.rlim_max;
321 if (setrlimit(RLIMIT_CORE, &limits) < 0) {
322 radlog(L_ERR|L_CONS, "Cannot disable core dumps: %s",
329 switch_users(); /* Don't do this yet, if we're just starting up. */
337 * Parse a string into a syslog facility level.
339 static int str2fac(const char *s)
342 if(!strcmp(s, "kern"))
347 if(!strcmp(s, "user"))
352 if(!strcmp(s, "mail"))
357 if(!strcmp(s, "daemon"))
362 if(!strcmp(s, "auth"))
367 if(!strcmp(s, "auth"))
372 if(!strcmp(s, "lpr"))
377 if(!strcmp(s, "news"))
382 if(!strcmp(s, "uucp"))
387 if(!strcmp(s, "cron"))
392 if(!strcmp(s, "authpriv"))
397 if(!strcmp(s, "ftp"))
402 if(!strcmp(s, "local0"))
407 if(!strcmp(s, "local1"))
412 if(!strcmp(s, "local2"))
417 if(!strcmp(s, "local3"))
422 if(!strcmp(s, "local4"))
427 if(!strcmp(s, "local5"))
432 if(!strcmp(s, "local6"))
437 if(!strcmp(s, "local7"))
442 fprintf(stderr, "%s: Error: Unknown syslog facility: %s\n",
447 /* this should never be reached */
451 int main(int argc, char *argv[])
454 RADIUS_PACKET *packet;
456 unsigned char buffer[4096];
457 struct sockaddr salocal;
458 struct sockaddr_in *sa;
470 struct timeval *tv = NULL;
472 syslog_facility = LOG_DAEMON;
474 set_auth_parameters(argc,argv);
478 * Open /dev/null, and make sure filedescriptors
479 * 0, 1 and 2 are connected to something.
482 while (devnull >= 0 && devnull < 3)
483 devnull = open("/dev/null", O_RDWR);
485 if ((progname = strrchr(argv[0], '/')) == NULL)
492 radius_dir = strdup(RADIUS_DIR);
494 signal(SIGHUP, sig_hup);
495 signal(SIGINT, sig_fatal);
496 signal(SIGQUIT, sig_fatal);
497 signal(SIGPIPE, SIG_IGN);
499 signal(SIGTRAP, sig_fatal);
502 signal(SIGIOT, sig_fatal);
505 /* this is right for threads, too, right?
506 * (Threads shouldn't get signals (from us) -- just be pthread_cancel()led.)
508 signal(SIGTERM, sig_fatal);
509 signal(SIGCHLD, sig_cleanup);
511 signal(SIGFPE, sig_fatal);
512 signal(SIGSEGV, sig_fatal);
513 signal(SIGILL, sig_fatal);
516 /* Close unused file descriptors. */
517 for (t = 32; t >= 3; t--)
521 /* Process the options. */
522 while ((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:p:sSvxXyz")) != EOF) {
527 log_auth_detail = TRUE;
531 radacct_dir = strdup(optarg);
534 #if defined(WITH_DBM) || defined(WITH_NDBM)
540 /* ignore for backwards compatibility with Cistron */
544 radius_dir = strdup(optarg);
556 if ((myip = ip_getaddr(optarg)) == INADDR_NONE) {
557 fprintf(stderr, "radiusd: %s: host unknown\n",
564 radlog_dir = strdup(optarg);
568 * We should also have this as a configuration
572 syslog_facility = str2fac(optarg);
576 log_stripped_names++;
580 radius_port = atoi(optarg);
583 case 's': /* Single process mode */
592 * BIG debugging mode for users who are
593 * TOO LAZY to type '-sfxxyz -l stdout' themselves.
600 mainconfig.log_auth = TRUE;
601 mainconfig.log_auth_badpass = TRUE;
602 mainconfig.log_auth_goodpass = TRUE;
603 radlog_dir = strdup("stdout");
612 mainconfig.log_auth = TRUE;
613 mainconfig.log_auth_badpass = TRUE;
617 mainconfig.log_auth_badpass = TRUE;
618 mainconfig.log_auth_goodpass = TRUE;
627 /* Get our PID: the configuration file reader uses it. */
628 radius_pid = getpid();
630 /* Read the configuration files, BEFORE doing anything else. */
631 if (reread_config(0) < 0) {
635 /* We need root to do mkdir() and chown(), so we do this before giving up root. -chad */
636 radlogdir_iswritable(uid_name);
638 /* Do this as soon as possible! Make exceptions above here. */
643 * If they asked for syslog, then give it to them.
644 * Also, initialize the logging facility with the
645 * configuration that they asked for.
647 if (!strcmp(radlog_dir, "syslog")) {
648 openlog(progname, LOG_PID, syslog_facility);
650 /* Do you want a warning if -g is used without a -l to activate it? */
653 /* Initialize the request list. */
657 * We prefer (in order) the port from the command-line,
658 * then the port from the configuration file, then
659 * the port that the system names "radius", then
662 if (radius_port != 0) {
663 auth_port = radius_port;
664 } /* else auth_port is set from the config file */
667 * Maybe auth_port *wasn't* set from the config file,
668 * or the config file set it to zero.
671 if (auth_port == 0) {
672 svp = getservbyname ("radius", "udp");
674 auth_port = ntohs(svp->s_port);
677 * We're getting auth_port from
678 * /etc/services, get acct_port from
681 svp = getservbyname ("radacct", "udp");
683 acct_port = ntohs(svp->s_port);
685 auth_port = PW_AUTH_UDP_PORT;
690 * Open Authentication socket.
693 authfd = socket (AF_INET, SOCK_DGRAM, 0);
695 perror("auth socket");
699 sa = (struct sockaddr_in *) &salocal;
700 memset ((char *) sa, '\0', sizeof(salocal));
701 sa->sin_family = AF_INET;
702 sa->sin_addr.s_addr = myip;
703 sa->sin_port = htons(auth_port);
705 result = bind (authfd, &salocal, sizeof(*sa));
707 perror ("auth bind");
708 DEBUG(" There appears to be another RADIUS server already running on the authentication port UDP %d.", auth_port);
713 * Open Accounting Socket.
715 * If we haven't already gotten acct_port from /etc/services,
716 * then make it auth_port + 1.
719 acct_port = auth_port + 1;
721 acctfd = socket (AF_INET, SOCK_DGRAM, 0);
723 perror ("acct socket");
727 sa = (struct sockaddr_in *) &salocal;
728 memset ((char *) sa, '\0', sizeof(salocal));
729 sa->sin_family = AF_INET;
730 sa->sin_addr.s_addr = myip;
731 sa->sin_port = htons(acct_port);
733 result = bind (acctfd, & salocal, sizeof(*sa));
735 perror ("acct bind");
736 DEBUG(" There appears to be another RADIUS server already running on the accounting port UDP %d.", acct_port);
741 * If we're proxying requests, open the proxy FD.
742 * Otherwise, don't do anything.
744 if (proxy_requests == TRUE) {
748 proxyfd = socket (AF_INET, SOCK_DGRAM, 0);
750 perror ("proxy socket");
754 sa = (struct sockaddr_in *) &salocal;
755 memset((char *) sa, '\0', sizeof(salocal));
756 sa->sin_family = AF_INET;
757 sa->sin_addr.s_addr = myip;
760 * Set the proxy port to be one more than the
763 for (proxy_port = acct_port + 1; proxy_port < 64000; proxy_port++) {
764 sa->sin_port = htons(proxy_port);
765 result = bind(proxyfd, & salocal, sizeof(*sa));
772 * Couldn't find a port to which we could bind.
774 if (proxy_port == 64000) {
775 perror("proxy bind");
781 * NOT proxying requests, set the FD to a bad value.
788 * Register built-in compare functions.
790 pair_builtincompare_init();
798 * Connect 0, 1 and 2 to /dev/null.
800 if (!debug_flag && devnull >= 0) {
802 if (strcmp(radlog_dir, "stdout") != 0) {
805 if (strcmp(radlog_dir, "stderr") != 0) {
808 if (devnull > 2) close(devnull);
813 * Disconnect from session
815 if (debug_flag == 0 && dont_fork == 0) {
818 radlog(L_ERR|L_CONS, "Couldn't fork");
823 * The parent exits, so the child can run in the background.
834 * Ensure that we're using the CORRECT pid after forking,
835 * NOT the one we started with.
837 radius_pid = getpid();
840 * Only write the PID file if we're running as a daemon.
842 * And write it AFTER we've forked, so that we write the
845 if (dont_fork == FALSE) {
848 fp = fopen(pid_file, "w");
850 fprintf(fp, "%d\n", (int) radius_pid);
853 radlog(L_ERR|L_CONS, "Failed writing process id to file %s: %s\n",
854 pid_file, strerror(errno));
860 * If we're spawning children, set up the thread pool.
862 if (spawn_flag == TRUE) {
868 * Use linebuffered or unbuffered stdout if
869 * the debug flag is on.
871 if (debug_flag == TRUE)
875 strcpy((char *)buffer, "*");
877 ip_ntoa((char *)buffer, myip);
880 if (proxy_requests == TRUE) {
881 radlog(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp, with proxy on %d/udp.",
882 buffer, auth_port, acct_port, proxy_port);
884 radlog(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp.",
885 buffer, auth_port, acct_port);
888 radlog(L_INFO, "Ready to process requests.");
891 * Receive user requests
895 if (reread_config(TRUE) < 0) {
899 radlog(L_INFO, "Ready to process requests.");
904 FD_SET(authfd, &readfds);
906 FD_SET(acctfd, &readfds);
908 FD_SET(proxyfd, &readfds);
910 if (rad_snmp.smux_fd >= 0)
911 FD_SET(rad_snmp.smux_fd, &readfds);
914 status = select(32, &readfds, NULL, NULL, tv);
917 * On interrupts, we clean up the
920 if (errno == EINTR) {
921 tv = rad_clean_list(time(NULL));
924 radlog(L_ERR, "Unexpected error in select(): %s",
930 * Loop over the open socket FD's, reading any data.
932 for (i = 0; i < 3; i++) {
934 if (i == 0) fd = authfd;
935 if (i == 1) fd = acctfd;
936 if (i == 2) fd = proxyfd;
937 if (fd < 0 || !FD_ISSET(fd, &readfds))
940 * Receive the packet.
942 packet = rad_recv(fd);
943 if (packet == NULL) {
944 radlog(L_ERR, "%s", librad_errstr);
949 rad_snmp.acct.total_requests++;
951 rad_snmp.auth.total_requests++;
955 * Check if we know this client for
956 * authfd and acctfd. Check if we know
957 * this proxy for proxyfd.
961 if ((cl = client_find(packet->src_ipaddr)) == NULL) {
962 radlog(L_ERR, "Ignoring request from unknown client %s:%d",
963 ip_ntoa((char *)buffer, packet->src_ipaddr),
971 } else { /* It came in on the proxy port */
973 if ((rl = realm_findbyaddr(packet->src_ipaddr)) == NULL) {
974 radlog(L_ERR, "Ignoring request from unknown proxy %s:%d",
975 ip_ntoa((char *)buffer, packet->src_ipaddr),
985 * Do yet another check, to see if the
986 * packet code is valid. We only understand
987 * a few, so stripping off obviously invalid
988 * packets here will make our life easier.
990 if (packet->code > PW_ACCESS_CHALLENGE) {
991 radlog(L_ERR, "Ignoring request from client %s:%d with unknown code %d", buffer, packet->src_port, packet->code);
996 request = rad_malloc(sizeof(REQUEST));
997 memset(request, 0, sizeof(REQUEST));
999 request->magic = REQUEST_MAGIC;
1001 request->packet = packet;
1002 request->proxy = NULL;
1003 request->reply = NULL;
1004 request->proxy_reply = NULL;
1005 request->config_items = NULL;
1006 request->username = NULL;
1007 request->password = NULL;
1008 request->timestamp = time(NULL);
1009 request->number = request_num_counter++;
1010 request->child_pid = NO_SUCH_CHILD_PID;
1011 request->container = NULL;
1012 request->options = RAD_REQUEST_OPTION_NONE;
1013 strNcpy(request->secret, (char *)secret, sizeof(request->secret));
1014 rad_process(request, spawn_flag);
1015 } /* loop over authfd, acctfd, proxyfd */
1019 * After handling all authentication/accounting
1020 * requests, THEN process any pending SMUX/SNMP
1023 * Note that the handling is done in the main server,
1024 * which probably isn't a Good Thing. It really
1025 * should be wrapped, and handled in a thread pool.
1027 if ((rad_snmp.smux_fd >= 0) &&
1028 FD_ISSET(rad_snmp.smux_fd, &readfds) &&
1029 (rad_snmp.smux_event == SMUX_READ)) {
1034 * If we've got to re-connect, then do so now,
1035 * before calling select again.
1037 if (rad_snmp.smux_event == SMUX_CONNECT) {
1043 * After processing all new requests,
1044 * check if we've got to delete old requests
1045 * from the request list.
1047 tv = rad_clean_list(time(NULL));
1049 } /* loop forever */
1054 * Process supported requests:
1056 * PW_AUTHENTICATION_REQUEST - Authentication request from
1057 * a client network access server.
1059 * PW_ACCOUNTING_REQUEST - Accounting request from
1060 * a client network access server.
1062 * PW_AUTHENTICATION_ACK
1063 * PW_AUTHENTICATION_REJECT
1064 * PW_ACCOUNTING_RESPONSE - Reply from a remote Radius server.
1065 * Relay reply back to original NAS.
1068 int rad_process(REQUEST *request, int dospawn)
1070 RAD_REQUEST_FUNP fun;
1074 assert(request->magic == REQUEST_MAGIC);
1076 switch(request->packet->code) {
1078 radlog(L_ERR, "Unknown packet type %d from client %s:%d "
1079 "- ID %d : IGNORED", request->packet->code,
1080 client_name(request->packet->src_ipaddr), request->packet->src_port,
1081 request->packet->id);
1082 request_free(&request);
1086 case PW_AUTHENTICATION_REQUEST:
1088 * Check for requests sent to the wrong port,
1089 * and ignore them, if so.
1091 if (request->packet->sockfd != authfd) {
1092 radlog(L_ERR, "Authentication-Request sent to a non-authentication port from "
1093 "client %s:%d - ID %d : IGNORED",
1094 client_name(request->packet->src_ipaddr), request->packet->src_port,
1095 request->packet->id);
1096 request_free(&request);
1099 fun = rad_authenticate;
1102 case PW_ACCOUNTING_REQUEST:
1104 * Check for requests sent to the wrong port,
1105 * and ignore them, if so.
1107 if (request->packet->sockfd != acctfd) {
1108 radlog(L_ERR, "Accounting-Request packet sent to a non-accounting port from "
1109 "client %s:%d - ID %d : IGNORED",
1110 client_name(request->packet->src_ipaddr), request->packet->src_port,
1111 request->packet->id);
1112 request_free(&request);
1115 fun = rad_accounting;
1118 case PW_AUTHENTICATION_ACK:
1119 case PW_AUTHENTICATION_REJECT:
1120 case PW_ACCOUNTING_RESPONSE:
1122 * Replies NOT sent to the proxy port get an
1123 * error message logged, and the packet is
1126 if (request->packet->sockfd != proxyfd) {
1127 radlog(L_ERR, "Reply packet code %d sent to a non-proxy reply port from "
1128 "client %s:%d - ID %d : IGNORED", request->packet->code,
1129 client_name(request->packet->src_ipaddr), request->packet->src_port,
1130 request->packet->id);
1131 request_free(&request);
1134 if (request->packet->code != PW_ACCOUNTING_RESPONSE) {
1135 fun = rad_authenticate;
1137 fun = rad_accounting;
1141 case PW_PASSWORD_REQUEST:
1143 * We don't support this anymore.
1145 radlog(L_ERR, "Deprecated password change request from client %s:%d - ID %d : IGNORED",
1146 client_name(request->packet->src_ipaddr), request->packet->src_port,
1147 request->packet->id);
1148 request_free(&request);
1154 * Check for a duplicate, or error.
1155 * Throw away the the request if so.
1157 request = rad_check_list(request);
1158 if (request == NULL) {
1162 assert(request->magic == REQUEST_MAGIC);
1165 * The request passes many of our sanity checks. From
1166 * here on in, if anything goes wrong, we send a reject
1167 * message, instead of dropping the packet.
1169 * Build the reply template from the request template.
1171 if (!request->reply) {
1172 if ((request->reply = rad_alloc(0)) == NULL) {
1173 radlog(L_ERR, "No memory");
1176 request->reply->sockfd = request->packet->sockfd;
1177 request->reply->dst_ipaddr = request->packet->src_ipaddr;
1178 request->reply->dst_port = request->packet->src_port;
1179 request->reply->id = request->packet->id;
1180 request->reply->code = 0; /* UNKNOWN code */
1181 memcpy(request->reply->vector, request->packet->vector, sizeof(request->reply->vector));
1182 request->reply->vps = NULL;
1183 request->reply->data = NULL;
1184 request->reply->data_len = 0;
1188 * If we're spawning a child thread, let it do all of
1189 * the work of handling a request, and exit.
1191 if (dospawn == TRUE) {
1193 * Maybe the spawn failed. If so, then we
1194 * trivially reject the request (because we can't
1195 * handle it), and return.
1197 if (rad_spawn_child(request, fun) < 0) {
1198 rad_reject(request);
1199 request->finished = TRUE;
1204 rad_respond(request, fun);
1209 * Reject a request, by sending a trivial reply packet.
1211 static void rad_reject(REQUEST *request)
1215 DEBUG2("Server rejecting request %d.", request->number);
1216 switch (request->packet->code) {
1218 * Accounting requests, etc. get dropped on the floor.
1220 case PW_ACCOUNTING_REQUEST:
1225 * Authentication requests get their Proxy-State
1226 * attributes copied over, and an otherwise blank
1227 * reject message sent.
1229 case PW_AUTHENTICATION_REQUEST:
1230 request->reply->code = PW_AUTHENTICATION_REJECT;
1233 * Need to copy Proxy-State from request->packet->vps
1235 vps = paircopy2(request->packet->vps, PW_PROXY_STATE);
1237 pairadd(&(request->reply->vps), vps);
1242 * If a reply exists, send it.
1244 if (request->reply->code != 0)
1245 rad_send(request->reply, request->secret);
1249 * Perform any RFC specified cleaning of outgoing replies
1251 static void rfc_clean(RADIUS_PACKET *packet)
1253 VALUE_PAIR *vps = NULL;
1255 switch (packet->code) {
1260 * Authentication REJECT's can have only
1261 * Reply-Mesaage and Proxy-State. We delete
1262 * everything other than Reply-Message, and
1263 * Proxy-State is added below, just before
1264 * the reply is sent.
1266 case PW_AUTHENTICATION_REJECT:
1267 pairmove2(&vps, &(packet->vps), PW_REPLY_MESSAGE);
1268 pairfree(&packet->vps);
1275 * FIXME: The next two functions should all
1276 * be in a module. But not until we have
1277 * more control over module execution.
1282 * Lowercase the string value of a pair.
1284 static int rad_lowerpair(REQUEST *request, VALUE_PAIR *vp) {
1289 rad_lowercase((char *)vp->strvalue);
1290 DEBUG2("rad_lowerpair: %s now '%s'", vp->name, vp->strvalue);
1295 * Remove spaces in a pair.
1297 static int rad_rmspace_pair(REQUEST *request, VALUE_PAIR *vp) {
1302 rad_rmspace((char *)vp->strvalue);
1303 vp->length = strlen((char *)vp->strvalue);
1304 DEBUG2("rad_rmspace_pair: %s now '%s'", vp->name, vp->strvalue);
1310 * Respond to a request packet.
1312 * Maybe we reply, maybe we don't.
1313 * Maybe we proxy the request to another server, or else maybe
1314 * we replicate it to another server.
1316 int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
1318 RADIUS_PACKET *packet, *original;
1320 int finished = FALSE;
1325 * Put the decoded packet into it's proper place.
1327 if (request->proxy_reply != NULL) {
1328 packet = request->proxy_reply;
1329 secret = request->proxysecret;
1330 original = request->proxy;
1332 packet = request->packet;
1333 secret = request->secret;
1337 assert(request->magic == REQUEST_MAGIC);
1340 * Decode the packet, verifying it's signature,
1341 * and parsing the attributes into structures.
1343 * Note that we do this CPU-intensive work in
1344 * a child thread, not the master. This helps to
1345 * spread the load a little bit.
1347 * Internal requests (ones that never go on the
1348 * wire) have ->data==NULL (data is the wire
1349 * format) and don't need to be "decoded"
1351 if (packet->data && rad_decode(packet, original, secret) != 0) {
1352 radlog(L_ERR, "%s", librad_errstr);
1353 rad_reject(request);
1354 goto finished_request;
1358 * For proxy replies, remove non-allowed
1359 * attributes from the list of VP's.
1361 if (request->proxy) {
1363 replicating = proxy_receive(request);
1364 switch (replicating) {
1366 /* on error just continue with next request */
1369 /* if this was a replicated request, mark it as
1370 * finished first, because it was postponed
1372 goto finished_request;
1377 * We should have a User-Name attribute now.
1379 if (request->username == NULL) {
1380 request->username = pairfind(request->packet->vps,
1385 * We have the semaphore, and have decoded the packet.
1386 * Let's process the request.
1388 assert(request->magic == REQUEST_MAGIC);
1391 * FIXME: All this lowercase/nospace junk will be moved
1392 * into a module after module failover is fully in place
1394 * See if we have to lower user/pass before processing
1396 if(strcmp(mainconfig.do_lower_user, "before") == 0)
1397 rad_lowerpair(request, request->username);
1398 if(strcmp(mainconfig.do_lower_pass, "before") == 0)
1399 rad_lowerpair(request, rad_getpass(request));
1401 if(strcmp(mainconfig.do_nospace_user, "before") == 0)
1402 rad_rmspace_pair(request, request->username);
1403 if(strcmp(mainconfig.do_nospace_pass, "before") == 0)
1404 rad_rmspace_pair(request, rad_getpass(request));
1408 /* See if we have to lower user/pass after processing */
1409 if(strcmp(mainconfig.do_lower_user, "after") == 0) {
1410 rad_lowerpair(request, request->username);
1413 if(strcmp(mainconfig.do_lower_pass, "after") == 0) {
1414 rad_lowerpair(request, rad_getpass(request));
1417 if(strcmp(mainconfig.do_nospace_user, "after") == 0) {
1418 rad_rmspace_pair(request, request->username);
1421 if(strcmp(mainconfig.do_nospace_pass, "after") == 0) {
1422 rad_rmspace_pair(request, rad_getpass(request));
1426 /* Reprocess if we rejected last time */
1427 if ((fun == rad_authenticate) &&
1428 (request->reply->code == PW_AUTHENTICATION_REJECT) &&
1430 pairfree(&request->config_items);
1435 * If we don't already have a proxy
1436 * packet for this request, we MIGHT have
1439 if (proxy_requests) {
1440 if (request->proxy == NULL) {
1441 proxy_sent = proxy_send(request);
1444 * sent==1 means it's been proxied. The child
1445 * is done handling the request, but the request
1448 if (proxy_sent == 1) {
1449 finished = request->finished;
1450 goto postpone_request;
1453 } else if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
1454 (request->reply->code == 0)) {
1456 * We're not configured to reply to the packet,
1457 * and we're not proxying, so the DEFAULT behaviour
1458 * is to REJECT the user.
1460 DEBUG2("There was no response configured: rejecting request %d", request->number);
1461 rad_reject(request);
1462 goto finished_request;
1466 * If we have a reply to send, copy the Proxy-State
1467 * attributes from the request to the tail of the reply,
1468 * and send the packet.
1470 assert(request->magic == REQUEST_MAGIC);
1471 if (request->reply->code != 0) {
1472 VALUE_PAIR *vp = NULL;
1475 * Perform RFC limitations on outgoing replies.
1477 rfc_clean(request->reply);
1480 * Need to copy Proxy-State from request->packet->vps
1482 vp = paircopy2(request->packet->vps, PW_PROXY_STATE);
1484 pairadd(&(request->reply->vps), vp);
1486 rad_send(request->reply, request->secret);
1490 * We're done processing the request, set the
1491 * request to be finished, clean up as necessary,
1492 * and forget about the request.
1498 * We're done handling the request. Free up the linked
1499 * lists of value pairs. This might take a long time,
1500 * so it's more efficient to do it in a child thread,
1501 * instead of in the main handler when it eventually
1502 * gets around to deleting the request.
1504 * Also, no one should be using these items after the
1505 * request is finished, and the reply is sent. Cleaning
1506 * them up here ensures that they're not being used again.
1508 * Hmm... cleaning them up in the child thread also seems
1509 * to make the server run more efficiently!
1513 * If we proxied this request, it's not safe to delete it until
1514 * after the proxy reply.
1516 * However, we DO mark the request as no longer being handled
1520 finished = request->finished;
1521 goto postpone_request;
1524 if (request->packet) {
1525 pairfree(&request->packet->vps);
1526 request->username = NULL;
1527 request->password = NULL;
1531 * If we've sent a reply to the NAS, then this request is
1532 * pretty much finished, and we have no more need for any
1533 * of the value-pair's in it, including the proxy stuff.
1535 if (request->reply->code != 0) {
1536 pairfree(&request->reply->vps);
1538 pairfree(&request->config_items);
1539 if (request->proxy) {
1540 pairfree(&request->proxy->vps);
1542 if (request->proxy_reply) {
1543 pairfree(&request->proxy_reply->vps);
1546 DEBUG2("Finished request %d", request->number);
1550 * Go to the next request, without marking
1551 * the current one as finished.
1554 DEBUG2("Going to the next request");
1559 * We are finished with the child thread. The thread is detached,
1560 * so that when it exits, there's nothing more for the server
1563 * If we're running with thread pools, then this frees up the
1564 * thread in the pool for another request.
1566 request->child_pid = NO_SUCH_CHILD_PID;
1568 request->finished = finished; /* do as the LAST thing before exiting */
1572 typedef struct rad_walk_t {
1578 * Clean up the request list, every so often.
1580 * This is done by walking through ALL of the list, and
1581 * - marking any requests which are finished, and expired
1582 * - killing any processes which are NOT finished after a delay
1583 * - deleting any marked requests.
1585 static REQUEST *last_request = NULL;
1586 static struct timeval *rad_clean_list(time_t now)
1589 * Static variables, so that we don't do all of this work
1590 * more than once per second.
1592 * Note that we have 'tv' and 'last_tv'. 'last_tv' is
1593 * pointed to by 'last_tv_ptr', and depending on the
1594 * system implementation of select(), it MAY be modified.
1596 * In that was, we want to use the ORIGINAL value, from
1597 * 'tv', and wipe out the (possibly modified) last_tv.
1599 static time_t last_cleaned_list = 0;
1600 static struct timeval tv, *last_tv_ptr = NULL;
1601 static struct timeval last_tv;
1609 * If we've already set up the timeout or cleaned the
1610 * request list this second, then don't do it again. We
1611 * simply return the sleep delay from last time.
1613 * Note that if we returned NULL last time, there was nothing
1614 * to do. BUT we've been woken up since then, which can only
1615 * happen if we received a packet. And if we've received a
1616 * packet, then there's some work to do in the future.
1618 * FIXME: We can probably use gettimeofday() for finer clock
1619 * resolution, as the current method will cause it to sleep
1622 if ((last_tv_ptr != NULL) &&
1623 (last_cleaned_list == now) &&
1628 * If we're NOT walking the entire request list,
1629 * then we want to iteratively check the request
1632 * If there is NO previous request, go look for one.
1635 last_request = rl_next(last_request);
1638 * On average, there will be one request per
1639 * 'cleanup_delay' requests, which needs to be
1642 * And only do this servicing, if we have a request
1646 for (i = 0; i < cleanup_delay; i++) {
1650 * This function call MAY delete the
1651 * request pointed to by 'last_request'.
1653 next = rl_next(last_request);
1654 refresh_request(last_request, &info);
1655 last_request = next;
1658 * Nothing to do any more, exit.
1665 DEBUG2("Waking up in %d seconds...",
1666 (int) last_tv_ptr->tv_sec);
1669 last_cleaned_list = now;
1670 last_request = NULL;
1671 DEBUG2("--- Walking the entire request list ---");
1673 #if WITH_THREAD_POOL
1675 * Only clean the thread pool if we've spawned child threads.
1678 thread_pool_clean(now);
1683 * Hmmm... this is Big Magic. We make it seem like
1684 * there's an additional second to wait, for a whole
1685 * host of reasons which I can't explain adequately,
1686 * but which cause the code to Just Work Right.
1690 rl_walk(refresh_request, &info);
1693 * We haven't found a time at which we need to wake up.
1694 * Return NULL, so that the select() call will sleep forever.
1696 if (info.smallest < 0) {
1697 DEBUG2("Nothing to do. Sleeping until we see a request.");
1702 * Set the time (in seconds) for how long we're
1703 * supposed to sleep.
1705 tv.tv_sec = info.smallest;
1707 DEBUG2("Waking up in %d seconds...", (int) info.smallest);
1710 * Remember how long we should sleep for.
1713 last_tv_ptr = &last_tv;
1718 * Walk through the request list, cleaning up complete child
1719 * requests, and verifing that there is only one process
1720 * responding to each request (duplicate requests are filtered
1723 * Also, check if the request is a reply from a request proxied to
1724 * a remote server. If so, play games with the request, and return
1727 static REQUEST *rad_check_list(REQUEST *request)
1733 * If the request has come in on the proxy FD, then
1734 * it's a proxy reply, so pass it through the proxy
1735 * code for checking the REQUEST list.
1737 if (request->packet->sockfd == proxyfd) {
1738 return proxy_check_list(request);
1741 * If the request already has a proxy packet,
1742 * then it obviously is not a new request, either.
1744 } else if (request->proxy != NULL) {
1748 now = request->timestamp; /* good enough for our purposes */
1751 * Look for an existing copy of this request.
1753 curreq = rl_find(request);
1754 if (curreq != NULL) {
1756 * We now check the authentication vectors.
1757 * If the client has sent us a request with
1758 * identical code && ID, but different vector,
1759 * then they MUST have gotten our response, so
1760 * we can delete the original request, and process
1763 * If the vectors are the same, then it's a duplicate
1764 * request, and we can send a duplicate reply.
1766 if (memcmp(curreq->packet->vector, request->packet->vector,
1767 sizeof(request->packet->vector)) == 0) {
1769 * Maybe we've saved a reply packet. If so,
1770 * re-send it. Otherwise, just complain.
1772 if ((curreq->reply) && (curreq->reply->code != 0)) {
1773 radlog(L_INFO, "Sending duplicate authentication reply"
1774 " to client %s:%d - ID: %d", client_name(curreq->packet->src_ipaddr),
1775 curreq->packet->src_port, curreq->packet->id);
1777 rad_send(curreq->reply, curreq->secret);
1780 * There's no reply, but maybe there's
1781 * an outstanding proxy request.
1783 * If so, then kick the proxy again.
1785 } else if (curreq->proxy != NULL) {
1786 if (proxy_synchronous) {
1787 if (!curreq->proxy_reply) {
1788 DEBUG2("Sending duplicate proxy request to client %s:%d - ID: %d",
1789 client_name(curreq->proxy->dst_ipaddr), request->packet->src_port,
1792 curreq->proxy_next_try = request->timestamp + proxy_retry_delay;
1793 rad_send(curreq->proxy, curreq->proxysecret);
1795 DEBUG2("Ignoring duplicate authentication packet"
1796 " from client %s:%d - ID: %d, as the proxy reply is currently being processed.",
1797 client_name(request->packet->src_ipaddr),
1798 request->packet->src_port,
1799 request->packet->id);
1802 DEBUG2("Ignoring duplicate authentication packet"
1803 " from client %s:%d - ID: %d, due to outstanding proxy request.",
1804 client_name(request->packet->src_ipaddr),
1805 request->packet->src_port,
1806 request->packet->id);
1810 * This request wasn't proxied.
1812 radlog(L_ERR, "Dropping duplicate authentication packet"
1813 " from client %s:%d - ID: %d", client_name(request->packet->src_ipaddr),
1814 request->packet->src_port, request->packet->id);
1818 * Delete the duplicate request.
1820 request_free(&request);
1824 * The packet vectors are different, so
1825 * we can delete the old request from
1828 } else if (curreq->finished) {
1829 if (last_request == curreq) {
1830 last_request = rl_next(last_request);
1835 * ??? the client sent us a new request
1836 * with the same ID, while we were
1837 * processing the old one! What should
1840 * Right now, we just drop the new packet..
1843 radlog(L_ERR, "Dropping conflicting authentication packet"
1844 " from client %s:%d - ID: %d",
1845 client_name(request->packet->src_ipaddr),
1846 request->packet->src_port,
1847 request->packet->id);
1848 request_free(&request);
1851 } /* a similar packet already exists. */
1854 * Count the total number of requests, to see if there
1855 * are too many. If so, return with an error.
1858 int request_count = rl_num_requests();
1861 * This is a new request. Let's see if it
1862 * makes us go over our configured bounds.
1864 if (request_count > max_requests) {
1865 radlog(L_ERR, "Dropping request (%d is too many): "
1866 "from client %s:%d - ID: %d", request_count,
1867 client_name(request->packet->src_ipaddr),
1868 request->packet->src_port,
1869 request->packet->id);
1870 radlog(L_INFO, "WARNING: Please check the radiusd.conf file.\n"
1871 "\tThe value for 'max_requests' is probably set too low.\n");
1872 request_free(&request);
1878 * Add this request to the list
1883 * And return the request to be handled.
1888 #ifndef WITH_THREAD_POOL
1890 typedef struct spawn_thread_t {
1892 RAD_REQUEST_FUNP fun;
1896 * Spawn a new child thread to handle this request, and ONLY
1899 static void *rad_spawn_thread(void *arg)
1901 spawn_thread_t *data = (spawn_thread_t *)arg;
1903 pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
1905 rad_respond(data->request, data->fun);
1913 * If we're using the thread pool, then the function in
1914 * 'threads.c' replaces this one.
1916 #ifndef WITH_THREAD_POOL
1918 * Spawns a child process or thread to perform
1919 * authentication/accounting and respond to RADIUS clients.
1921 static int rad_spawn_child(REQUEST *request, RAD_REQUEST_FUNP fun)
1923 child_pid_t child_pid;
1926 /* spawning and registering a child is a critical section, so
1927 * we refuse to handle SIGCHLDs normally until we're finished. */
1928 signal(SIGCHLD, queue_sig_cleanup);
1933 spawn_thread_t *data;
1934 pthread_attr_t attr;
1936 data = (spawn_thread_t *) rad_malloc(sizeof(spawn_thread_t));
1937 memset(data, 0, sizeof(data));
1938 data->request = request;
1942 * Initialize the thread's attributes to detached.
1944 * We could call pthread_detach() later, but if
1945 * the thread exits between the create & detach
1946 * calls, it will need to be joined, which will
1949 pthread_attr_init(&attr);
1950 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1953 * Create a child thread, complaining on error.
1955 rcode = pthread_create(&request->child_pid, &attr,
1956 rad_spawn_thread, data);
1958 radlog(L_ERR, "Thread create failed for request from nas %s - ID: %d : %s",
1959 nas_name2(request->packet), request->packet->id,
1962 goto exit_child_critsec;
1964 pthread_attr_destroy(&attr);
1971 if (child_pid < 0) {
1972 radlog(L_ERR, "Fork failed for request from nas %s - ID: %d",
1973 nas_name2(request->packet),
1974 request->packet->id);
1976 goto exit_child_critsec;
1979 if (child_pid == 0) {
1982 * This is the child, it should go ahead and respond
1984 signal(SIGCHLD, SIG_DFL);
1985 rad_respond(request, fun);
1990 * Register the Child
1992 request->child_pid = child_pid;
1996 signal(SIGCHLD, sig_cleanup);
1997 if (needs_child_cleanup > 0) {
2002 #endif /* WITH_THREAD_POOL */
2005 #ifndef HAVE_PTHREAD_H
2006 static int sig_cleanup_walker(REQUEST *req, void *data)
2008 int pid = (int)data;
2009 if ( req->child_pid != pid ) {
2010 return RL_WALK_CONTINUE;
2012 req->child_pid = NO_SUCH_CHILD_PID;
2017 /* used in critical section */
2018 void queue_sig_cleanup(int sig) {
2019 sig = sig; /* -Wunused */
2020 needs_child_cleanup++;
2026 void sig_cleanup(int sig)
2028 #ifndef HAVE_PTHREAD_H
2034 sig = sig; /* -Wunused */
2038 needs_child_cleanup = 0; /* reset the queued cleanup number */
2041 * Reset the signal handler, if required.
2043 reset_signal(SIGCHLD, sig_cleanup);
2046 * If we're using pthreads, then there are NO child processes,
2047 * so the waitpid() call, and the following code, is useless.
2049 #ifndef HAVE_PTHREAD_H
2051 pid = waitpid((pid_t)-1, &status, WNOHANG);
2056 * Check to see if the child did a bad thing.
2057 * If so, kill ALL processes in the current
2058 * process group, to prevent further attacks.
2060 if (debug_flag && (WIFSIGNALED(status))) {
2061 radlog(L_ERR|L_CONS, "MASTER: Child PID %d failed to catch "
2062 "signal %d: killing all active servers.\n",
2063 pid, WTERMSIG(status));
2069 * Loop over ALL of the active requests, looking
2070 * for the one which caused the signal.
2072 if (rl_walk(sig_cleanup_walker, (void*)pid) != 0) {
2073 radlog(L_ERR, "Failed to cleanup child %d", pid);
2077 #endif /* !defined HAVE_PTHREAD_H */
2081 * Display the syntax for starting this program.
2083 static void usage(void)
2086 "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-p port] [-"
2087 #if defined(WITH_DBM) || defined(WITH_NDBM)
2090 "AcfnsSvXxyz]\n", progname);
2091 fprintf(stderr, "Options:\n\n");
2092 fprintf(stderr, " -a acct_dir use accounting directory 'acct_dir'.\n");
2093 fprintf(stderr, " -A Log auth detail.\n");
2094 #if defined(WITH_DBM) || defined(WITH_NDBM)
2095 fprintf(stderr, " -b Use DBM.\n");
2097 fprintf(stderr, " -d db_dir Use database directory 'db_dir'.\n");
2098 fprintf(stderr, " -f Run as a foreground process, not a daemon.\n");
2099 fprintf(stderr, " -h Print this help message.\n");
2100 fprintf(stderr, " -i address Listen only in the given IP address.\n");
2101 fprintf(stderr, " -l log_dir Log messages to 'log_dir'. Special values are:\n");
2102 fprintf(stderr, " stdout == log all messages to standard output.\n");
2103 fprintf(stderr, " syslog == log all messages to the system logger.\n");
2104 fprintf(stderr, " -p port Bind to 'port', and not to the radius/udp, or 1646/udp.\n");
2105 fprintf(stderr, " -s Do not spawn child processes to handle requests.\n");
2106 fprintf(stderr, " -S Log stripped names.\n");
2107 fprintf(stderr, " -v Print server version information.\n");
2108 fprintf(stderr, " -X Turn on full debugging. (Means: -sfxxyz -l stdout)\n");
2109 fprintf(stderr, " -x Turn on partial debugging. (-xx gives more debugging).\n");
2110 fprintf(stderr, " -y Log authentication failures, with password.\n");
2111 fprintf(stderr, " -z Log authentication successes, with password.\n");
2117 * We got a fatal signal. Clean up and exit.
2119 static void sig_fatal(int sig)
2121 const char *me = "MASTER: ";
2123 if (radius_pid != getpid()) {
2129 radlog(L_ERR, "%sfailed in select() - exit.", me);
2132 radlog(L_INFO, "%sexit.", me);
2135 radlog(L_ERR, "%sexit on signal (%d)", me, sig);
2140 * We're running as a daemon, we're the MASTER daemon,
2141 * and we got a fatal signal. Tear the rest of the
2142 * daemons down, as something absolutely horrible happened.
2144 if ((debug_flag == 0) && (dont_fork == 0) &&
2145 (radius_pid == getpid())) {
2147 * Kill all of the processes in the current
2153 exit(sig == SIGTERM ? 0 : 1);
2158 * We got the hangup signal.
2159 * Re-read the configuration files.
2162 static void sig_hup(int sig)
2164 sig = sig; /* -Wunused */
2165 reset_signal(SIGHUP, sig_hup);
2168 * Only do the reload if we're the main server, both
2169 * for processes, and for threads.
2171 if (getpid() == radius_pid) {
2175 rad_snmp.smux_failures = 0;
2176 rad_snmp.smux_event = SMUX_CONNECT;
2181 * Do a proxy check of the REQUEST list when using the new proxy code.
2183 static REQUEST *proxy_check_list(REQUEST *request)
2188 * Find the original request in the request list
2190 oldreq = rl_find_proxy(request);
2193 * If there is already a reply,
2194 * maybe the new one is a duplicate?
2196 if (oldreq->proxy_reply) {
2197 if (memcmp(oldreq->proxy_reply->vector,
2198 request->packet->vector,
2199 sizeof(oldreq->proxy_reply->vector)) == 0) {
2200 DEBUG2("Ignoring duplicate proxy reply");
2201 request_free(&request);
2205 * ??? The home server gave us a new
2206 * proxy reply, which doesn't match
2207 * the old one. Delete it!
2209 DEBUG2("Ignoring conflicting proxy reply");
2210 request_free(&request);
2217 * If we haven't found the old request, complain.
2219 radlog(L_PROXY, "No request found for proxy reply from server %s - ID %d",
2220 client_name(request->packet->src_ipaddr),
2221 request->packet->id);
2222 request_free(&request);
2227 * Refresh the old request, and update it with the proxy reply.
2229 * ??? Can we delete the proxy request here?
2230 * Is there any more need for it?
2232 oldreq->timestamp = request->timestamp;
2233 oldreq->proxy_reply = request->packet;
2234 request->packet = NULL;
2235 request_free(&request);
2240 * Refresh a request, by using proxy_retry_delay, cleanup_delay,
2241 * max_request_time, etc.
2243 * When walking over the request list, all of the per-request
2244 * magic is done here.
2246 static int refresh_request(REQUEST *request, void *data)
2248 rad_walk_t *info = (rad_walk_t *) data;
2250 child_pid_t child_pid;
2252 assert(request->magic == REQUEST_MAGIC);
2255 * If the request has finished processing,
2256 * AND it's child has been cleaned up,
2257 * AND it's time to clean up the request,
2258 * OR, it's an accounting request.
2259 * THEN, go delete it.
2261 * If this is an accounting request, we delete it
2262 * immediately, as there CANNOT be duplicate accounting
2263 * packets. If there are, then something else is
2264 * seriously wrong...
2266 if (request->finished &&
2267 (request->child_pid == NO_SUCH_CHILD_PID) &&
2268 ((request->timestamp + cleanup_delay <= info->now) ||
2269 (request->packet->code == PW_ACCOUNTING_REQUEST))) {
2271 * Request completed, delete it, and unlink it
2272 * from the currently 'alive' list of requests.
2274 DEBUG2("Cleaning up request %d ID %d with timestamp %08lx",
2275 request->number, request->packet->id,
2276 (unsigned long)request->timestamp);
2279 * Delete the request.
2282 return RL_WALK_CONTINUE;
2286 * Maybe the child process
2287 * handling the request has hung:
2288 * kill it, and continue.
2290 if ((request->timestamp + max_request_time) <= info->now) {
2293 child_pid = request->child_pid;
2294 number = request->number;
2296 if (kill_unresponsive_children) {
2297 if (child_pid != NO_SUCH_CHILD_PID) {
2299 * This request seems to have hung
2302 #if WITH_THREAD_POOL || HAVE_PTHREAD_H
2303 radlog(L_ERR, "Killing unresponsive thread for request %d",
2305 pthread_cancel(child_pid);
2307 radlog(L_ERR, "Killing unresponsive child %lu for request %d",
2308 child_pid, request->number);
2309 kill(child_pid, SIGTERM);
2311 } /* else no proxy reply, quietly fail */
2314 * Delete the request.
2317 child_pid = NO_SUCH_CHILD_PID; /* mark it as deleted. */
2320 * Maybe we haven't killed it. In that case, print
2323 } else if ((child_pid != NO_SUCH_CHILD_PID) &&
2324 ((request->options & RAD_REQUEST_OPTION_LOGGED_CHILD) == 0)) {
2325 radlog(L_ERR, "WARNING: Unresponsive child (id %lu) for request %d",
2329 * Set the option that we've sent a log message,
2330 * so that we don't send more than one message
2333 request->options |= RAD_REQUEST_OPTION_LOGGED_CHILD;
2335 return RL_WALK_CONTINUE;
2339 * The request is finished.
2341 if (request->finished) goto setup_timeout;
2344 * We're not proxying requests at all.
2346 if (!proxy_requests) goto setup_timeout;
2349 * We're proxying synchronously, so we don't retry it here.
2350 * Some other code takes care of retrying the proxy requests.
2352 if (proxy_synchronous) goto setup_timeout;
2355 * The proxy retry delay is zero, meaning don't retry.
2357 if (proxy_retry_delay == 0) goto setup_timeout;
2360 * There is no proxied request for this packet, so there's
2363 if (!request->proxy) goto setup_timeout;
2366 * We've already seen the proxy reply, so we don't need
2367 * to send another proxy request.
2369 if (request->proxy_reply) goto setup_timeout;
2372 * It's not yet time to re-send this proxied request.
2374 if (request->proxy_next_try > info->now) goto setup_timeout;
2377 * If the proxy retry count is zero, then
2378 * we've sent the last try, and have NOT received
2379 * a reply from the end server. In that case,
2380 * we don't bother trying again, but just mark
2381 * the request as finished, and go to the next one.
2383 if (request->proxy_try_count == 0) {
2384 request->finished = TRUE;
2385 rad_reject(request);
2390 * We're trying one more time, so count down
2391 * the tries, and set the next try time.
2393 request->proxy_try_count--;
2394 request->proxy_next_try = info->now + proxy_retry_delay;
2396 /* Fix up Acct-Delay-Time */
2397 if (request->proxy->code == PW_ACCOUNTING_REQUEST) {
2398 VALUE_PAIR *delaypair;
2399 delaypair = pairfind(request->proxy->vps, PW_ACCT_DELAY_TIME);
2402 delaypair = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
2404 radlog(L_ERR|L_CONS, "no memory");
2407 pairadd(&request->proxy->vps, delaypair);
2409 delaypair->lvalue = info->now - request->proxy->timestamp;
2411 /* Must recompile the valuepairs to wire format */
2412 free(request->proxy->data);
2413 request->proxy->data = NULL;
2414 } /* proxy accounting request */
2417 * Assert that we have NOT seen the proxy reply yet.
2419 * If we HAVE seen it, then we SHOULD NOT be bugging the
2422 assert(request->proxy_reply == NULL);
2425 * Send the proxy packet.
2427 rad_send(request->proxy, request->proxysecret);
2431 * Don't do more long-term checks, if we've got to wake
2434 if (info->smallest == 0) {
2435 return RL_WALK_CONTINUE;
2439 * The request is finished. Wake up when it's time to
2442 if (request->finished) {
2443 difference = (request->timestamp + cleanup_delay) - info->now;
2445 } else if (request->proxy && !request->proxy_reply) {
2447 * The request is NOT finished, but there is an
2448 * outstanding proxy request, with no matching
2451 * Wake up when it's time to re-send
2452 * the proxy request.
2454 difference = request->proxy_next_try - info->now;
2458 * The request is NOT finished.
2460 * Wake up when it's time to kill the errant
2463 difference = (request->timestamp + max_request_time) - info->now;
2467 * If the server is CPU starved, then we CAN miss a time
2468 * for servicing requests. In which case the 'difference'
2469 * value will be negative. select() doesn't like that,
2472 if (difference < 0) {
2477 * Update the 'smallest' time.
2479 if ((info->smallest < 0) ||
2480 (difference < info->smallest)) {
2481 info->smallest = difference;
2484 return RL_WALK_CONTINUE;