ENABLE_OPENSSL_VERSION_CHECK was intended to be used to disable checks for vulnerable...
[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-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>
26  */
27
28 #include <freeradius-devel/ident.h>
29 RCSID("$Id$")
30
31 #include <freeradius-devel/radiusd.h>
32 #include <freeradius-devel/modules.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 #include <signal.h>
41
42 #ifdef HAVE_GETOPT_H
43 #       include <getopt.h>
44 #endif
45
46 #ifdef HAVE_SYS_WAIT_H
47 #       include <sys/wait.h>
48 #endif
49 #ifndef WEXITSTATUS
50 #       define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
51 #endif
52 #ifndef WIFEXITED
53 #       define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
54 #endif
55
56 #ifdef HAVE_OPENSSL_CRYPTO_H
57 #include <openssl/ssl.h>
58 #endif
59
60 /*
61  *  Global variables.
62  */
63 const char *progname = NULL;
64 const char *radius_dir = NULL;
65 const char *radacct_dir = NULL;
66 const char *radlog_dir = NULL;
67 const char *radlib_dir = NULL;
68 int log_stripped_names;
69 int debug_flag = 0;
70 int check_config = FALSE;
71
72 const char *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION_STRING
73 #ifdef RADIUSD_VERSION_COMMIT
74 " (git #" RADIUSD_VERSION_COMMIT ")"
75 #endif
76 ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
77
78 pid_t radius_pid;
79
80 /*
81  *  Configuration items.
82  */
83
84 /*
85  *      Static functions.
86  */
87 static void usage(int);
88
89 static void sig_fatal (int);
90 #ifdef SIGHUP
91 static void sig_hup (int);
92 #endif
93
94 /*
95  *      The main guy.
96  */
97 int main(int argc, char *argv[])
98 {
99         int rcode;
100         int argval;
101         int spawn_flag = TRUE;
102         int dont_fork = FALSE;
103         int flag = 0;
104         int from_child[2] = {-1, -1};
105
106         int devnull;
107
108         /*
109          *      If the server was built with debugging enabled always install
110          *      the basic fatal signal handlers.
111          */
112 #ifndef NDEBUG
113         fr_fault_setup(getenv("PANIC_ACTION"), argv[0]);
114 #endif
115
116 #ifdef HAVE_SIGACTION
117         struct sigaction act;
118 #endif
119
120 #ifdef OSFC2
121         set_auth_parameters(argc,argv);
122 #endif
123
124         if ((progname = strrchr(argv[0], FR_DIR_SEP)) == NULL)
125                 progname = argv[0];
126         else
127                 progname++;
128
129 #ifdef WIN32
130         {
131                 WSADATA wsaData;
132                 if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
133                         fprintf(stderr, "%s: Unable to initialize socket library.\n");
134                         return 1;
135                 }
136         }
137 #endif
138
139         debug_flag = 0;
140         spawn_flag = TRUE;
141         radius_dir = strdup(RADIUS_DIR);
142
143         /*
144          *      Ensure that the configuration is initialized.
145          */
146         memset(&mainconfig, 0, sizeof(mainconfig));
147         mainconfig.myip.af = AF_UNSPEC;
148         mainconfig.port = -1;
149         mainconfig.name = "radiusd";
150
151 #ifdef HAVE_SIGACTION
152         memset(&act, 0, sizeof(act));
153         act.sa_flags = 0 ;
154         sigemptyset( &act.sa_mask ) ;
155 #endif
156
157         /*
158          *      Don't put output anywhere until we get told a little
159          *      more.
160          */
161         mainconfig.radlog_dest = RADLOG_NULL;
162         mainconfig.radlog_fd = -1;
163         mainconfig.log_file = NULL;
164
165         /*  Process the options.  */
166         while ((argval = getopt(argc, argv, "Cd:fhi:l:mn:p:stvxX")) != EOF) {
167
168                 switch(argval) {
169                         case 'C':
170                                 check_config = TRUE;
171                                 spawn_flag = FALSE;
172                                 dont_fork = TRUE;
173                                 break;
174
175                         case 'd':
176                                 if (radius_dir) free(radius_dir);
177                                 radius_dir = strdup(optarg);
178                                 break;
179
180                         case 'f':
181                                 dont_fork = TRUE;
182                                 break;
183
184                         case 'h':
185                                 usage(0);
186                                 break;
187
188                         case 'l':
189                                 if (strcmp(optarg, "stdout") == 0) {
190                                         goto do_stdout;
191                                 }
192                                 mainconfig.log_file = strdup(optarg);
193                                 mainconfig.radlog_dest = RADLOG_FILES;
194                                 mainconfig.radlog_fd = open(mainconfig.log_file,
195                                                             O_WRONLY | O_APPEND | O_CREAT, 0640);
196                                 if (mainconfig.radlog_fd < 0) {
197                                         fprintf(stderr, "radiusd: Failed to open log file %s: %s\n", mainconfig.log_file, strerror(errno));
198                                         exit(1);
199                                 }
200                                 fr_log_fp = fdopen(mainconfig.radlog_fd, "a");
201                                 break;
202
203                         case 'i':
204                                 if (ip_hton(optarg, AF_UNSPEC, &mainconfig.myip) < 0) {
205                                         fprintf(stderr, "radiusd: Invalid IP Address or hostname \"%s\"\n", optarg);
206                                         exit(1);
207                                 }
208                                 flag |= 1;
209                                 break;
210
211                         case 'n':
212                                 mainconfig.name = optarg;
213                                 break;
214
215                         case 'm':
216                                 mainconfig.debug_memory = 1;
217                                 break;
218
219                         case 'p':
220                                 mainconfig.port = atoi(optarg);
221                                 if ((mainconfig.port <= 0) ||
222                                     (mainconfig.port >= 65536)) {
223                                         fprintf(stderr, "radiusd: Invalid port number %s\n", optarg);
224                                         exit(1);
225                                 }
226                                 flag |= 2;
227                                 break;
228
229                         case 's':       /* Single process mode */
230                                 spawn_flag = FALSE;
231                                 dont_fork = TRUE;
232                                 break;
233
234                         case 't':       /* no child threads */
235                                 spawn_flag = FALSE;
236                                 break;
237
238                         case 'v':
239                                 /* Don't print timestamps */
240                                 debug_flag += 2;
241                                 fr_log_fp = stdout;
242                                 mainconfig.radlog_dest = RADLOG_STDOUT;
243                                 mainconfig.radlog_fd = STDOUT_FILENO;
244
245                                 version();
246                                 exit(0);
247                         case 'X':
248                                 spawn_flag = FALSE;
249                                 dont_fork = TRUE;
250                                 debug_flag += 2;
251                                 mainconfig.log_auth = TRUE;
252                                 mainconfig.log_auth_badpass = TRUE;
253                                 mainconfig.log_auth_goodpass = TRUE;
254                 do_stdout:
255                                 fr_log_fp = stdout;
256                                 mainconfig.radlog_dest = RADLOG_STDOUT;
257                                 mainconfig.radlog_fd = STDOUT_FILENO;
258                                 break;
259
260                         case 'x':
261                                 debug_flag++;
262                                 break;
263
264                         default:
265                                 usage(1);
266                                 break;
267                 }
268         }
269
270         if (flag && (flag != 0x03)) {
271                 fprintf(stderr, "radiusd: The options -i and -p cannot be used individually.\n");
272                 exit(1);
273         }
274
275         if (debug_flag)
276                 version();
277
278
279         /*  Read the configuration files, BEFORE doing anything else.  */
280         if (read_mainconfig(0) < 0) {
281                 exit(1);
282         }
283
284 #ifdef HAVE_OPENSSL_CRYPTO_H
285         /*
286          *      Initialize the OpenSSL library before calling any of its
287          *      functions.
288          */
289         SSL_library_init();
290         SSL_load_error_strings();
291
292         /*
293          *      Mismatch between build time OpenSSL and linked SSL,
294          *      better to die here than segfault later.
295          */
296         if (ssl_check_version(mainconfig.allow_vulnerable_openssl) < 0) {
297                 exit(1);
298         }
299 #endif
300
301         /*  Load the modules AFTER doing SSL checks */
302         if (setup_modules(FALSE, mainconfig.config) < 0) {
303                 return -1;
304         }
305
306         /* Set the panic action (if required) */
307         if (mainconfig.panic_action &&
308 #ifndef NDEBUG
309             !getenv("PANIC_ACTION") &&
310 #endif
311             (fr_fault_setup(mainconfig.panic_action, argv[0]) < 0)) {
312                 exit(EXIT_FAILURE);
313         }
314
315 #ifndef __MINGW32__
316
317         devnull = open("/dev/null", O_RDWR);
318         if (devnull < 0) {
319                 radlog(L_ERR|L_CONS, "Failed opening /dev/null: %s\n", strerror(errno));
320                 exit(1);
321         }
322
323         /*
324          *  Disconnect from session
325          */
326         if (dont_fork == FALSE) {
327                 pid_t pid;
328
329                 /*
330                  *  Really weird things happen if we leave stdin open and call
331                  *  things like system() later.
332                  */
333                 if (dont_fork == 0) {
334                         dup2(devnull, STDIN_FILENO);
335                 }
336
337                 if (pipe(from_child) != 0) {
338                         radlog(L_ERR, "Couldn't open pipe for child status: %s", strerror(errno));
339                         exit(1);
340                 }
341
342                 pid = fork();
343                 if (pid < 0) {
344                         radlog(L_ERR, "Couldn't fork: %s", strerror(errno));
345                         exit(1);
346                 }
347
348                 /*
349                  *  The parent exits, so the child can run in the background.
350                  *
351                  *  As the child can still encounter an error during initialisation
352                  *  we do a blocking read on a pipe between it and the parent.
353                  *
354                  *  Just before entering the event loop the child will
355                  */
356                 if (pid > 0) {
357                         uint8_t ret = 0;
358                         int stat_loc;
359
360                         /* So the pipe is correctly widowed if the child exits */
361                         close(from_child[1]);
362
363                         if ((read(from_child[0], &ret, 1) < 0)) {
364                                 ret = 0;
365                         }
366
367                         /* For cleanliness... */
368                         close(from_child[0]);
369
370                         /* Don't turn children into zombies */
371                         if (!ret) {
372                                 waitpid(pid, &stat_loc, WNOHANG);
373                                 exit(1);
374                         }
375
376                         exit(0);
377                 }
378
379                 /* so the pipe is correctly widowed if the parent exits?! */
380                 close(from_child[0]);
381 #ifdef HAVE_SETSID
382                 setsid();
383 #endif
384         }
385 #endif
386
387         /*
388          *  Ensure that we're using the CORRECT pid after forking,
389          *  NOT the one we started with.
390          */
391         radius_pid = getpid();
392
393         /*
394          *      STDOUT & STDERR go to /dev/null, unless we have "-x",
395          *      then STDOUT & STDERR go to the "-l log" destination.
396          *
397          *      The complexity here is because "-l log" can go to
398          *      STDOUT or STDERR, too.
399          */
400         if (mainconfig.radlog_dest == RADLOG_STDOUT) {
401                 setlinebuf(stdout);
402                 mainconfig.radlog_fd = STDOUT_FILENO;
403
404                 /*
405                  *      If we're debugging, allow STDERR to go to
406                  *      STDOUT too, for executed programs,
407                  */
408                 if (debug_flag) {
409                         dup2(STDOUT_FILENO, STDERR_FILENO);
410                 } else {
411                         dup2(devnull, STDERR_FILENO);
412                 }
413
414         } else if (mainconfig.radlog_dest == RADLOG_STDERR) {
415                 setlinebuf(stderr);
416                 mainconfig.radlog_fd = STDERR_FILENO;
417
418                 /*
419                  *      If we're debugging, allow STDOUT to go to
420                  *      STDERR too, for executed programs,
421                  */
422                 if (debug_flag) {
423                         dup2(STDERR_FILENO, STDOUT_FILENO);
424                 } else {
425                         dup2(devnull, STDOUT_FILENO);
426                 }
427
428         } else if (mainconfig.radlog_dest == RADLOG_SYSLOG) {
429                 /*
430                  *      Discard STDOUT and STDERR no matter what the
431                  *      status of debugging.  Syslog isn't a file
432                  *      descriptor, so we can't use it.
433                  */
434                 dup2(devnull, STDOUT_FILENO);
435                 dup2(devnull, STDERR_FILENO);
436
437         } else if (debug_flag) {
438                 /*
439                  *      If we're debugging, allow STDOUT and STDERR to
440                  *      go to the log file.
441                  */
442                 dup2(mainconfig.radlog_fd, STDOUT_FILENO);
443                 dup2(mainconfig.radlog_fd, STDERR_FILENO);
444
445         } else {
446                 /*
447                  *      Not debugging, and the log isn't STDOUT or
448                  *      STDERR.  Ensure that we move both of them to
449                  *      /dev/null, so that the calling terminal can
450                  *      exit, and the output from executed programs
451                  *      doesn't pollute STDOUT / STDERR.
452                  */
453                 dup2(devnull, STDOUT_FILENO);
454                 dup2(devnull, STDERR_FILENO);
455         }
456
457         close(devnull);
458
459         /*
460          *      Now we have logging check that the OpenSSL
461          */
462
463         /*
464          *      Initialize the event pool, including threads.
465          */
466         radius_event_init(mainconfig.config, spawn_flag);
467
468         /*
469          *      Now that we've set everything up, we can install the signal
470          *      handlers.  Before this, if we get any signal, we don't know
471          *      what to do, so we might as well do the default, and die.
472          */
473 #ifdef SIGPIPE
474         signal(SIGPIPE, SIG_IGN);
475 #endif
476 #ifdef HAVE_SIGACTION
477         act.sa_handler = sig_hup;
478         sigaction(SIGHUP, &act, NULL);
479         act.sa_handler = sig_fatal;
480         sigaction(SIGTERM, &act, NULL);
481 #else
482 #ifdef SIGHUP
483         signal(SIGHUP, sig_hup);
484 #endif
485         signal(SIGTERM, sig_fatal);
486 #endif
487         /*
488          *      If we're debugging, then a CTRL-C will cause the
489          *      server to die immediately.  Use SIGTERM to shut down
490          *      the server cleanly in that case.
491          */
492         if ((mainconfig.debug_memory == 1) || (debug_flag == 0)) {
493 #ifdef HAVE_SIGACTION
494                 act.sa_handler = sig_fatal;
495                 sigaction(SIGINT, &act, NULL);
496                 sigaction(SIGQUIT, &act, NULL);
497 #else
498                 signal(SIGINT, sig_fatal);
499 #ifdef SIGQUIT
500                 signal(SIGQUIT, sig_fatal);
501 #endif
502 #endif
503         }
504
505         /*
506          *      Everything seems to have loaded OK, exit gracefully.
507          */
508         if (check_config) {
509                 DEBUG("Configuration appears to be OK.");
510                 exit(0);
511         }
512
513         radius_stats_init(0);
514
515         /*
516          *  Only write the PID file if we're running as a daemon.
517          *
518          *  And write it AFTER we've forked, so that we write the
519          *  correct PID.
520          */
521         if (dont_fork == FALSE) {
522                 FILE *fp;
523
524                 fp = fopen(mainconfig.pid_file, "w");
525                 if (fp != NULL) {
526                         /*
527                          *      FIXME: What about following symlinks,
528                          *      and having it over-write a normal file?
529                          */
530                         fprintf(fp, "%d\n", (int) radius_pid);
531                         fclose(fp);
532                 } else {
533                         radlog(L_ERR|L_CONS, "Failed creating PID file %s: %s\n",
534                                mainconfig.pid_file, strerror(errno));
535                         exit(1);
536                 }
537
538                 /*
539                  *      Inform parent (who should still be waiting) that
540                  *      the rest of initialisation went OK, and that it
541                  *      should exit with a 0 status.
542                  */
543                 write(from_child[1], "\001", 1);
544                 close(from_child[1]);
545         }
546
547         /*
548          *      Process requests until HUP or exit.
549          */
550         while ((rcode = radius_event_process()) == 0x80) {
551                 radius_stats_init(1);
552                 hup_mainconfig();
553         }
554
555         if (rcode < 0) {
556                 radlog(L_ERR, "Exiting due to internal error: %s",
557                        fr_strerror());
558                 rcode = 2;
559         } else {
560                 radlog(L_INFO, "Exiting normally.");
561                 rcode = 1;
562         }
563
564         /*
565          *      Ignore the TERM signal: we're
566          *      about to die.
567          */
568         signal(SIGTERM, SIG_IGN);
569
570         /*
571          *      Send a TERM signal to all
572          *      associated processes
573          *      (including us, which gets
574          *      ignored.)
575          */
576 #ifndef __MINGW32__
577         if (spawn_flag) kill(-radius_pid, SIGTERM);
578 #endif
579
580         /*
581          *      We're exiting, so we can delete the PID
582          *      file.  (If it doesn't exist, we can ignore
583          *      the error returned by unlink)
584          */
585         if (dont_fork == FALSE) {
586                 unlink(mainconfig.pid_file);
587         }
588
589         radius_event_free();
590
591         /*
592          *      Detach any modules.
593          */
594         detach_modules();
595
596         xlat_free();            /* modules may have xlat's */
597
598         /*
599          *      Free the configuration items.
600          */
601         free_mainconfig();
602
603         free(radius_dir);
604
605 #ifdef WIN32
606         WSACleanup();
607 #endif
608
609         return (rcode - 1);
610 }
611
612
613 /*
614  *  Display the syntax for starting this program.
615  */
616 static void NEVER_RETURNS usage(int status)
617 {
618         FILE *output = status?stderr:stdout;
619
620         fprintf(output,
621                         "Usage: %s [-d db_dir] [-l log_dir] [-i address] [-n name] [-fsvXx]\n", progname);
622         fprintf(output, "Options:\n\n");
623         fprintf(output, "  -C              Check configuration and exit.\n");
624         fprintf(output, "  -d raddb_dir    Configuration files are in \"raddbdir/*\".\n");
625         fprintf(output, "  -f              Run as a foreground process, not a daemon.\n");
626         fprintf(output, "  -h              Print this help message.\n");
627         fprintf(output, "  -i ipaddr       Listen on ipaddr ONLY.\n");
628         fprintf(output, "  -l log_file     Logging output will be written to this file.\n");
629         fprintf(output, "  -m              On SIGINT or SIGQUIT exit cleanly instead of immediately.\n");
630         fprintf(output, "  -n name         Read raddb/name.conf instead of raddb/radiusd.conf\n");
631         fprintf(output, "  -p port         Listen on port ONLY.\n");
632         fprintf(output, "  -s              Do not spawn child processes to handle requests.\n");
633         fprintf(output, "  -t              Disable threads.\n");
634         fprintf(output, "  -v              Print server version information.\n");
635         fprintf(output, "  -X              Turn on full debugging.\n");
636         fprintf(output, "  -x              Turn on additional debugging. (-xx gives more debugging).\n");
637         exit(status);
638 }
639
640
641 /*
642  *      We got a fatal signal.
643  */
644 static void sig_fatal(int sig)
645 {
646         if (getpid() != radius_pid) _exit(sig);
647
648         switch(sig) {
649                 case SIGTERM:
650                         radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
651                         break;
652
653                 case SIGINT:
654 #ifdef SIGQUIT
655                 case SIGQUIT:
656 #endif
657                         if (mainconfig.debug_memory) {
658                                 radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
659                                 break;
660                         }
661                         /* FALL-THROUGH */
662
663                 default:
664                         _exit(sig);
665         }
666 }
667
668 #ifdef SIGHUP
669 /*
670  *  We got the hangup signal.
671  *  Re-read the configuration files.
672  */
673 static void sig_hup(int sig)
674 {
675         sig = sig; /* -Wunused */
676
677         reset_signal(SIGHUP, sig_hup);
678
679         radius_signal_self(RADIUS_SIGNAL_SELF_HUP);
680 }
681 #endif