The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
radiusd.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: f864edef9cfece035c6493fe3dd869cce95de17a $
19  *
20  * @file radiusd.c
21  * @brief Main loop of the radius server.
22  *
23  * @copyright 2000-2018 The FreeRADIUS server project
24  * @copyright 1999,2000 Miquel van Smoorenburg (miquels@cistron.nl)
25  * @copyright 2000 Alan DeKok (aland@freeradius.org)
26  * @copyright 2000 Alan Curry (pacman-radius@cqc.com)
27  * @copyright 2000 Jeff Carneal (jeff@apex.net)
28  * @copyright 2000 Chad Miller (cmiller@surfsouth.com)
29  */
30 RCSID("$Id: f864edef9cfece035c6493fe3dd869cce95de17a $")
31 
32 #include <freeradius-devel/server/base.h>
33 #include <freeradius-devel/server/dependency.h>
34 #include <freeradius-devel/server/map_proc.h>
35 #include <freeradius-devel/server/module.h>
36 #include <freeradius-devel/server/radmin.h>
37 #include <freeradius-devel/server/state.h>
38 #include <freeradius-devel/server/virtual_servers.h>
39 #include <freeradius-devel/util/debug.h>
40 #include <freeradius-devel/util/size.h>
41 #include <freeradius-devel/util/strerror.h>
42 
43 #include <freeradius-devel/tls/base.h>
44 #include <freeradius-devel/tls/log.h>
45 
46 #include <freeradius-devel/unlang/base.h>
47 
48 #include <freeradius-devel/util/misc.h>
49 #include <freeradius-devel/util/syserror.h>
50 
51 #ifdef HAVE_CAPABILITY_H
52 #include <freeradius-devel/util/cap.h>
53 #endif
54 
55 #include <ctype.h>
56 #include <fcntl.h>
57 #include <signal.h>
58 #include <sys/file.h>
59 #include <sys/mman.h>
60 
61 #ifdef HAVE_GETOPT_H
62 # include <getopt.h>
63 #endif
64 
65 #ifdef HAVE_SYS_WAIT_H
66 # include <sys/wait.h>
67 #endif
68 #ifndef WEXITSTATUS
69 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
70 #endif
71 #ifndef WIFEXITED
72 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
73 #endif
74 
75 #ifdef HAVE_SYSTEMD
76 # include <systemd/sd-daemon.h>
77 #endif
78 
79 #ifdef WITH_TLS
80 # include <freeradius-devel/tls/version.h>
81 #endif
82 
83 char const *radiusd_version = RADIUSD_VERSION_BUILD("FreeRADIUS");
84 static pid_t radius_pid;
85 
86 /*
87  * Configuration items.
88  */
89 
90 /*
91  * Static functions.
92  */
93 static void usage(main_config_t const *config, int status);
94 
95 static void sig_fatal (int);
96 #ifdef SIGHUP
97 static void sig_hup (int);
98 #endif
99 
100 /** Configure talloc debugging features
101  *
102  * @param[in] config The main config.
103  * @return
104  * - 1 on config conflict.
105  * - 0 on success.
106  * - -1 on error.
107  */
109 {
110  if (config->spawn_workers) {
111  if (config->talloc_memory_report) {
112  fr_strerror_printf("talloc_memory_report requires single threaded mode (-s | -X)");
113  return 1;
114  }
115  return 0;
116  }
117 
118  if (!config->talloc_memory_report) {
119  talloc_disable_null_tracking();
120  return 0;
121  }
122 
123  talloc_enable_null_tracking();
124 
125  return 0;
126 }
127 
128 
129 /** Create module and xlat per-thread instances
130  *
131  */
132 static int thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el, UNUSED void *uctx)
133 {
134  if (modules_rlm_thread_instantiate(ctx, el) < 0) return -1;
135 
136  if (virtual_servers_thread_instantiate(ctx, el) < 0) return -1;
137 
138  if (xlat_thread_instantiate(ctx, el) < 0) return -1;
139 #ifdef WITH_TLS
140  if (fr_openssl_thread_init(main_config->openssl_async_pool_init,
141  main_config->openssl_async_pool_max) < 0) return -1;
142 #endif
143  return 0;
144 }
145 
146 /** Explicitly cleanup module/xlat resources
147  *
148  */
149 static void thread_detach(UNUSED void *uctx)
150 {
152 
154 
156 }
157 
158 #define EXIT_WITH_FAILURE \
159 do { \
160  ret = EXIT_FAILURE; \
161  goto cleanup; \
162 } while (0)
163 
164 #define EXIT_WITH_SUCCESS \
165 do { \
166  ret = EXIT_SUCCESS; \
167  goto cleanup; \
168 } while (0)
169 
170 static fr_event_timer_t const *fr_time_sync_ev = NULL;
171 
173 {
175 
176  (void) fr_event_timer_in(el, el, &fr_time_sync_ev, when, fr_time_sync_event, NULL);
177  (void) fr_time_sync();
178 }
179 
180 #ifndef NDEBUG
181 /** Encourage the server to exit after a period of time
182  *
183  * @param[in] el The main loop.
184  * @param[in] now Current time. Should be 0, when adding the event.
185  * @param[in] uctx Pointer to a fr_time_delta_t indicating how long
186  * the server should run before exit.
187  */
188 static void fr_exit_after(fr_event_list_t *el, fr_time_t now, void *uctx)
189 {
190  static fr_event_timer_t const *ev;
191 
192  fr_time_delta_t exit_after = *(fr_time_delta_t *)uctx;
193 
194  if (fr_time_eq(now, fr_time_wrap(0))) {
195  if (fr_event_timer_in(el, el, &ev, exit_after, fr_exit_after, uctx) < 0) {
196  PERROR("Failed inserting exit event");
197  }
198  return;
199  }
200 
202 }
203 #endif
204 
205 #ifdef HAVE_CAPABILITY_H
206 #define DUMP_CAPABILITIES(_phase) \
207 { \
208  char *cap_str; \
209  if (fr_cap_set_to_str(talloc_autofree_context(), &cap_str) < 0) { \
210  PWARN("Failed retrieving %s capabilities", _phase); \
211  } else { \
212  INFO("%s capabilities: %s", _phase, cap_str); \
213  talloc_free(cap_str); \
214  } \
215 }
216 #else
217 #define DUMP_CAPABILITIES(_phase)
218 #endif
219 
220 /** Entry point for the daemon
221  *
222  * @hidecallgraph
223  */
224 int main(int argc, char *argv[])
225 {
226  int status;
227  int c;
228  bool display_version = false;
229  bool radmin = false;
230  int from_child[2] = {-1, -1};
231  char const *program;
232  fr_schedule_t *sc = NULL;
233  int ret = EXIT_SUCCESS;
234 
235  TALLOC_CTX *global_ctx = NULL;
236  main_config_t *config = NULL;
237  bool talloc_memory_report = false;
238 
239  bool raddb_dir_set = false;
240 
241  size_t pool_size = 0;
242  void *pool_page_start = NULL, *pool_page_end = NULL;
243  bool do_mprotect;
244 
245 #ifndef NDEBUG
246  fr_time_delta_t exit_after = fr_time_delta_wrap(0);
247 #endif
248  /*
249  * Must be called first, so the handler is called last
250  */
252 
253  /*
254  * Setup talloc callbacks so we get useful errors
255  */
256  (void) fr_talloc_fault_setup();
257 
258  /*
259  * We probably don't want to free the talloc global_ctx context
260  * directly, so we'll allocate a new context beneath it, and
261  * free that before any leak reports.
262  */
263  {
264  char *env;
265 
266  /*
267  * If a FR_GLOBAL_POOL value is provided and
268  * is of a valid size, we pre-allocate a global
269  * memory pool, and mprotect() it once we're done
270  * parsing the global config.
271  *
272  * This lets us catch stray writes into global
273  * memory.
274  */
275  env = getenv("FR_GLOBAL_POOL");
276  if (env) {
277  if (fr_size_from_str(&pool_size, &FR_SBUFF_IN(env, strlen(env))) < 0) {
278  fr_perror("Invalid pool size string \"%s\"", env);
280  }
281 
282  /*
283  * Pre-allocate a global memory pool for the static
284  * config to exist in. We mprotect() this later to
285  * catch any stray writes.
286  */
288  &pool_page_start, &pool_page_end, pool_size);
289  do_mprotect = true;
290  } else {
291  global_ctx = talloc_new(talloc_autofree_context());
292  do_mprotect = false;
293  }
294 
295  if (!global_ctx) {
296  fprintf(stderr, "Failed allocating global context\n");
298  }
299  }
300 
301  /*
302  * Allocate the main config structure.
303  * It's allocated so we can hang talloced buffers off it.
304  */
306  if (!config) {
307  fprintf(stderr, "Failed allocating main config");
309  }
310 
311  /*
312  * Set some default values
313  */
314  program = strrchr(argv[0], FR_DIR_SEP);
315  if (!program) {
316  program = argv[0];
317  } else {
318  program++;
319  }
320  main_config_name_set_default(config, program, false);
321 
322  config->daemonize = true;
323  config->spawn_workers = true;
324 
325 #ifdef OSFC2
326  set_auth_parameters(argc, argv);
327 #endif
328 
329 #ifdef WIN32
330  {
331  WSADATA wsaData;
332  if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
333  fprintf(stderr, "%s: Unable to initialize socket library.\n", config->name);
335  }
336  }
337 #endif
338 
339  fr_debug_lvl = 0;
340  fr_time_start();
341 
342  /*
343  * Don't put output anywhere until we get told a little
344  * more.
345  */
347  default_log.fd = -1;
348  default_log.print_level = true;
350 
351  /*
352  * Set the panic action and enable other debugging facilities
353  */
354  if (fr_fault_setup(global_ctx, getenv("PANIC_ACTION"), argv[0]) < 0) {
355  fr_perror("Failed installing fault handlers... continuing");
356  }
357 
358  /* Process the options. */
359  while ((c = getopt(argc, argv, "Cd:D:e:fhi:l:Mmn:p:PrsS:tTvxX")) != -1) switch (c) {
360  case 'C':
361  check_config = true;
362  config->spawn_workers = false;
363  config->daemonize = false;
364  break;
365 
366  case 'd':
368  raddb_dir_set = true;
369  break;
370 
371  case 'D':
373  break;
374 
375 #ifndef NDEBUG
376  case 'e':
377  exit_after = fr_time_delta_from_sec(atoi(optarg));
378  break;
379 #endif
380 
381  case 'f':
382  config->daemonize = false;
383  break;
384 
385  case 'h':
386  usage(config, EXIT_SUCCESS);
387  break;
388 
389  case 'l':
390  if (strcmp(optarg, "stdout") == 0) goto do_stdout;
391 
392  config->log_file = talloc_typed_strdup(global_ctx, optarg);
395  default_log.fd = open(config->log_file, O_WRONLY | O_APPEND | O_CREAT, 0640);
396  if (default_log.fd < 0) {
397  fprintf(stderr, "%s: Failed to open log file %s: %s\n",
398  config->name, config->log_file, fr_syserror(errno));
400  }
401  break;
402 
403  case 'm':
404  config->allow_multiple_procs = true;
405  break;
406 
407  case 'M':
408  config->talloc_memory_report = true;
409  break;
410 
411  case 'n':
412  main_config_name_set_default(config, optarg, true);
413  break;
414 
415  case 'P': /* Force the PID to be written, even in -f mode */
416  config->write_pid = true;
417  break;
418 
419  case 'r': /* internal radmin-style control interface */
420  config->spawn_workers = false;
421  config->daemonize = false;
422  radmin = true;
423  break;
424 
425  case 's': /* Single process mode */
426  config->spawn_workers = false;
427  config->daemonize = false;
428  break;
429 
430  case 'S': /* Migration support */
431  if (main_config_parse_option(optarg) < 0) {
432  fprintf(stderr, "%s: Unknown configuration option '%s'\n",
433  config->name, optarg);
435  }
436  break;
437 
438  case 't': /* no child threads */
439  config->spawn_workers = false;
440  break;
441 
442  case 'T': /* enable timestamps */
444  break;
445 
446  case 'v':
447  display_version = true;
448  break;
449 
450  case 'X':
451  config->spawn_workers = false;
452  config->daemonize = false;
453  fr_debug_lvl += 2;
454  if (fr_debug_lvl > 2) default_log.suppress_secrets = false;
455 
456  do_stdout:
458  default_log.fd = STDOUT_FILENO;
459  break;
460 
461  case 'x':
462  fr_debug_lvl++;
463  if (fr_debug_lvl > 2) default_log.suppress_secrets = false;
464  break;
465 
466  default:
467  usage(config, EXIT_FAILURE);
468  break;
469  }
470 
471  /*
472  * Allow the configuration directory to be set from an
473  * environment variable. This allows tests to change the
474  * configuration directory without changing the scripts
475  * being executed.
476  */
477  if (!raddb_dir_set) {
478  char const *raddb_dir = getenv("FREERADIUS_CONFIG_DIR");
479 
480  if (raddb_dir) main_config_raddb_dir_set(config, raddb_dir);
481  }
482 
483  /*
484  * We've now got enough information to check to see
485  * if another process is running with the same config.
486  */
487  config->debug_level = fr_debug_lvl;
488 
489  /*
490  * Mismatch between the binary and the libraries it depends on.
491  */
493  fr_perror("%s", config->name);
495  }
496 
498 
499 #ifdef WITH_TLS
500  /*
501  * Mismatch between build time OpenSSL and linked SSL, better to die
502  * here than segfault later.
503  */
505 
506  /*
507  * Initialising OpenSSL once, here, is safer than having individual modules do it.
508  * Must be called before display_version to ensure relevant engines are loaded.
509  *
510  * fr_openssl_init() must be called before *ANY* OpenSSL functions are used, which is why
511  * it's called so early.
512  */
513  if (fr_openssl_init() < 0) EXIT_WITH_FAILURE;
514 #endif
515 
516  /*
517  * According to the talloc peeps, no two threads may modify any part of
518  * a ctx tree with a common root without synchronisation.
519  *
520  * So we can't run with a null context and threads.
521  */
522  if (talloc_config_set(config) != 0) {
523  fr_perror("%s", config->name);
525  }
526 
527  /*
528  * Better here, so it doesn't matter whether we get passed -xv or -vx.
529  */
530  if (display_version) {
531  if (fr_debug_lvl == 0) fr_debug_lvl = 1;
533  default_log.fd = STDOUT_FILENO;
534 
535  INFO("%s - %s", config->name, radiusd_version);
538  }
539 
541 
542  /*
543  * Under linux CAP_SYS_PTRACE is usually only available before setuid/setguid,
544  * so we need to check whether we can attach before calling those functions
545  * (in main_config_init()).
546  */
548 
549  /*
550  * Write the PID always if we're running as a daemon.
551  */
552  if (config->daemonize) config->write_pid = true;
553 
554  /*
555  * Initialize the DL infrastructure, which is used by the
556  * config file parser. Note that we pass an empty path
557  * here, as we haven't yet read the configuration file.
558  */
559  modules_init(NULL);
560 
561  /*
562  * Initialise the top level dictionary hashes which hold
563  * the protocols.
564  */
565  if (!fr_dict_global_ctx_init(NULL, true, config->dict_dir)) {
566  fr_perror("%s", program);
568  }
569 
570 #ifdef WITH_TLS
571  if (fr_tls_dict_init() < 0) {
572  fr_perror("%s", program);
574  }
575 #endif
576 
577  /*
578  * Setup the global structures for module lists
579  */
580  if (modules_rlm_init() < 0) {
581  fr_perror("%s", program);
583  }
584 
585  if (virtual_servers_init() < 0) {
586  fr_perror("%s", program);
588  }
589 
590  /*
591  * Load dictionary attributes used
592  * for requests.
593  */
594  if (request_global_init() < 0) {
595  fr_perror("%s", program);
597  }
598 
599  /*
600  * Read the configuration files, BEFORE doing anything else.
601  */
603 
604  if (!config->suppress_secrets) default_log.suppress_secrets = false;
605 
606  /*
607  * Check we're the only process using this config.
608  */
609  if (!config->allow_multiple_procs) {
611  case 0: /* No other processes running */
612  break;
613 
614  case -1: /* Permissions error - fail open */
615  PWARN("%s - Process concurrency checks disabled", program);
616  break;
617 
618  case 1:
619  default: /* All other errors */
620  fr_perror("%s", program);
622  }
623  }
624 
625  /*
626  * Set panic_action from the main config if one wasn't specified in the
627  * environment.
628  */
629  if (config->panic_action && !getenv("PANIC_ACTION") &&
630  (fr_fault_setup(global_ctx, config->panic_action, argv[0]) < 0)) {
631  fr_perror("radiusd - Failed configuring panic action: %s", config->name);
633  }
634 
635  /*
636  * This is very useful in figuring out why the panic_action didn't fire.
637  */
639 
640  /*
641  * Call this again now we've loaded the configuration. Yes I know...
642  */
643  if (talloc_config_set(config) < 0) {
644  fr_perror("%s", config->name);
646  }
647 
648  /*
649  * Check for vulnerabilities in the version of libssl were linked against.
650  */
651 #ifdef WITH_TLS
652 # ifdef ENABLE_OPENSSL_VERSION_CHECK
653  if (fr_openssl_version_check(config->allow_vulnerable_openssl) < 0) EXIT_WITH_FAILURE;
654 # endif
655 
656  /*
657  * Toggle FIPS mode
658  */
659  if (config->openssl_fips_mode_is_set &&
660  (fr_openssl_fips_mode(config->openssl_fips_mode) < 0)) EXIT_WITH_FAILURE;
661 #endif
662 
663  /*
664  * The systemd watchdog enablement must be checked before we
665  * daemonize, but the watchdog notifications can come from any
666  * process.
667  */
668 #ifdef HAVE_SYSTEMD_WATCHDOG
669  if (!check_config) main_loop_set_sd_watchdog_interval();
670 #else
671  /*
672  * If the default systemd unit file is used, but the server wasn't
673  * built with support for systemd, the status returned by systemctl
674  * will stay permanently as "activating".
675  *
676  * We detect this condition and warn about it here, using the
677  * presence of the NOTIFY_SOCKET environmental variable to determine
678  * whether we're running under systemd.
679  */
680  if (getenv("NOTIFY_SOCKET")) INFO("Built without support for systemd watchdog, but running under systemd");
681 #endif
682 
683  /*
684  * Don't allow radmin when checking the config.
685  */
686  if (check_config) radmin = false;
687 
688  if (fr_radmin_start(config, radmin) < 0) EXIT_WITH_FAILURE;
689 
690  /*
691  * Disconnect from session
692  */
693  if (config->daemonize) {
694  pid_t pid;
695  int devnull;
696 
697  DUMP_CAPABILITIES("pre-fork");
698 
699  /*
700  * Really weird things happen if we leave stdin open and call things like
701  * system() later.
702  */
703  devnull = open("/dev/null", O_RDWR);
704  if (devnull < 0) {
705  ERROR("Failed opening /dev/null: %s", fr_syserror(errno));
707  }
708  dup2(devnull, STDIN_FILENO);
709 
710  close(devnull);
711 
712  if (pipe(from_child) != 0) {
713  ERROR("Couldn't open pipe for child status: %s", fr_syserror(errno));
715  }
716 
717  pid = fork();
718  if (pid < 0) {
719  ERROR("Couldn't fork: %s", fr_syserror(errno));
721  }
722 
723  /*
724  * The parent exits, so the child can run in the background.
725  *
726  * As the child can still encounter an error during initialisation
727  * we do a blocking read on a pipe between it and the parent.
728  *
729  * Just before entering the event loop the child will send a success
730  * or failure message to the parent, via the pipe.
731  */
732  if (pid > 0) {
733  uint8_t child_ret;
734  int stat_loc;
735 
736  /* So the pipe is correctly widowed if the child exits */
737  close(from_child[1]);
738 
739  /*
740  * The child writes a 0x01 byte on success, and closes
741  * the pipe on error.
742  */
743  if ((read(from_child[0], &child_ret, 1) < 0)) child_ret = 0;
744 
745  /* For cleanliness... */
746  close(from_child[0]);
747 
748  /* Don't turn children into zombies */
749  if (child_ret == 0) {
750  waitpid(pid, &stat_loc, WNOHANG);
752  }
753 
754 #ifdef HAVE_SYSTEMD
755  /*
756  * Update the systemd MAINPID to be our child,
757  * as the parent is about to exit.
758  */
759  sd_notifyf(0, "MAINPID=%lu", (unsigned long)pid);
760 #endif
761 
762  goto cleanup;
763  /*
764  * The child needs to increment the semaphore as the parent
765  * is going to exit, and it will decrement the semaphore.
766  */
767  } else if (pid == 0) {
769  PWARN("%s - Failed incrementing exclusive proc semaphore in child", program);
770  }
771  }
772 
773  /* so the pipe is correctly widowed if the parent exits?! */
774  close(from_child[0]);
775 #ifdef HAVE_SETSID
776  setsid();
777 #endif
778 
779  DUMP_CAPABILITIES("post-fork");
780  } else {
781  DUMP_CAPABILITIES("pre-suid-down");
782  }
783 
784  /*
785  * Ensure that we're using the CORRECT pid after forking, NOT the one
786  * we started with.
787  */
788  radius_pid = getpid();
789 
790  /*
791  * Initialise the interpreter, registering operations.
792  */
794 
795  if (server_init(config->root_cs) < 0) EXIT_WITH_FAILURE;
796 
797  /*
798  * Everything seems to have loaded OK, exit gracefully.
799  */
800  if (check_config) {
801  DEBUG("Configuration appears to be OK");
802  goto cleanup;
803  }
804 
805  /*
806  * Initialise the SNMP stats structures
807  */
808  if (fr_snmp_init() < 0) {
809  PERROR("Failed initialising SNMP");
811  }
812 
813  /*
814  * Initialize the global event loop which handles things like
815  * systemd.
816  *
817  * This has to be done post-fork in case we're using kqueue, where the
818  * queue isn't inherited by the child process.
819  */
820  if (main_loop_init() < 0) {
821  PERROR("Failed initialising main event loop");
823  }
824 
825  /*
826  * Start the network / worker threads.
827  */
828  {
829  fr_event_list_t *el = NULL;
830  fr_schedule_config_t *schedule;
831 
832  schedule = talloc_zero(global_ctx, fr_schedule_config_t);
833  schedule->max_workers = config->max_workers;
834  schedule->max_networks = config->max_networks;
835  schedule->stats_interval = config->stats_interval;
836 
837  schedule->network.max_outstanding = config->max_requests;
838 
839 #define COPY(_x) schedule->worker._x = config->_x
840  COPY(max_requests);
841  COPY(max_request_time);
842 
843  /*
844  * Single server mode: use the global event list.
845  * Otherwise, each network thread will create
846  * its own event list.
847  */
848  if (!config->spawn_workers) {
850  }
851 
852  /*
853  * Fix spurious messages
854  */
857  thread_instantiate, thread_detach, schedule);
858  if (!sc) {
859  PERROR("Failed starting the scheduler");
861  }
862 
863  /*
864  * Tell the virtual servers to open their sockets.
865  */
867  }
868 
869  /*
870  * At this point, no one has any business *ever* going
871  * back to root uid.
872  */
874 
875  DUMP_CAPABILITIES("post-suid-down");
876 
877  /*
878  * Dropping down may change the RLIMIT_CORE value, so
879  * reset it back to what to should be here.
880  */
882 
883  /*
884  * If we're debugging, then a CTRL-C will cause the server to die
885  * immediately. Use SIGTERM to shut down the server cleanly in
886  * that case.
887  */
888  if (fr_set_signal(SIGINT, sig_fatal) < 0) {
889  set_signal_error:
890  PERROR("Failed installing signal handler");
892  }
893 
894 #ifdef SIGQUIT
895  if (fr_set_signal(SIGQUIT, sig_fatal) < 0) goto set_signal_error;
896 #endif
897 
898  /*
899  * Now that we've set everything up, we can install the signal
900  * handlers. Before this, if we get any signal, we don't know
901  * what to do, so we might as well do the default, and die.
902  */
903 #ifdef SIGPIPE
904  signal(SIGPIPE, SIG_IGN);
905 #endif
906 
907  if (fr_set_signal(SIGHUP, sig_hup) < 0) goto set_signal_error;
908  if (fr_set_signal(SIGTERM, sig_fatal) < 0) goto set_signal_error;
909 
910 #ifdef WITH_STATS
912 #endif
913 
914  /*
915  * Write the PID after we've forked, so that we write the correct one.
916  */
917  if (config->write_pid) {
918  FILE *fp;
919 
920  fp = fopen(config->pid_file, "w");
921  if (fp != NULL) {
922  /*
923  * @fixme What about following symlinks,
924  * and having it over-write a normal file?
925  */
926  fprintf(fp, "%d\n", (int) radius_pid);
927  fclose(fp);
928  } else {
929  ERROR("Failed creating PID file %s: %s", config->pid_file, fr_syserror(errno));
931  }
932  }
933 
934  trigger_exec(NULL, NULL, "server.start", false, NULL);
935 
936  /*
937  * Inform the parent (who should still be waiting) that the rest of
938  * initialisation went OK, and that it should exit with a 0 status.
939  * If we don't get this far, then we just close the pipe on exit, and the
940  * parent gets a read failure.
941  */
942  if (config->daemonize) {
943  if (write(from_child[1], "\001", 1) < 0) {
944  WARN("Failed informing parent of successful start: %s",
945  fr_syserror(errno));
946  }
947  close(from_child[1]);
948  }
949 
950  /*
951  * Clear the libfreeradius error buffer.
952  */
954 
955  /*
956  * Prevent anything from modifying the dictionaries
957  * they're now immutable.
958  */
960 
961  /*
962  * Protect global memory - If something attempts
963  * to write to this memory we get a SIGBUS.
964  */
965  if (do_mprotect) {
966  if (mprotect(pool_page_start, (uintptr_t)pool_page_end - (uintptr_t)pool_page_start, PROT_READ) < 0) {
967  PERROR("Protecting global memory failed: %s", fr_syserror(errno));
969  }
970  DEBUG("Global memory protected");
971  }
972 
974 #ifndef NDEBUG
975  if (fr_time_delta_ispos(exit_after)) fr_exit_after(main_loop_event_list(), fr_time_wrap(0), &exit_after);
976 #endif
977  /*
978  * Process requests until HUP or exit.
979  */
980  INFO("Ready to process requests"); /* we were actually ready a while ago, but oh well */
981  while ((status = main_loop_start()) == 0x80) {
982 #ifdef WITH_STATS
984 #endif
986  }
987 
988  /*
989  * Ignore the TERM signal: we're about to die.
990  */
991  signal(SIGTERM, SIG_IGN);
992 
993  /*
994  * Unprotect global memory
995  */
996  if (do_mprotect) {
997  if (mprotect(pool_page_start, (uintptr_t)pool_page_end - (uintptr_t)pool_page_start,
998  PROT_READ | PROT_WRITE) < 0) {
999  PERROR("Unprotecting global memory failed: %s", fr_syserror(errno));
1001  }
1002  DEBUG("Global memory unprotected");
1003  }
1004 
1005  if (status < 0) {
1006  PERROR("Exiting due to internal error");
1007  ret = EXIT_FAILURE;
1008  } else {
1009  INFO("Exiting normally");
1010  ret = EXIT_SUCCESS;
1011  }
1012 
1013  fr_radmin_stop();
1014 
1015  /*
1016  * Fire signal and stop triggers after ignoring SIGTERM, so handlers are
1017  * not killed with the rest of the process group, below.
1018  */
1019  if (status == 2) trigger_exec(NULL, NULL, "server.signal.term", true, NULL);
1020  trigger_exec(NULL, NULL, "server.stop", false, NULL);
1021 
1022  /*
1023  * Stop the scheduler, this signals the network and worker threads
1024  * to exit gracefully. fr_schedule_destroy only returns once all
1025  * threads have been joined.
1026  */
1027  (void) fr_schedule_destroy(&sc);
1028 
1029  /*
1030  * We're exiting, so we can delete the PID file.
1031  * (If it doesn't exist, we can ignore the error returned by unlink)
1032  */
1033  if (config->daemonize) unlink(config->pid_file);
1034 
1035  /*
1036  * Free memory in an explicit and consistent order
1037  *
1038  * We could let everything be freed by the global_ctx
1039  * context, but in some cases there are odd interactions
1040  * with destructors that may cause double frees and
1041  * SEGVs.
1042  */
1043  if (!config->spawn_workers) {
1045 
1047  fr_event_loop_exit(el, 1);
1048  }
1049 
1050  main_loop_free();
1051 
1052  /*
1053  * Send a TERM signal to all associated processes
1054  * (including us, which gets ignored.)
1055  *
1056  * This _shouldn't_ be needed, but may help with
1057  * processes created by the exec code or triggers.
1058  */
1059  if (config->spawn_workers) {
1060  INFO("All threads have exited, sending SIGTERM to remaining children");
1061  kill(-radius_pid, SIGTERM);
1062  }
1063 
1064  /*
1065  * Remove the semaphore, allowing other processes
1066  * to start. We do this before the cleanup label
1067  * as the parent process MUST NOT call this
1068  * function as it exits, otherwise the semaphore
1069  * is removed and there's no exclusivity.
1070  */
1072 
1073 cleanup:
1074  /*
1075  * This may not have been done earlier if we're
1076  * exiting due to a startup error.
1077  */
1078  (void) fr_schedule_destroy(&sc);
1079 
1080  /*
1081  * Ensure all thread local memory is cleaned up
1082  * before we start cleaning up global resources.
1083  * This is necessary for single threaded mode
1084  * to ensure that thread local resources that
1085  * depend on global resources are freed at the
1086  * appropriate time.
1087  */
1089 
1090  fr_snmp_free();
1091 
1092  server_free();
1093 
1094  /*
1095  * Free any resources used by the unlang interpreter.
1096  */
1098 
1099 #ifdef WITH_TLS
1100  fr_openssl_free(); /* Cleanup any memory alloced by OpenSSL and placed into globals */
1101 #endif
1102 
1103  if (config) talloc_memory_report = config->talloc_memory_report; /* Grab this before we free the config */
1104 
1105  /*
1106  * Virtual servers need to be freed before modules
1107  * as state entries containing data with module-specific
1108  * destructors may exist.
1109  */
1111 
1112  /*
1113  * Free modules, this needs to be done explicitly
1114  * because some libraries used by modules use atexit
1115  * handlers registered after ours, and they may deinit
1116  * themselves before we free the modules and cause
1117  * crashes on exit.
1118  */
1119  modules_rlm_free();
1120 
1121 #ifdef WITH_TLS
1122  fr_tls_dict_free();
1123 #endif
1124 
1125  /*
1126  * And now nothing should be left anywhere except the
1127  * parsed configuration items.
1128  */
1130 
1131  /*
1132  * Cleanup everything else
1133  */
1134  if (talloc_free(global_ctx) < 0) {
1135 #ifndef NDEBUG
1136  fr_perror("radiusd");
1137  ret = EXIT_FAILURE;
1138 #endif
1139  }
1140 
1141  /*
1142  * Anything not cleaned up by the above is allocated in
1143  * the NULL top level context, and is likely leaked memory.
1144  */
1145  if (talloc_memory_report) fr_log_talloc_report(NULL);
1146 
1147  /*
1148  * If we're running under LSAN, try and SUID back up so
1149  * we don't inteferere with the onexit() handler.
1150  */
1152  fr_strerror_clear(); /* clear error buffer */
1153 
1154  /*
1155  * Ensure our atexit handlers run before any other
1156  * atexit handlers registered by third party libraries.
1157  */
1159 
1160  return ret;
1161 }
1162 
1163 /*
1164  * Display the syntax for starting this program.
1165  */
1166 static NEVER_RETURNS void usage(main_config_t const *config, int status)
1167 {
1168  FILE *output = status ? stderr : stdout;
1169 
1170  fprintf(output, "Usage: %s [options]\n", config->name);
1171  fprintf(output, "Options:\n");
1172  fprintf(output, " -C Check configuration and exit.\n");
1173  fprintf(stderr, " -d <raddb> Set configuration directory (defaults to " RADDBDIR ").\n");
1174  fprintf(stderr, " -D <dictdir> Set main dictionary directory (defaults to " DICTDIR ").\n");
1175 #ifndef NDEBUG
1176  fprintf(output, " -e <seconds> Exit after the specified number of seconds. Useful for diagnosing \"crash-on-exit\" issues.\n");
1177 #endif
1178  fprintf(output, " -f Run as a foreground process, not a daemon.\n");
1179  fprintf(output, " -h Print this help message.\n");
1180  fprintf(output, " -l <log_file> Logging output will be written to this file.\n");
1181 #ifndef NDEBUG
1182  fprintf(output, " -L <size> When running in memory debug mode, set a hard limit on talloced memory\n");
1183 #endif
1184  fprintf(output, " -n <name> Read raddb/name.conf instead of raddb/radiusd.conf.\n");
1185  fprintf(output, " -m Allow multiple processes reading the same radiusd.conf to exist simultaneously.\n");
1186 #ifndef NDEBUG
1187  fprintf(output, " -M Enable talloc memory debugging, and issue a memory report when the server terminates\n");
1188 #endif
1189  fprintf(output, " -P Always write out PID, even with -f.\n");
1190  fprintf(output, " -s Do not spawn child processes to handle requests (same as -ft).\n");
1191  fprintf(output, " -t Disable threads.\n");
1192  fprintf(output, " -T Prepend timestamps to log messages.\n");
1193  fprintf(output, " -v Print server version information.\n");
1194  fprintf(output, " -X Turn on full debugging (similar to -tfxxl stdout).\n");
1195  fprintf(output, " -x Turn on additional debugging (-xx gives more debugging).\n");
1196  fr_exit(status);
1197 }
1198 
1199 
1200 /*
1201  * We got a fatal signal.
1202  */
1203 static void sig_fatal(int sig)
1204 {
1205  if (getpid() != radius_pid) _exit(sig);
1206 
1207  switch (sig) {
1208  case SIGTERM:
1210  break;
1211 
1212  case SIGINT:
1213 #ifdef SIGQUIT
1214  case SIGQUIT:
1215 #endif
1217  break;
1218 
1219  default:
1220  fr_exit(sig);
1221  }
1222 }
1223 
1224 #ifdef SIGHUP
1225 /*
1226  * We got the hangup signal.
1227  * Re-read the configuration files.
1228  */
1229 static void sig_hup(UNUSED int sig)
1230 {
1231  reset_signal(SIGHUP, sig_hup);
1232 
1234 }
1235 #endif
int fr_atexit_global_setup(void)
Setup the atexit handler, should be called at the start of a program's execution.
Definition: atexit.c:160
int fr_atexit_global_trigger_all(void)
Cause all global free triggers to fire.
Definition: atexit.c:286
#define fr_atexit_thread_trigger_all(...)
Definition: atexit.h:233
void fr_radmin_stop(void)
Definition: radmin.c:1101
int fr_radmin_start(main_config_t *config, bool cli)
Definition: radmin.c:1064
#define RCSID(id)
Definition: build.h:444
#define NEVER_RETURNS
Should be placed before the function return type.
Definition: build.h:311
#define UNUSED
Definition: build.h:313
bool check_config
Definition: cf_file.c:66
char const * fr_debug_state_to_msg(fr_debug_state_t state)
Return current value of debug_state.
Definition: debug.c:524
int fr_log_talloc_report(TALLOC_CTX const *ctx)
Generate a talloc memory report for a context and print to stderr/stdout.
Definition: debug.c:1120
int fr_reset_dumpable(void)
Reset dumpable state to previously configured value.
Definition: debug.c:873
int fr_fault_setup(TALLOC_CTX *ctx, char const *cmd, char const *program)
Registers signal handlers to execute panic_action on fatal signal.
Definition: debug.c:1215
int fr_get_lsan_state(void)
Definition: debug.c:261
void fr_debug_state_store(void)
Should be run before using setuid or setgid to get useful results.
Definition: debug.c:504
void fr_talloc_fault_setup(void)
Register talloc fault handlers.
Definition: debug.c:1196
fr_debug_state_t fr_debug_state
Whether we're attached to by a debugger.
Definition: debug.c:104
#define fr_exit(_x)
Exit, producing a log message in debug builds.
Definition: debug.h:226
void dependency_version_print(void)
Definition: dependency.c:369
int rad_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
Definition: dependency.c:64
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
#define DEBUG(fmt,...)
Definition: dhcpclient.c:39
void fr_dict_global_ctx_read_only(void)
Mark all dictionaries and the global dictionary ctx as read only.
Definition: dict_util.c:4097
fr_dict_gctx_t * fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir)
Initialise the global protocol hashes.
Definition: dict_util.c:3984
#define fr_event_timer_in(...)
Definition: event.h:255
uint32_t max_outstanding
Definition: network.h:46
void server_free(void)
Free src/lib/server/.
Definition: base.c:111
int server_init(CONF_SECTION *cs)
Initialize src/lib/server/.
Definition: base.c:41
#define PERROR(_fmt,...)
Definition: log.h:228
#define PWARN(_fmt,...)
Definition: log.h:227
void rad_suid_up(void)
Definition: util.c:894
bool rad_suid_is_down_permanent(void)
Return whether we've permanently dropped root privileges.
Definition: util.c:915
void(*)(int) reset_signal(int signo, void(*func)(int))
Definition: util.c:53
void rad_suid_down_permanent(void)
Definition: util.c:903
void unlang_global_free(void)
Definition: base.c:134
int unlang_global_init(void)
Definition: base.c:74
waitpid(reap->pid_ev->pid, &status, 0)
talloc_free(reap)
void fr_event_loop_exit(fr_event_list_t *el, int code)
Signal an event loop exit with the specified code.
Definition: event.c:2737
Stores all information relating to an event list.
Definition: event.c:411
A timer event.
Definition: event.c:102
int fr_debug_lvl
Definition: log.c:42
static FILE * devnull
File handle for /dev/null.
Definition: log.c:58
fr_log_t default_log
Definition: log.c:290
@ L_DST_NULL
Discard log messages.
Definition: log.h:83
@ L_DST_FILES
Log to a file on disk.
Definition: log.h:79
@ L_DST_STDOUT
Log to stdout.
Definition: log.h:78
@ L_TIMESTAMP_ON
Always log timestamps.
Definition: log.h:90
int main_config_parse_option(char const *value)
Definition: main_config.c:1516
int main_config_free(main_config_t **config)
Definition: main_config.c:1429
void main_config_raddb_dir_set(main_config_t *config, char const *name)
Set the global radius config directory.
Definition: main_config.c:859
void main_config_exclusive_proc_done(UNUSED main_config_t const *config)
Clean up the semaphore when the main config is freed.
Definition: main_config.c:874
void main_config_hup(main_config_t *config)
Definition: main_config.c:1475
int main_config_exclusive_proc(main_config_t *config)
Check to see if we're the only process using this configuration file (or PID file if specified)
Definition: main_config.c:913
void main_config_name_set_default(main_config_t *config, char const *name, bool overwrite_config)
Set the server name.
Definition: main_config.c:840
int main_config_init(main_config_t *config)
Definition: main_config.c:1033
main_config_t const * main_config
Main server configuration.
Definition: main_config.c:69
int main_config_exclusive_proc_child(UNUSED main_config_t const *config)
Increment the semaphore in the child process so that it's not released when the parent exits.
Definition: main_config.c:892
main_config_t * main_config_alloc(TALLOC_CTX *ctx)
Allocate a main_config_t struct, setting defaults.
Definition: main_config.c:1000
void main_config_dict_dir_set(main_config_t *config, char const *name)
Set the global dictionary directory.
Definition: main_config.c:988
Main server configuration.
Definition: main_config.h:51
int main_loop_start(void)
Definition: main_loop.c:192
fr_event_list_t * main_loop_event_list(void)
Return the main loop event list.
Definition: main_loop.c:162
void main_loop_signal_raise(int flag)
Definition: main_loop.c:79
int main_loop_init(void)
Initialise the main event loop, setting up signal handlers.
Definition: main_loop.c:251
void main_loop_free(void)
Definition: main_loop.c:187
@ RADIUS_SIGNAL_SELF_HUP
Definition: main_loop.h:36
@ RADIUS_SIGNAL_SELF_TERM
Definition: main_loop.h:37
unsigned char uint8_t
Definition: merged_model.c:30
int fr_set_signal(int sig, sig_t func)
Sets a signal handler using sigaction if available, else signal.
Definition: misc.c:47
void modules_rlm_thread_detach(void)
Frees thread-specific data for all registered backend modules.
Definition: module_rlm.c:926
int modules_rlm_free(void)
Cleanup all global structures.
Definition: module_rlm.c:1138
int modules_rlm_thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el)
Allocates thread-specific data for all registered backend modules.
Definition: module_rlm.c:939
int modules_rlm_init(void)
Initialise the module list structure.
Definition: module_rlm.c:1156
static const conf_parser_t config[]
Definition: base.c:188
#define WARN(fmt,...)
Definition: radclient.h:47
#define INFO(fmt,...)
Definition: radict.c:54
int main(int argc, char *argv[])
Entry point for the daemon.
Definition: radiusd.c:224
static void thread_detach(UNUSED void *uctx)
Explicitly cleanup module/xlat resources.
Definition: radiusd.c:149
static fr_event_timer_t const * fr_time_sync_ev
Definition: radiusd.c:170
static void fr_exit_after(fr_event_list_t *el, fr_time_t now, void *uctx)
Encourage the server to exit after a period of time.
Definition: radiusd.c:188
#define COPY(_x)
#define DUMP_CAPABILITIES(_phase)
Definition: radiusd.c:217
static void usage(main_config_t const *config, int status)
Definition: radiusd.c:1166
#define EXIT_WITH_SUCCESS
Definition: radiusd.c:164
char const * radiusd_version
Definition: radiusd.c:83
static void fr_time_sync_event(fr_event_list_t *el, UNUSED fr_time_t now, UNUSED void *uctx)
Definition: radiusd.c:172
static int thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el, UNUSED void *uctx)
Create module and xlat per-thread instances.
Definition: radiusd.c:132
static int talloc_config_set(main_config_t *config)
Configure talloc debugging features.
Definition: radiusd.c:108
static void sig_fatal(int)
Definition: radiusd.c:1203
static pid_t radius_pid
Definition: radiusd.c:84
#define EXIT_WITH_FAILURE
Definition: radiusd.c:158
static bool cleanup
Definition: radsniff.c:60
int request_global_init(void)
Definition: request.c:698
#define FR_SBUFF_IN(_start, _len_or_end)
fr_schedule_t * fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el, fr_log_t *logger, fr_log_lvl_t lvl, fr_schedule_thread_instantiate_t worker_thread_instantiate, fr_schedule_thread_detach_t worker_thread_detach, fr_schedule_config_t *config)
Create a scheduler and spawn the child threads.
Definition: schedule.c:409
int fr_schedule_destroy(fr_schedule_t **sc_to_free)
Destroy a scheduler, and tell its child threads to exit.
Definition: schedule.c:703
The scheduler.
Definition: schedule.c:125
fr_network_config_t network
configuration for each network;
Definition: schedule.h:68
uint32_t max_workers
number of network threads
Definition: schedule.h:65
fr_time_delta_t stats_interval
print channel statistics
Definition: schedule.h:70
uint32_t max_networks
number of network threads
Definition: schedule.h:64
void radius_stats_init(int flag)
Definition: stats.c:149
Signals that can be sent to a request.
fr_slen_t fr_size_from_str(size_t *out, fr_sbuff_t *in)
Parse a size string with optional unit.
Definition: size.c:40
static const uchar sc[16]
Definition: smbdes.c:115
void fr_snmp_free(void)
Definition: snmp.c:1119
int fr_snmp_init(void)
Initialise the tree of SNMP map structures used to attach callbacks to OIDs.
Definition: snmp.c:1101
void modules_init(char const *lib_dir)
Perform global initialisation for modules.
Definition: module.c:1163
#define fr_time()
Allow us to arbitrarily manipulate time.
Definition: state_test.c:8
fr_log_dst_t dst
Log destination.
Definition: log.h:97
int fd
File descriptor to write messages to.
Definition: log.h:112
fr_log_timestamp_t timestamp
Prefix log messages with timestamps.
Definition: log.h:110
bool suppress_secrets
suppress secrets when printing to this destination
Definition: log.h:108
char const * file
Path to log file.
Definition: log.h:113
bool print_level
sometimes we don't want log levels printed
Definition: log.h:106
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: syserror.c:243
TALLOC_CTX * talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, void **end, size_t size)
Return a page aligned talloc memory pool.
Definition: talloc.c:239
static TALLOC_CTX * global_ctx
Definition: talloc.c:32
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition: talloc.c:333
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition: talloc.h:51
int fr_time_sync(void)
Get a new fr_time_monotonic_to_realtime value.
Definition: time.c:102
int fr_time_start(void)
Initialize the local time.
Definition: time.c:150
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
Definition: time.h:588
#define fr_time_delta_wrap(_time)
Definition: time.h:152
#define fr_time_wrap(_time)
Definition: time.h:145
#define fr_time_delta_ispos(_a)
Definition: time.h:288
#define fr_time_eq(_a, _b)
Definition: time.h:241
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
"server local" time.
Definition: time.h:69
int fr_openssl_version_consistent(void)
Definition: version.c:325
int trigger_exec(unlang_interpret_t *intp, CONF_SECTION const *cs, char const *name, bool rate_limit, fr_pair_list_t *args)
Execute a trigger - call an executable to process an event.
Definition: trigger.c:280
close(uq->fd)
static fr_event_list_t * el
void xlat_thread_detach(void)
Destroy any thread specific xlat instances.
Definition: xlat_inst.c:484
int xlat_thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el)
Create thread specific instance tree and create thread instances.
Definition: xlat_inst.c:439
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition: strerror.c:733
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition: strerror.c:577
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
Definition: version.c:40
#define RADIUSD_VERSION_BUILD(_x)
Create a version string for a utility in the suite of FreeRADIUS utilities.
Definition: version.h:58
#define RADIUSD_MAGIC_NUMBER
Definition: version.h:81
int virtual_servers_open(fr_schedule_t *sc)
Open all the listen sockets.
void virtual_servers_thread_detach(void)
Free thread-specific data for all process modules and listeners.
int virtual_servers_init(void)
Performs global initialisation for the virtual server code.
int virtual_servers_free(void)
int virtual_servers_thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el)
Perform thread instantiation for all process modules and listeners.