fa0fcfa843f7508e7331fee19dd234aa9641cd61
[freeradius.git] / src / main / radiusd.c
1 /*
2  * radiusd.c    Main loop of the radius server.
3  *
4  * Version:     $Id$
5  *
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.
10  *
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.
15  *
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
19  *
20  * Copyright 2000-2012  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>
26  */
27
28 RCSID("$Id$")
29
30 #include <freeradius-devel/radiusd.h>
31 #include <freeradius-devel/modules.h>
32 #include <freeradius-devel/state.h>
33 #include <freeradius-devel/rad_assert.h>
34
35 #include <sys/file.h>
36
37 #include <fcntl.h>
38 #include <ctype.h>
39
40 #ifdef HAVE_GETOPT_H
41 #       include <getopt.h>
42 #endif
43
44 #ifdef HAVE_SYS_WAIT_H
45 #       include <sys/wait.h>
46 #endif
47 #ifndef WEXITSTATUS
48 #       define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
49 #endif
50 #ifndef WIFEXITED
51 #       define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
52 #endif
53
54 /*
55  *  Global variables.
56  */
57 char const      *progname = NULL;
58 char const      *radacct_dir = NULL;
59 char const      *radlog_dir = NULL;
60 char const      *radlib_dir = NULL;
61 bool            log_stripped_names;
62
63 char const *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION_STRING
64 #ifdef RADIUSD_VERSION_COMMIT
65 " (git #" STRINGIFY(RADIUSD_VERSION_COMMIT) ")"
66 #endif
67 ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
68
69 static pid_t radius_pid;
70
71 /*
72  *  Configuration items.
73  */
74
75 /*
76  *      Static functions.
77  */
78 static void usage(int);
79
80 static void sig_fatal (int);
81 #ifdef SIGHUP
82 static void sig_hup (int);
83 #endif
84
85 /*
86  *      The main guy.
87  */
88 int main(int argc, char *argv[])
89 {
90         int rcode = EXIT_SUCCESS;
91         int status;
92         int argval;
93         bool spawn_flag = true;
94         bool display_version = false;
95         int flag = 0;
96         int from_child[2] = {-1, -1};
97         fr_state_t *state = NULL;
98
99         /*
100          *  We probably don't want to free the talloc autofree context
101          *  directly, so we'll allocate a new context beneath it, and
102          *  free that before any leak reports.
103          */
104         TALLOC_CTX *autofree = talloc_init("main");
105
106 #ifdef OSFC2
107         set_auth_parameters(argc, argv);
108 #endif
109
110         if ((progname = strrchr(argv[0], FR_DIR_SEP)) == NULL)
111                 progname = argv[0];
112         else
113                 progname++;
114
115 #ifdef WIN32
116         {
117                 WSADATA wsaData;
118                 if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
119                         fprintf(stderr, "%s: Unable to initialize socket library.\n", progname);
120                         exit(EXIT_FAILURE);
121                 }
122         }
123 #endif
124
125         rad_debug_lvl = 0;
126         set_radius_dir(autofree, RADIUS_DIR);
127
128         /*
129          *      Ensure that the configuration is initialized.
130          */
131         memset(&main_config, 0, sizeof(main_config));
132         main_config.myip.af = AF_UNSPEC;
133         main_config.port = 0;
134         main_config.name = "radiusd";
135         main_config.daemonize = true;
136
137         /*
138          *      Don't put output anywhere until we get told a little
139          *      more.
140          */
141         default_log.dst = L_DST_NULL;
142         default_log.fd = -1;
143         main_config.log_file = NULL;
144
145         /*  Process the options.  */
146         while ((argval = getopt(argc, argv, "Cd:D:fhi:l:mMn:p:PstvxX")) != EOF) {
147
148                 switch (argval) {
149                         case 'C':
150                                 check_config = true;
151                                 spawn_flag = false;
152                                 main_config.daemonize = false;
153                                 break;
154
155                         case 'd':
156                                 set_radius_dir(autofree, optarg);
157                                 break;
158
159                         case 'D':
160                                 main_config.dictionary_dir = talloc_typed_strdup(autofree, optarg);
161                                 break;
162
163                         case 'f':
164                                 main_config.daemonize = false;
165                                 break;
166
167                         case 'h':
168                                 usage(0);
169                                 break;
170
171                         case 'l':
172                                 if (strcmp(optarg, "stdout") == 0) {
173                                         goto do_stdout;
174                                 }
175                                 main_config.log_file = strdup(optarg);
176                                 default_log.dst = L_DST_FILES;
177                                 default_log.fd = open(main_config.log_file,
178                                                             O_WRONLY | O_APPEND | O_CREAT, 0640);
179                                 if (default_log.fd < 0) {
180                                         fprintf(stderr, "radiusd: Failed to open log file %s: %s\n", main_config.log_file, fr_syserror(errno));
181                                         exit(EXIT_FAILURE);
182                                 }
183                                 fr_log_fp = fdopen(default_log.fd, "a");
184                                 break;
185
186                         case 'i':
187                                 if (ip_hton(&main_config.myip, AF_UNSPEC, optarg, false) < 0) {
188                                         fprintf(stderr, "radiusd: Invalid IP Address or hostname \"%s\"\n", optarg);
189                                         exit(EXIT_FAILURE);
190                                 }
191                                 flag |= 1;
192                                 break;
193
194                         case 'n':
195                                 main_config.name = optarg;
196                                 break;
197
198                         case 'm':
199                                 main_config.debug_memory = true;
200                                 break;
201
202                         case 'M':
203                                 main_config.memory_report = true;
204                                 main_config.debug_memory = true;
205                                 break;
206
207                         case 'p':
208                         {
209                                 unsigned long port;
210
211                                 port = strtoul(optarg, 0, 10);
212                                 if ((port == 0) || (port > UINT16_MAX)) {
213                                         fprintf(stderr, "radiusd: Invalid port number \"%s\"\n", optarg);
214                                         exit(EXIT_FAILURE);
215                                 }
216
217                                 main_config.port = (uint16_t) port;
218                                 flag |= 2;
219                         }
220                                 break;
221
222                         case 'P':
223                                 /* Force the PID to be written, even in -f mode */
224                                 main_config.write_pid = true;
225                                 break;
226
227                         case 's':       /* Single process mode */
228                                 spawn_flag = false;
229                                 main_config.daemonize = false;
230                                 break;
231
232                         case 't':       /* no child threads */
233                                 spawn_flag = false;
234                                 break;
235
236                         case 'v':
237                                 display_version = true;
238                                 break;
239
240                         case 'X':
241                                 spawn_flag = false;
242                                 main_config.daemonize = false;
243                                 rad_debug_lvl += 2;
244                                 main_config.log_auth = true;
245                                 main_config.log_auth_badpass = true;
246                                 main_config.log_auth_goodpass = true;
247                 do_stdout:
248                                 fr_log_fp = stdout;
249                                 default_log.dst = L_DST_STDOUT;
250                                 default_log.fd = STDOUT_FILENO;
251                                 break;
252
253                         case 'x':
254                                 rad_debug_lvl++;
255                                 break;
256
257                         default:
258                                 usage(1);
259                                 break;
260                 }
261         }
262
263         /*
264          *  Mismatch between the binary and the libraries it depends on.
265          */
266         if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) {
267                 fr_perror("radiusd");
268                 exit(EXIT_FAILURE);
269         }
270
271         if (rad_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) exit(EXIT_FAILURE);
272
273         /*
274          *  Mismatch between build time OpenSSL and linked SSL, better to die
275          *  here than segfault later.
276          */
277 #ifdef HAVE_OPENSSL_CRYPTO_H
278         if (ssl_check_consistency() < 0) exit(EXIT_FAILURE);
279 #endif
280
281         if (flag && (flag != 0x03)) {
282                 fprintf(stderr, "radiusd: The options -i and -p cannot be used individually.\n");
283                 exit(EXIT_FAILURE);
284         }
285
286         /*
287          *  According to the talloc peeps, no two threads may modify any part of
288          *  a ctx tree with a common root without synchronisation.
289          *
290          *  So we can't run with a null context and threads.
291          */
292         if (main_config.memory_report) {
293                 if (spawn_flag) {
294                         fprintf(stderr, "radiusd: The server cannot produce memory reports (-M) in threaded mode\n");
295                         exit(EXIT_FAILURE);
296                 }
297                 talloc_enable_null_tracking();
298         } else {
299                 talloc_disable_null_tracking();
300         }
301
302         /*
303          *  Better here, so it doesn't matter whether we get passed -xv or -vx.
304          */
305         if (display_version) {
306                 /* Don't print timestamps */
307                 rad_debug_lvl += 2;
308                 fr_log_fp = stdout;
309                 default_log.dst = L_DST_STDOUT;
310                 default_log.fd = STDOUT_FILENO;
311
312                 INFO("%s: %s", progname, radiusd_version);
313                 version_print();
314                 exit(EXIT_SUCCESS);
315         }
316
317         if (rad_debug_lvl) version_print();
318
319         /*
320          *  Under linux CAP_SYS_PTRACE is usually only available before setuid/setguid,
321          *  so we need to check whether we can attach before calling those functions
322          *  (in main_config_init()).
323          */
324         fr_store_debug_state();
325
326         /*
327          *  Initialising OpenSSL once, here, is safer than having individual modules do it.
328          */
329 #ifdef HAVE_OPENSSL_CRYPTO_H
330         tls_global_init();
331 #endif
332
333         /*
334          *  Write the PID always if we're running as a daemon.
335          */
336         if (main_config.daemonize) main_config.write_pid = true;
337
338         /*
339          *  Read the configuration files, BEFORE doing anything else.
340          */
341         if (main_config_init() < 0) exit(EXIT_FAILURE);
342
343         /*
344          *  This is very useful in figuring out why the panic_action didn't fire.
345          */
346         INFO("%s", fr_debug_state_to_msg(fr_debug_state));
347
348         /*
349          *  Check for vulnerabilities in the version of libssl were linked against.
350          */
351 #if defined(HAVE_OPENSSL_CRYPTO_H) && defined(ENABLE_OPENSSL_VERSION_CHECK)
352         if (tls_global_version_check(main_config.allow_vulnerable_openssl) < 0) exit(EXIT_FAILURE);
353 #endif
354
355         fr_talloc_fault_setup();
356
357         /*
358          *  Set the panic action (if required)
359          */
360         {
361                 char const *panic_action = NULL;
362
363                 panic_action = getenv("PANIC_ACTION");
364                 if (!panic_action) panic_action = main_config.panic_action;
365
366                 if (panic_action && (fr_fault_setup(panic_action, argv[0]) < 0)) {
367                         fr_perror("radiusd");
368                         exit(EXIT_FAILURE);
369                 }
370         }
371
372 #ifndef __MINGW32__
373         /*
374          *  Disconnect from session
375          */
376         if (main_config.daemonize) {
377                 pid_t pid;
378                 int devnull;
379
380                 /*
381                  *  Really weird things happen if we leave stdin open and call things like
382                  *  system() later.
383                  */
384                 devnull = open("/dev/null", O_RDWR);
385                 if (devnull < 0) {
386                         ERROR("Failed opening /dev/null: %s", fr_syserror(errno));
387                         exit(EXIT_FAILURE);
388                 }
389                 dup2(devnull, STDIN_FILENO);
390
391                 close(devnull);
392
393                 if (pipe(from_child) != 0) {
394                         ERROR("Couldn't open pipe for child status: %s", fr_syserror(errno));
395                         exit(EXIT_FAILURE);
396                 }
397
398                 pid = fork();
399                 if (pid < 0) {
400                         ERROR("Couldn't fork: %s", fr_syserror(errno));
401                         exit(EXIT_FAILURE);
402                 }
403
404                 /*
405                  *  The parent exits, so the child can run in the background.
406                  *
407                  *  As the child can still encounter an error during initialisation
408                  *  we do a blocking read on a pipe between it and the parent.
409                  *
410                  *  Just before entering the event loop the child will send a success
411                  *  or failure message to the parent, via the pipe.
412                  */
413                 if (pid > 0) {
414                         uint8_t ret = 0;
415                         int stat_loc;
416
417                         /* So the pipe is correctly widowed if the child exits */
418                         close(from_child[1]);
419
420                         /*
421                          *  The child writes a 0x01 byte on success, and closes
422                          *  the pipe on error.
423                          */
424                         if ((read(from_child[0], &ret, 1) < 0)) {
425                                 ret = 0;
426                         }
427
428                         /* For cleanliness... */
429                         close(from_child[0]);
430
431                         /* Don't turn children into zombies */
432                         if (!ret) {
433                                 waitpid(pid, &stat_loc, WNOHANG);
434                                 exit(EXIT_FAILURE);
435                         }
436
437                         exit(EXIT_SUCCESS);
438                 }
439
440                 /* so the pipe is correctly widowed if the parent exits?! */
441                 close(from_child[0]);
442 #  ifdef HAVE_SETSID
443                 setsid();
444 #  endif
445         }
446 #endif
447
448         /*
449          *  Ensure that we're using the CORRECT pid after forking, NOT the one
450          *  we started with.
451          */
452         radius_pid = getpid();
453
454         /*
455          *  Initialize any event loops just enough so module instantiations can
456          *  add fd/event to them, but do not start them yet.
457          *
458          *  This has to be done post-fork in case we're using kqueue, where the
459          *  queue isn't inherited by the child process.
460          */
461         if (!radius_event_init(autofree)) exit(EXIT_FAILURE);
462
463         /*
464          *   Load the modules
465          */
466         if (modules_init(main_config.config) < 0) exit(EXIT_FAILURE);
467
468         /*
469          *  Redirect stderr/stdout as appropriate.
470          */
471         if (radlog_init(&default_log, main_config.daemonize) < 0) {
472                 ERROR("%s", fr_strerror());
473                 exit(EXIT_FAILURE);
474         }
475
476         event_loop_started = true;
477
478         /*
479          *  Start the event loop(s) and threads.
480          */
481         radius_event_start(main_config.config, spawn_flag);
482
483         /*
484          *  Now that we've set everything up, we can install the signal
485          *  handlers.  Before this, if we get any signal, we don't know
486          *  what to do, so we might as well do the default, and die.
487          */
488 #ifdef SIGPIPE
489         signal(SIGPIPE, SIG_IGN);
490 #endif
491
492         if ((fr_set_signal(SIGHUP, sig_hup) < 0) ||
493             (fr_set_signal(SIGTERM, sig_fatal) < 0)) {
494                 ERROR("%s", fr_strerror());
495                 exit(EXIT_FAILURE);
496         }
497
498         /*
499          *  If we're debugging, then a CTRL-C will cause the server to die
500          *  immediately.  Use SIGTERM to shut down the server cleanly in
501          *  that case.
502          */
503         if (main_config.debug_memory || (rad_debug_lvl == 0)) {
504                 if ((fr_set_signal(SIGINT, sig_fatal) < 0)
505 #ifdef SIGQUIT
506                 || (fr_set_signal(SIGQUIT, sig_fatal) < 0)
507 #endif
508                 ) {
509                         ERROR("%s", fr_strerror());
510                         exit(EXIT_FAILURE);
511                 }
512         }
513
514         /*
515          *  Everything seems to have loaded OK, exit gracefully.
516          */
517         if (check_config) {
518                 DEBUG("Configuration appears to be OK");
519
520                 /* for -C -m|-M */
521                 if (main_config.debug_memory) goto cleanup;
522
523                 exit(EXIT_SUCCESS);
524         }
525
526 #ifdef WITH_STATS
527         radius_stats_init(0);
528 #endif
529
530         /*
531          *  Write the PID after we've forked, so that we write the correct one.
532          */
533         if (main_config.write_pid) {
534                 FILE *fp;
535
536                 fp = fopen(main_config.pid_file, "w");
537                 if (fp != NULL) {
538                         /*
539                          *  @fixme What about following symlinks,
540                          *  and having it over-write a normal file?
541                          */
542                         fprintf(fp, "%d\n", (int) radius_pid);
543                         fclose(fp);
544                 } else {
545                         ERROR("Failed creating PID file %s: %s", main_config.pid_file, fr_syserror(errno));
546                         exit(EXIT_FAILURE);
547                 }
548         }
549
550         exec_trigger(NULL, NULL, "server.start", false);
551
552         /*
553          *  Inform the parent (who should still be waiting) that the rest of
554          *  initialisation went OK, and that it should exit with a 0 status.
555          *  If we don't get this far, then we just close the pipe on exit, and the
556          *  parent gets a read failure.
557          */
558         if (main_config.daemonize) {
559                 if (write(from_child[1], "\001", 1) < 0) {
560                         WARN("Failed informing parent of successful start: %s",
561                              fr_syserror(errno));
562                 }
563                 close(from_child[1]);
564         }
565
566         /*
567          *  Clear the libfreeradius error buffer.
568          */
569         fr_strerror();
570
571         /*
572          *  Initialise the state rbtree (used to link multiple rounds of challenges).
573          */
574         state = fr_state_init(NULL);
575
576         /*
577          *  Process requests until HUP or exit.
578          */
579         while ((status = radius_event_process()) == 0x80) {
580 #ifdef WITH_STATS
581                 radius_stats_init(1);
582 #endif
583                 main_config_hup();
584         }
585         if (status < 0) {
586                 ERROR("Exiting due to internal error: %s", fr_strerror());
587                 rcode = EXIT_FAILURE;
588         } else {
589                 INFO("Exiting normally");
590         }
591
592         /*
593          *  Ignore the TERM signal: we're about to die.
594          */
595         signal(SIGTERM, SIG_IGN);
596
597         /*
598          *   Fire signal and stop triggers after ignoring SIGTERM, so handlers are
599          *   not killed with the rest of the process group, below.
600          */
601         if (status == 2) exec_trigger(NULL, NULL, "server.signal.term", true);
602         exec_trigger(NULL, NULL, "server.stop", false);
603
604         /*
605          *  Send a TERM signal to all associated processes
606          *  (including us, which gets ignored.)
607          */
608 #ifndef __MINGW32__
609         if (spawn_flag) kill(-radius_pid, SIGTERM);
610 #endif
611
612         /*
613          *  We're exiting, so we can delete the PID file.
614          *  (If it doesn't exist, we can ignore the error returned by unlink)
615          */
616         if (main_config.daemonize) unlink(main_config.pid_file);
617
618         radius_event_free();
619
620 cleanup:
621         /*
622          *  Detach any modules.
623          */
624         modules_free();
625
626         xlat_free();            /* modules may have xlat's */
627
628         fr_state_delete(state);
629
630         /*
631          *  Free the configuration items.
632          */
633         main_config_free();
634
635 #ifdef WIN32
636         WSACleanup();
637 #endif
638
639 #ifdef HAVE_OPENSSL_CRYPTO_H
640         tls_global_cleanup();
641 #endif
642
643         /*
644          *  So we don't see autofreed memory in the talloc report
645          */
646         talloc_free(autofree);
647
648         if (main_config.memory_report) {
649                 INFO("Allocated memory at time of report:");
650                 fr_log_talloc_report(NULL);
651         }
652
653         return rcode;
654 }
655
656
657 /*
658  *  Display the syntax for starting this program.
659  */
660 static void NEVER_RETURNS usage(int status)
661 {
662         FILE *output = status?stderr:stdout;
663
664         fprintf(output, "Usage: %s [options]\n", progname);
665         fprintf(output, "Options:\n");
666         fprintf(output, "  -C            Check configuration and exit.\n");
667         fprintf(stderr, "  -d <raddb>    Set configuration directory (defaults to " RADDBDIR ").\n");
668         fprintf(stderr, "  -D <dictdir>  Set main dictionary directory (defaults to " DICTDIR ").\n");
669         fprintf(output, "  -f            Run as a foreground process, not a daemon.\n");
670         fprintf(output, "  -h            Print this help message.\n");
671         fprintf(output, "  -i <ipaddr>   Listen on ipaddr ONLY.\n");
672         fprintf(output, "  -l <log_file> Logging output will be written to this file.\n");
673         fprintf(output, "  -m            On SIGINT or SIGQUIT exit cleanly instead of immediately.\n");
674         fprintf(output, "  -n <name>     Read raddb/name.conf instead of raddb/radiusd.conf.\n");
675         fprintf(output, "  -p <port>     Listen on port ONLY.\n");
676         fprintf(output, "  -P            Always write out PID, even with -f.\n");
677         fprintf(output, "  -s            Do not spawn child processes to handle requests.\n");
678         fprintf(output, "  -t            Disable threads.\n");
679         fprintf(output, "  -v            Print server version information.\n");
680         fprintf(output, "  -X            Turn on full debugging.\n");
681         fprintf(output, "  -x            Turn on additional debugging. (-xx gives more debugging).\n");
682         exit(status);
683 }
684
685
686 /*
687  *      We got a fatal signal.
688  */
689 static void sig_fatal(int sig)
690 {
691         if (getpid() != radius_pid) _exit(sig);
692
693         switch (sig) {
694         case SIGTERM:
695                 radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
696                 break;
697
698         case SIGINT:
699 #ifdef SIGQUIT
700         case SIGQUIT:
701 #endif
702                 if (main_config.debug_memory || main_config.memory_report) {
703                         radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
704                         break;
705                 }
706                 /* FALL-THROUGH */
707
708         default:
709                 fr_exit(sig);
710         }
711 }
712
713 #ifdef SIGHUP
714 /*
715  *  We got the hangup signal.
716  *  Re-read the configuration files.
717  */
718 static void sig_hup(UNUSED int sig)
719 {
720         reset_signal(SIGHUP, sig_hup);
721
722         radius_signal_self(RADIUS_SIGNAL_SELF_HUP);
723 }
724 #endif