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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * Copyright 2000-2004,2006 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 #include <freeradius-devel/ident.h>
31 #include <freeradius-devel/autoconf.h>
35 #ifdef HAVE_NETINET_IN_H
36 # include <netinet/in.h>
54 #ifdef HAVE_SYS_SELECT_H
55 # include <sys/select.h>
58 #ifdef HAVE_SYS_WAIT_H
59 # include <sys/wait.h>
62 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
65 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
68 #include <freeradius-devel/radiusd.h>
69 #include <freeradius-devel/rad_assert.h>
70 #include <freeradius-devel/modules.h>
71 #include <freeradius-devel/request_list.h>
72 #include <freeradius-devel/radius_snmp.h>
74 #define SLEEP_FOREVER (65536)
79 const char *progname = NULL;
80 const char *radius_dir = NULL;
81 const char *radacct_dir = NULL;
82 const char *radlog_dir = NULL;
83 const char *radlib_dir = NULL;
84 int log_stripped_names;
86 int log_auth_detail = FALSE;
87 int need_reload = FALSE;
89 const char *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
92 static pid_t radius_pid;
93 static int debug_memory = 0;
96 * Configuration items.
98 static int do_exit = 0;
103 static void usage(int);
105 static void sig_fatal (int);
106 static void sig_hup (int);
111 int main(int argc, char *argv[])
114 unsigned char buffer[4096];
120 int sleep_time = SLEEP_FOREVER;
121 int spawn_flag = TRUE;
122 int dont_fork = FALSE;
123 int sig_hup_block = FALSE;
124 time_t last_cleaned_lists = 0;
126 #ifdef HAVE_SIGACTION
127 struct sigaction act;
129 rad_listen_t *listener;
132 set_auth_parameters(argc,argv);
135 if ((progname = strrchr(argv[0], '/')) == NULL)
142 radius_dir = strdup(RADIUS_DIR);
145 * Ensure that the configuration is initialized.
147 memset(&mainconfig, 0, sizeof(mainconfig));
148 mainconfig.myip.af = AF_UNSPEC;
149 mainconfig.port = -1;
150 mainconfig.radiusd_conf = strdup("radiusd.conf");
152 #ifdef HAVE_SIGACTION
153 memset(&act, 0, sizeof(act));
155 sigemptyset( &act.sa_mask ) ;
159 * Don't put output anywhere until we get told a little
162 mainconfig.radlog_fd = -1;
163 mainconfig.log_file = NULL;
165 /* Process the options. */
166 while ((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:mn:p:sSvxXyz")) != EOF) {
171 log_auth_detail = TRUE;
175 if (radacct_dir) free(radacct_dir);
176 radacct_dir = strdup(optarg);
180 /* ignore for backwards compatibility with Cistron */
184 if (radius_dir) free(radius_dir);
185 radius_dir = strdup(optarg);
197 if (ip_hton(optarg, AF_UNSPEC, &mainconfig.myip) < 0) {
198 fprintf(stderr, "radiusd: Invalid IP Address or hostname \"%s\"\n", optarg);
204 if ((strcmp(optarg, "stdout") == 0) ||
205 (strcmp(optarg, "stderr") == 0) ||
206 (strcmp(optarg, "syslog") == 0)) {
207 fprintf(stderr, "radiusd: -l %s is unsupported. Use log_destination in radiusd.conf\n", optarg);
210 if (radlog_dir) free(radlog_dir);
211 radlog_dir = strdup(optarg);
215 fprintf(stderr, "radiusd: -g is unsupported. Use log_destination in radiusd.conf.\n");
224 if ((strchr(optarg, '/') != NULL) ||
225 (strchr(optarg, '.') != NULL) ||
226 (strlen(optarg) > 45)) usage(1);
228 snprintf(buffer, sizeof(buffer), "%s.conf",
230 if (mainconfig.radiusd_conf)
231 free(mainconfig.radiusd_conf);
232 mainconfig.radiusd_conf = strdup(buffer);
236 log_stripped_names++;
240 mainconfig.port = atoi(optarg);
241 if ((mainconfig.port <= 0) ||
242 (mainconfig.port >= 65536)) {
243 fprintf(stderr, "radiusd: Invalid port number %s\n", optarg);
248 case 's': /* Single process mode */
258 * BIG debugging mode for users who are
259 * TOO LAZY to type '-sfxxyz -l stdout' themselves.
265 mainconfig.log_auth = TRUE;
266 mainconfig.log_auth_badpass = TRUE;
267 mainconfig.log_auth_goodpass = TRUE;
268 mainconfig.radlog_dest = RADLOG_STDOUT;
269 mainconfig.radlog_fd = STDOUT_FILENO;
277 mainconfig.log_auth = TRUE;
278 mainconfig.log_auth_badpass = TRUE;
282 mainconfig.log_auth_badpass = TRUE;
283 mainconfig.log_auth_goodpass = TRUE;
292 /* Read the configuration files, BEFORE doing anything else. */
293 if (read_mainconfig(0) < 0) {
298 * Disconnect from session
300 if (debug_flag == 0 && dont_fork == FALSE) {
303 radlog(L_ERR|L_CONS, "Couldn't fork");
308 * The parent exits, so the child can run in the background.
319 * If we're NOT debugging, trap fatal signals, so we can
320 * easily clean up after ourselves.
322 * If we ARE debugging, don't trap them, so we can
325 if ((mainconfig.allow_core_dumps == FALSE) && (debug_flag == 0)) {
327 #ifdef HAVE_SIGACTION
328 act.sa_handler = sig_fatal;
329 sigaction(SIGSEGV, &act, NULL);
331 signal(SIGSEGV, sig_fatal);
337 if (mainconfig.do_snmp) radius_snmp_init();
341 * Ensure that we're using the CORRECT pid after forking,
342 * NOT the one we started with.
344 radius_pid = getpid();
348 * Only write the PID file if we're running as a daemon.
350 * And write it AFTER we've forked, so that we write the
353 if (dont_fork == FALSE) {
356 fp = fopen(mainconfig.pid_file, "w");
359 * FIXME: What about following symlinks,
360 * and having it over-write a normal file?
362 fprintf(fp, "%d\n", (int) radius_pid);
365 radlog(L_ERR|L_CONS, "Failed creating PID file %s: %s\n",
366 mainconfig.pid_file, strerror(errno));
372 * If we're running as a daemon, close the default file
373 * descriptors, AFTER forking.
378 devnull = open("/dev/null", O_RDWR);
380 radlog(L_ERR|L_CONS, "Failed opening /dev/null: %s\n",
384 dup2(devnull, STDIN_FILENO);
385 if (mainconfig.radlog_dest == RADLOG_STDOUT) {
386 mainconfig.radlog_fd = dup(STDOUT_FILENO);
388 dup2(devnull, STDOUT_FILENO);
389 if (mainconfig.radlog_dest == RADLOG_STDERR) {
390 mainconfig.radlog_fd = dup(STDERR_FILENO);
392 dup2(devnull, STDERR_FILENO);
397 * It's called the thread pool, but it does a little
400 thread_pool_init(spawn_flag);
403 * Use linebuffered or unbuffered stdout if
404 * the debug flag is on.
406 if (debug_flag == TRUE)
410 * Print out which ports we're listening on.
412 for (listener = mainconfig.listen;
414 listener = listener->next) {
415 listener->print(listener, buffer, sizeof(buffer));
416 switch (listener->type) {
417 case RAD_LISTEN_AUTH:
418 DEBUG("Listening on authentication address %s", buffer);
421 case RAD_LISTEN_ACCT:
422 DEBUG("Listening on accounting address %s", buffer);
425 case RAD_LISTEN_PROXY:
426 DEBUG("Listening on proxy address %s", buffer);
429 case RAD_LISTEN_DETAIL:
430 DEBUG("Listening on detail file %s", buffer);
439 * Now that we've set everything up, we can install the signal
440 * handlers. Before this, if we get any signal, we don't know
441 * what to do, so we might as well do the default, and die.
443 signal(SIGPIPE, SIG_IGN);
444 #ifdef HAVE_SIGACTION
445 act.sa_handler = sig_hup;
446 sigaction(SIGHUP, &act, NULL);
447 act.sa_handler = sig_fatal;
448 sigaction(SIGTERM, &act, NULL);
450 signal(SIGHUP, sig_hup);
451 signal(SIGTERM, sig_fatal);
454 * If we're debugging, then a CTRL-C will cause the
455 * server to die immediately. Use SIGTERM to shut down
456 * the server cleanly in that case.
458 if ((debug_memory == 1) || (debug_flag == 0)) {
459 #ifdef HAVE_SIGACTION
460 act.sa_handler = sig_fatal;
461 sigaction(SIGINT, &act, NULL);
462 sigaction(SIGQUIT, &act, NULL);
464 signal(SIGINT, sig_fatal);
465 signal(SIGQUIT, sig_fatal);
469 radlog(L_INFO, "Ready to process requests.");
472 * Receive user requests
476 * If we've been told to exit, then do so,
477 * even if we have data waiting.
483 * Ignore the TERM signal: we're about
486 signal(SIGTERM, SIG_IGN);
489 * Send a TERM signal to all associated
490 * processes (including us, which gets
493 kill(-radius_pid, SIGTERM);
496 * FIXME: Kill child threads, and
501 * FIXME: clean up any active REQUEST
506 * We're exiting, so we can delete the PID
507 * file. (If it doesn't exist, we can ignore
508 * the error returned by unlink)
510 if (dont_fork == FALSE) {
511 unlink(mainconfig.pid_file);
515 * Free the configuration items.
520 * Detach any modules.
527 * SIGTERM gets do_exit=0,
528 * and we want to exit cleanly.
530 * Other signals make us exit
531 * with an error status.
537 #ifdef HAVE_PTHREAD_H
539 * Threads: wait for all threads to stop
540 * processing before re-loading the
541 * config, so we don't pull the rug out
545 if (spawn_flag) for(;;) {
547 * Block until there are '0' threads
548 * with a REQUEST handle.
550 sig_hup_block = TRUE;
551 if( (total_active_threads() == 0) ||
553 sig_hup_block = FALSE;
560 if (read_mainconfig(TRUE) < 0) {
565 radlog(L_INFO, "Ready to process requests.");
572 * Loop over all the listening FD's.
574 for (listener = mainconfig.listen;
576 listener = listener->next) {
577 if (listener->fd < 0) continue;
579 FD_SET(listener->fd, &readfds);
580 if (listener->fd > max_fd) max_fd = listener->fd;
584 if (mainconfig.do_snmp &&
585 (rad_snmp.smux_fd >= 0)) {
586 FD_SET(rad_snmp.smux_fd, &readfds);
587 if (rad_snmp.smux_fd > max_fd) max_fd = rad_snmp.smux_fd;
591 if (sleep_time == SLEEP_FOREVER) {
592 DEBUG2("Nothing to do. Sleeping until we see a request.");
593 status = select(max_fd + 1, &readfds, NULL, NULL, NULL);
597 DEBUG2("Waking up in %d seconds...", sleep_time);
599 tv.tv_sec = sleep_time;
601 status = select(max_fd + 1, &readfds, NULL, NULL, &tv);
605 * On interrupts, we clean up the request
606 * list. We then continue with the loop,
607 * so that if we're supposed to exit,
608 * then the code at the start of the loop
609 * catches that, and exits.
611 if (errno == EINTR) {
612 #ifdef MEMORY_USE_DEBUGGING
614 * Run the server in debugging mode,
615 * without threads, and give it a
616 * SIGHUP. It will clean up after
617 * itself, and any memory left over
618 * should be allocated by C libraries,
627 radlog(L_ERR, "Unexpected error in select(): %s",
632 time_now = time(NULL);
633 #ifndef HAVE_PTHREAD_H
635 * If there are no child threads, then there may
636 * be child processes. In that case, wait for
637 * their exit status, and throw that exit status
638 * away. This helps get rid of zxombie children.
640 while (waitpid(-1, &argval, WNOHANG) > 0) {
646 * Loop over the open socket FD's, reading any data.
648 for (listener = mainconfig.listen;
650 listener = listener->next) {
651 RAD_REQUEST_FUNP fun;
653 if ((listener->fd >= 0) &&
654 !FD_ISSET(listener->fd, &readfds))
658 * Receive the packet.
660 if (sig_hup_block != FALSE) {
665 * Do per-socket receive processing of the
668 if (!listener->recv(listener, &fun, &request)) {
673 * Drop the request into the thread pool,
674 * and let the thread pool take care of
675 * doing something with it.
677 if (!thread_pool_addrequest(request, fun)) {
679 * FIXME: Maybe just drop
680 * the packet on the floor?
682 request_reject(request, REQUEST_FAIL_NO_THREADS);
683 request->finished = TRUE;
685 } /* loop over listening sockets*/
688 if (mainconfig.do_snmp) {
690 * After handling all authentication/accounting
691 * requests, THEN process any pending SMUX/SNMP
694 * Note that the handling is done in the main server,
695 * which probably isn't a Good Thing. It really
696 * should be wrapped, and handled in a thread pool.
698 if ((rad_snmp.smux_fd >= 0) &&
699 FD_ISSET(rad_snmp.smux_fd, &readfds) &&
700 (rad_snmp.smux_event == SMUX_READ)) {
705 * If we've got to re-connect, then do so now,
706 * before calling select again.
708 if (rad_snmp.smux_event == SMUX_CONNECT) {
715 * Loop through the request lists once per
716 * second, to clean up old requests.
718 if (last_cleaned_lists != time_now) {
719 last_cleaned_lists = time_now;
721 DEBUG2("--- Walking the entire request list ---");
722 sleep_time = SLEEP_FOREVER;
723 for (listener = mainconfig.listen;
725 listener = listener->next) {
728 next = listener->update(listener, time_now);
729 if (next < sleep_time) {
735 #ifdef HAVE_PTHREAD_H
738 * Only clean the thread pool if we're spawning
742 thread_pool_clean(time_now);
750 * Display the syntax for starting this program.
752 static void NEVER_RETURNS usage(int status)
754 FILE *output = status?stderr:stdout;
757 "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-AcfnsSvXxyz]\n", progname);
758 fprintf(output, "Options:\n\n");
759 fprintf(output, " -a acct_dir use accounting directory 'acct_dir'.\n");
760 fprintf(output, " -A Log auth detail.\n");
761 fprintf(output, " -d raddb_dir Configuration files are in \"raddbdir/*\".\n");
762 fprintf(output, " -f Run as a foreground process, not a daemon.\n");
763 fprintf(output, " -h Print this help message.\n");
764 fprintf(output, " -i ipaddr Listen on ipaddr ONLY\n");
765 fprintf(output, " -l log_dir Log file is \"log_dir/radius.log\" (not used in debug mode)\n");
766 fprintf(output, " -p port Listen on port ONLY\n");
767 fprintf(output, " -s Do not spawn child processes to handle requests.\n");
768 fprintf(output, " -S Log stripped names.\n");
769 fprintf(output, " -v Print server version information.\n");
770 fprintf(output, " -X Turn on full debugging.\n");
771 fprintf(output, " -x Turn on additional debugging. (-xx gives more debugging).\n");
772 fprintf(output, " -y Log authentication failures, with password.\n");
773 fprintf(output, " -z Log authentication successes, with password.\n");
779 * We got a fatal signal.
781 static void sig_fatal(int sig)
785 /* We can't really do anything intelligent here so just die */
805 * We got the hangup signal.
806 * Re-read the configuration files.
809 static void sig_hup(int sig)
811 sig = sig; /* -Wunused */
813 reset_signal(SIGHUP, sig_hup);
816 * Only do the reload if we're the main server, both
817 * for processes, and for threads.
819 if (getpid() == radius_pid) {
823 if (mainconfig.do_snmp) {
824 rad_snmp.smux_failures = 0;
825 rad_snmp.smux_event = SMUX_CONNECT;