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