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[] =
14 #include <sys/types.h>
15 #include <sys/socket.h>
17 #include <netinet/in.h>
32 # include <sys/select.h>
44 # include <sys/wait.h>
47 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
50 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
58 #include <sys/resource.h>
63 const char *progname = NULL;
64 char *radius_dir = NULL;
65 char *radacct_dir = NULL;
66 char *radlog_dir = NULL;
67 const char *radlib_dir = NULL;
68 int log_stripped_names;
71 uint32_t myip = INADDR_ANY;
72 int log_auth_detail = FALSE;
74 int log_auth_pass = FALSE;
78 int proxy_retry_delay = RETRY_DELAY;
79 int proxy_retry_count = RETRY_COUNT;
80 int proxy_synchronous = TRUE;
82 static int got_child = FALSE;
83 static int request_list_busy = FALSE;
87 static int spawn_flag = TRUE;
88 static pid_t radius_pid;
89 static int need_reload = FALSE;
90 static struct rlimit core_limits;
91 static time_t last_cleaned_list;
92 static int proxy_requests = TRUE;
95 * We keep the incoming requests in an array, indexed by ID.
97 * Each array element contains a linked list of active requests,
98 * a count of the number of requests, and a time at which the first
99 * request in the list must be serviced.
101 typedef struct REQUEST_LIST {
102 REQUEST *first_request;
107 static REQUEST_LIST request_list[256];
110 * Configuration items.
112 static int allow_core_dumps = FALSE;
113 static int max_request_time = MAX_REQUEST_TIME;
114 static int cleanup_delay = CLEANUP_DELAY;
115 static int max_requests = MAX_REQUESTS;
116 static const char *pid_file = NULL;
118 #if !defined(__linux__) && !defined(__GNU_LIBRARY__)
122 static void usage(void);
124 static void sig_fatal (int);
125 static void sig_hup (int);
127 static void rad_reject(REQUEST *request);
128 static int rad_process (REQUEST *, int);
129 static int rad_clean_list(void);
130 static REQUEST *rad_check_list(REQUEST *);
131 static REQUEST *proxy_check_list(REQUEST *request);
132 struct timeval *proxy_setuptimeout(struct timeval *);
133 void proxy_retry(void);
134 #ifndef WITH_THREAD_POOL
135 static int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
137 extern int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
141 * A mapping of configuration file names to internal variables
143 static CONF_PARSER server_config[] = {
144 { "max_request_time", PW_TYPE_INTEGER, &max_request_time },
145 { "cleanup_delay", PW_TYPE_INTEGER, &cleanup_delay },
146 { "max_requests", PW_TYPE_INTEGER, &max_requests },
147 { "port", PW_TYPE_INTEGER, &auth_port },
148 { "allow_core_dumps", PW_TYPE_BOOLEAN, &allow_core_dumps },
149 { "log_stripped_names", PW_TYPE_BOOLEAN, &log_stripped_names },
150 { "log_auth", PW_TYPE_BOOLEAN, &log_auth },
151 { "log_auth_pass", PW_TYPE_BOOLEAN, &log_auth_pass },
152 { "pidfile", PW_TYPE_STRING_PTR, &pid_file },
153 { "log_dir", PW_TYPE_STRING_PTR, &radlog_dir },
154 { "lib_dir", PW_TYPE_STRING_PTR, &radlib_dir },
155 { "acct_dir", PW_TYPE_STRING_PTR, &radacct_dir },
156 { "bind_address", PW_TYPE_IPADDR, &myip },
157 { "proxy_requests", PW_TYPE_BOOLEAN, &proxy_requests },
159 { "confdir", PW_TYPE_STRING_PTR, &radius_dir },
166 * Map the proxy server configuration parameters to variables.
168 static CONF_PARSER proxy_config[] = {
169 { "retry_delay", PW_TYPE_INTEGER, &proxy_retry_delay },
170 { "retry_count", PW_TYPE_INTEGER, &proxy_retry_count },
171 { "synchonous", PW_TYPE_BOOLEAN, &proxy_synchronous },
179 static void reread_config(int reload)
186 log(L_INFO, "Starting - reading configuration files ...");
187 } else if (pid == radius_pid) {
188 log(L_INFO, "Reloading configuration files.");
191 /* Read users file etc. */
192 if (res == 0 && read_config_files() != 0)
196 if (pid == radius_pid) {
198 "Errors reading config file - EXITING");
204 * And parse the server's configuration values.
206 cs = cf_section_find("main");
210 cf_section_parse(cs, server_config);
213 * Go update our behaviour, based on the configuration
216 if (allow_core_dumps) {
217 if (setrlimit(RLIMIT_CORE, &core_limits) < 0) {
218 log(L_ERR|L_CONS, "Cannot update core dump limit: %s",
223 * If we're running as a daemon, and core
224 * dumps are enabled, log that information.
226 } else if ((core_limits.rlim_cur != 0) && !debug_flag)
227 log(L_INFO, "Core dumps are enabled.");
229 } else if (!debug_flag) {
231 * Not debugging. Set the core size to zero, to
232 * prevent security breaches. i.e. People
233 * reading passwords from the 'core' file.
235 struct rlimit limits;
238 limits.rlim_max = core_limits.rlim_max;
240 if (setrlimit(RLIMIT_CORE, &limits) < 0) {
241 log(L_ERR|L_CONS, "Cannot disable core dumps: %s",
248 * Parse the server's proxy configuration values.
250 if (proxy_requests) {
251 cs = cf_section_find("proxy");
255 cf_section_parse(cs, proxy_config);
260 * Parse a string into a syslog facility level.
262 static int str2fac(const char *s)
265 if(!strcmp(s, "kern"))
270 if(!strcmp(s, "user"))
275 if(!strcmp(s, "mail"))
280 if(!strcmp(s, "daemon"))
285 if(!strcmp(s, "auth"))
290 if(!strcmp(s, "auth"))
295 if(!strcmp(s, "lpr"))
300 if(!strcmp(s, "news"))
305 if(!strcmp(s, "uucp"))
310 if(!strcmp(s, "cron"))
315 if(!strcmp(s, "authpriv"))
320 if(!strcmp(s, "ftp"))
325 if(!strcmp(s, "local0"))
330 if(!strcmp(s, "local1"))
335 if(!strcmp(s, "local2"))
340 if(!strcmp(s, "local3"))
345 if(!strcmp(s, "local4"))
350 if(!strcmp(s, "local5"))
355 if(!strcmp(s, "local6"))
360 if(!strcmp(s, "local7"))
365 fprintf(stderr, "%s: Error: Unknown syslog facility: %s\n",
370 /* this should never be reached */
374 int main(int argc, char **argv)
378 RADIUS_PACKET *packet;
379 unsigned char buffer[4096];
380 struct sockaddr salocal;
381 struct sockaddr_in *sa;
384 struct timeval tv, *tvp;
393 int dont_fork = FALSE;
395 int syslog_facility = LOG_DAEMON;
398 set_auth_parameters(argc,argv);
402 * Open /dev/null, and make sure filedescriptors
403 * 0, 1 and 2 are connected to something.
406 while (devnull >= 0 && devnull < 3)
407 devnull = open("/dev/null", O_RDWR);
409 if ((progname = strrchr(argv[0], '/')) == NULL)
416 radacct_dir = strdup(RADACCT_DIR);
417 radius_dir = strdup(RADIUS_DIR);
418 radlog_dir = strdup(RADLOG_DIR);
419 radlib_dir = strdup(LIBDIR);
420 pid_file = strdup(RADIUS_PID);
422 signal(SIGHUP, sig_hup);
423 signal(SIGINT, sig_fatal);
424 signal(SIGQUIT, sig_fatal);
426 signal(SIGTRAP, sig_fatal);
429 signal(SIGIOT, sig_fatal);
433 * Pooled threads and child threads define their own
436 #ifndef WITH_THREAD_POOL
437 #ifndef HAVE_PTHREAD_H
438 signal(SIGTERM, sig_fatal);
441 signal(SIGCHLD, sig_cleanup);
443 signal(SIGFPE, sig_fatal);
444 signal(SIGSEGV, sig_fatal);
445 signal(SIGILL, sig_fatal);
449 * Close unused file descriptors.
451 for (t = 32; t >= 3; t--)
452 if(t!=devnull) close(t);
455 * Process the options.
457 while((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:np:sSvxXyz")) != EOF) {
462 log_auth_detail = TRUE;
466 if (radacct_dir) free(radacct_dir);
467 radacct_dir = strdup(optarg);
470 #if defined(WITH_DBM) || defined(WITH_NDBM)
476 /* ignore for backwards compatibility with Cistron */
480 if (radius_dir) free(radius_dir);
481 radius_dir = strdup(optarg);
493 if ((myip = ip_getaddr(optarg)) == INADDR_ANY) {
494 fprintf(stderr, "radiusd: %s: host unknown\n",
501 if (radlog_dir) free(radlog_dir);
502 radlog_dir = strdup(optarg);
506 * We should also have this as a configuration
510 syslog_facility = str2fac(optarg);
514 librad_dodns = FALSE;
518 log_stripped_names++;
522 radius_port = atoi(optarg);
525 case 's': /* Single process mode */
534 * BIG debugging mode for users who are
535 * TOO LAZY to type '-sfxxyz -l stdout' themselves.
543 log_auth_pass = TRUE;
544 radlog_dir = strdup("stdout");
557 log_auth_pass = TRUE;
567 * Get out PID: the configuration file reader uses it.
569 radius_pid = getpid();
572 * Get the current maximum for core files.
574 if (getrlimit(RLIMIT_CORE, &core_limits) < 0) {
575 log(L_ERR|L_CONS, "Failed to get current core limit:"
576 " %s", strerror(errno));
581 * Read the configuration files, BEFORE doing anything else.
587 * If they asked for syslog, then give it to them.
588 * Also, initialize the logging facility with the
589 * configuration that they asked for.
591 if (!strcmp(radlog_dir, "syslog")) {
592 openlog(progname, LOG_PID, syslog_facility);
594 /* Do you want a warning if -g is used without a -l to activate it? */
598 * Initialize the request_list[] array.
600 for (i = 0; i < 256; i++) {
601 request_list[i].first_request = NULL;
602 request_list[i].request_count = 0;
603 request_list[i].service_time = 0;
607 * Open Authentication socket.
609 * We prefer (in order) the port from the command-line,
610 * then the port from the configuration file, then
611 * the port that the system names "radius", then
614 svp = getservbyname ("radius", "udp");
616 auth_port = radius_port;
618 radius_port = auth_port;
621 if (auth_port == 0) {
623 auth_port = ntohs(svp->s_port);
625 auth_port = PW_AUTH_UDP_PORT;
628 authfd = socket (AF_INET, SOCK_DGRAM, 0);
630 perror("auth socket");
634 sa = (struct sockaddr_in *) & salocal;
635 memset ((char *) sa, '\0', sizeof (salocal));
636 sa->sin_family = AF_INET;
637 sa->sin_addr.s_addr = myip;
638 sa->sin_port = htons(auth_port);
640 result = bind (authfd, & salocal, sizeof (*sa));
642 perror ("auth bind");
647 * Open Accounting Socket.
649 * We prefer (in order) the authentication port + 1,
650 * then the port that the system names "radacct".
652 svp = getservbyname ("radacct", "udp");
653 if (radius_port || svp == NULL)
654 acct_port = auth_port + 1;
656 acct_port = ntohs(svp->s_port);
658 acctfd = socket (AF_INET, SOCK_DGRAM, 0);
660 perror ("acct socket");
664 sa = (struct sockaddr_in *) & salocal;
665 memset ((char *) sa, '\0', sizeof (salocal));
666 sa->sin_family = AF_INET;
667 sa->sin_addr.s_addr = myip;
668 sa->sin_port = htons(acct_port);
670 result = bind (acctfd, & salocal, sizeof (*sa));
672 perror ("acct bind");
677 * If we're proxying requests, open the proxy FD.
678 * Otherwise, don't do anything.
680 if (proxy_requests) {
684 proxyfd = socket (AF_INET, SOCK_DGRAM, 0);
686 perror ("proxy socket");
690 sa = (struct sockaddr_in *) & salocal;
691 memset ((char *) sa, '\0', sizeof (salocal));
692 sa->sin_family = AF_INET;
693 sa->sin_addr.s_addr = myip;
696 * Set the proxy port to be one more than the
699 for (proxy_port = acct_port + 1; proxy_port < 64000; proxy_port++) {
700 sa->sin_port = htons(proxy_port);
701 result = bind (proxyfd, & salocal, sizeof (*sa));
708 * Couldn't find a port to which we could bind.
710 if (proxy_port == 64000) {
711 perror("proxy bind");
717 * NOT proxying requests, set the FD to a bad value.
724 * Register built-in compare functions.
726 pair_builtincompare_init();
729 * Initialize other, miscellaneous variables.
731 last_cleaned_list = time(NULL);
735 * Connect 0, 1 and 2 to /dev/null.
737 if (!debug_flag && devnull >= 0) {
739 if (strcmp(radlog_dir, "stdout") != 0) {
743 if (devnull > 2) close(devnull);
748 * Disconnect from session
750 if(debug_flag == 0 && dont_fork == 0) {
753 log(L_ERR|L_CONS, "Couldn't fork");
758 * The parent exits, so the child can run in the background.
769 * Ensure that we're using the CORRECT pid after forking,
770 * NOT the one we started with.
772 radius_pid = getpid();
776 * Only write the PID file if we're running as a daemon.
778 * And write it AFTER we've forked, so that we write the
781 if (dont_fork == FALSE) {
784 fp = fopen(pid_file, "w");
786 fprintf(fp, "%d\n", radius_pid);
789 log(L_ERR|L_CONS, "Failed writing process id to file %s: %s\n",
790 pid_file, strerror(errno));
797 * If we're spawning children, set up the thread pool.
805 * Use linebuffered or unbuffered stdout if
806 * the debug flag is on.
808 if (debug_flag) setlinebuf(stdout);
813 ip_ntoa((char *)buffer, myip);
816 if (proxy_requests) {
817 log(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp, with proxy on %d/udp.",
818 buffer, auth_port, acct_port, proxy_port);
820 log(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp.",
821 buffer, auth_port, acct_port);
825 * Note that we NO LONGER fork an accounting process!
826 * We used to do it for historical reasons, but that
829 log(L_INFO, "Ready to process requests.");
832 * Receive user requests
842 FD_SET(authfd, &readfds);
844 FD_SET(acctfd, &readfds);
846 FD_SET(proxyfd, &readfds);
847 tvp = proxy_setuptimeout(&tv);
849 status = select(32, &readfds, NULL, NULL, tvp);
852 * On interrupts, we clean up the
855 if (errno == EINTR) {
865 for (i = 0; i < 3; i++) {
867 if (i == 0) fd = authfd;
868 if (i == 1) fd = acctfd;
869 if (i == 2) fd = proxyfd;
870 if (fd < 0 || !FD_ISSET(fd, &readfds))
874 * Receive the packet.
876 packet = rad_recv(fd);
877 if (packet == NULL) {
878 log(L_ERR, "%s", librad_errstr);
883 * Check if we know this client.
885 if ((cl = client_find(packet->src_ipaddr)) == NULL) {
886 log(L_ERR, "Ignoring request from unknown client %s",
893 * Do yet another check, to see if the
894 * packet code is valid. We only understand
895 * a few, so stripping off obviously invalid
896 * packets here will make our life easier.
898 if (packet->code > PW_ACCESS_CHALLENGE) {
899 log(L_ERR, "Ignoring request from client %s with unknown code %d", buffer, packet->code);
904 if ((request = malloc(sizeof(REQUEST))) == NULL) {
905 log(L_ERR|L_CONS, "no memory");
908 memset(request, 0, sizeof(REQUEST));
910 request->magic = REQUEST_MAGIC;
912 request->packet = packet;
913 request->proxy = NULL;
914 request->reply = NULL;
915 request->proxy_reply = NULL;
916 request->config_items = NULL;
917 request->username = NULL;
918 request->password = NULL;
919 request->timestamp = time(NULL);
920 request->child_pid = NO_SUCH_CHILD_PID;
921 request->prev = NULL;
922 request->next = NULL;
923 strcpy(request->secret, cl->secret);
924 rad_process(request, spawn_flag);
928 * After processing all new requests,
929 * check if we've got to delete old requests
930 * from the request list.
938 * Process supported requests:
940 * PW_AUTHENTICATION_REQUEST - Authentication request from
941 * a client network access server.
943 * PW_ACCOUNTING_REQUEST - Accounting request from
944 * a client network access server.
946 * PW_AUTHENTICATION_ACK
947 * PW_AUTHENTICATION_REJECT
948 * PW_ACCOUNTING_RESPONSE - Reply from a remote Radius server.
949 * Relay reply back to original NAS.
952 int rad_process(REQUEST *request, int dospawn)
954 RAD_REQUEST_FUNP fun;
958 assert(request->magic == REQUEST_MAGIC);
960 switch(request->packet->code) {
962 case PW_AUTHENTICATION_REQUEST:
964 * Check for requests sent to the wrongport,
965 * and ignore them, if so.
967 if (request->packet->sockfd != authfd) {
968 log(L_ERR, "Request packet code %d sent to authentication port from "
969 "client %s - ID %d : IGNORED",
970 request->packet->code,
971 client_name(request->packet->src_ipaddr),
972 request->packet->id);
973 request_free(request);
978 case PW_ACCOUNTING_REQUEST:
980 * Check for requests sent to the wrong port,
981 * and ignore them, if so.
983 if (request->packet->sockfd != acctfd) {
984 log(L_ERR, "Request packet code %d sent to accounting port from "
985 "client %s - ID %d : IGNORED",
986 request->packet->code,
987 client_name(request->packet->src_ipaddr),
988 request->packet->id);
989 request_free(request);
994 case PW_AUTHENTICATION_ACK:
995 case PW_AUTHENTICATION_REJECT:
996 case PW_ACCOUNTING_RESPONSE:
998 * Replies NOT sent to the proxy port get an
999 * error message logged, and the packet is
1002 if (request->packet->sockfd != proxyfd) {
1003 log(L_ERR, "Reply packet code %d sent to request port from "
1004 "client %s - ID %d : IGNORED",
1005 request->packet->code,
1006 client_name(request->packet->src_ipaddr),
1007 request->packet->id);
1008 request_free(request);
1014 assert(request->magic == REQUEST_MAGIC);
1017 * Select the required function and indicate if
1018 * we need to fork off a child to handle it.
1020 switch(request->packet->code) {
1022 case PW_AUTHENTICATION_ACK:
1023 case PW_AUTHENTICATION_REJECT:
1024 case PW_AUTHENTICATION_REQUEST:
1025 fun = rad_authenticate;
1028 case PW_ACCOUNTING_RESPONSE:
1029 case PW_ACCOUNTING_REQUEST:
1030 fun = rad_accounting;
1033 case PW_PASSWORD_REQUEST:
1035 * We don't support this anymore.
1037 log(L_ERR, "Deprecated password change request from client %s "
1038 "- ID %d : IGNORED",
1039 client_name(request->packet->src_ipaddr),
1040 request->packet->id);
1041 request_free(request);
1046 log(L_ERR, "Unknown packet type %d from client %s "
1047 "- ID %d : IGNORED",
1048 request->packet->code,
1049 client_name(request->packet->src_ipaddr),
1050 request->packet->id);
1051 request_free(request);
1057 * If we did NOT select a function, then exit immediately.
1060 request_free(request);
1065 * Check for a duplicate, or error.
1066 * Throw away the the request if so.
1068 request = rad_check_list(request);
1069 if (request == NULL) {
1073 assert(request->magic == REQUEST_MAGIC);
1076 * If we're spawning a child thread, let it do all of
1077 * the work of handling a request, and exit.
1081 * Maybe the spawn failed. If so, then we
1082 * trivially reject the request (because we can't
1083 * handle it), and return.
1085 if (rad_spawn_child(request, fun) < 0) {
1086 rad_reject(request);
1087 request->finished = TRUE;
1092 rad_respond(request, fun);
1097 * Reject a request, by sending a trivial reply packet.
1099 static void rad_reject(REQUEST *request)
1101 DEBUG2("Server rejecting request.");
1102 switch (request->packet->code) {
1104 * Accounting requests, etc. get dropped on the floor.
1106 case PW_ACCOUNTING_REQUEST:
1111 * Authentication requests get their Proxy-State
1112 * attributes copied over, and an otherwise blank
1113 * reject message sent.
1115 case PW_AUTHENTICATION_REQUEST:
1116 request->reply = build_reply(PW_AUTHENTICATION_REJECT,
1117 request, NULL, NULL);
1122 * If a reply exists, send it.
1124 if (request->reply) {
1125 rad_send(request->reply, request->secret);
1130 * Respond to a request packet.
1132 * Maybe we reply, maybe we don't.
1133 * Maybe we proxy the request to another server, or else maybe
1134 * we replicate it to another server.
1136 int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
1138 RADIUS_PACKET *packet, *original;
1140 int finished = FALSE;
1144 * Put the decoded packet into it's proper place.
1146 if (request->proxy_reply != NULL) {
1147 packet = request->proxy_reply;
1148 secret = request->proxysecret;
1149 original = request->proxy;
1151 packet = request->packet;
1152 secret = request->secret;
1156 assert(request->magic == REQUEST_MAGIC);
1159 * Decode the packet, verifying it's signature,
1160 * and parsing the attributes into structures.
1162 * Note that we do this CPU-intensive work in
1163 * a child thread, not the master. This helps to
1164 * spread the load a little bit.
1166 if (rad_decode(packet, original, secret) != 0) {
1167 log(L_ERR, "%s", librad_errstr);
1168 rad_reject(request);
1169 goto finished_request;
1173 * For proxy replies, remove non-allowed
1174 * attributes from the list of VP's.
1176 if (request->proxy) {
1178 replicating = proxy_receive(request);
1179 if (replicating != 0) {
1185 * We should have a User-Name attribute now.
1187 if (request->username == NULL) {
1188 request->username = pairfind(request->packet->vps,
1193 * We have the semaphore, and have decoded the packet.
1194 * Let's process the request.
1196 assert(request->magic == REQUEST_MAGIC);
1200 * If we don't already have a proxy
1201 * packet for this request, we MIGHT have
1204 if (proxy_requests) {
1205 if (request->proxy == NULL) {
1206 proxy_sent = proxy_send(request);
1209 * sent==1 means it's been proxied. The child
1210 * is done handling the request, but the request
1213 if (proxy_sent == 1) {
1214 goto postpone_request;
1217 } else if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
1218 (request->reply == NULL)) {
1220 * We're not configured to reply to the packet,
1221 * and we're not proxying, so the DEFAULT behaviour
1222 * is to REJECT the user.
1224 DEBUG2("There was no response configured: rejecting the user.");
1225 rad_reject(request);
1226 goto finished_request;
1230 * If there's a reply, send it to the NAS.
1232 assert(request->magic == REQUEST_MAGIC);
1234 rad_send(request->reply, request->secret);
1237 * We're done processing the request, set the
1238 * request to be finished, clean up as necessary,
1239 * and forget about the request.
1243 * We're done handling the request. Free up the linked
1244 * lists of value pairs. This might take a long time,
1245 * so it's more efficient to do it in a child thread,
1246 * instead of in the main handler when it eventually
1247 * gets around to deleting the request.
1249 * Also, no one should be using these items after the
1250 * request is finished, and the reply is sent. Cleaning
1251 * them up here ensures that they're not being used again.
1253 * Hmm... cleaning them up in the child thread also seems
1254 * to make the server run more efficiently!
1257 /* If we proxied this request, it's not safe to delete it until
1258 * after the proxy reply
1261 goto postpone_request;
1263 if (request->packet && request->packet->vps) {
1264 pairfree(request->packet->vps);
1265 request->packet->vps = NULL;
1266 request->username = NULL;
1267 request->password = NULL;
1269 if (request->reply && request->reply->vps) {
1270 pairfree(request->reply->vps);
1271 request->reply->vps = NULL;
1273 if (request->config_items) {
1274 pairfree(request->config_items);
1275 request->config_items = NULL;
1278 DEBUG2("Finished request");
1282 * Go to the next request, without marking
1283 * the current one as finished.
1286 DEBUG2("Going to the next request");
1289 * If this is an accounting request, ensure
1290 * that we delete it immediately, as there CANNOT be
1291 * duplicate accounting packets. If there are, then
1292 * something else is seriously wrong...
1294 if (request->packet->code == PW_ACCOUNTING_REQUEST) {
1295 request->timestamp = 0;
1298 #if WITH_THREAD_POOL
1299 request->child_pid = NO_SUCH_CHILD_PID;
1301 request->finished = finished; /* do as the LAST thing before exiting */
1308 * Clean up the request list, every so often.
1310 * This is done by walking through ALL of the list, and
1311 * - joining any child threads which have exited. (If not pooling)
1312 * - killing any processes which are NOT finished after a delay
1313 * - deleting any requests which are finished, and expired
1315 static int rad_clean_list(void)
1320 child_pid_t child_pid;
1323 int cleaned = FALSE;
1325 curtime = time(NULL);
1328 * Don't bother checking the list if we've done it
1329 * within the last second.
1331 if ((curtime - last_cleaned_list) == 0) {
1335 #if WITH_THREAD_POOL
1337 * Only clean the thread pool if we've spawned child threads.
1340 thread_pool_clean();
1345 * When mucking around with the request list, we block
1346 * asynchronous access (through the SIGCHLD handler) to
1347 * the list - equivalent to sigblock(SIGCHLD).
1349 request_list_busy = TRUE;
1351 for (id = 0; id < 256; id++) {
1352 curreq = request_list[id].first_request;
1355 while (curreq != NULL) {
1356 assert(curreq->magic == REQUEST_MAGIC);
1359 * Maybe the child process handling the request
1360 * has hung: kill it, and continue.
1362 if (!curreq->finished &&
1363 (curreq->timestamp + max_request_time) <= curtime) {
1364 if (curreq->child_pid != NO_SUCH_CHILD_PID) {
1366 * This request seems to have hung
1369 child_pid = curreq->child_pid;
1370 log(L_ERR, "Killing unresponsive child %d",
1372 child_kill(child_pid, SIGTERM);
1373 } /* else no proxy reply, quietly fail */
1376 * Mark the request as unsalvagable.
1378 curreq->child_pid = NO_SUCH_CHILD_PID;
1379 curreq->finished = TRUE;
1380 curreq->timestamp = 0;
1384 * Delete the current request, if it's
1385 * marked as such. That is, the request
1386 * must be finished, there must be no
1387 * child associated with that request,
1388 * and it's timestamp must be marked to
1391 if (curreq->finished &&
1392 (curreq->child_pid == NO_SUCH_CHILD_PID) &&
1393 (curreq->timestamp + cleanup_delay <= curtime)) {
1395 * Request completed, delete it,
1396 * and unlink it from the
1397 * currently 'alive' list of
1400 DEBUG2("Cleaning up request ID %d with timestamp %08x",
1401 curreq->packet->id, curreq->timestamp);
1402 prevreq = curreq->prev;
1403 if (request_list[id].request_count == 0) {
1404 DEBUG("HORRIBLE ERROR!!!");
1406 request_list[id].request_count--;
1410 if (prevreq == NULL) {
1411 request_list[id].first_request = curreq->next;
1412 request_free(curreq);
1413 curreq = request_list[id].first_request;
1415 prevreq->next = curreq->next;
1416 request_free(curreq);
1417 curreq = prevreq->next;
1420 curreq->prev = prevreq;
1422 } else { /* the request is still alive */
1424 curreq = curreq->next;
1426 } /* end of walking the request list for that ID */
1427 } /* for each entry in the request list array */
1430 for (id = 0; id < 256; id++) {
1431 request_count += request_list[id].request_count;
1435 * Only print this if anything's changed.
1438 static int old_request_count = -1;
1440 if (request_count != old_request_count) {
1441 DEBUG2("%d requests left in the list", request_count);
1442 old_request_count = request_count;
1447 * We're done playing with the request list.
1449 request_list_busy = FALSE;
1450 last_cleaned_list = curtime;
1456 * Walk through the request list, cleaning up complete child
1457 * requests, and verifing that there is only one process
1458 * responding to each request (duplicate requests are filtered
1461 * Also, check if the request is a reply from a request proxied to
1462 * a remote server. If so, play games with the request, and return
1465 static REQUEST *rad_check_list(REQUEST *request)
1471 REQUEST_LIST *request_list_entry;
1477 * If the request has come in on the proxy FD, then
1478 * it's a proxy reply, so pass it through the proxy
1479 * code for checking the REQUEST_LIST.
1481 if (request->packet->sockfd == proxyfd) {
1482 return proxy_check_list(request);
1485 * If the request already has a proxy packet,
1486 * then it obviously is not a new request, either.
1488 } else if (request->proxy != NULL) {
1492 request_list_entry = &request_list[request->packet->id];
1494 assert((request_list_entry->first_request == NULL) ||
1495 (request_list_entry->request_count != 0));
1496 assert((request_list_entry->first_request != NULL) ||
1497 (request_list_entry->request_count == 0));
1498 curreq = request_list_entry->first_request;
1500 pkt = request->packet;
1502 curtime = request->timestamp; /* good enough for our purposes */
1506 * When mucking around with the request list, we block
1507 * asynchronous access (through the SIGCHLD handler) to
1508 * the list - equivalent to sigblock(SIGCHLD).
1510 request_list_busy = TRUE;
1512 while (curreq != NULL) {
1513 assert(curreq->packet->id == pkt->id);
1516 * Let's see if we received a duplicate of
1517 * a packet we already have in our list.
1519 * We do this be checking the src IP, (NOT port)
1520 * the packet code, and ID.
1522 if ((curreq->packet->src_ipaddr == pkt->src_ipaddr) &&
1523 (curreq->packet->code == pkt->code)) {
1525 * We now check the authentication vectors.
1526 * If the client has sent us a request with
1527 * identical code && ID, but different vector,
1528 * then they MUST have gotten our response, so
1529 * we can delete the original request, and process
1532 * If the vectors are the same, then it's a duplicate
1533 * request, and we can send a duplicate reply.
1535 if (memcmp(curreq->packet->vector, pkt->vector,
1536 sizeof(pkt->vector)) == 0) {
1538 * Maybe we've saved a reply packet. If so,
1539 * re-send it. Otherwise, just complain.
1541 if (curreq->reply) {
1543 "Sending duplicate authentication reply"
1544 " to client %s - ID: %d",
1545 client_name(request->packet->src_ipaddr),
1546 request->packet->id);
1547 rad_send(curreq->reply, curreq->secret);
1550 * There's no reply, but maybe there's
1551 * an outstanding proxy request.
1553 * If so, then kick the proxy again.
1555 } else if (curreq->proxy != NULL) {
1556 if (proxy_synchronous) {
1557 DEBUG2("Sending duplicate proxy request to client %s - ID: %d",
1558 client_name(curreq->proxy->dst_ipaddr),
1560 curreq->proxy_next_try = request->timestamp + RETRY_DELAY;
1561 rad_send(curreq->proxy, curreq->proxysecret);
1563 DEBUG2("Ignoring duplicate authentication packet"
1564 " from client %s - ID: %d, due to outstanding proxy request.",
1565 client_name(request->packet->src_ipaddr),
1566 request->packet->id);
1570 "Dropping duplicate authentication packet"
1571 " from client %s - ID: %d",
1572 client_name(request->packet->src_ipaddr),
1573 request->packet->id);
1577 * Delete the duplicate request, and
1578 * stop processing the request list.
1580 request_free(request);
1585 * The packet vectors are different, so
1586 * we can mark the old request to be
1587 * deleted from the list.
1589 * Note that we don't actually delete it...
1592 if (curreq->finished) {
1593 curreq->timestamp = 0;
1596 * ??? the client sent us a new request
1597 * with the same ID, while we were processing
1598 * the old one! What should we do?
1601 "Dropping conflicting authentication packet"
1602 " from client %s - ID: %d",
1603 client_name(request->packet->src_ipaddr),
1604 request->packet->id);
1605 request_free(request);
1613 * Ugh... duplicated code is bad...
1617 * Delete the current request, if it's
1618 * marked as such. That is, the request
1619 * must be finished, there must be no
1620 * child associated with that request,
1621 * and it's timestamp must be marked to
1624 if (curreq->finished &&
1625 (curreq->child_pid == NO_SUCH_CHILD_PID) &&
1626 (curreq->timestamp + cleanup_delay <= curtime)) {
1628 * Request completed, delete it,
1629 * and unlink it from the
1630 * currently 'alive' list of
1633 DEBUG2("Cleaning up request ID %d with timestamp %08x",
1634 curreq->packet->id, curreq->timestamp);
1635 prevreq = curreq->prev;
1636 if (request_list[id].request_count == 0) {
1637 DEBUG("HORRIBLE ERROR!!!");
1639 request_list[id].request_count--;
1642 if (prevreq == NULL) {
1643 request_list[id].first_request = curreq->next;
1644 request_free(curreq);
1645 curreq = request_list[id].first_request;
1647 prevreq->next = curreq->next;
1648 request_free(curreq);
1649 curreq = prevreq->next;
1652 curreq->prev = prevreq;
1654 } else { /* the request is still alive */
1656 curreq = curreq->next;
1659 } /* end of walking the request list */
1662 * If we've received a duplicate packet, 'request' is NULL.
1664 if (request == NULL) {
1665 request_list_busy = FALSE;
1669 assert(request_list_entry->request_count == request_count);
1672 * Count the total number of requests, to see if there
1673 * are too many. If so, stop counting immediately,
1674 * and return with an error.
1677 for (i = 0; i < 256; i++) {
1678 request_count += request_list[i].request_count;
1681 * This is a new request. Let's see if it
1682 * makes us go over our configured bounds.
1684 if (request_count > max_requests) {
1685 log(L_ERR, "Dropping request (%d is too many): "
1686 "from client %s - ID: %d", request_count,
1687 client_name(request->packet->src_ipaddr),
1688 request->packet->id);
1689 sig_cleanup(SIGCHLD);
1690 request_free(request);
1691 request_list_busy = FALSE;
1697 * Add this request to the list
1699 request->prev = prevreq;
1700 request->next = NULL;
1701 request->child_pid = NO_SUCH_CHILD_PID;
1702 request_list_entry->request_count++;
1704 if (prevreq == NULL) {
1705 assert(request_list_entry->first_request == NULL);
1706 assert(request_list_entry->request_count == 1);
1707 request_list_entry->first_request = request;
1709 assert(request_list_entry->first_request != NULL);
1710 prevreq->next = request;
1714 * And return the request to be handled.
1716 request_list_busy = FALSE;
1720 #ifndef WITH_THREAD_POOL
1722 typedef struct spawn_thread_t {
1724 RAD_REQUEST_FUNP fun;
1728 * If the child *thread* gets a termination signal,
1729 * then exit from the thread.
1731 static void sig_term(int sig)
1733 sig = sig; /* -Wunused */
1738 * Spawn a new child thread to handle this request, and ONLY
1741 static void *rad_spawn_thread(void *arg)
1744 spawn_thread_t *data = (spawn_thread_t *)arg;
1747 * Note that this behaviour only works on Linux.
1749 * It's generally NOT the thing to do, and should
1752 * Q: How do we signal a hung thread, and tell it to
1755 signal(SIGTERM, sig_term);
1758 * Keep only allowed attributes in the request.
1760 if (data->request->proxy) {
1761 replicating = proxy_receive(data->request);
1762 if (replicating != 0) {
1763 data->request->finished = TRUE;
1769 rad_respond(data->request, data->fun);
1770 data->request->child_pid = NO_SUCH_CHILD_PID;
1778 * If we're using the thread pool, then the function in
1779 * 'threads.c' replaces this one.
1781 #ifndef WITH_THREAD_POOL
1783 * Spawns a child process or thread to perform
1784 * authentication/accounting and respond to RADIUS clients.
1786 static int rad_spawn_child(REQUEST *request, RAD_REQUEST_FUNP fun)
1788 child_pid_t child_pid;
1792 spawn_thread_t *data;
1794 data = (spawn_thread_t *) malloc(sizeof(spawn_thread_t));
1795 memset(data, 0, sizeof(data));
1796 data->request = request;
1800 * Create a child thread, complaining on error.
1802 rcode = pthread_create(&child_pid, NULL, rad_spawn_thread, data);
1804 log(L_ERR, "Thread create failed for request from nas %s - ID: %d : %s",
1805 nas_name2(request->packet),
1806 request->packet->id,
1812 * Detach it, so it's state is automagically cleaned up on exit.
1814 pthread_detach(child_pid);
1821 if (child_pid < 0) {
1822 log(L_ERR, "Fork failed for request from nas %s - ID: %d",
1823 nas_name2(request->packet),
1824 request->packet->id);
1828 if (child_pid == 0) {
1831 * This is the child, it should go ahead and respond
1833 signal(SIGCHLD, SIG_DFL);
1834 rad_respond(request, fun);
1840 * Register the Child
1842 request->child_pid = child_pid;
1844 sig_cleanup(SIGCHLD);
1847 #endif /* WITH_THREAD_POOL */
1850 void sig_cleanup(int sig)
1856 sig = sig; /* -Wunused */
1859 * request_list_busy is a lock on the request list
1861 if (request_list_busy) {
1868 * Reset the signal handler, if required.
1870 reset_signal(SIGCHLD, sig_cleanup);
1873 pid = waitpid((pid_t)-1, &status, WNOHANG);
1878 * Check to see if the child did a bad thing.
1879 * If so, kill ALL processes in the current
1880 * process group, to prevent further attacks.
1882 if (debug_flag && (WIFSIGNALED(status))) {
1883 log(L_ERR|L_CONS, "MASTER: Child PID %d failed to catch signal %d: killing all active servers.\n",
1884 pid, WTERMSIG(status));
1890 * Service all of the requests in the queues
1892 for (i = 0; i < 256; i++) {
1893 curreq = request_list[i].first_request;
1894 while (curreq != (REQUEST *)NULL) {
1895 if (curreq->child_pid == pid) {
1896 curreq->child_pid = NO_SUCH_CHILD_PID;
1899 curreq = curreq->next;
1906 * Display the syntax for starting this program.
1908 static void usage(void)
1911 "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-p port] [-"
1912 #if defined(WITH_DBM) || defined(WITH_NDBM)
1915 "AcfnsSvXxyz]\n", progname);
1916 fprintf(stderr, "Options:\n\n");
1917 fprintf(stderr, " -a acct_dir use accounting directory 'acct_dir'.\n");
1918 fprintf(stderr, " -A Log auth detail.\n");
1919 #if defined(WITH_DBM) || defined(WITH_NDBM)
1920 fprintf(stderr, " -b Use DBM.\n");
1922 fprintf(stderr, " -d db_dir Use database directory 'db_dir'.\n");
1923 fprintf(stderr, " -f Run as a foreground process, not a daemon.\n");
1924 fprintf(stderr, " -h Print this help message.\n");
1925 fprintf(stderr, " -i address Listen only in the given IP address.\n");
1926 fprintf(stderr, " -l log_dir Log messages to 'log_dir'. Special values are:\n");
1927 fprintf(stderr, " stdout == log all messages to standard output.\n");
1928 fprintf(stderr, " syslog == log all messages to the system logger.\n");
1929 fprintf(stderr, " -n Do not do DNS host name lookups.\n");
1930 fprintf(stderr, " -p port Bind to 'port', and not to the radius/udp, or 1646/udp.\n");
1931 fprintf(stderr, " -s Do not spawn child processes to handle requests.\n");
1932 fprintf(stderr, " -S Log stripped names.\n");
1933 fprintf(stderr, " -v Print server version information.\n");
1934 fprintf(stderr, " -X Turn on full debugging. (Means: -sfxxyz -l stdout)\n");
1935 fprintf(stderr, " -x Turn on partial debugging. (-xx gives more debugging).\n");
1936 fprintf(stderr, " -y Log authentication failures, with password.\n");
1937 fprintf(stderr, " -z Log authentication successes, with password.\n");
1943 * We got a fatal signal. Clean up and exit.
1945 static void sig_fatal(int sig)
1947 const char *me = "MASTER: ";
1949 if (radius_pid != getpid()) {
1955 log(L_ERR, "%saccounting process died - exit.", me);
1958 log(L_ERR, "%sfailed in select() - exit.", me);
1961 log(L_INFO, "%sexit.", me);
1964 log(L_ERR, "%sexit on signal (%d)", me, sig);
1969 if (radius_pid == getpid()) {
1971 * Kill all of the processes in the current
1977 exit(sig == SIGTERM ? 0 : 1);
1982 * We got the hangup signal.
1983 * Re-read the configuration files.
1986 static void sig_hup(int sig)
1988 sig = sig; /* -Wunused */
1989 reset_signal(SIGHUP, sig_hup);
1992 * Only do the reload if we're the main server, both
1993 * for processes, and for threads.
1995 if (getpid() == radius_pid) {
2001 * Do a proxy check of the REQUEST_LIST when using the new proxy code.
2003 * This function and the next two are here because they have to access
2004 * the REQUEST_LIST structure, which is 'static' to this C file.
2006 static REQUEST *proxy_check_list(REQUEST *request)
2013 * Find the original request in the request list
2016 pkt = request->packet;
2018 for (id = 0; (id < 256) && (oldreq == NULL); id++) {
2019 for (oldreq = request_list[id].first_request ;
2021 oldreq = oldreq->next) {
2024 * See if this reply packet matches a proxy
2025 * packet which we sent.
2027 if (oldreq->proxy &&
2028 (oldreq->proxy->dst_ipaddr == pkt->src_ipaddr) &&
2029 (oldreq->proxy->dst_port == pkt->src_port) &&
2030 (oldreq->proxy->id == pkt->id)) {
2032 * If there is already a reply,
2033 * maybe the new one is a duplicate?
2035 if (oldreq->proxy_reply) {
2036 if (memcmp(oldreq->proxy_reply->vector,
2037 request->packet->vector,
2038 sizeof(oldreq->proxy_reply->vector)) == 0) {
2039 DEBUG2("Ignoring duplicate proxy reply");
2040 request_free(request);
2044 * got other stuff...
2048 } /* else no reply, this one must match */
2055 * If we haven't found the old request, complain.
2057 if (oldreq == NULL) {
2058 log(L_PROXY, "Unrecognized proxy reply from server %s - ID %d",
2059 client_name(request->packet->src_ipaddr),
2060 request->packet->id);
2061 request_free(request);
2066 * Refresh the old request,. and update it.
2068 oldreq->timestamp += 5;
2069 oldreq->proxy_reply = request->packet;
2070 request->packet = NULL;
2071 request_free(request);
2075 struct timeval *proxy_setuptimeout(struct timeval *tv)
2077 time_t now = time(NULL);
2078 time_t difference, smallest = 0;
2083 if (proxy_requests) {
2084 for (id = 0; id < 256; id++) {
2085 for (p = request_list[id].first_request; p; p = p->next)
2089 if (!p->proxy_is_replicate)
2091 difference = p->proxy_next_try - now;
2094 smallest = difference;
2096 if (difference < smallest)
2097 smallest = difference;
2104 * Not found one, tell the server to wake up a second
2105 * later anyways, so that it can service the lists.
2107 * FIXME: It would be better if the select() would
2108 * actually wake up when there's something to do, and
2109 * no sooner. Waking up _every_ second is kludgy
2118 tv->tv_sec = smallest;
2123 void proxy_retry(void)
2125 time_t now = time(NULL);
2129 for (id = 0; id < 256; id++) {
2130 for (p = request_list[id].first_request; p; p = p->next) {
2133 if (p->proxy_next_try <= now) {
2134 if (p->proxy_try_count) {
2135 --p->proxy_try_count;
2136 p->proxy_next_try = now + proxy_retry_delay;
2138 /* Fix up Acct-Delay-Time */
2139 if (p->proxy->code == PW_ACCOUNTING_REQUEST) {
2140 VALUE_PAIR *delaypair;
2141 delaypair = pairfind(p->proxy->vps, PW_ACCT_DELAY_TIME);
2144 delaypair = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
2146 log(L_ERR|L_CONS, "no memory");
2149 pairadd(&p->proxy->vps, delaypair);
2151 delaypair->lvalue = now - p->proxy->timestamp;
2153 /* Must recompile the valuepairs to wire format */
2154 free(p->proxy->data);
2155 p->proxy->data = NULL;
2158 rad_send(p->proxy, p->proxysecret);