Add version consistency checks between applications, libfreeradius-radius, libfreerad...
[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 #" STRINGIFY(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 the binary and the libraries it depends on
292          */
293         if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) {
294                 fr_perror("radiusd");
295                 exit(EXIT_FAILURE);
296         }
297
298         if (rad_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) {
299                 exit(EXIT_FAILURE);
300         }
301
302         /*
303          *      Mismatch between build time OpenSSL and linked SSL,
304          *      better to die here than segfault later.
305          */
306 #ifdef HAVE_OPENSSL_CRYPTO_H
307         if (ssl_check_version() < 0) {
308                 exit(EXIT_FAILURE);
309         }
310
311         /*
312          *      Initialising OpenSSL once, here, is safer than having individual
313          *      modules do it.
314          */
315         tls_global_init();
316 #endif
317
318         if (flag && (flag != 0x03)) {
319                 fprintf(stderr, "radiusd: The options -i and -p cannot be used individually.\n");
320                 exit(EXIT_FAILURE);
321         }
322
323         if (debug_flag) {
324                 version();
325         }
326
327         /*  Read the configuration files, BEFORE doing anything else.  */
328         if (read_mainconfig(0) < 0) {
329                 exit(EXIT_FAILURE);
330         }
331
332 #ifndef __MINGW32__
333         /*
334          *  Disconnect from session
335          */
336         if (dont_fork == false) {
337                 pid_t pid;
338
339                 if (pipe(from_child) != 0) {
340                         ERROR("Couldn't open pipe for child status: %s", strerror(errno));
341                         exit(EXIT_FAILURE);
342                 }
343
344                 pid = fork();
345                 if (pid < 0) {
346                         ERROR("Couldn't fork: %s", strerror(errno));
347                         exit(EXIT_FAILURE);
348                 }
349
350                 /*
351                  *  The parent exits, so the child can run in the background.
352                  *
353                  *  As the child can still encounter an error during initialisation
354                  *  we do a blocking read on a pipe between it and the parent.
355                  *
356                  *  Just before entering the event loop the child will send a success
357                  *  or failure message to the parent, via the pipe.
358                  */
359                 if (pid > 0) {
360                         uint8_t ret = 0;
361                         int stat_loc;
362
363                         /* So the pipe is correctly widowed if the child exits */
364                         close(from_child[1]);
365
366                         /*
367                          *      The child writes a 0x01 byte on
368                          *      success, and closes the pipe on error.
369                          */
370                         if ((read(from_child[0], &ret, 1) < 0)) {
371                                 ret = 0;
372                         }
373
374                         /* For cleanliness... */
375                         close(from_child[0]);
376
377                         /* Don't turn children into zombies */
378                         if (!ret) {
379                                 waitpid(pid, &stat_loc, WNOHANG);
380                                 exit(EXIT_FAILURE);
381                         }
382
383                         exit(EXIT_SUCCESS);
384                 }
385
386                 /* so the pipe is correctly widowed if the parent exits?! */
387                 close(from_child[0]);
388 #ifdef HAVE_SETSID
389                 setsid();
390 #endif
391         }
392 #endif
393
394         /*
395          *  Ensure that we're using the CORRECT pid after forking,
396          *  NOT the one we started with.
397          */
398         radius_pid = getpid();
399
400         /*
401          *      If we're running as a daemon, close the default file
402          *      descriptors, AFTER forking.
403          */
404         if (!debug_flag) {
405                 int devnull;
406
407                 devnull = open("/dev/null", O_RDWR);
408                 if (devnull < 0) {
409                         ERROR("Failed opening /dev/null: %s\n",
410                                strerror(errno));
411                         exit(EXIT_FAILURE);
412                 }
413                 dup2(devnull, STDIN_FILENO);
414                 if (default_log.dest == L_DST_STDOUT) {
415                         setlinebuf(stdout);
416                         default_log.fd = STDOUT_FILENO;
417                 } else {
418                         dup2(devnull, STDOUT_FILENO);
419                 }
420                 if (default_log.dest == L_DST_STDERR) {
421                         setlinebuf(stderr);
422                         default_log.fd = STDERR_FILENO;
423                 } else {
424                         dup2(devnull, STDERR_FILENO);
425                 }
426                 close(devnull);
427
428         } else {
429                 setlinebuf(stdout); /* unbuffered output */
430         }
431
432         /*
433          *      Now we have logging check that the OpenSSL
434          */
435
436         /*
437          *      Initialize the event pool, including threads.
438          */
439         radius_event_init(mainconfig.config, spawn_flag);
440
441         /*
442          *      Now that we've set everything up, we can install the signal
443          *      handlers.  Before this, if we get any signal, we don't know
444          *      what to do, so we might as well do the default, and die.
445          */
446 #ifdef SIGPIPE
447         signal(SIGPIPE, SIG_IGN);
448 #endif
449 #ifdef HAVE_SIGACTION
450         act.sa_handler = sig_hup;
451         sigaction(SIGHUP, &act, NULL);
452         act.sa_handler = sig_fatal;
453         sigaction(SIGTERM, &act, NULL);
454 #else
455 #ifdef SIGHUP
456         signal(SIGHUP, sig_hup);
457 #endif
458         signal(SIGTERM, sig_fatal);
459 #endif
460         /*
461          *      If we're debugging, then a CTRL-C will cause the
462          *      server to die immediately.  Use SIGTERM to shut down
463          *      the server cleanly in that case.
464          */
465         if ((mainconfig.debug_memory == 1) || (debug_flag == 0)) {
466 #ifdef HAVE_SIGACTION
467                 act.sa_handler = sig_fatal;
468                 sigaction(SIGINT, &act, NULL);
469                 sigaction(SIGQUIT, &act, NULL);
470 #else
471                 signal(SIGINT, sig_fatal);
472 #ifdef SIGQUIT
473                 signal(SIGQUIT, sig_fatal);
474 #endif
475 #endif
476         }
477
478         /*
479          *      Everything seems to have loaded OK, exit gracefully.
480          */
481         if (check_config) {
482                 DEBUG("Configuration appears to be OK.");
483
484                 /* for -C -m|-M */
485                 if (mainconfig.debug_memory) {
486                         goto cleanup;
487                 }
488
489                 exit(EXIT_SUCCESS);
490         }
491
492 #ifdef WITH_STATS
493         radius_stats_init(0);
494 #endif
495
496         /*
497          *      Write out the PID anyway if were in foreground mode.
498          */
499         if (!dont_fork) write_pid = true;
500
501         /*
502          *  Only write the PID file if we're running as a daemon.
503          *
504          *  And write it AFTER we've forked, so that we write the
505          *  correct PID.
506          */
507         if (write_pid) {
508                 FILE *fp;
509
510                 fp = fopen(mainconfig.pid_file, "w");
511                 if (fp != NULL) {
512                         /*
513                          *      FIXME: What about following symlinks,
514                          *      and having it over-write a normal file?
515                          */
516                         fprintf(fp, "%d\n", (int) radius_pid);
517                         fclose(fp);
518                 } else {
519                         ERROR("Failed creating PID file %s: %s\n",
520                                mainconfig.pid_file, strerror(errno));
521                         exit(EXIT_FAILURE);
522                 }
523         }
524
525         exec_trigger(NULL, NULL, "server.start", false);
526
527         /*
528          *      Inform the parent (who should still be waiting) that
529          *      the rest of initialisation went OK, and that it should
530          *      exit with a 0 status.  If we don't get this far, then
531          *      we just close the pipe on exit, and the parent gets a
532          *      read failure.
533          */
534         if (!dont_fork) {
535                 if (write(from_child[1], "\001", 1) < 0) {
536                         WARN("Failed informing parent of successful start: %s",
537                              strerror(errno));
538                 }
539                 close(from_child[1]);
540         }
541
542         /*
543          *      Process requests until HUP or exit.
544          */
545         while ((status = radius_event_process()) == 0x80) {
546 #ifdef WITH_STATS
547                 radius_stats_init(1);
548 #endif
549                 hup_mainconfig();
550         }
551         if (status < 0) {
552                 ERROR("Exiting due to internal error: %s", fr_strerror());
553                 rcode = EXIT_FAILURE;
554         } else {
555                 INFO("Exiting normally.");
556         }
557
558         exec_trigger(NULL, NULL, "server.stop", false);
559
560         /*
561          *      Ignore the TERM signal: we're
562          *      about to die.
563          */
564         signal(SIGTERM, SIG_IGN);
565
566         /*
567          *      Send a TERM signal to all
568          *      associated processes
569          *      (including us, which gets
570          *      ignored.)
571          */
572 #ifndef __MINGW32__
573         if (spawn_flag) kill(-radius_pid, SIGTERM);
574 #endif
575
576         /*
577          *      We're exiting, so we can delete the PID
578          *      file.  (If it doesn't exist, we can ignore
579          *      the error returned by unlink)
580          */
581         if (dont_fork == false) {
582                 unlink(mainconfig.pid_file);
583         }
584
585         radius_event_free();
586
587 cleanup:
588         /*
589          *      Detach any modules.
590          */
591         detach_modules();
592
593         xlat_free();            /* modules may have xlat's */
594
595         /*
596          *      Free the configuration items.
597          */
598         free_mainconfig();
599
600         rad_const_free(radius_dir);
601
602 #ifdef WIN32
603         WSACleanup();
604 #endif
605
606         if (memory_report) {
607                 INFO("Allocated memory at time of report:");
608                 log_talloc_report(NULL);
609         }
610
611         return rcode;
612 }
613
614
615 /*
616  *  Display the syntax for starting this program.
617  */
618 static void NEVER_RETURNS usage(int status)
619 {
620         FILE *output = status?stderr:stdout;
621
622         fprintf(output, "Usage: %s [-d db_dir] [-l log_dir] [-i address] [-n name] [-fsvXx]\n", progname);
623         fprintf(output, "Options:\n");
624         fprintf(output, "  -C            Check configuration and exit.\n");
625         fprintf(output, "  -d raddb_dir  Configuration files are in \"raddbdir/*\".\n");
626         fprintf(output, "  -f            Run as a foreground process, not a daemon.\n");
627         fprintf(output, "  -h            Print this help message.\n");
628         fprintf(output, "  -i ipaddr     Listen on ipaddr ONLY.\n");
629         fprintf(output, "  -l log_file   Logging output will be written to this file.\n");
630         fprintf(output, "  -m            On SIGINT or SIGQUIT exit cleanly instead of immediately.\n");
631         fprintf(output, "  -n name       Read raddb/name.conf instead of raddb/radiusd.conf.\n");
632         fprintf(output, "  -p port       Listen on port ONLY.\n");
633         fprintf(output, "  -P            Always write out PID, even with -f.\n");
634         fprintf(output, "  -s            Do not spawn child processes to handle requests.\n");
635         fprintf(output, "  -t            Disable threads.\n");
636         fprintf(output, "  -v            Print server version information.\n");
637         fprintf(output, "  -X            Turn on full debugging.\n");
638         fprintf(output, "  -x            Turn on additional debugging. (-xx gives more debugging).\n");
639         exit(status);
640 }
641
642
643 /*
644  *      We got a fatal signal.
645  */
646 static void sig_fatal(int sig)
647 {
648         if (getpid() != radius_pid) _exit(sig);
649
650         switch(sig) {
651                 case SIGTERM:
652                         radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
653                         break;
654
655                 case SIGINT:
656 #ifdef SIGQUIT
657                 case SIGQUIT:
658 #endif
659                         if (mainconfig.debug_memory || memory_report) {
660                                 radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
661                                 break;
662                         }
663                         /* FALL-THROUGH */
664
665                 default:
666                         _exit(sig);
667         }
668 }
669
670 #ifdef SIGHUP
671 /*
672  *  We got the hangup signal.
673  *  Re-read the configuration files.
674  */
675 static void sig_hup(UNUSED int sig)
676 {
677         reset_signal(SIGHUP, sig_hup);
678
679         radius_signal_self(RADIUS_SIGNAL_SELF_HUP);
680 }
681 #endif