2 * radiusd.c Main loop of the radius server.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2000,2001,2002,2003,2004 The FreeRADIUS server project
21 * Copyright 1999,2000 Miquel van Smoorenburg <miquels@cistron.nl>
22 * Copyright 2000 Alan DeKok <aland@ox.org>
23 * Copyright 2000 Alan Curry <pacman-radius@cqc.com>
24 * Copyright 2000 Jeff Carneal <jeff@apex.net>
25 * Copyright 2000 Chad Miller <cmiller@surfsouth.com>
28 /* don't look here for the version, run radiusd -v or look in version.c */
29 static const char rcsid[] =
33 #include "libradius.h"
37 #ifdef HAVE_NETINET_IN_H
38 # include <netinet/in.h>
56 #ifdef HAVE_SYS_SELECT_H
57 # include <sys/select.h>
60 #ifdef HAVE_SYS_WAIT_H
61 # include <sys/wait.h>
64 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
67 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
71 #include "rad_assert.h"
74 #include "request_list.h"
75 #include "radius_snmp.h"
80 const char *progname = NULL;
81 const char *radius_dir = NULL;
82 const char *radacct_dir = NULL;
83 const char *radlog_dir = NULL;
84 const char *radlib_dir = NULL;
85 int log_stripped_names;
87 int log_auth_detail = FALSE;
88 int need_reload = FALSE;
89 const char *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
91 static time_t time_now;
92 static pid_t radius_pid;
95 * Configuration items.
97 static time_t start_time = 0;
98 static int do_exit = 0;
103 static void usage(int);
105 static void sig_fatal (int);
106 static void sig_hup (int);
108 static int rad_status_server(REQUEST *request);
112 * Check if an incoming request is "ok"
114 * It takes packets, not requests. It sees if the packet looks
115 * OK. If so, it does a number of sanity checks on it.
117 static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
118 rad_listen_t *listener)
121 RAD_REQUEST_FUNP fun = NULL;
124 * Some sanity checks, based on the packet code.
126 switch(packet->code) {
127 case PW_AUTHENTICATION_REQUEST:
129 * Check for requests sent to the wrong
130 * port, and ignore them, if so.
132 if (listener->type != RAD_LISTEN_AUTH) {
133 RAD_SNMP_INC(rad_snmp.auth.total_packets_dropped);
134 radlog(L_ERR, "Authentication-Request sent to a non-authentication port from "
135 "client %s port %d - ID %d : IGNORED",
136 client_name(&packet->src_ipaddr),
137 packet->src_port, packet->id);
140 fun = rad_authenticate;
143 case PW_ACCOUNTING_REQUEST:
145 * Check for requests sent to the wrong
146 * port, and ignore them, if so.
148 if (listener->type != RAD_LISTEN_ACCT) {
149 RAD_SNMP_INC(rad_snmp.acct.total_packets_dropped);
150 radlog(L_ERR, "Accounting-Request packet sent to a non-accounting port from "
151 "client %s port %d - ID %d : IGNORED",
152 client_name(&packet->src_ipaddr),
153 packet->src_port, packet->id);
156 fun = rad_accounting;
159 case PW_AUTHENTICATION_ACK:
160 case PW_ACCESS_CHALLENGE:
161 case PW_AUTHENTICATION_REJECT:
163 * Replies NOT sent to the proxy port get
164 * an error message logged, and the
167 if (listener->type != RAD_LISTEN_PROXY) {
168 RAD_SNMP_INC(rad_snmp.auth.total_packets_dropped);
169 radlog(L_ERR, "Authentication reply packet code %d sent to a non-proxy reply port from "
170 "client %s port %d - ID %d : IGNORED",
172 client_name(&packet->src_ipaddr),
173 packet->src_port, packet->id);
176 fun = rad_authenticate;
179 case PW_ACCOUNTING_RESPONSE:
181 * Replies NOT sent to the proxy port get
182 * an error message logged, and the
185 if (listener->type != RAD_LISTEN_PROXY) {
186 RAD_SNMP_INC(rad_snmp.acct.total_packets_dropped);
187 radlog(L_ERR, "Accounting reply packet code %d sent to a non-proxy reply port from "
188 "client %s port %d - ID %d : IGNORED",
190 client_name(&packet->src_ipaddr),
191 packet->src_port, packet->id);
194 fun = rad_accounting;
197 case PW_STATUS_SERVER:
198 if (!mainconfig.status_server) {
199 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
202 fun = rad_status_server;
205 case PW_PASSWORD_REQUEST:
206 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
209 * We don't support this anymore.
211 radlog(L_ERR, "Deprecated password change request from client %s port %d - ID %d : IGNORED",
212 client_name(&packet->src_ipaddr),
213 packet->src_port, packet->id);
218 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
220 radlog(L_ERR, "Unknown packet code %d from client %s:%d "
221 "- ID %d : IGNORED", packet->code,
222 client_name(&packet->src_ipaddr),
223 packet->src_port, packet->id);
227 } /* switch over packet types */
230 * Don't handle proxy replies here. They need to
231 * return the *old* request, so we can re-process it.
233 if (listener->type == RAD_LISTEN_PROXY) {
238 * If there is no existing request of id, code, etc.,
239 * then we can return, and let it be processed.
241 if ((curreq = rl_find(packet)) == NULL) {
243 * Count the total number of requests, to see if
244 * there are too many. If so, return with an
247 if (mainconfig.max_requests) {
248 int request_count = rl_num_requests();
251 * This is a new request. Let's see if
252 * it makes us go over our configured
255 if (request_count > mainconfig.max_requests) {
256 radlog(L_ERR, "Dropping request (%d is too many): "
257 "from client %s:%d - ID: %d", request_count,
258 client_name(&packet->src_ipaddr),
259 packet->src_port, packet->id);
260 radlog(L_INFO, "WARNING: Please check the radiusd.conf file.\n"
261 "\tThe value for 'max_requests' is probably set too low.\n");
263 } /* else there were a small number of requests */
264 } /* else there was no configured limit for requests */
267 * FIXME: Add checks for system load. If the
268 * system is busy, start dropping requests...
270 * We can probably keep some statistics
271 * ourselves... if there are more requests
272 * coming in than we can handle, start dropping
280 * "fake" requests MUST NEVER be in the request list.
282 * They're used internally in the server. Any reply
283 * is a reply to the local server, and any proxied packet
284 * gets sent outside of the tunnel.
286 rad_assert((curreq->options & RAD_REQUEST_OPTION_FAKE_REQUEST) == 0);
289 * The current request isn't finished, which
290 * means that the NAS sent us a new packet, while
291 * we are still processing the old request.
293 if (!curreq->finished) {
295 * If the authentication vectors are identical,
296 * then the NAS is re-transmitting it, trying to
297 * kick us into responding to the request.
299 if (memcmp(curreq->packet->vector, packet->vector,
300 sizeof(packet->vector)) == 0) {
301 RAD_SNMP_INC(rad_snmp.auth.total_dup_requests);
304 * It's not finished because the request
305 * was proxied, but there was no reply
306 * from the home server.
308 if (curreq->proxy && !curreq->proxy_reply) {
310 * We're taking care of sending
311 * duplicate proxied packets, so
312 * we ignore any duplicate
313 * requests from the NAS.
315 * FIXME: Make it ALWAYS synchronous!
317 if (!mainconfig.proxy_synchronous) {
318 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
320 DEBUG2("Ignoring duplicate packet from client "
321 "%s:%d - ID: %d, due to outstanding proxied request %d.",
322 client_name(&packet->src_ipaddr),
323 packet->src_port, packet->id,
328 * We ARE proxying the request,
329 * and we have NOT received a
330 * proxy reply yet, and we ARE
331 * doing synchronous proxying.
333 * In that case, go kick
334 * the home RADIUS server
340 DEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
341 inet_ntop(curreq->proxy->dst_ipaddr.af,
342 &curreq->proxy->dst_ipaddr.ipaddr,
343 buffer, sizeof(buffer)), curreq->proxy->dst_port,
347 curreq->proxy_next_try = time_now + mainconfig.proxy_retry_delay;
348 rad_send(curreq->proxy, curreq->packet,
349 curreq->proxysecret);
351 } /* else the packet was not proxied */
354 * Someone's still working on it, so we
355 * ignore the duplicate request.
357 radlog(L_ERR, "Discarding duplicate request from "
358 "client %s port %d - ID: %d due to unfinished request %d",
359 client_name(&packet->src_ipaddr),
360 packet->src_port, packet->id,
363 } /* else the authentication vectors were different */
366 * The authentication vectors are different, so
367 * the NAS has given up on us, as we've taken too
368 * long to process the request. This is a
371 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
373 radlog(L_ERR, "Dropping conflicting packet from "
374 "client %s port %d - ID: %d due to unfinished request %d",
375 client_name(&packet->src_ipaddr),
376 packet->src_port, packet->id,
382 * The old request is finished. We now check the
383 * authentication vectors. If the client has sent us a
384 * request with identical code && ID, but different
385 * vector, then they MUST have gotten our response, so we
386 * can delete the original request, and process the new
389 * If the vectors are the same, then it's a duplicate
390 * request, and we can send a duplicate reply.
392 if (memcmp(curreq->packet->vector, packet->vector,
393 sizeof(packet->vector)) == 0) {
394 RAD_SNMP_INC(rad_snmp.auth.total_dup_requests);
397 * If the packet has been delayed, then silently
398 * send a response, and clear the delayed flag.
400 * Note that this means if the NAS kicks us while
401 * we're delaying a reject, then the reject may
402 * be sent sooner than otherwise.
404 * This COULD be construed as a bug. Maybe what
405 * we want to do is to ignore the duplicate
406 * packet, and send the reject later.
408 if (curreq->options & RAD_REQUEST_OPTION_DELAYED_REJECT) {
409 curreq->options &= ~RAD_REQUEST_OPTION_DELAYED_REJECT;
410 rad_send(curreq->reply, curreq->packet, curreq->secret);
415 * Maybe we've saved a reply packet. If so,
416 * re-send it. Otherwise, just complain.
418 if (curreq->reply->code != 0) {
419 DEBUG2("Sending duplicate reply "
420 "to client %s port %d - ID: %d",
421 client_name(&packet->src_ipaddr),
422 packet->src_port, packet->id);
423 rad_send(curreq->reply, curreq->packet, curreq->secret);
428 * Else we never sent a reply to the NAS,
429 * as we decided somehow we didn't like the request.
431 * This shouldn't happen, in general...
433 DEBUG2("Discarding duplicate request from client %s port %d - ID: %d",
434 client_name(&packet->src_ipaddr),
435 packet->src_port, packet->id);
437 } /* else the vectors were different, so we discard the old request. */
440 * 'packet' has the same source IP, source port, code,
441 * and Id as 'curreq', but a different authentication
442 * vector. We can therefore delete 'curreq', as we were
443 * only keeping it around to send out duplicate replies,
444 * if the first reply got lost in the network.
449 * The request is OK. We can process it...
451 * Don't bother checking the maximum nubmer of requests
452 * here. we've just deleted one, so we KNOW we're under
453 * the limit if we add one more.
460 * Do a proxy check of the REQUEST list when using the new proxy code.
462 static REQUEST *proxy_ok(RADIUS_PACKET *packet)
469 * Find the original request in the request list
471 oldreq = rl_find_proxy(packet);
474 * If we haven't found the original request which was
475 * sent, to get this reply. Complain, and discard this
476 * request, as there's no way for us to send it to a NAS.
479 radlog(L_PROXY, "No outstanding request was found for proxy reply from home server %s port %d - ID %d",
480 inet_ntop(packet->src_ipaddr.af,
481 &packet->src_ipaddr.ipaddr,
482 buffer, sizeof(buffer)),
483 packet->src_port, packet->id);
488 * The proxy reply has arrived too late, as the original
489 * (old) request has timed out, been rejected, and marked
490 * as finished. The client has already received a
491 * response, so there is nothing that can be done. Delete
492 * the tardy reply from the home server, and return NULL.
494 if ((oldreq->reply->code != 0) ||
495 (oldreq->finished)) {
496 radlog(L_ERR, "Reply from home server %s port %d - ID: %d arrived too late for request %d. Try increasing 'retry_delay' or 'max_request_time'",
497 inet_ntop(packet->src_ipaddr.af,
498 &packet->src_ipaddr.ipaddr,
499 buffer, sizeof(buffer)),
500 packet->src_port, packet->id,
506 * If there is already a reply, maybe this one is a
509 if (oldreq->proxy_reply) {
510 if (memcmp(oldreq->proxy_reply->vector,
512 sizeof(oldreq->proxy_reply->vector)) == 0) {
513 radlog(L_ERR, "Discarding duplicate reply from home server %s port %d - ID: %d for request %d",
514 inet_ntop(packet->src_ipaddr.af,
515 &packet->src_ipaddr.ipaddr,
516 buffer, sizeof(buffer)),
517 packet->src_port, packet->id,
521 * ? The home server gave us a new *
522 * proxy reply, which doesn't match * the
525 DEBUG2("Ignoring conflicting proxy reply");
529 * We've already received a reply, so
530 * we discard this one, as we don't want
531 * to do duplicate work.
534 } /* else there wasn't a proxy reply yet, so we can process it */
537 * Refresh the old request, and update it with the proxy
540 * ? Can we delete the proxy request here? * Is there
541 * any more need for it?
543 * FIXME: we probably shouldn't be updating the time
546 oldreq->timestamp = time_now;
547 oldreq->proxy_reply = packet;
550 * Now that we've verified the packet IS actually
551 * from that realm, and not forged, we can go mark the
552 * realms for this home server as active.
554 * If we had done this check in the 'find realm by IP address'
555 * function, then an attacker could force us to use a home
556 * server which was inactive, by forging reply packets
557 * which didn't match any request. We would think that
558 * the reply meant the home server was active, would
559 * re-activate the realms, and THEN bounce the packet
562 for (cl = mainconfig.realms; cl != NULL; cl = cl->next) {
563 if (oldreq->proxy_reply->src_ipaddr.af != cl->ipaddr.af) continue;
564 if (cl->ipaddr.af != AF_INET) continue; /* FIXME */
566 if (oldreq->proxy_reply->src_ipaddr.ipaddr.ip4addr.s_addr == cl->ipaddr.ipaddr.ip4addr.s_addr) {
567 if (oldreq->proxy_reply->src_port == cl->auth_port) {
569 cl->last_reply = oldreq->timestamp;
570 } else if (oldreq->proxy_reply->src_port == cl->acct_port) {
571 cl->acct_active = TRUE;
572 cl->last_reply = oldreq->timestamp;
581 * Do more checks, this time on the REQUEST data structure.
583 * The main purpose of this code is to handle proxied requests.
585 static REQUEST *request_ok(RADIUS_PACKET *packet, uint8_t *secret,
586 rad_listen_t *listener)
588 REQUEST *request = NULL;
591 * If the request has come in on the proxy FD, then
592 * it's a proxy reply, so pass it through the code which
593 * tries to find the original request, which we should
594 * process, rather than processing the reply as a "new"
597 if (listener->type == RAD_LISTEN_PROXY) {
599 * Find the old request, based on the current
602 request = proxy_ok(packet);
606 rad_assert(request->magic == REQUEST_MAGIC);
609 * We must have passed through the code below
610 * for the original request, which adds the
611 * reply packet to it.
613 rad_assert(request->reply != NULL);
615 } else { /* remember the new request */
617 * A unique per-request counter.
619 static int request_num_counter = 0;
621 request = request_alloc(); /* never fails */
622 request->packet = packet;
623 request->number = request_num_counter++;
624 strNcpy(request->secret, (char *)secret,
625 sizeof(request->secret));
628 * Remember the request.
633 * ADD IN "server identifier" from "listen"
638 * The request passes many of our sanity checks.
639 * From here on in, if anything goes wrong, we
640 * send a reject message, instead of dropping the
643 * Build the reply template from the request
646 rad_assert(request->reply == NULL);
647 if ((request->reply = rad_alloc(0)) == NULL) {
648 radlog(L_ERR, "No memory");
651 request->reply->sockfd = request->packet->sockfd;
652 request->reply->dst_ipaddr = request->packet->src_ipaddr;
653 request->reply->src_ipaddr = request->packet->dst_ipaddr;
654 request->reply->dst_port = request->packet->src_port;
655 request->reply->src_port = request->packet->dst_port;
656 request->reply->id = request->packet->id;
657 request->reply->code = 0; /* UNKNOWN code */
658 memcpy(request->reply->vector, request->packet->vector,
659 sizeof(request->reply->vector));
660 request->reply->vps = NULL;
661 request->reply->data = NULL;
662 request->reply->data_len = 0;
672 int main(int argc, char *argv[])
675 RADIUS_PACKET *packet;
677 unsigned char buffer[4096];
683 struct timeval *tv = NULL;
684 int spawn_flag = TRUE;
685 int dont_fork = FALSE;
686 int sig_hup_block = FALSE;
688 #ifdef HAVE_SIGACTION
689 struct sigaction act;
691 rad_listen_t *listener;
694 set_auth_parameters(argc,argv);
697 if ((progname = strrchr(argv[0], '/')) == NULL)
704 radius_dir = strdup(RADIUS_DIR);
707 * Ensure that the configuration is initialized.
709 memset(&mainconfig, 0, sizeof(mainconfig));
710 mainconfig.myip.af = AF_UNSPEC;
711 mainconfig.port = -1;
713 #ifdef HAVE_SIGACTION
714 memset(&act, 0, sizeof(act));
716 sigemptyset( &act.sa_mask ) ;
719 /* Process the options. */
720 while ((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:p:sSvxXyz")) != EOF) {
725 log_auth_detail = TRUE;
729 if (radacct_dir) free(radacct_dir);
730 radacct_dir = strdup(optarg);
734 /* ignore for backwards compatibility with Cistron */
738 if (radius_dir) free(radius_dir);
739 radius_dir = strdup(optarg);
751 if (ip_hton(optarg, AF_INET, &mainconfig.myip) < 0) {
752 fprintf(stderr, "radiusd: Invalid IP Address or hostname \"%s\"\n", optarg);
758 if ((strcmp(optarg, "stdout") == 0) ||
759 (strcmp(optarg, "stderr") == 0) ||
760 (strcmp(optarg, "syslog") == 0)) {
761 fprintf(stderr, "radiusd: -l %s is unsupported. Use log_destination in radiusd.conf\n", optarg);
764 radlog_dir = strdup(optarg);
768 fprintf(stderr, "radiusd: -g is unsupported. Use log_destination in radiusd.conf.\n");
773 log_stripped_names++;
777 mainconfig.port = atoi(optarg);
778 if ((mainconfig.port <= 0) ||
779 (mainconfig.port >= 65536)) {
780 fprintf(stderr, "radiusd: Invalid port number %s\n", optarg);
785 case 's': /* Single process mode */
795 * BIG debugging mode for users who are
796 * TOO LAZY to type '-sfxxyz -l stdout' themselves.
802 mainconfig.log_auth = TRUE;
803 mainconfig.log_auth_badpass = TRUE;
804 mainconfig.log_auth_goodpass = TRUE;
805 mainconfig.radlog_dest = RADLOG_STDOUT;
813 mainconfig.log_auth = TRUE;
814 mainconfig.log_auth_badpass = TRUE;
818 mainconfig.log_auth_badpass = TRUE;
819 mainconfig.log_auth_goodpass = TRUE;
831 radius_pid = getpid();
833 /* Read the configuration files, BEFORE doing anything else. */
834 if (read_mainconfig(0) < 0) {
839 * If we're NOT debugging, trap fatal signals, so we can
840 * easily clean up after ourselves.
842 * If we ARE debugging, don't trap them, so we can
845 if ((mainconfig.allow_core_dumps == FALSE) && (debug_flag == 0)) {
847 #ifdef HAVE_SIGACTION
848 act.sa_handler = sig_fatal;
849 sigaction(SIGSEGV, &act, NULL);
851 signal(SIGSEGV, sig_fatal);
856 /* Reload the modules. */
857 DEBUG2("radiusd: entering modules setup");
858 if (setup_modules() < 0) {
859 radlog(L_ERR|L_CONS, "Errors setting up modules");
863 /* Initialize the request list. */
867 if (mainconfig.do_snmp) radius_snmp_init();
871 * Disconnect from session
873 if (debug_flag == 0 && dont_fork == FALSE) {
876 radlog(L_ERR|L_CONS, "Couldn't fork");
881 * The parent exits, so the child can run in the background.
892 * Ensure that we're using the CORRECT pid after forking,
893 * NOT the one we started with.
895 radius_pid = getpid();
899 * Only write the PID file if we're running as a daemon.
901 * And write it AFTER we've forked, so that we write the
904 if (dont_fork == FALSE) {
907 fp = fopen(mainconfig.pid_file, "w");
910 * FIXME: What about following symlinks,
911 * and having it over-write a normal file?
913 fprintf(fp, "%d\n", (int) radius_pid);
916 radlog(L_ERR|L_CONS, "Failed creating PID file %s: %s\n",
917 mainconfig.pid_file, strerror(errno));
923 * If we're running as a daemon, close the default file
924 * descriptors, AFTER forking.
926 mainconfig.radlog_fd = -1;
928 mainconfig.radlog_fd = STDOUT_FILENO;
932 devnull = open("/dev/null", O_RDWR);
934 radlog(L_ERR|L_CONS, "Failed opening /dev/null: %s\n",
938 dup2(devnull, STDIN_FILENO);
939 if (mainconfig.radlog_dest == RADLOG_STDOUT) {
940 mainconfig.radlog_fd = dup(STDOUT_FILENO);
942 dup2(devnull, STDOUT_FILENO);
943 if (mainconfig.radlog_dest == RADLOG_STDERR) {
944 mainconfig.radlog_fd = dup(STDERR_FILENO);
946 dup2(devnull, STDERR_FILENO);
951 * It's called the thread pool, but it does a little
954 thread_pool_init(spawn_flag);
957 * Use linebuffered or unbuffered stdout if
958 * the debug flag is on.
960 if (debug_flag == TRUE)
964 * Print out which ports we're listening on.
966 for (listener = mainconfig.listen;
968 listener = listener->next) {
969 if ((listener->ipaddr.af == AF_INET) &&
970 (listener->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
971 strcpy((char *)buffer, "*");
973 ip_ntoh(&listener->ipaddr, buffer, sizeof(buffer));
976 switch (listener->type) {
977 case RAD_LISTEN_AUTH:
978 DEBUG("Listening on authentication %s:%d",
979 buffer, listener->port);
982 case RAD_LISTEN_ACCT:
983 DEBUG("Listening on accounting %s:%d",
984 buffer, listener->port);
987 case RAD_LISTEN_PROXY:
988 DEBUG("Listening on proxy %s:%d",
989 buffer, listener->port);
998 * Now that we've set everything up, we can install the signal
999 * handlers. Before this, if we get any signal, we don't know
1000 * what to do, so we might as well do the default, and die.
1002 signal(SIGPIPE, SIG_IGN);
1003 #ifdef HAVE_SIGACTION
1004 act.sa_handler = sig_hup;
1005 sigaction(SIGHUP, &act, NULL);
1006 act.sa_handler = sig_fatal;
1007 sigaction(SIGTERM, &act, NULL);
1009 signal(SIGHUP, sig_hup);
1010 signal(SIGTERM, sig_fatal);
1013 * If we're debugging, then a CTRL-C will cause the
1014 * server to die immediately. Use SIGTERM to shut down
1015 * the server cleanly in that case.
1017 if (debug_flag == 0) {
1018 #ifdef HAVE_SIGACTION
1019 act.sa_handler = sig_fatal;
1020 sigaction(SIGINT, &act, NULL);
1021 sigaction(SIGQUIT, &act, NULL);
1023 signal(SIGINT, sig_fatal);
1024 signal(SIGQUIT, sig_fatal);
1028 radlog(L_INFO, "Ready to process requests.");
1029 start_time = time(NULL);
1032 * Receive user requests
1036 * If we've been told to exit, then do so,
1037 * even if we have data waiting.
1040 DEBUG("Exiting...");
1043 * Ignore the TERM signal: we're about
1046 signal(SIGTERM, SIG_IGN);
1049 * Send a TERM signal to all associated
1050 * processes (including us, which gets
1053 kill(-radius_pid, SIGTERM);
1056 * FIXME: Kill child threads, and
1061 * Detach any modules.
1066 * FIXME: clean up any active REQUEST
1071 * We're exiting, so we can delete the PID
1072 * file. (If it doesn't exist, we can ignore
1073 * the error returned by unlink)
1075 if (dont_fork == FALSE) {
1076 unlink(mainconfig.pid_file);
1080 * Free the configuration items.
1085 * SIGTERM gets do_exit=0,
1086 * and we want to exit cleanly.
1088 * Other signals make us exit
1089 * with an error status.
1095 #ifdef HAVE_PTHREAD_H
1097 * Threads: wait for all threads to stop
1098 * processing before re-loading the
1099 * config, so we don't pull the rug out
1103 if (!spawn_flag) for(;;) {
1105 * Block until there are '0' threads
1106 * with a REQUEST handle.
1108 sig_hup_block = TRUE;
1109 if( (total_active_threads() == 0) ||
1111 sig_hup_block = FALSE;
1118 if (read_mainconfig(TRUE) < 0) {
1122 /* Reload the modules. */
1123 DEBUG2("radiusd: entering modules setup");
1124 if (setup_modules() < 0) {
1125 radlog(L_ERR|L_CONS, "Errors setting up modules");
1129 need_reload = FALSE;
1130 radlog(L_INFO, "Ready to process requests.");
1137 * Loop over all the listening FD's.
1139 for (listener = mainconfig.listen;
1141 listener = listener->next) {
1142 FD_SET(listener->fd, &readfds);
1143 if (listener->fd > max_fd) max_fd = listener->fd;
1147 if (mainconfig.do_snmp &&
1148 (rad_snmp.smux_fd >= 0)) {
1149 FD_SET(rad_snmp.smux_fd, &readfds);
1150 if (rad_snmp.smux_fd > max_fd) max_fd = rad_snmp.smux_fd;
1153 status = select(max_fd + 1, &readfds, NULL, NULL, tv);
1156 * On interrupts, we clean up the request
1157 * list. We then continue with the loop,
1158 * so that if we're supposed to exit,
1159 * then the code at the start of the loop
1160 * catches that, and exits.
1162 if (errno == EINTR) {
1163 #ifdef MEMORY_USE_DEBUGGING
1165 * Run the server in debugging mode,
1166 * without threads, and give it a
1167 * SIGHUP. It will clean up after
1168 * itself, and any memory left over
1169 * should be allocated by C libraries,
1179 tv = rl_clean_list(time(NULL));
1182 radlog(L_ERR, "Unexpected error in select(): %s",
1187 time_now = time(NULL);
1188 #ifndef HAVE_PTHREAD_H
1190 * If there are no child threads, then there may
1191 * be child processes. In that case, wait for
1192 * their exit status, and throw that exit status
1193 * away. This helps get rid of zxombie children.
1195 while (waitpid(-1, &argval, WNOHANG) > 0) {
1201 * Loop over the open socket FD's, reading any data.
1203 for (listener = mainconfig.listen;
1205 listener = listener->next) {
1206 RAD_REQUEST_FUNP fun;
1208 if (!FD_ISSET(listener->fd, &readfds))
1211 * Receive the packet.
1213 if (sig_hup_block != FALSE) {
1216 packet = rad_recv(listener->fd);
1217 if (packet == NULL) {
1218 radlog(L_ERR, "%s", librad_errstr);
1222 RAD_SNMP_TYPE_INC(listener, total_requests);
1225 * FIXME: Move this next check into
1226 * the packet_ok() function, and add
1227 * a 'secret' to the RAIDUS_PACKET
1228 * data structure. This involves changing
1229 * a bunch of code, but it's probably the
1234 * Check if we know this client for
1235 * authentication and accounting. Check if we know
1236 * this proxy for proxying.
1238 if (listener->type != RAD_LISTEN_PROXY) {
1240 if ((cl = client_find(&packet->src_ipaddr)) == NULL) {
1241 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
1243 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
1244 inet_ntop(packet->src_ipaddr.af,
1245 &packet->src_ipaddr.ipaddr,
1246 buffer, sizeof(buffer)),
1251 secret = cl->secret;
1252 } else { /* It came in on the proxy port */
1255 if (packet->src_ipaddr.af != AF_INET) {
1256 rad_assert("PROXY IPV6 NOT SUPPORTED" == NULL);
1259 if ((rl = realm_findbyaddr(packet->src_ipaddr.ipaddr.ip4addr.s_addr,
1260 packet->src_port)) == NULL) {
1261 radlog(L_ERR, "Ignoring request from unknown home server %s port %d",
1262 inet_ntop(packet->src_ipaddr.af,
1263 &packet->src_ipaddr.ipaddr,
1264 buffer, sizeof(buffer)),
1271 * The secret isn't needed here,
1272 * as it's already in the old request
1278 * Do some simple checks before we process
1281 if ((fun = packet_ok(packet, listener)) == NULL) {
1287 * Allocate a new request for packets from
1288 * our clients, OR find the old request,
1289 * for packets which are replies from a home
1292 request = request_ok(packet, secret, listener);
1299 * Drop the request into the thread pool,
1300 * and let the thread pool take care of
1301 * doing something with it.
1303 if (!thread_pool_addrequest(request, fun)) {
1305 * FIXME: Maybe just drop
1306 * the packet on the floor?
1308 request_reject(request, REQUEST_FAIL_NO_THREADS);
1309 request->finished = TRUE;
1311 } /* loop over listening sockets*/
1314 if (mainconfig.do_snmp) {
1316 * After handling all authentication/accounting
1317 * requests, THEN process any pending SMUX/SNMP
1320 * Note that the handling is done in the main server,
1321 * which probably isn't a Good Thing. It really
1322 * should be wrapped, and handled in a thread pool.
1324 if ((rad_snmp.smux_fd >= 0) &&
1325 FD_ISSET(rad_snmp.smux_fd, &readfds) &&
1326 (rad_snmp.smux_event == SMUX_READ)) {
1331 * If we've got to re-connect, then do so now,
1332 * before calling select again.
1334 if (rad_snmp.smux_event == SMUX_CONNECT) {
1341 * After processing all new requests,
1342 * check if we've got to delete old requests
1343 * from the request list.
1345 tv = rl_clean_list(time_now);
1346 #ifdef HAVE_PTHREAD_H
1349 * Only clean the thread pool if we're spawning
1353 thread_pool_clean(time_now);
1358 } /* loop forever */
1363 * Display the syntax for starting this program.
1365 static void usage(int status)
1367 FILE *output = status?stderr:stdout;
1370 "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-AcfnsSvXxyz]\n", progname);
1371 fprintf(output, "Options:\n\n");
1372 fprintf(output, " -a acct_dir use accounting directory 'acct_dir'.\n");
1373 fprintf(output, " -A Log auth detail.\n");
1374 fprintf(output, " -d raddb_dir Configuration files are in \"raddbdir/*\".\n");
1375 fprintf(output, " -f Run as a foreground process, not a daemon.\n");
1376 fprintf(output, " -h Print this help message.\n");
1377 fprintf(output, " -i ipaddr Listen on ipaddr ONLY\n");
1378 fprintf(output, " -l log_dir Log file is \"log_dir/radius.log\" (not used in debug mode)\n");
1379 fprintf(output, " -p port Listen on port ONLY\n");
1380 fprintf(output, " -s Do not spawn child processes to handle requests.\n");
1381 fprintf(output, " -S Log stripped names.\n");
1382 fprintf(output, " -v Print server version information.\n");
1383 fprintf(output, " -X Turn on full debugging.\n");
1384 fprintf(output, " -x Turn on additional debugging. (-xx gives more debugging).\n");
1385 fprintf(output, " -y Log authentication failures, with password.\n");
1386 fprintf(output, " -z Log authentication successes, with password.\n");
1392 * We got a fatal signal.
1394 static void sig_fatal(int sig)
1398 /* We can't really do anything intelligent here so just die */
1411 * We got the hangup signal.
1412 * Re-read the configuration files.
1415 static void sig_hup(int sig)
1417 sig = sig; /* -Wunused */
1419 reset_signal(SIGHUP, sig_hup);
1422 * Only do the reload if we're the main server, both
1423 * for processes, and for threads.
1425 if (getpid() == radius_pid) {
1429 if (mainconfig.do_snmp) {
1430 rad_snmp.smux_failures = 0;
1431 rad_snmp.smux_event = SMUX_CONNECT;
1438 * Process and reply to a server-status request.
1439 * Like rad_authenticate and rad_accounting this should
1440 * live in it's own file but it's so small we don't bother.
1442 static int rad_status_server(REQUEST *request)
1449 * Reply with an ACK. We might want to add some more
1450 * interesting reply attributes, such as server uptime.
1452 t = request->timestamp - start_time;
1453 sprintf(reply_msg, "FreeRADIUS up %d day%s, %02d:%02d",
1454 (int)(t / 86400), (t / 86400) == 1 ? "" : "s",
1455 (int)((t / 3600) % 24), (int)(t / 60) % 60);
1456 request->reply->code = PW_AUTHENTICATION_ACK;
1458 vp = pairmake("Reply-Message", reply_msg, T_OP_SET);
1459 pairadd(&request->reply->vps, vp); /* don't need to check if !vp */