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