2 * radiusd.c Main loop of the radius server.
8 /* don't look here for the version, run radiusd -v or look in version.c */
9 static const char rcsid[] =
16 #include <sys/socket.h>
20 #include <netinet/in.h>
40 #include <sys/select.h>
48 # include <sys/wait.h>
51 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
54 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
63 #include "radius_snmp.h"
66 #include <sys/resource.h>
74 const char *progname = NULL;
75 char *radius_dir = NULL;
76 char *radacct_dir = NULL;
77 char *radlog_dir = NULL;
78 const char *radlib_dir = NULL;
79 int log_stripped_names;
82 uint32_t myip = INADDR_ANY;
83 int log_auth_detail = FALSE;
87 int proxy_retry_delay = RETRY_DELAY;
88 int proxy_retry_count = RETRY_COUNT;
89 int proxy_synchronous = TRUE;
90 int need_reload = FALSE;
91 struct main_config_t mainconfig;
93 static int got_child = FALSE;
94 static int request_list_busy = FALSE;
98 static int spawn_flag = TRUE;
99 static pid_t radius_pid;
100 static struct rlimit core_limits;
101 static int proxy_requests = TRUE;
104 * We keep the incoming requests in an array, indexed by ID.
106 * Each array element contains a linked list of active requests,
107 * a count of the number of requests, and a time at which the first
108 * request in the list must be serviced.
110 typedef struct REQUEST_LIST {
111 REQUEST *first_request;
113 time_t last_cleaned_list;
116 static REQUEST_LIST request_list[256];
119 * Configuration items.
121 static int allow_core_dumps = FALSE;
122 static int max_request_time = MAX_REQUEST_TIME;
123 static int cleanup_delay = CLEANUP_DELAY;
124 static int max_requests = MAX_REQUESTS;
125 static int dont_fork = FALSE;
126 static const char *pid_file = NULL;
127 static uid_t server_uid;
128 static gid_t server_gid;
129 static const char *uid_name = NULL;
130 static const char *gid_name = NULL;
132 #if !defined(__linux__) && !defined(__GNU_LIBRARY__)
136 static void usage(void);
138 static void sig_fatal (int);
139 static void sig_hup (int);
141 static void rad_reject(REQUEST *request);
142 static int rad_process (REQUEST *, int);
143 static int rad_clean_list(time_t curtime);
144 static REQUEST *rad_check_list(REQUEST *);
145 static REQUEST *proxy_check_list(REQUEST *request);
146 static struct timeval *setuptimeout();
147 static void refresh_request(REQUEST *request, time_t now);
148 #ifndef WITH_THREAD_POOL
149 static int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
151 extern int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
155 * A mapping of configuration file names to internal variables
157 static CONF_PARSER server_config[] = {
158 { "max_request_time", PW_TYPE_INTEGER,
159 &max_request_time, Stringify(MAX_REQUEST_TIME) },
160 { "cleanup_delay", PW_TYPE_INTEGER,
161 &cleanup_delay, Stringify(CLEANUP_DELAY) },
162 { "max_requests", PW_TYPE_INTEGER,
163 &max_requests, Stringify(MAX_REQUESTS) },
164 { "port", PW_TYPE_INTEGER,
165 &auth_port, Stringify(PW_AUTH_UDP_PORT) },
166 { "allow_core_dumps", PW_TYPE_BOOLEAN, &allow_core_dumps, "no" },
167 { "log_stripped_names", PW_TYPE_BOOLEAN, &log_stripped_names,"no" },
168 { "log_auth", PW_TYPE_BOOLEAN, &mainconfig.log_auth, "no" },
169 { "log_auth_badpass", PW_TYPE_BOOLEAN, &mainconfig.log_auth_badpass, "no" },
170 { "log_auth_goodpass", PW_TYPE_BOOLEAN, &mainconfig.log_auth_goodpass, "no" },
171 { "pidfile", PW_TYPE_STRING_PTR, &pid_file, "${run_dir}/radiusd.pid"},
172 { "bind_address", PW_TYPE_IPADDR, &myip, "*" },
173 { "proxy_requests", PW_TYPE_BOOLEAN, &proxy_requests, "yes" },
174 { "user", PW_TYPE_STRING_PTR, &uid_name, NULL},
175 { "group", PW_TYPE_STRING_PTR, &gid_name, NULL},
176 { "usercollide", PW_TYPE_BOOLEAN, &mainconfig.do_usercollide, "no" },
177 { "lower_user", PW_TYPE_BOOLEAN, &mainconfig.do_lower_user, "no" },
178 { "lower_pass", PW_TYPE_BOOLEAN, &mainconfig.do_lower_pass, "no" },
179 { "lower_time", PW_TYPE_STRING_PTR, &mainconfig.lower_time, "before" },
180 { "nospace_user", PW_TYPE_BOOLEAN, &mainconfig.do_nospace_user, "no" },
181 { "nospace_pass", PW_TYPE_BOOLEAN, &mainconfig.do_nospace_pass, "no" },
182 { "nospace_time", PW_TYPE_STRING_PTR, &mainconfig.nospace_time, "before" },
183 { NULL, -1, NULL, NULL }
187 * Map the proxy server configuration parameters to variables.
189 static CONF_PARSER proxy_config[] = {
190 { "retry_delay", PW_TYPE_INTEGER,
191 &proxy_retry_delay, Stringify(RETRY_DELAY) },
192 { "retry_count", PW_TYPE_INTEGER,
193 &proxy_retry_count, Stringify(RETRY_COUNT) },
194 { "synchronous", PW_TYPE_BOOLEAN, &proxy_synchronous, "yes" },
196 { NULL, -1, NULL, NULL }
202 static int reread_config(int reload)
208 radlog(L_INFO, "Starting - reading configuration files ...");
209 } else if (pid == radius_pid) {
210 radlog(L_INFO, "Reloading configuration files.");
213 /* First read radiusd.conf */
214 DEBUG2("reread_config: reading radiusd.conf");
215 if (read_radius_conf_file() < 0) {
216 radlog(L_ERR|L_CONS, "Errors reading radiusd.conf");
221 * And parse the server's configuration values.
223 cs = cf_section_find(NULL);
225 radlog(L_ERR|L_CONS, "No configuration information in radiusd.conf!");
228 cf_section_parse(cs, server_config);
231 * Reload the modules.
233 DEBUG2("read_config_files: entering modules setup");
234 if (setup_modules() < 0) {
235 radlog(L_ERR|L_CONS, "Errors setting up modules");
240 * Go update our behaviour, based on the configuration
243 if (allow_core_dumps) {
244 if (setrlimit(RLIMIT_CORE, &core_limits) < 0) {
245 radlog(L_ERR|L_CONS, "Cannot update core dump limit: %s",
250 * If we're running as a daemon, and core
251 * dumps are enabled, log that information.
253 } else if ((core_limits.rlim_cur != 0) && !debug_flag)
254 radlog(L_INFO, "Core dumps are enabled.");
256 } else if (!debug_flag) {
258 * Not debugging. Set the core size to zero, to
259 * prevent security breaches. i.e. People
260 * reading passwords from the 'core' file.
262 struct rlimit limits;
265 limits.rlim_max = core_limits.rlim_max;
267 if (setrlimit(RLIMIT_CORE, &limits) < 0) {
268 radlog(L_ERR|L_CONS, "Cannot disable core dumps: %s",
275 * Set the UID and GID, but only if we're NOT running
285 gr = getgrnam(gid_name);
287 radlog(L_ERR|L_CONS, "Cannot switch to Group %s: %s", gid_name, strerror(errno));
290 server_gid = gr->gr_gid;
291 if (setgid(server_gid) < 0) {
292 radlog(L_ERR|L_CONS, "Failed setting Group to %s: %s", gid_name, strerror(errno));
303 pw = getpwnam(uid_name);
305 radlog(L_ERR|L_CONS, "Cannot switch to User %s: %s", uid_name, strerror(errno));
308 server_uid = pw->pw_uid;
309 if (setuid(server_uid) < 0) {
310 radlog(L_ERR|L_CONS, "Failed setting User to %s: %s", uid_name, strerror(errno));
318 * Parse the server's proxy configuration values.
320 if ((proxy_requests) &&
321 ((cs = cf_section_find("proxy")) != NULL)) {
322 cf_section_parse(cs, proxy_config);
329 * Parse a string into a syslog facility level.
331 static int str2fac(const char *s)
334 if(!strcmp(s, "kern"))
339 if(!strcmp(s, "user"))
344 if(!strcmp(s, "mail"))
349 if(!strcmp(s, "daemon"))
354 if(!strcmp(s, "auth"))
359 if(!strcmp(s, "auth"))
364 if(!strcmp(s, "lpr"))
369 if(!strcmp(s, "news"))
374 if(!strcmp(s, "uucp"))
379 if(!strcmp(s, "cron"))
384 if(!strcmp(s, "authpriv"))
389 if(!strcmp(s, "ftp"))
394 if(!strcmp(s, "local0"))
399 if(!strcmp(s, "local1"))
404 if(!strcmp(s, "local2"))
409 if(!strcmp(s, "local3"))
414 if(!strcmp(s, "local4"))
419 if(!strcmp(s, "local5"))
424 if(!strcmp(s, "local6"))
429 if(!strcmp(s, "local7"))
434 fprintf(stderr, "%s: Error: Unknown syslog facility: %s\n",
439 /* this should never be reached */
443 int main(int argc, char **argv)
446 RADIUS_PACKET *packet;
448 unsigned char buffer[4096];
449 struct sockaddr salocal;
450 struct sockaddr_in *sa;
460 int syslog_facility = LOG_DAEMON;
465 set_auth_parameters(argc,argv);
469 * Open /dev/null, and make sure filedescriptors
470 * 0, 1 and 2 are connected to something.
473 while (devnull >= 0 && devnull < 3)
474 devnull = open("/dev/null", O_RDWR);
476 if ((progname = strrchr(argv[0], '/')) == NULL)
483 radius_dir = strdup(RADIUS_DIR);
485 signal(SIGHUP, sig_hup);
486 signal(SIGINT, sig_fatal);
487 signal(SIGQUIT, sig_fatal);
489 signal(SIGPIPE, SIG_IGN);
492 signal(SIGTRAP, sig_fatal);
495 signal(SIGIOT, sig_fatal);
499 * Pooled threads and child threads define their own
502 #ifndef WITH_THREAD_POOL
503 #ifndef HAVE_PTHREAD_H
504 signal(SIGTERM, sig_fatal);
507 signal(SIGCHLD, sig_cleanup);
509 signal(SIGFPE, sig_fatal);
510 signal(SIGSEGV, sig_fatal);
511 signal(SIGILL, sig_fatal);
515 * Close unused file descriptors.
517 for (t = 32; t >= 3; t--)
518 if(t!=devnull) close(t);
521 * Process the options.
523 while((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:p:sSvxXyz")) != EOF) {
528 log_auth_detail = TRUE;
532 if (radacct_dir) free(radacct_dir);
533 radacct_dir = strdup(optarg);
536 #if defined(WITH_DBM) || defined(WITH_NDBM)
542 /* ignore for backwards compatibility with Cistron */
546 if (radius_dir) free(radius_dir);
547 radius_dir = strdup(optarg);
559 if ((myip = ip_getaddr(optarg)) == INADDR_NONE) {
560 fprintf(stderr, "radiusd: %s: host unknown\n",
567 if (radlog_dir) free(radlog_dir);
568 radlog_dir = strdup(optarg);
572 * We should also have this as a configuration
576 syslog_facility = str2fac(optarg);
580 log_stripped_names++;
584 radius_port = atoi(optarg);
587 case 's': /* Single process mode */
596 * BIG debugging mode for users who are
597 * TOO LAZY to type '-sfxxyz -l stdout' themselves.
604 mainconfig.log_auth = TRUE;
605 mainconfig.log_auth_badpass = TRUE;
606 mainconfig.log_auth_goodpass = TRUE;
607 radlog_dir = strdup("stdout");
616 mainconfig.log_auth = TRUE;
617 mainconfig.log_auth_badpass = TRUE;
621 mainconfig.log_auth_badpass = TRUE;
622 mainconfig.log_auth_goodpass = TRUE;
632 * Get out PID: the configuration file reader uses it.
634 radius_pid = getpid();
637 * Get the current maximum for core files.
639 if (getrlimit(RLIMIT_CORE, &core_limits) < 0) {
640 radlog(L_ERR|L_CONS, "Failed to get current core limit:"
641 " %s", strerror(errno));
646 * Read the configuration files, BEFORE doing anything else.
648 if (reread_config(0) < 0) {
654 * If they asked for syslog, then give it to them.
655 * Also, initialize the logging facility with the
656 * configuration that they asked for.
658 if (!strcmp(radlog_dir, "syslog")) {
659 openlog(progname, LOG_PID, syslog_facility);
661 /* Do you want a warning if -g is used without a -l to activate it? */
665 * Initialize the request_list[] array.
667 for (i = 0; i < 256; i++) {
668 request_list[i].first_request = NULL;
669 request_list[i].request_count = 0;
670 request_list[i].last_cleaned_list = 0;
674 * We prefer (in order) the port from the command-line,
675 * then the port from the configuration file, then
676 * the port that the system names "radius", then
680 auth_port = radius_port;
681 } /* else auth_port is set from the config file */
684 * Maybe auth_port *wasn't* set from the config file,
685 * or the config file set it to zero.
688 if (auth_port == 0) {
689 svp = getservbyname ("radius", "udp");
691 auth_port = ntohs(svp->s_port);
694 * We're getting auth_port from
695 * /etc/services, get acct_port from
698 svp = getservbyname ("radacct", "udp");
699 if (svp) acct_port = ntohs(svp->s_port);
701 auth_port = PW_AUTH_UDP_PORT;
706 * Open Authentication socket.
709 authfd = socket (AF_INET, SOCK_DGRAM, 0);
711 perror("auth socket");
715 sa = (struct sockaddr_in *) & salocal;
716 memset ((char *) sa, '\0', sizeof (salocal));
717 sa->sin_family = AF_INET;
718 sa->sin_addr.s_addr = myip;
719 sa->sin_port = htons(auth_port);
721 result = bind (authfd, & salocal, sizeof (*sa));
723 perror ("auth bind");
728 * Open Accounting Socket.
730 * If we haven't already gotten acct_port from /etc/services,
731 * then make it auth_port + 1.
734 acct_port = auth_port + 1;
736 acctfd = socket (AF_INET, SOCK_DGRAM, 0);
738 perror ("acct socket");
742 sa = (struct sockaddr_in *) & salocal;
743 memset ((char *) sa, '\0', sizeof (salocal));
744 sa->sin_family = AF_INET;
745 sa->sin_addr.s_addr = myip;
746 sa->sin_port = htons(acct_port);
748 result = bind (acctfd, & salocal, sizeof (*sa));
750 perror ("acct bind");
755 * If we're proxying requests, open the proxy FD.
756 * Otherwise, don't do anything.
758 if (proxy_requests) {
762 proxyfd = socket (AF_INET, SOCK_DGRAM, 0);
764 perror ("proxy socket");
768 sa = (struct sockaddr_in *) & salocal;
769 memset ((char *) sa, '\0', sizeof (salocal));
770 sa->sin_family = AF_INET;
771 sa->sin_addr.s_addr = myip;
774 * Set the proxy port to be one more than the
777 for (proxy_port = acct_port + 1; proxy_port < 64000; proxy_port++) {
778 sa->sin_port = htons(proxy_port);
779 result = bind (proxyfd, & salocal, sizeof (*sa));
786 * Couldn't find a port to which we could bind.
788 if (proxy_port == 64000) {
789 perror("proxy bind");
795 * NOT proxying requests, set the FD to a bad value.
802 * Register built-in compare functions.
804 pair_builtincompare_init();
812 * Connect 0, 1 and 2 to /dev/null.
814 if (!debug_flag && devnull >= 0) {
816 if (strcmp(radlog_dir, "stdout") != 0) {
820 if (devnull > 2) close(devnull);
825 * Disconnect from session
827 if (debug_flag == 0 && dont_fork == 0) {
830 radlog(L_ERR|L_CONS, "Couldn't fork");
835 * The parent exits, so the child can run in the background.
846 * Ensure that we're using the CORRECT pid after forking,
847 * NOT the one we started with.
849 radius_pid = getpid();
852 * Only write the PID file if we're running as a daemon.
854 * And write it AFTER we've forked, so that we write the
857 if (dont_fork == FALSE) {
860 fp = fopen(pid_file, "w");
862 fprintf(fp, "%d\n", (int) radius_pid);
865 radlog(L_ERR|L_CONS, "Failed writing process id to file %s: %s\n",
866 pid_file, strerror(errno));
872 * If we're spawning children, set up the thread pool.
880 * Use linebuffered or unbuffered stdout if
881 * the debug flag is on.
883 if (debug_flag) setlinebuf(stdout);
886 strcpy((char *)buffer, "*");
888 ip_ntoa((char *)buffer, myip);
891 if (proxy_requests) {
892 radlog(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp, with proxy on %d/udp.",
893 buffer, auth_port, acct_port, proxy_port);
895 radlog(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp.",
896 buffer, auth_port, acct_port);
900 * Note that we NO LONGER fork an accounting process!
901 * We used to do it for historical reasons, but that
904 radlog(L_INFO, "Ready to process requests.");
907 * Receive user requests
913 if (reread_config(TRUE) < 0) {
917 radlog(L_INFO, "Ready to process requests.");
922 FD_SET(authfd, &readfds);
924 FD_SET(acctfd, &readfds);
926 FD_SET(proxyfd, &readfds);
928 if (rad_snmp.smux_fd >= 0)
929 FD_SET(rad_snmp.smux_fd, &readfds);
932 status = select(32, &readfds, NULL, NULL,
937 * On interrupts, we clean up the
940 if (errno == EINTR) {
944 radlog(L_ERR, "Unexpected error in select(): %s",
950 * Loop over the open socket FD's, reading any data.
952 for (i = 0; i < 3; i++) {
954 if (i == 0) fd = authfd;
955 if (i == 1) fd = acctfd;
956 if (i == 2) fd = proxyfd;
957 if (fd < 0 || !FD_ISSET(fd, &readfds))
960 * Receive the packet.
962 packet = rad_recv(fd);
963 if (packet == NULL) {
964 radlog(L_ERR, "%s", librad_errstr);
969 rad_snmp.acct_total_requests++;
971 rad_snmp.auth_total_requests++;
975 * Check if we know this client for
976 * authfd and acctfd. Check if we know
977 * this proxy for proxyfd.
981 if ((cl = client_find(packet->src_ipaddr)) == NULL) {
982 radlog(L_ERR, "Ignoring request from unknown client %s:%d",
983 ip_ntoa(buffer, packet->src_ipaddr),
991 } else { /* It came in on the proxy port */
993 if ((rl = realm_findbyaddr(packet->src_ipaddr)) == NULL) {
994 radlog(L_ERR, "Ignoring request from unknown proxy %s:%d",
995 ip_ntoa(buffer, packet->src_ipaddr),
1000 secret = rl->secret;
1005 * Do yet another check, to see if the
1006 * packet code is valid. We only understand
1007 * a few, so stripping off obviously invalid
1008 * packets here will make our life easier.
1010 if (packet->code > PW_ACCESS_CHALLENGE) {
1011 radlog(L_ERR, "Ignoring request from client %s:%d with unknown code %d", buffer, packet->src_port, packet->code);
1016 if ((request = malloc(sizeof(REQUEST))) == NULL) {
1017 radlog(L_ERR|L_CONS, "no memory");
1020 memset(request, 0, sizeof(REQUEST));
1022 request->magic = REQUEST_MAGIC;
1024 request->packet = packet;
1025 request->proxy = NULL;
1026 request->reply = NULL;
1027 request->proxy_reply = NULL;
1028 request->config_items = NULL;
1029 request->username = NULL;
1030 request->password = NULL;
1031 request->timestamp = now;
1032 request->child_pid = NO_SUCH_CHILD_PID;
1033 request->prev = NULL;
1034 request->next = NULL;
1035 strNcpy(request->secret, (char *)secret, sizeof(request->secret));
1036 rad_process(request, spawn_flag);
1037 } /* loop over authfd, acctfd, proxyfd */
1040 * After processing all new requests,
1041 * check if we've got to delete old requests
1042 * from the request list.
1044 rad_clean_list(now);
1047 * When receiving a packet, or timeout,
1048 * service the proxy request list.
1053 * After handling all authentication/accounting
1054 * requests, THEN process any pending SMUX/SNMP
1057 * Note that the handling is done in the main server,
1058 * which probably isn't a Good Thing. It really
1059 * should be wrapped, and handled in a thread pool.
1061 if ((rad_snmp.smux_fd >= 0) &&
1062 FD_ISSET(rad_snmp.smux_fd, &readfds) &&
1063 (rad_snmp.smux_event == SMUX_READ)) {
1068 * If we've got to re-connect, then do so now,
1069 * before calling select again.
1071 if (rad_snmp.smux_event == SMUX_CONNECT) {
1075 } /* loop forever */
1080 * Process supported requests:
1082 * PW_AUTHENTICATION_REQUEST - Authentication request from
1083 * a client network access server.
1085 * PW_ACCOUNTING_REQUEST - Accounting request from
1086 * a client network access server.
1088 * PW_AUTHENTICATION_ACK
1089 * PW_AUTHENTICATION_REJECT
1090 * PW_ACCOUNTING_RESPONSE - Reply from a remote Radius server.
1091 * Relay reply back to original NAS.
1094 int rad_process(REQUEST *request, int dospawn)
1096 RAD_REQUEST_FUNP fun;
1100 assert(request->magic == REQUEST_MAGIC);
1102 switch(request->packet->code) {
1104 case PW_AUTHENTICATION_REQUEST:
1106 * Check for requests sent to the wrong port,
1107 * and ignore them, if so.
1109 if (request->packet->sockfd != authfd) {
1110 radlog(L_ERR, "Request packet code %d sent to authentication port from "
1111 "client %s:%d - ID %d : IGNORED",
1112 request->packet->code,
1113 client_name(request->packet->src_ipaddr),
1114 request->packet->src_port,
1115 request->packet->id);
1116 request_free(request);
1121 case PW_ACCOUNTING_REQUEST:
1123 * Check for requests sent to the wrong port,
1124 * and ignore them, if so.
1126 if (request->packet->sockfd != acctfd) {
1127 radlog(L_ERR, "Request packet code %d sent to accounting port from "
1128 "client %s:%d - ID %d : IGNORED",
1129 request->packet->code,
1130 client_name(request->packet->src_ipaddr),
1131 request->packet->src_port,
1132 request->packet->id);
1133 request_free(request);
1138 case PW_AUTHENTICATION_ACK:
1139 case PW_AUTHENTICATION_REJECT:
1140 case PW_ACCOUNTING_RESPONSE:
1142 * Replies NOT sent to the proxy port get an
1143 * error message logged, and the packet is
1146 if (request->packet->sockfd != proxyfd) {
1147 radlog(L_ERR, "Reply packet code %d sent to request port from "
1148 "client %s:%d - ID %d : IGNORED",
1149 request->packet->code,
1150 client_name(request->packet->src_ipaddr),
1151 request->packet->src_port,
1152 request->packet->id);
1153 request_free(request);
1159 assert(request->magic == REQUEST_MAGIC);
1162 * Select the required function and indicate if
1163 * we need to fork off a child to handle it.
1165 switch(request->packet->code) {
1167 case PW_AUTHENTICATION_ACK:
1168 case PW_AUTHENTICATION_REJECT:
1169 case PW_AUTHENTICATION_REQUEST:
1170 fun = rad_authenticate;
1173 case PW_ACCOUNTING_RESPONSE:
1174 case PW_ACCOUNTING_REQUEST:
1175 fun = rad_accounting;
1178 case PW_PASSWORD_REQUEST:
1180 * We don't support this anymore.
1182 radlog(L_ERR, "Deprecated password change request from client %s:%d "
1183 "- ID %d : IGNORED",
1184 client_name(request->packet->src_ipaddr),
1185 request->packet->src_port,
1186 request->packet->id);
1187 request_free(request);
1192 radlog(L_ERR, "Unknown packet type %d from client %s:%d "
1193 "- ID %d : IGNORED",
1194 request->packet->code,
1195 client_name(request->packet->src_ipaddr),
1196 request->packet->src_port,
1197 request->packet->id);
1198 request_free(request);
1204 * If we did NOT select a function, then exit immediately.
1207 request_free(request);
1212 * Check for a duplicate, or error.
1213 * Throw away the the request if so.
1215 request = rad_check_list(request);
1216 if (request == NULL) {
1220 assert(request->magic == REQUEST_MAGIC);
1223 * The request passes many of our sanity checks. From
1224 * here on in, if anything goes wrong, we send a reject
1225 * message, instead of dropping the packet.
1227 * Build the reply template from the request template.
1229 if ((request->reply = rad_alloc(0)) == NULL) {
1230 fprintf(stderr, "out of memory\n");
1233 request->reply->sockfd = request->packet->sockfd;
1234 request->reply->dst_ipaddr = request->packet->src_ipaddr;
1235 request->reply->dst_port = request->packet->src_port;
1236 request->reply->id = request->packet->id;
1237 request->reply->code = 0; /* UNKNOWN code */
1238 memcpy(request->reply->vector, request->packet->vector,
1239 sizeof(request->reply->vector));
1240 request->reply->vps = NULL;
1241 request->reply->data = NULL;
1244 * If we're spawning a child thread, let it do all of
1245 * the work of handling a request, and exit.
1249 * Maybe the spawn failed. If so, then we
1250 * trivially reject the request (because we can't
1251 * handle it), and return.
1253 if (rad_spawn_child(request, fun) < 0) {
1254 rad_reject(request);
1255 request->finished = TRUE;
1260 rad_respond(request, fun);
1265 * Reject a request, by sending a trivial reply packet.
1267 static void rad_reject(REQUEST *request)
1271 DEBUG2("Server rejecting request.");
1272 switch (request->packet->code) {
1274 * Accounting requests, etc. get dropped on the floor.
1276 case PW_ACCOUNTING_REQUEST:
1281 * Authentication requests get their Proxy-State
1282 * attributes copied over, and an otherwise blank
1283 * reject message sent.
1285 case PW_AUTHENTICATION_REQUEST:
1286 request->reply->code = PW_AUTHENTICATION_REJECT;
1289 * Need to copy Proxy-State from request->packet->vps
1291 vps = paircopy2(request->packet->vps, PW_PROXY_STATE);
1293 pairadd(&(request->reply->vps), vps);
1298 * If a reply exists, send it.
1300 if (request->reply->code) {
1301 rad_send(request->reply, request->secret);
1306 * Perform any RFC specified cleaning of outgoing replies
1308 static void rfc_clean(RADIUS_PACKET *packet)
1310 VALUE_PAIR *vps = NULL;
1312 switch (packet->code) {
1317 * Authentication REJECT's can have only
1318 * Reply-Mesaage and Proxy-State. We delete
1319 * everything other than Reply-Message, and
1320 * Proxy-State is added below, just before
1321 * the reply is sent.
1323 case PW_AUTHENTICATION_REJECT:
1324 pairmove2(&vps, &(packet->vps), PW_REPLY_MESSAGE);
1325 pairfree(packet->vps);
1332 * FIXME: The next two functions should all
1333 * be in a module. But not until we have
1334 * more control over module execution.
1339 * Lowercase the string value of a pair.
1341 static int rad_lowerpair(REQUEST *request, VALUE_PAIR *vp) {
1346 rad_lowercase(vp->strvalue);
1347 DEBUG2("rad_lowerpair: %s now '%s'", vp->name, vp->strvalue);
1352 * Remove spaces in a pair.
1354 static int rad_rmspace_pair(REQUEST *request, VALUE_PAIR *vp) {
1359 rad_rmspace(vp->strvalue);
1360 vp->length = strlen(vp->strvalue);
1361 DEBUG2("rad_rmspace_pair: %s now '%s'", vp->name, vp->strvalue);
1367 * Respond to a request packet.
1369 * Maybe we reply, maybe we don't.
1370 * Maybe we proxy the request to another server, or else maybe
1371 * we replicate it to another server.
1373 int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
1375 RADIUS_PACKET *packet, *original;
1377 int finished = FALSE;
1382 * Put the decoded packet into it's proper place.
1384 if (request->proxy_reply != NULL) {
1385 packet = request->proxy_reply;
1386 secret = request->proxysecret;
1387 original = request->proxy;
1389 packet = request->packet;
1390 secret = request->secret;
1394 assert(request->magic == REQUEST_MAGIC);
1397 * Decode the packet, verifying it's signature,
1398 * and parsing the attributes into structures.
1400 * Note that we do this CPU-intensive work in
1401 * a child thread, not the master. This helps to
1402 * spread the load a little bit.
1404 if (rad_decode(packet, original, secret) != 0) {
1405 radlog(L_ERR, "%s", librad_errstr);
1406 rad_reject(request);
1407 goto finished_request;
1411 * For proxy replies, remove non-allowed
1412 * attributes from the list of VP's.
1414 if (request->proxy) {
1416 replicating = proxy_receive(request);
1417 if (replicating != 0) {
1423 * We should have a User-Name attribute now.
1425 if (request->username == NULL) {
1426 request->username = pairfind(request->packet->vps,
1431 * We have the semaphore, and have decoded the packet.
1432 * Let's process the request.
1434 assert(request->magic == REQUEST_MAGIC);
1437 * FIXME: All this lowercase/nospace junk will be moved
1438 * into a module after module failover is fully in place
1440 * See if we have to lower user/pass before processing
1442 if(strcmp(mainconfig.lower_time, "before") == 0) {
1443 if(mainconfig.do_lower_user)
1444 rad_lowerpair(request, request->username);
1445 if(mainconfig.do_lower_pass)
1446 rad_lowerpair(request, rad_getpass(request));
1448 if(strcmp(mainconfig.nospace_time, "before") == 0) {
1449 if(mainconfig.do_nospace_user)
1450 rad_rmspace_pair(request, request->username);
1451 if(mainconfig.do_nospace_pass)
1452 rad_rmspace_pair(request, rad_getpass(request));
1456 /* See if we have to lower user/pass after processing */
1457 if(strcmp(mainconfig.lower_time, "after") == 0) {
1458 if(mainconfig.do_lower_user)
1459 rad_lowerpair(request, request->username);
1460 if(mainconfig.do_lower_pass)
1461 rad_lowerpair(request, rad_getpass(request));
1465 if(strcmp(mainconfig.nospace_time, "after") == 0) {
1466 if(mainconfig.do_nospace_user)
1467 rad_rmspace_pair(request, request->username);
1468 if(mainconfig.do_nospace_pass)
1469 rad_rmspace_pair(request, rad_getpass(request));
1473 /* Reprocess if we rejected last time */
1474 if ((fun == rad_authenticate) &&
1475 (request->reply->code == PW_AUTHENTICATION_REJECT) &&
1480 * If we don't already have a proxy
1481 * packet for this request, we MIGHT have
1484 if (proxy_requests) {
1485 if (request->proxy == NULL) {
1486 proxy_sent = proxy_send(request);
1489 * sent==1 means it's been proxied. The child
1490 * is done handling the request, but the request
1493 if (proxy_sent == 1) {
1494 goto postpone_request;
1497 } else if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
1498 (request->reply == NULL)) {
1500 * We're not configured to reply to the packet,
1501 * and we're not proxying, so the DEFAULT behaviour
1502 * is to REJECT the user.
1504 DEBUG2("There was no response configured: rejecting the user.");
1505 rad_reject(request);
1506 goto finished_request;
1510 * If we have a reply to send, copy the Proxy-State
1511 * attributes from the request to the tail of the reply,
1512 * and send the packet.
1514 assert(request->magic == REQUEST_MAGIC);
1515 if (request->reply->code != 0) {
1516 VALUE_PAIR *vp = NULL;
1519 * Perform RFC limitations on outgoing replies.
1521 rfc_clean(request->reply);
1524 * Need to copy Proxy-State from request->packet->vps
1526 vp = paircopy2(request->packet->vps, PW_PROXY_STATE);
1528 pairadd(&(request->reply->vps), vp);
1530 rad_send(request->reply, request->secret);
1534 * We're done processing the request, set the
1535 * request to be finished, clean up as necessary,
1536 * and forget about the request.
1540 * We're done handling the request. Free up the linked
1541 * lists of value pairs. This might take a long time,
1542 * so it's more efficient to do it in a child thread,
1543 * instead of in the main handler when it eventually
1544 * gets around to deleting the request.
1546 * Also, no one should be using these items after the
1547 * request is finished, and the reply is sent. Cleaning
1548 * them up here ensures that they're not being used again.
1550 * Hmm... cleaning them up in the child thread also seems
1551 * to make the server run more efficiently!
1554 /* If we proxied this request, it's not safe to delete it until
1555 * after the proxy reply
1558 goto postpone_request;
1560 if (request->packet && request->packet->vps) {
1561 pairfree(request->packet->vps);
1562 request->packet->vps = NULL;
1563 request->username = NULL;
1564 request->password = NULL;
1566 if (request->reply && request->reply->vps) {
1567 pairfree(request->reply->vps);
1568 request->reply->vps = NULL;
1570 if (request->config_items) {
1571 pairfree(request->config_items);
1572 request->config_items = NULL;
1575 DEBUG2("Finished request");
1579 * Go to the next request, without marking
1580 * the current one as finished.
1583 DEBUG2("Going to the next request");
1586 * If this is an accounting request, ensure
1587 * that we delete it immediately, as there CANNOT be
1588 * duplicate accounting packets. If there are, then
1589 * something else is seriously wrong...
1591 if (request->packet->code == PW_ACCOUNTING_REQUEST) {
1592 request->timestamp = 0;
1595 #if WITH_THREAD_POOL
1596 request->child_pid = NO_SUCH_CHILD_PID;
1598 request->finished = finished; /* do as the LAST thing before exiting */
1605 * Clean up the request list, every so often.
1607 * This is done by walking through ALL of the list, and
1608 * - marking any requests which are finished, and expired
1609 * - killing any processes which are NOT finished after a delay
1610 * - deleting any marked requests.
1612 static int rad_clean_list(time_t now)
1614 static time_t last_cleaned_list = 0;
1617 int cleaned = FALSE;
1620 * Don't bother checking the list if we've done it
1621 * within the last second.
1623 * However, at LEAST once per second, go through the entire
1624 * request list again, ensuring that ALL of the request ID's
1625 * have been processed.
1627 if (last_cleaned_list == now) {
1630 last_cleaned_list = now;
1632 #if WITH_THREAD_POOL
1634 * Only clean the thread pool if we've spawned child threads.
1637 thread_pool_clean(now);
1642 * When mucking around with the request list, we block
1643 * asynchronous access (through the SIGCHLD handler) to
1644 * the list - equivalent to sigblock(SIGCHLD).
1646 request_list_busy = TRUE;
1649 for (id = 0; id < 256; id++) {
1654 * If we've cleaned this entry in the last
1655 * second, don't do it now.
1657 if (request_list[id].last_cleaned_list == now) {
1658 request_count += request_list[id].request_count;
1661 request_list[id].last_cleaned_list = now;
1664 * Set up for looping over the requests
1667 curreq = request_list[id].first_request;
1668 prevptr = &(request_list[id].first_request);
1670 while (curreq != NULL) {
1671 assert(curreq->magic == REQUEST_MAGIC);
1674 * Handle cleanup_delay, max_request_time,
1675 * proxy_retry, for this request.
1677 refresh_request(curreq, now);
1680 * If the request has been marked as deleted,
1681 * then remove it from the request list.
1683 if (curreq->timestamp == 0) {
1684 if (request_list[id].request_count == 0) {
1685 DEBUG("HORRIBLE ERROR!!!");
1687 request_list[id].request_count--;
1691 * Unlink the current request
1692 * from the request queue.
1694 *prevptr = curreq->next;
1696 curreq->next->prev = curreq->prev;
1698 request_free(curreq);
1702 * Else the request is still being
1703 * processed. Skip it.
1706 prevptr = &(curreq->next);
1707 curreq = curreq->next;
1709 } /* end of walking the request list for that ID */
1711 request_count += request_list[id].request_count;
1712 } /* for each entry in the request list array */
1715 * Only print debugging information if anything's changed.
1718 static int old_request_count = -1;
1720 if (request_count != old_request_count) {
1721 DEBUG2("%d requests left in the list", request_count);
1722 old_request_count = request_count;
1727 * We're done playing with the request list.
1729 request_list_busy = FALSE;
1735 * Walk through the request list, cleaning up complete child
1736 * requests, and verifing that there is only one process
1737 * responding to each request (duplicate requests are filtered
1740 * Also, check if the request is a reply from a request proxied to
1741 * a remote server. If so, play games with the request, and return
1744 static REQUEST *rad_check_list(REQUEST *request)
1750 REQUEST_LIST *request_list_entry;
1756 * If the request has come in on the proxy FD, then
1757 * it's a proxy reply, so pass it through the proxy
1758 * code for checking the REQUEST_LIST.
1760 if (request->packet->sockfd == proxyfd) {
1761 return proxy_check_list(request);
1764 * If the request already has a proxy packet,
1765 * then it obviously is not a new request, either.
1767 } else if (request->proxy != NULL) {
1771 request_list_entry = &request_list[request->packet->id];
1773 assert((request_list_entry->first_request == NULL) ||
1774 (request_list_entry->request_count != 0));
1775 assert((request_list_entry->first_request != NULL) ||
1776 (request_list_entry->request_count == 0));
1778 curreq = request_list_entry->first_request;
1780 pkt = request->packet;
1782 now = request->timestamp; /* good enough for our purposes */
1786 * When mucking around with the request list, we block
1787 * asynchronous access (through the SIGCHLD handler) to
1788 * the list - equivalent to sigblock(SIGCHLD).
1790 request_list_busy = TRUE;
1792 while (curreq != NULL) {
1794 * The packet ID's MUST be the same, as we're in
1795 * request_list[request->packet->id]
1797 assert(curreq->packet->id == pkt->id);
1800 * Let's see if we received a duplicate of
1801 * a packet we already have in our list.
1803 * We do this by checking the src IP, src port,
1804 * the packet code, and ID.
1806 if ((curreq->packet->src_ipaddr == pkt->src_ipaddr) &&
1807 (curreq->packet->src_port == pkt->src_port) &&
1808 (curreq->packet->code == pkt->code)) {
1810 * We now check the authentication vectors.
1811 * If the client has sent us a request with
1812 * identical code && ID, but different vector,
1813 * then they MUST have gotten our response, so
1814 * we can delete the original request, and process
1817 * If the vectors are the same, then it's a duplicate
1818 * request, and we can send a duplicate reply.
1820 if (memcmp(curreq->packet->vector, pkt->vector,
1821 sizeof(pkt->vector)) == 0) {
1823 * Maybe we've saved a reply packet. If so,
1824 * re-send it. Otherwise, just complain.
1826 if (curreq->reply) {
1828 "Sending duplicate authentication reply"
1829 " to client %s:%d - ID: %d",
1830 client_name(request->packet->src_ipaddr),
1831 request->packet->src_port,
1832 request->packet->id);
1835 * Use the SOURCE port as the DESTINATION
1836 * port of the duplicate reply.
1838 curreq->reply->dst_port = request->packet->src_port;
1839 rad_send(curreq->reply, curreq->secret);
1842 * There's no reply, but maybe there's
1843 * an outstanding proxy request.
1845 * If so, then kick the proxy again.
1847 } else if (curreq->proxy != NULL) {
1848 if (proxy_synchronous) {
1849 DEBUG2("Sending duplicate proxy request to client %s:%d - ID: %d",
1850 client_name(curreq->proxy->dst_ipaddr),
1851 request->packet->src_port,
1854 curreq->proxy_next_try = request->timestamp + proxy_retry_delay;
1855 rad_send(curreq->proxy, curreq->proxysecret);
1857 DEBUG2("Ignoring duplicate authentication packet"
1858 " from client %s:%d - ID: %d, due to outstanding proxy request.",
1859 client_name(request->packet->src_ipaddr),
1860 request->packet->src_port,
1861 request->packet->id);
1865 "Dropping duplicate authentication packet"
1866 " from client %s:%d - ID: %d",
1867 client_name(request->packet->src_ipaddr),
1868 request->packet->src_port,
1869 request->packet->id);
1873 * Delete the duplicate request, and
1874 * stop processing the request list.
1876 request_free(request);
1881 * The packet vectors are different, so
1882 * we can mark the old request to be
1883 * deleted from the list.
1885 * Note that we don't actually delete it...
1888 if (curreq->finished) {
1889 curreq->timestamp = 0;
1892 * ??? the client sent us a new request
1893 * with the same ID, while we were
1894 * processing the old one! What should
1898 "Dropping conflicting authentication packet"
1899 " from client %s:%d - ID: %d",
1900 client_name(request->packet->src_ipaddr),
1901 request->packet->src_port,
1902 request->packet->id);
1903 request_free(request);
1911 * Ugh... duplicated code is bad...
1915 * Delete the current request, if it's
1916 * marked as such. That is, the request
1917 * must be finished, there must be no
1918 * child associated with that request,
1919 * and it's timestamp must be marked to
1922 if (curreq->finished &&
1923 (curreq->child_pid == NO_SUCH_CHILD_PID) &&
1924 (curreq->timestamp + cleanup_delay <= now)) {
1926 * Request completed, delete it,
1927 * and unlink it from the
1928 * currently 'alive' list of
1931 DEBUG2("Cleaning up request ID %d with timestamp %08lx",
1933 (unsigned long)curreq->timestamp);
1934 prevreq = curreq->prev;
1935 if (request_list[id].request_count == 0) {
1936 DEBUG("HORRIBLE ERROR!!!");
1938 request_list[id].request_count--;
1941 if (prevreq == NULL) {
1942 request_list[id].first_request = curreq->next;
1943 request_free(curreq);
1944 curreq = request_list[id].first_request;
1946 prevreq->next = curreq->next;
1947 request_free(curreq);
1948 curreq = prevreq->next;
1951 curreq->prev = prevreq;
1953 } else { /* the request is still alive */
1955 curreq = curreq->next;
1958 } /* end of walking the request list */
1961 * If we've received a duplicate packet, 'request' is NULL.
1963 if (request == NULL) {
1964 request_list_busy = FALSE;
1968 assert(request_list_entry->request_count == request_count);
1971 * Count the total number of requests, to see if there
1972 * are too many. If so, stop counting immediately,
1973 * and return with an error.
1977 for (i = 0; i < 256; i++) {
1978 request_count += request_list[i].request_count;
1981 * This is a new request. Let's see if it
1982 * makes us go over our configured bounds.
1984 if (request_count > max_requests) {
1985 radlog(L_ERR, "Dropping request (%d is too many): "
1986 "from client %s:%d - ID: %d", request_count,
1987 client_name(request->packet->src_ipaddr),
1988 request->packet->src_port,
1989 request->packet->id);
1990 radlog(L_INFO, "WARNING: Please check the radiusd.conf file.\n\tThe value for 'max_requests' is probably set too low.\n");
1991 request_free(request);
1992 request_list_busy = FALSE;
1999 * Add this request to the list
2001 request->prev = prevreq;
2002 request->next = NULL;
2003 request->child_pid = NO_SUCH_CHILD_PID;
2004 request_list_entry->request_count++;
2006 if (prevreq == NULL) {
2007 assert(request_list_entry->first_request == NULL);
2008 assert(request_list_entry->request_count == 1);
2009 request_list_entry->first_request = request;
2011 assert(request_list_entry->first_request != NULL);
2012 prevreq->next = request;
2016 * And return the request to be handled.
2018 request_list_busy = FALSE;
2022 #ifndef WITH_THREAD_POOL
2024 typedef struct spawn_thread_t {
2026 RAD_REQUEST_FUNP fun;
2030 * If the child *thread* gets a termination signal,
2031 * then exit from the thread.
2033 static void sig_term(int sig)
2035 sig = sig; /* -Wunused */
2040 * Spawn a new child thread to handle this request, and ONLY
2043 static void *rad_spawn_thread(void *arg)
2046 spawn_thread_t *data = (spawn_thread_t *)arg;
2049 * Note that this behaviour only works on Linux.
2051 * It's generally NOT the thing to do, and should
2054 * Q: How do we signal a hung thread, and tell it to
2057 signal(SIGTERM, sig_term);
2060 * Keep only allowed attributes in the request.
2062 if (data->request->proxy) {
2063 replicating = proxy_receive(data->request);
2064 if (replicating != 0) {
2065 data->request->finished = TRUE;
2071 rad_respond(data->request, data->fun);
2072 data->request->child_pid = NO_SUCH_CHILD_PID;
2080 * If we're using the thread pool, then the function in
2081 * 'threads.c' replaces this one.
2083 #ifndef WITH_THREAD_POOL
2085 * Spawns a child process or thread to perform
2086 * authentication/accounting and respond to RADIUS clients.
2088 static int rad_spawn_child(REQUEST *request, RAD_REQUEST_FUNP fun)
2090 child_pid_t child_pid;
2094 spawn_thread_t *data;
2096 data = (spawn_thread_t *) malloc(sizeof(spawn_thread_t));
2097 memset(data, 0, sizeof(data));
2098 data->request = request;
2102 * Create a child thread, complaining on error.
2104 rcode = pthread_create(&child_pid, NULL, rad_spawn_thread, data);
2106 radlog(L_ERR, "Thread create failed for request from nas %s - ID: %d : %s",
2107 nas_name2(request->packet),
2108 request->packet->id,
2114 * Detach it, so it's state is automagically cleaned up on exit.
2116 pthread_detach(child_pid);
2123 if (child_pid < 0) {
2124 radlog(L_ERR, "Fork failed for request from nas %s - ID: %d",
2125 nas_name2(request->packet),
2126 request->packet->id);
2130 if (child_pid == 0) {
2133 * This is the child, it should go ahead and respond
2135 signal(SIGCHLD, SIG_DFL);
2136 rad_respond(request, fun);
2142 * Register the Child
2144 request->child_pid = child_pid;
2147 #endif /* WITH_THREAD_POOL */
2150 void sig_cleanup(int sig)
2152 #ifndef HAVE_PTHREAD_H
2159 sig = sig; /* -Wunused */
2162 * request_list_busy is a lock on the request list
2164 if (request_list_busy) {
2171 * Reset the signal handler, if required.
2173 reset_signal(SIGCHLD, sig_cleanup);
2176 * If we're using pthreads, then there are NO child processes,
2177 * so the waitpid() call, and the following code, is useless.
2179 #ifndef HAVE_PTHREAD_H
2181 pid = waitpid((pid_t)-1, &status, WNOHANG);
2186 * Check to see if the child did a bad thing.
2187 * If so, kill ALL processes in the current
2188 * process group, to prevent further attacks.
2190 if (debug_flag && (WIFSIGNALED(status))) {
2191 radlog(L_ERR|L_CONS, "MASTER: Child PID %d failed to catch signal %d: killing all active servers.\n",
2192 pid, WTERMSIG(status));
2198 * Service all of the requests in the queues
2200 for (i = 0; i < 256; i++) {
2201 curreq = request_list[i].first_request;
2202 while (curreq != (REQUEST *)NULL) {
2203 if (curreq->child_pid == pid) {
2204 curreq->child_pid = NO_SUCH_CHILD_PID;
2207 curreq = curreq->next;
2211 #endif /* !defined HAVE_PTHREAD_H */
2215 * Display the syntax for starting this program.
2217 static void usage(void)
2220 "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-p port] [-"
2221 #if defined(WITH_DBM) || defined(WITH_NDBM)
2224 "AcfnsSvXxyz]\n", progname);
2225 fprintf(stderr, "Options:\n\n");
2226 fprintf(stderr, " -a acct_dir use accounting directory 'acct_dir'.\n");
2227 fprintf(stderr, " -A Log auth detail.\n");
2228 #if defined(WITH_DBM) || defined(WITH_NDBM)
2229 fprintf(stderr, " -b Use DBM.\n");
2231 fprintf(stderr, " -d db_dir Use database directory 'db_dir'.\n");
2232 fprintf(stderr, " -f Run as a foreground process, not a daemon.\n");
2233 fprintf(stderr, " -h Print this help message.\n");
2234 fprintf(stderr, " -i address Listen only in the given IP address.\n");
2235 fprintf(stderr, " -l log_dir Log messages to 'log_dir'. Special values are:\n");
2236 fprintf(stderr, " stdout == log all messages to standard output.\n");
2237 fprintf(stderr, " syslog == log all messages to the system logger.\n");
2238 fprintf(stderr, " -p port Bind to 'port', and not to the radius/udp, or 1646/udp.\n");
2239 fprintf(stderr, " -s Do not spawn child processes to handle requests.\n");
2240 fprintf(stderr, " -S Log stripped names.\n");
2241 fprintf(stderr, " -v Print server version information.\n");
2242 fprintf(stderr, " -X Turn on full debugging. (Means: -sfxxyz -l stdout)\n");
2243 fprintf(stderr, " -x Turn on partial debugging. (-xx gives more debugging).\n");
2244 fprintf(stderr, " -y Log authentication failures, with password.\n");
2245 fprintf(stderr, " -z Log authentication successes, with password.\n");
2251 * We got a fatal signal. Clean up and exit.
2253 static void sig_fatal(int sig)
2255 const char *me = "MASTER: ";
2257 if (radius_pid != getpid()) {
2263 radlog(L_ERR, "%saccounting process died - exit.", me);
2266 radlog(L_ERR, "%sfailed in select() - exit.", me);
2269 radlog(L_INFO, "%sexit.", me);
2272 radlog(L_ERR, "%sexit on signal (%d)", me, sig);
2277 * We're running as a daemon, we're the MASTER daemon,
2278 * and we got a fatal signal. Tear the rest of the
2279 * daemons down, as something absolutely horrible happened.
2281 if ((debug_flag == 0) && (dont_fork == 0) &&
2282 (radius_pid == getpid())) {
2284 * Kill all of the processes in the current
2290 exit(sig == SIGTERM ? 0 : 1);
2295 * We got the hangup signal.
2296 * Re-read the configuration files.
2299 static void sig_hup(int sig)
2301 sig = sig; /* -Wunused */
2302 reset_signal(SIGHUP, sig_hup);
2305 * Only do the reload if we're the main server, both
2306 * for processes, and for threads.
2308 if (getpid() == radius_pid) {
2314 * Do a proxy check of the REQUEST_LIST when using the new proxy code.
2316 * This function and the next two are here because they have to access
2317 * the REQUEST_LIST structure, which is 'static' to this C file.
2319 static REQUEST *proxy_check_list(REQUEST *request)
2326 * Find the original request in the request list
2329 pkt = request->packet;
2331 for (id = 0; (id < 256) && (oldreq == NULL); id++) {
2332 for (oldreq = request_list[id].first_request ;
2334 oldreq = oldreq->next) {
2337 * See if this reply packet matches a proxy
2338 * packet which we sent.
2340 if (oldreq->proxy &&
2341 (oldreq->proxy->dst_ipaddr == pkt->src_ipaddr) &&
2342 (oldreq->proxy->dst_port == pkt->src_port) &&
2343 (oldreq->proxy->id == pkt->id)) {
2345 * If there is already a reply,
2346 * maybe the new one is a duplicate?
2348 if (oldreq->proxy_reply) {
2349 if (memcmp(oldreq->proxy_reply->vector,
2350 request->packet->vector,
2351 sizeof(oldreq->proxy_reply->vector)) == 0) {
2352 DEBUG2("Ignoring duplicate proxy reply");
2353 request_free(request);
2361 } /* else no reply, this one must match */
2364 * Exit from request list loop
2365 * while oldreq != NULL, which will
2366 * cause the outer loop to stop, too.
2369 } /* the reply matches a proxied request */
2370 } /* for all requests in the id request list */
2371 } /* for all 256 id's*/
2374 * If we haven't found the old request, complain.
2376 if (oldreq == NULL) {
2377 radlog(L_PROXY, "Unrecognized proxy reply from server %s - ID %d",
2378 client_name(request->packet->src_ipaddr),
2379 request->packet->id);
2380 request_free(request);
2385 * Refresh the old request, and update it with the proxy reply.
2387 * ??? Can we delete the proxy request here?
2388 * Is there any more need for it?
2390 oldreq->timestamp = request->timestamp;
2391 oldreq->proxy_reply = request->packet;
2392 request->packet = NULL;
2393 request_free(request);
2398 * Walk through all of the requests, checking cleanup times,
2399 * proxy retry times, and maximum request times. We then set the
2400 * time delay until the server has to service the request queue.
2402 * This time delay is used by the main select() loop, to sleep
2403 * until either a packet comes in, or until there's some work
2406 static struct timeval *setuptimeout()
2408 time_t now = time(NULL);
2409 time_t difference, smallest = 0;
2410 int foundone = FALSE;
2415 * Static variables, so that we don't do all of this work
2416 * more than once per second.
2418 * Note that we have 'tv' and 'last_tv'. 'last_tv' is
2419 * pointed to by 'last_tv_ptr', and depending on the
2420 * system implementation of select(), it MAY be modified.
2422 * In that was, we want to use the ORIGINAL value, from
2423 * 'tv', and wipe out the (possibly modified) last_tv.
2425 static time_t last_setup = 0;
2426 static struct timeval tv, *last_tv_ptr = NULL;
2427 static struct timeval last_tv;
2430 * If we've already set up the timeout this second,
2431 * don't do it again. We simply return the sleep delay
2434 * Note that if we returned NULL last time, there was nothing
2435 * to do. BUT we've been woken up since then, which can only
2436 * happen if we received a packet. And if we've received a
2437 * packet, then there's some work to do in the future.
2439 * FIXME: We can probably use gettimeofday() for finer clock
2440 * resolution, as the current method will cause it to sleep
2443 if ((last_tv_ptr != NULL) &&
2444 (last_setup == now) &&
2447 DEBUG2("Waking up in %d seconds...",
2448 (int) last_tv_ptr->tv_sec);
2452 last_setup = now; /* remember when we last set up the sleep timer */
2454 difference = 1; /* initialize it to a non-zero value */
2457 * Loop over all of the outstanding requests.
2459 for (id = 0; id < 256; id++) {
2460 for (curreq = request_list[id].first_request; curreq; curreq = curreq->next) {
2462 * The request is marked to be
2463 * cleaned up: ignore it.
2465 if (curreq->timestamp == 0) {
2467 } else if (curreq->finished) {
2469 * The request is finished.
2470 * Wake up when it's time to clean
2473 difference = (curreq->timestamp + cleanup_delay) - now;
2475 } else if (curreq->proxy && !curreq->proxy_reply) {
2477 * The request is NOT finished, but there
2478 * is an outstanding proxy request,
2479 * with no matching proxy reply.
2481 * Wake up when it's time to re-send
2482 * the proxy request.
2484 difference = curreq->proxy_next_try - now;
2488 * The request is NOT finished.
2490 * Wake up when it's time to kill
2491 * the errant thread/process.
2493 difference = (curreq->timestamp + max_request_time) - now;
2497 * Found a valid request, with a time at which
2498 * we're going to to wake up.
2502 smallest = difference;
2504 if (difference < smallest)
2505 smallest = difference;
2508 if (difference <= 0) break; /* short-circuit */
2509 } /* loop over linked list for that ID */
2511 if (difference <= 0) break; /* short-circuit */
2512 } /* loop over 256 ID's */
2515 * We haven't found a time at which we need to wake up.
2516 * Return NULL, so that the select() call will sleep forever.
2519 DEBUG2("Nothing to do. Sleeping until we see a request.");
2525 * If the server is CPU starved, then we CAN miss a time
2526 * for servicing requests. In which case the 'smallest'
2527 * value will be negative. select() doesn't like that,
2530 if (smallest < 0) smallest = 0;
2533 * Set the time (in seconds) for how long we're
2534 * supposed to sleep.
2536 tv.tv_sec = smallest;
2538 DEBUG2("Waking up in %d seconds...", (int) smallest);
2541 * Remember how long we should sleep for.
2544 last_tv_ptr = &last_tv;
2549 * Refresh a request, by using proxy_retry_delay, cleanup_delay,
2550 * max_request_time, etc.
2552 * When walking over the request list, all of the per-request
2553 * magic is done here.
2555 static void refresh_request(REQUEST *request, time_t now)
2557 child_pid_t child_pid;
2560 * If the request has finished processing,
2561 * AND it's child has been cleaned up,
2562 * AND it's time to clean up the request,
2563 * THEN, go delete it.
2565 if (request->finished &&
2566 (request->child_pid == NO_SUCH_CHILD_PID) &&
2567 (request->timestamp + cleanup_delay <= now)) {
2569 * Request completed, delete it, and unlink it
2570 * from the currently 'alive' list of requests.
2572 DEBUG2("Cleaning up request ID %d with timestamp %08lx",
2573 request->packet->id,
2574 (unsigned long)request->timestamp);
2577 * Mark the request to be deleted.
2579 request->timestamp = 0;
2585 * Maybe the child process
2586 * handling the request has hung:
2587 * kill it, and continue.
2589 if ((request->timestamp + max_request_time) <= now) {
2590 if (request->child_pid != NO_SUCH_CHILD_PID) {
2592 * This request seems to have hung
2595 child_pid = request->child_pid;
2596 radlog(L_ERR, "Killing unresponsive child %d",
2598 child_kill(child_pid, SIGTERM);
2599 } /* else no proxy reply, quietly fail */
2602 * Mark the request as unsalvagable.
2604 request->child_pid = NO_SUCH_CHILD_PID;
2605 request->finished = TRUE;
2606 request->timestamp = 0;
2611 * Do any proxy request handling.
2613 * If we're not doing proxy requests, OR if the retry delay
2614 * is zero (only retry synchronously), then don't bother
2615 * checking the request for proxy retries.
2617 if ((!proxy_requests) ||
2618 (proxy_retry_delay == 0)) {
2623 * The request is finished, (but it hasn't yet
2624 * been removed from the list.)
2625 * OR there is no proxy request,
2626 * OR we already have seen the reply (so we don't
2627 * need to send another proxy request),
2628 * OR the next try is to be done later.
2632 * FIXME: These retries should be binned by
2633 * the next try time, so we don't have to do
2634 * all of this work on every second.
2636 * That will also get rid of these checks, as
2637 * a packet can get removed from the bin when
2638 * the proxy reply is received.
2640 if ((request->finished) ||
2641 (!request->proxy) ||
2642 (request->proxy_reply) ||
2643 (request->proxy_next_try > now)) {
2648 * If the proxy retry count is zero, then
2649 * we've sent the last try, and have NOT received
2650 * a reply from the end server. In that case,
2651 * we don't bother trying again, but just mark
2652 * the request as finished, and go to the next one.
2654 * Note that we do NOT immediately delete the request,
2655 * on the off chance that the proxy replies before we've
2656 * thrown the request away.
2658 if (request->proxy_try_count == 0) {
2659 request->finished = TRUE;
2660 rad_reject(request);
2665 * We're trying one more time, so count down
2666 * the tries, and set the next try time.
2668 request->proxy_try_count--;
2669 request->proxy_next_try = now + proxy_retry_delay;
2671 /* Fix up Acct-Delay-Time */
2672 if (request->proxy->code == PW_ACCOUNTING_REQUEST) {
2673 VALUE_PAIR *delaypair;
2674 delaypair = pairfind(request->proxy->vps, PW_ACCT_DELAY_TIME);
2677 delaypair = paircreate(PW_ACCT_DELAY_TIME,
2680 radlog(L_ERR|L_CONS, "no memory");
2683 pairadd(&request->proxy->vps, delaypair);
2685 delaypair->lvalue = now - request->proxy->timestamp;
2687 /* Must recompile the valuepairs to wire format */
2688 free(request->proxy->data);
2689 request->proxy->data = NULL;
2690 } /* proxy accounting request */
2693 * Send the proxy packet.
2695 rad_send(request->proxy, request->proxysecret);