All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mainconfig.c
Go to the documentation of this file.
1 /*
2  * mainconf.c Handle the server's configuration.
3  *
4  * Version: $Id: 45225e865dd5fdc599902bea379c2a693909f083 $
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 2002,2006-2007 The FreeRADIUS server project
21  * Copyright 2002 Alan DeKok <aland@ox.org>
22  */
23 
24 RCSID("$Id: 45225e865dd5fdc599902bea379c2a693909f083 $")
25 
26 #include <freeradius-devel/radiusd.h>
27 #include <freeradius-devel/modules.h>
28 #include <freeradius-devel/modpriv.h>
29 #include <freeradius-devel/rad_assert.h>
30 
31 #include <sys/stat.h>
32 #include <pwd.h>
33 #include <grp.h>
34 
35 #ifdef HAVE_SYSLOG_H
36 # include <syslog.h>
37 #endif
38 
39 #ifdef HAVE_FCNTL_H
40 # include <fcntl.h>
41 #endif
42 
43 main_config_t main_config; //!< Main server configuration.
44 
46 extern fr_log_t debug_log;
47 
48 fr_cond_t *debug_condition = NULL; //!< Condition used to mark packets up for checking.
49 fr_log_t debug_log = { .fd = -1, .dst = L_DST_NULL };
50 bool event_loop_started = false; //!< Whether the main event loop has been started yet.
51 
52 typedef struct cached_config_t {
54  time_t created;
57 
58 static cached_config_t *cs_cache = NULL;
59 
60 /*
61  * Temporary local variables for parsing the configuration
62  * file.
63  */
64 #ifdef HAVE_SETUID
65 /*
66  * Systems that have set/getresuid also have setuid.
67  */
68 static uid_t server_uid = 0;
69 static gid_t server_gid = 0;
70 static char const *uid_name = NULL;
71 static char const *gid_name = NULL;
72 #endif
73 static char const *chroot_dir = NULL;
74 static bool allow_core_dumps = false;
75 static char const *radlog_dest = NULL;
76 
77 /*
78  * These are not used anywhere else..
79  */
80 static char const *localstatedir = NULL;
81 static char const *prefix = NULL;
82 static char const *my_name = NULL;
83 static char const *sbindir = NULL;
84 static char const *run_dir = NULL;
85 static char const *syslog_facility = NULL;
86 static bool do_colourise = false;
87 
88 static char const *radius_dir = NULL; //!< Path to raddb directory
89 
90 /**********************************************************************
91  *
92  * We need to figure out where the logs go, before doing anything
93  * else. This is so that the log messages go to the correct
94  * place.
95  *
96  * BUT, we want the settings from the command line to over-ride
97  * the ones in the configuration file. So, these items are
98  * parsed ONLY if there is no "-l foo" on the command line.
99  *
100  **********************************************************************/
101 
102 /*
103  * Log destinations
104  */
105 static const CONF_PARSER startup_log_config[] = {
106  { FR_CONF_POINTER("destination", PW_TYPE_STRING, &radlog_dest), .dflt = "files" },
107  { FR_CONF_POINTER("syslog_facility", PW_TYPE_STRING, &syslog_facility), .dflt = STRINGIFY(0) },
108 
109  { FR_CONF_POINTER("localstatedir", PW_TYPE_STRING, &localstatedir), .dflt = "${prefix}/var"},
110  { FR_CONF_POINTER("logdir", PW_TYPE_STRING, &radlog_dir), .dflt = "${localstatedir}/log"},
111  { FR_CONF_POINTER("file", PW_TYPE_STRING, &main_config.log_file), .dflt = "${logdir}/radius.log" },
114 };
115 
116 
117 /*
118  * Basic configuration for the server.
119  */
121  { FR_CONF_POINTER("log", PW_TYPE_SUBSECTION, NULL), .dflt = (void const *) startup_log_config },
122 
123  { FR_CONF_POINTER("name", PW_TYPE_STRING, &my_name), .dflt = "radiusd" },
124  { FR_CONF_POINTER("prefix", PW_TYPE_STRING, &prefix), .dflt = "/usr/local" },
125 
126  { FR_CONF_POINTER("log_file", PW_TYPE_STRING, &main_config.log_file) },
127  { FR_CONF_POINTER("log_destination", PW_TYPE_STRING, &radlog_dest) },
130 };
131 
132 
133 /**********************************************************************
134  *
135  * Now that we've parsed the log destination, AND the security
136  * items, we can parse the rest of the configuration items.
137  *
138  **********************************************************************/
139 static const CONF_PARSER log_config[] = {
140  { FR_CONF_POINTER("stripped_names", PW_TYPE_BOOLEAN, &log_stripped_names), .dflt = "no" },
141  { FR_CONF_POINTER("auth", PW_TYPE_BOOLEAN, &main_config.log_auth), .dflt = "no" },
142  { FR_CONF_POINTER("auth_badpass", PW_TYPE_BOOLEAN, &main_config.log_auth_badpass), .dflt = "no" },
143  { FR_CONF_POINTER("auth_goodpass", PW_TYPE_BOOLEAN, &main_config.log_auth_goodpass), .dflt = "no" },
144  { FR_CONF_POINTER("msg_badpass", PW_TYPE_STRING, &main_config.auth_badpass_msg) },
145  { FR_CONF_POINTER("msg_goodpass", PW_TYPE_STRING, &main_config.auth_goodpass_msg) },
146  { FR_CONF_POINTER("colourise", PW_TYPE_BOOLEAN, &do_colourise) },
148  { FR_CONF_POINTER("msg_denied", PW_TYPE_STRING, &main_config.denied_msg), .dflt = "You are already logged in - access denied" },
149 #ifdef WITH_CONF_WRITE
150  { FR_CONF_POINTER("write_dir", PW_TYPE_STRING, &main_config.write_dir), .dflt = NULL },
151 #endif
153 };
154 
155 
156 /*
157  * Security configuration for the server.
158  */
159 static const CONF_PARSER security_config[] = {
160  { FR_CONF_POINTER("max_attributes", PW_TYPE_INTEGER, &fr_max_attributes), .dflt = STRINGIFY(0) },
161  { FR_CONF_POINTER("reject_delay", PW_TYPE_TIMEVAL, &main_config.reject_delay), .dflt = STRINGIFY(0) },
162  { FR_CONF_POINTER("status_server", PW_TYPE_BOOLEAN, &main_config.status_server), .dflt = "no" },
163 #ifdef ENABLE_OPENSSL_VERSION_CHECK
164  { FR_CONF_POINTER("allow_vulnerable_openssl", PW_TYPE_STRING, &main_config.allow_vulnerable_openssl), .dflt = "no" },
165 #endif
166  { FR_CONF_POINTER("state_seed", PW_TYPE_INTEGER, &main_config.state_seed) },
168 };
169 
170 static const CONF_PARSER resources[] = {
171  /*
172  * Don't set a default here. It's set in the code, below. This means that
173  * the config item will *not* get printed out in debug mode, so that no one knows
174  * it exists.
175  */
176  { FR_CONF_POINTER("talloc_pool_size", PW_TYPE_INTEGER, &main_config.talloc_pool_size) },
178 };
179 
180 static const CONF_PARSER server_config[] = {
181  /*
182  * FIXME: 'prefix' is the ONLY one which should be
183  * configured at compile time. Hard-coding it here is
184  * bad. It will be cleaned up once we clean up the
185  * hard-coded defines for the locations of the various
186  * files.
187  */
188  { FR_CONF_POINTER("name", PW_TYPE_STRING, &my_name), .dflt = "radiusd" },
189  { FR_CONF_POINTER("prefix", PW_TYPE_STRING, &prefix), .dflt = "/usr/local" },
190  { FR_CONF_POINTER("localstatedir", PW_TYPE_STRING, &localstatedir), .dflt = "${prefix}/var"},
191  { FR_CONF_POINTER("sbindir", PW_TYPE_STRING, &sbindir), .dflt = "${prefix}/sbin"},
192  { FR_CONF_POINTER("logdir", PW_TYPE_STRING, &radlog_dir), .dflt = "${localstatedir}/log"},
193  { FR_CONF_POINTER("run_dir", PW_TYPE_STRING, &run_dir), .dflt = "${localstatedir}/run/${name}"},
194  { FR_CONF_POINTER("libdir", PW_TYPE_STRING, &radlib_dir), .dflt = "${prefix}/lib"},
195  { FR_CONF_POINTER("radacctdir", PW_TYPE_STRING, &radacct_dir), .dflt = "${logdir}/radacct" },
196  { FR_CONF_POINTER("panic_action", PW_TYPE_STRING, &main_config.panic_action) },
197  { FR_CONF_POINTER("hostname_lookups", PW_TYPE_BOOLEAN, &fr_dns_lookups), .dflt = "no" },
198  { FR_CONF_POINTER("max_request_time", PW_TYPE_INTEGER, &main_config.max_request_time), .dflt = STRINGIFY(MAX_REQUEST_TIME) },
199  { FR_CONF_POINTER("cleanup_delay", PW_TYPE_INTEGER, &main_config.cleanup_delay), .dflt = STRINGIFY(CLEANUP_DELAY) },
200  { FR_CONF_POINTER("continuation_timeout", PW_TYPE_INTEGER, &main_config.continuation_timeout), .dflt = "15" },
201  { FR_CONF_POINTER("max_requests", PW_TYPE_INTEGER, &main_config.max_requests), .dflt = STRINGIFY(MAX_REQUESTS) },
202  { FR_CONF_POINTER("pidfile", PW_TYPE_STRING, &main_config.pid_file), .dflt = "${run_dir}/radiusd.pid"},
203  { FR_CONF_POINTER("checkrad", PW_TYPE_STRING, &main_config.checkrad), .dflt = "${sbindir}/checkrad" },
204 
205  { FR_CONF_POINTER("debug_level", PW_TYPE_INTEGER, &main_config.debug_level), .dflt = "0" },
206 
207 #ifdef WITH_PROXY
208  { FR_CONF_POINTER("proxy_requests", PW_TYPE_BOOLEAN, &main_config.proxy_requests), .dflt = "yes" },
209 #endif
210  { FR_CONF_POINTER("log", PW_TYPE_SUBSECTION, NULL), .dflt = (void const *) log_config },
211 
212  { FR_CONF_POINTER("resources", PW_TYPE_SUBSECTION, NULL), .dflt = (void const *) resources },
213 
214  /*
215  * People with old configs will have these. They are listed
216  * AFTER the "log" section, so if they exist in radiusd.conf,
217  * it will prefer "log_foo = bar" to "log { foo = bar }".
218  * They're listed with default values of NULL, so that if they
219  * DON'T exist in radiusd.conf, then the previously parsed
220  * values for "log { foo = bar}" will be used.
221  */
222  { FR_CONF_POINTER("log_auth", PW_TYPE_BOOLEAN | PW_TYPE_DEPRECATED, &main_config.log_auth) },
223  { FR_CONF_POINTER("log_auth_badpass", PW_TYPE_BOOLEAN | PW_TYPE_DEPRECATED, &main_config.log_auth_badpass) },
224  { FR_CONF_POINTER("log_auth_goodpass", PW_TYPE_BOOLEAN | PW_TYPE_DEPRECATED, &main_config.log_auth_goodpass) },
226 
227  { FR_CONF_POINTER("security", PW_TYPE_SUBSECTION, NULL), .dflt = (void const *) security_config },
229 };
230 
231 
232 /**********************************************************************
233  *
234  * The next few items are here as a "bootstrap" for security.
235  * They allow the server to switch users, chroot, while still
236  * opening the various output files with the correct permission.
237  *
238  * It's rare (or impossible) to have parse errors here, so we
239  * don't worry too much about that. In contrast, when we parse
240  * the rest of the configuration, we CAN get parse errors. We
241  * want THOSE parse errors to go to the log file, and we want the
242  * log file to have the correct permissions.
243  *
244  **********************************************************************/
246 #ifdef HAVE_SETUID
247  { FR_CONF_POINTER("user", PW_TYPE_STRING, &uid_name) },
248  { FR_CONF_POINTER("group", PW_TYPE_STRING, &gid_name) },
249 #endif
250  { FR_CONF_POINTER("chroot", PW_TYPE_STRING, &chroot_dir) },
251  { FR_CONF_POINTER("allow_core_dumps", PW_TYPE_BOOLEAN, &allow_core_dumps), .dflt = "no" },
253 };
254 
255 static const CONF_PARSER bootstrap_config[] = {
256  { FR_CONF_POINTER("security", PW_TYPE_SUBSECTION, NULL), .dflt = (void const *) bootstrap_security_config },
257 
258  { FR_CONF_POINTER("name", PW_TYPE_STRING, &my_name), .dflt = "radiusd" },
259  { FR_CONF_POINTER("prefix", PW_TYPE_STRING, &prefix), .dflt = "/usr/local" },
260  { FR_CONF_POINTER("localstatedir", PW_TYPE_STRING, &localstatedir), .dflt = "${prefix}/var"},
261 
262  { FR_CONF_POINTER("logdir", PW_TYPE_STRING, &radlog_dir), .dflt = "${localstatedir}/log"},
263  { FR_CONF_POINTER("run_dir", PW_TYPE_STRING, &run_dir), .dflt = "${localstatedir}/run/${name}"},
264 
265  /*
266  * For backwards compatibility.
267  */
268 #ifdef HAVE_SETUID
269  { FR_CONF_POINTER("user", PW_TYPE_STRING | PW_TYPE_DEPRECATED, &uid_name) },
270  { FR_CONF_POINTER("group", PW_TYPE_STRING | PW_TYPE_DEPRECATED, &gid_name) },
271 #endif
272  { FR_CONF_POINTER("chroot", PW_TYPE_STRING | PW_TYPE_DEPRECATED, &chroot_dir) },
273  { FR_CONF_POINTER("allow_core_dumps", PW_TYPE_BOOLEAN | PW_TYPE_DEPRECATED, &allow_core_dumps) },
275 };
276 
277 
278 static size_t config_escape_func(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
279 {
280  size_t len = 0;
281  static char const disallowed[] = "%{}\\'\"`";
282 
283  while (in[0]) {
284  /*
285  * Non-printable characters get replaced with their
286  * mime-encoded equivalents.
287  */
288  if ((in[0] < 32)) {
289  if (outlen <= 3) break;
290 
291  snprintf(out, outlen, "=%02X", (unsigned char) in[0]);
292  in++;
293  out += 3;
294  outlen -= 3;
295  len += 3;
296  continue;
297 
298  } else if (strchr(disallowed, *in) != NULL) {
299  if (outlen <= 2) break;
300 
301  out[0] = '\\';
302  out[1] = *in;
303  in++;
304  out += 2;
305  outlen -= 2;
306  len += 2;
307  continue;
308  }
309 
310  /*
311  * Only one byte left.
312  */
313  if (outlen <= 1) {
314  break;
315  }
316 
317  /*
318  * Allowed character.
319  */
320  *out = *in;
321  out++;
322  in++;
323  outlen--;
324  len++;
325  }
326  *out = '\0';
327  return len;
328 }
329 
330 /*
331  * Xlat for %{config:section.subsection.attribute}
332  */
333 static ssize_t xlat_config(char **out, size_t outlen,
334  UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
335  REQUEST *request, char const *fmt)
336 {
337  char const *value;
338  CONF_PAIR *cp;
339  CONF_ITEM *ci;
340  char buffer[1024];
341 
342  /*
343  * Expand it safely.
344  */
345  if (radius_xlat(buffer, sizeof(buffer), request, fmt, config_escape_func, NULL) < 0) return 0;
346 
347  ci = cf_reference_item(request->root->config,
348  request->root->config, buffer);
349  if (!ci || !cf_item_is_pair(ci)) {
350  REDEBUG("Config item \"%s\" does not exist", fmt);
351  return -1;
352  }
353 
354  cp = cf_item_to_pair(ci);
355 
356  /*
357  * Ensure that we only copy what's necessary.
358  *
359  * If 'outlen' is too small, then the output is chopped to fit.
360  */
361  value = cf_pair_value(cp);
362  if (!value) return 0;
363 
364  if (outlen > strlen(value)) outlen = strlen(value) + 1;
365 
366  strlcpy(*out, value, outlen);
367 
368  return strlen(*out);
369 }
370 
371 
372 /*
373  * Xlat for %{client:foo}
374  */
375 static ssize_t xlat_client(char **out, size_t outlen,
376  UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
377  REQUEST *request, char const *fmt)
378 {
379  char const *value = NULL;
380  CONF_PAIR *cp;
381 
382  if (!request->client) {
383  RWDEBUG("No client associated with this request");
384  return 0;
385  }
386 
387  cp = cf_pair_find(request->client->cs, fmt);
388  if (!cp || !(value = cf_pair_value(cp))) {
389  if (strcmp(fmt, "shortname") == 0 && request->client->shortname) {
390  value = request->client->shortname;
391  }
392  else if (strcmp(fmt, "nas_type") == 0 && request->client->nas_type) {
393  value = request->client->nas_type;
394  } else {
395  **out = '\0';
396  return 0;
397  }
398  }
399 
400  strlcpy(*out, value, outlen);
401 
402  return strlen(*out);
403 }
404 
405 /*
406  * Xlat for %{getclient:<ipaddr>.foo}
407  */
408 static ssize_t xlat_getclient(char **out, size_t outlen,
409  UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
410  REQUEST *request, char const *fmt)
411 {
412  char const *value = NULL;
413  char buffer[INET6_ADDRSTRLEN], *q;
414  char const *p = fmt;
415  fr_ipaddr_t ip;
416  CONF_PAIR *cp;
417  RADCLIENT *client = NULL;
418 
419  q = strrchr(p, '.');
420  if (!q || (q == p) || (((size_t)(q - p)) > sizeof(buffer))) {
421  REDEBUG("Invalid client string");
422  goto error;
423  }
424 
425  strlcpy(buffer, p, (q + 1) - p);
426  if (fr_inet_pton(&ip, buffer, -1, AF_UNSPEC, false, true) < 0) {
427  REDEBUG("\"%s\" is not a valid IPv4 or IPv6 address", buffer);
428  goto error;
429  }
430 
431  fmt = q + 1;
432 
433  client = client_find(NULL, &ip, IPPROTO_IP);
434  if (!client) {
435  RDEBUG("No client found with IP \"%s\"", buffer);
436  return 0;
437  }
438 
439  cp = cf_pair_find(client->cs, fmt);
440  if (!cp || !(value = cf_pair_value(cp))) {
441  if (strcmp(fmt, "shortname") == 0) {
442  strlcpy(*out, request->client->shortname, outlen);
443  return strlen(*out);
444  }
445  return 0;
446  }
447 
448  strlcpy(*out, value, outlen);
449  return strlen(*out);
450 
451 error:
452  return -1;
453 }
454 
455 /*
456  * Xlat for %{listen:foo}
457  */
458 static ssize_t xlat_listen(char **out, size_t outlen,
459  UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
460  REQUEST *request, char const *fmt)
461 {
462  char const *value = NULL;
463  CONF_PAIR *cp;
464 
465  if (!request->listener) {
466  RWDEBUG("No listener associated with this request");
467  return 0;
468  }
469 
470  cp = cf_pair_find(request->listener->cs, fmt);
471  if (!cp || !(value = cf_pair_value(cp))) {
472  RDEBUG("Listener does not contain config item \"%s\"", fmt);
473  return 0;
474  }
475 
476  strlcpy(*out, value, outlen);
477 
478  return strlen(*out);
479 }
480 
481 
482 #ifdef HAVE_SETUID
483 /*
484  * Do chroot, if requested.
485  *
486  * Switch UID and GID to what is specified in the config file
487  */
488 static int switch_users(CONF_SECTION *cs)
489 {
490  bool do_suid = false;
491  bool do_sgid = false;
492 
493  /*
494  * Get the current maximum for core files. Do this
495  * before anything else so as to ensure it's properly
496  * initialized.
497  */
498  if (fr_set_dumpable_init() < 0) {
499  fr_perror("%s", main_config.name);
500  return 0;
501  }
502 
503  /*
504  * Don't do chroot/setuid/setgid if we're in debugging
505  * as non-root.
506  */
507  if (rad_debug_lvl && (getuid() != 0)) return 1;
508 
509  if (cf_section_parse(cs, NULL, bootstrap_config) < 0) {
510  fprintf(stderr, "%s: Error: Failed to parse user/group information.\n",
511  main_config.name);
512  return 0;
513  }
514 
515 #ifdef HAVE_GRP_H
516  /*
517  * Get the correct GID for the server.
518  */
519  server_gid = getgid();
520 
521  if (gid_name) {
522  struct group *gr;
523 
524  gr = getgrnam(gid_name);
525  if (!gr) {
526  fprintf(stderr, "%s: Cannot get ID for group %s: %s\n",
527  main_config.name, gid_name, fr_syserror(errno));
528  return 0;
529  }
530 
531  if (server_gid != gr->gr_gid) {
532  server_gid = gr->gr_gid;
533  do_sgid = true;
534  }
535  }
536 #endif
537 
538  /*
539  * Get the correct UID for the server.
540  */
541  server_uid = getuid();
542 
543  if (uid_name) {
544  struct passwd *user;
545 
546  if (rad_getpwnam(cs, &user, uid_name) < 0) {
547  fprintf(stderr, "%s: Cannot get passwd entry for user %s: %s\n",
548  main_config.name, uid_name, fr_strerror());
549  return 0;
550  }
551 
552  /*
553  * We're not the correct user. Go set that.
554  */
555  if (server_uid != user->pw_uid) {
556  server_uid = user->pw_uid;
557  do_suid = true;
558 #ifdef HAVE_INITGROUPS
559  if (initgroups(uid_name, server_gid) < 0) {
560  fprintf(stderr, "%s: Cannot initialize supplementary group list for user %s: %s\n",
561  main_config.name, uid_name, fr_syserror(errno));
562  talloc_free(user);
563  return 0;
564  }
565 #endif
566  }
567 
568  talloc_free(user);
569  }
570 
571  /*
572  * Do chroot BEFORE changing UIDs.
573  */
574  if (chroot_dir) {
575  if (chroot(chroot_dir) < 0) {
576  fprintf(stderr, "%s: Failed to perform chroot %s: %s",
577  main_config.name, chroot_dir, fr_syserror(errno));
578  return 0;
579  }
580 
581  /*
582  * Note that we leave chdir alone. It may be
583  * OUTSIDE of the root. This allows us to read
584  * the configuration from "-d ./etc/raddb", with
585  * the chroot as "./chroot/" for example. After
586  * the server has been loaded, it does a "cd
587  * ${logdir}" below, so that core files (if any)
588  * go to a logging directory.
589  *
590  * This also allows the configuration of the
591  * server to be outside of the chroot. If the
592  * server is statically linked, then the only
593  * things needed inside of the chroot are the
594  * logging directories.
595  */
596  }
597 
598 #ifdef HAVE_GRP_H
599  /*
600  * Set the GID. Don't bother checking it.
601  */
602  if (do_sgid) {
603  if (setgid(server_gid) < 0){
604  fprintf(stderr, "%s: Failed setting group to %s: %s",
605  main_config.name, gid_name, fr_syserror(errno));
606  return 0;
607  }
608  }
609 #endif
610 
611  /*
612  * The directories for PID files and logs must exist. We
613  * need to create them if we're told to write files to
614  * those directories.
615  *
616  * Because this creation is new in 3.0.9, it's a soft
617  * fail.
618  *
619  */
620  if (main_config.write_pid) {
621  char *my_dir;
622 
623  my_dir = talloc_strdup(NULL, run_dir);
624  if (rad_mkdir(my_dir, 0750, server_uid, server_gid) < 0) {
625  DEBUG("Failed to create run_dir %s: %s",
626  my_dir, strerror(errno));
627  }
628  talloc_free(my_dir);
629  }
630 
631  if (default_log.dst == L_DST_FILES) {
632  char *my_dir;
633 
634  my_dir = talloc_strdup(NULL, radlog_dir);
635  if (rad_mkdir(my_dir, 0750, server_uid, server_gid) < 0) {
636  DEBUG("Failed to create logdir %s: %s",
637  my_dir, strerror(errno));
638  }
639  talloc_free(my_dir);
640  }
641 
642  /*
643  * Once we're done with all of the privileged work,
644  * permanently change the UID.
645  */
646  if (do_suid) {
647  rad_suid_set_down_uid(server_uid);
648  rad_suid_down();
649  }
650 
651  /*
652  * If we don't already have a log file open, open one
653  * now. We may not have been logging anything yet. The
654  * server normally starts up fairly quietly.
655  */
656  if ((default_log.dst == L_DST_FILES) &&
657  (default_log.fd < 0)) {
658  default_log.fd = open(main_config.log_file,
659  O_WRONLY | O_APPEND | O_CREAT, 0640);
660  if (default_log.fd < 0) {
661  fprintf(stderr, "%s: Failed to open log file %s: %s\n",
662  main_config.name, main_config.log_file, fr_syserror(errno));
663  return 0;
664  }
665  }
666 
667  /*
668  * If we need to change UID, ensure that the log files
669  * have the correct owner && group.
670  *
671  * We have to do this because some log files MAY already
672  * have been written as root. We need to change them to
673  * have the correct ownership before proceeding.
674  */
675  if ((do_suid || do_sgid) &&
676  (default_log.dst == L_DST_FILES)) {
677  if (fchown(default_log.fd, server_uid, server_gid) < 0) {
678  fprintf(stderr, "%s: Cannot change ownership of log file %s: %s\n",
679  main_config.name, main_config.log_file, fr_syserror(errno));
680  return 0;
681  }
682  }
683 
684  /*
685  * This also clears the dumpable flag if core dumps
686  * aren't allowed.
687  */
688  if (fr_set_dumpable(allow_core_dumps) < 0) {
689  ERROR("%s", fr_strerror());
690  }
691 
692  if (allow_core_dumps) {
693  INFO("Core dumps are enabled");
694  }
695 
696  return 1;
697 }
698 #endif /* HAVE_SETUID */
699 
700 /** Set the global radius config directory.
701  *
702  * @param ctx Where to allocate the memory for the path string.
703  * @param path to config dir root e.g. /usr/local/etc/raddb
704  */
705 void set_radius_dir(TALLOC_CTX *ctx, char const *path)
706 {
707  if (radius_dir) {
708  char *p;
709 
710  memcpy(&p, &radius_dir, sizeof(p));
711  talloc_free(p);
712  radius_dir = NULL;
713  }
714  if (path) radius_dir = talloc_typed_strdup(ctx, path);
715 }
716 
717 /** Get the global radius config directory.
718  *
719  * @return the global radius config directory.
720  */
721 char const *get_radius_dir(void)
722 {
723  return radius_dir;
724 }
725 
726 /*
727  * Read config files.
728  *
729  * This function can ONLY be called from the main server process.
730  */
732 {
733  char const *p = NULL;
734  CONF_SECTION *cs, *subcs;
735  struct stat statbuf;
736  cached_config_t *cc;
737  char buffer[1024];
738 
739  if (stat(radius_dir, &statbuf) < 0) {
740  ERROR("Errors reading %s: %s",
741  radius_dir, fr_syserror(errno));
742  return -1;
743  }
744 
745 #ifdef S_IWOTH
746  if ((statbuf.st_mode & S_IWOTH) != 0) {
747  ERROR("Configuration directory %s is globally writable. Refusing to start due to insecure configuration.",
748  radius_dir);
749  return -1;
750  }
751 #endif
752 
753 #if 0 && defined(S_IROTH)
754  if (statbuf.st_mode & S_IROTH != 0) {
755  ERROR("Configuration directory %s is globally readable. Refusing to start due to insecure configuration.",
756  radius_dir);
757  return -1;
758  }
759 #endif
760  INFO("Starting - reading configuration files ...");
761 
762  /*
763  * We need to load the dictionaries before reading the
764  * configuration files. This is because of the
765  * pre-compilation in conffile.c. That should probably
766  * be fixed to be done as a second stage.
767  */
768  if (!main_config.dictionary_dir) {
769  main_config.dictionary_dir = talloc_typed_strdup(NULL, DICTDIR);
770  }
771 
772  /*
773  * About sizeof(REQUEST) + sizeof(RADIUS_PACKET) * 2 + sizeof(VALUE_PAIR) * 400
774  *
775  * Which should be enough for many configurations.
776  */
777  main_config.talloc_pool_size = 8 * 1024; /* default */
778 
779  /*
780  * Read the distribution dictionaries first, then
781  * the ones in raddb.
782  */
783  DEBUG2("including dictionary file %s/%s", main_config.dictionary_dir, RADIUS_DICTIONARY);
784  if (fr_dict_init(NULL, &main_config.dict, main_config.dictionary_dir, RADIUS_DICTIONARY, "radius") != 0) {
785  ERROR("Errors reading dictionary: %s",
786  fr_strerror());
787  return -1;
788  }
789 
790 #define DICT_READ_OPTIONAL(_d, _n) \
791 do {\
792  switch (fr_dict_read(main_config.dict, _d, _n)) {\
793  case -1:\
794  ERROR("Errors reading %s/%s: %s", _d, _n, fr_strerror());\
795  return -1;\
796  case 0:\
797  DEBUG2("including dictionary file %s/%s", _d,_n);\
798  break;\
799  default:\
800  break;\
801  }\
802 } while (0)
803 
804  /*
805  * Try to load protocol-specific dictionaries. It's OK
806  * if they don't exist.
807  */
808 #ifdef WITH_DHCP
809  DICT_READ_OPTIONAL(main_config.dictionary_dir, "dictionary.dhcp");
810 #endif
811 
812 #ifdef WITH_VMPS
813  DICT_READ_OPTIONAL(main_config.dictionary_dir, "dictionary.vqp");
814 #endif
815 
816  /*
817  * It's OK if this one doesn't exist.
818  */
820 
821  cs = cf_section_alloc(NULL, "main", NULL);
822  if (!cs) return -1;
823 
824  /*
825  * Add a 'feature' subsection off the main config
826  * We check if it's defined first, as the user may
827  * have defined their own feature flags, or want
828  * to manually override the ones set by modules
829  * or the server.
830  */
831  subcs = cf_section_sub_find(cs, "feature");
832  if (!subcs) {
833  subcs = cf_section_alloc(cs, "feature", NULL);
834  if (!subcs) return -1;
835 
836  cf_section_add(cs, subcs);
837  }
838  version_init_features(subcs);
839 
840  /*
841  * Add a 'version' subsection off the main config
842  * We check if it's defined first, this is for
843  * backwards compatibility.
844  */
845  subcs = cf_section_sub_find(cs, "version");
846  if (!subcs) {
847  subcs = cf_section_alloc(cs, "version", NULL);
848  if (!subcs) return -1;
849  cf_section_add(cs, subcs);
850  }
851  version_init_numbers(subcs);
852 
853  /* Read the configuration file */
854  snprintf(buffer, sizeof(buffer), "%.200s/%.50s.conf", radius_dir, main_config.name);
855  if (cf_file_read(cs, buffer) < 0) {
856  ERROR("Errors reading or parsing %s", buffer);
857  talloc_free(cs);
858  return -1;
859  }
860 
861  /*
862  * If there was no log destination set on the command line,
863  * set it now.
864  */
865  if (default_log.dst == L_DST_NULL) {
866  if (cf_section_parse(cs, NULL, startup_server_config) < 0) {
867  fprintf(stderr, "%s: Error: Failed to parse log{} section.\n",
868  main_config.name);
869  cf_file_free(cs);
870  return -1;
871  }
872 
873  if (!radlog_dest) {
874  fprintf(stderr, "%s: Error: No log destination specified.\n",
875  main_config.name);
876  cf_file_free(cs);
877  return -1;
878  }
879 
880  default_log.dst = fr_str2int(log_str2dst, radlog_dest,
882  if (default_log.dst == L_DST_NUM_DEST) {
883  fprintf(stderr, "%s: Error: Unknown log_destination %s\n",
884  main_config.name, radlog_dest);
885  cf_file_free(cs);
886  return -1;
887  }
888 
889  if (default_log.dst == L_DST_SYSLOG) {
890  /*
891  * Make sure syslog_facility isn't NULL
892  * before using it
893  */
894  if (!syslog_facility) {
895  fprintf(stderr, "%s: Error: Syslog chosen but no facility was specified\n",
896  main_config.name);
897  cf_file_free(cs);
898  return -1;
899  }
900  main_config.syslog_facility = fr_str2int(syslog_facility_table, syslog_facility, -1);
901  if (main_config.syslog_facility < 0) {
902  fprintf(stderr, "%s: Error: Unknown syslog_facility %s\n",
903  main_config.name, syslog_facility);
904  cf_file_free(cs);
905  return -1;
906  }
907 
908 #ifdef HAVE_SYSLOG_H
909  /*
910  * Call openlog only once, when the
911  * program starts.
912  */
913  openlog(main_config.name, LOG_PID, main_config.syslog_facility);
914 #endif
915 
916  } else if (default_log.dst == L_DST_FILES) {
917  if (!main_config.log_file) {
918  fprintf(stderr, "%s: Error: Specified \"files\" as a log destination, but no log filename was given!\n",
919  main_config.name);
920  cf_file_free(cs);
921  return -1;
922  }
923  }
924  }
925 
926 #ifdef HAVE_SETUID
927  /*
928  * Switch users as early as possible.
929  */
930  if (!switch_users(cs)) fr_exit(1);
931 #endif
932 
933  main_config.state_seed = 256; /* initialize it to a non-standard value */
934 
935  /*
936  * This allows us to figure out where, relative to
937  * radiusd.conf, the other configuration files exist.
938  */
939  if (cf_section_parse(cs, NULL, server_config) < 0) return -1;
940 
941  /*
942  * We ignore colourization of output until after the
943  * configuration files have been parsed.
944  */
945  p = getenv("TERM");
946  if (do_colourise && p && isatty(default_log.fd) && strstr(p, "xterm")) {
947  default_log.colourise = true;
948  } else {
949  default_log.colourise = false;
950  }
951 
952  /*
953  * Starting the server, WITHOUT "-x" on the
954  * command-line: use whatever is in the config
955  * file.
956  */
957  if (rad_debug_lvl == 0) {
958  rad_debug_lvl = main_config.debug_level;
959  }
961 
962  FR_INTEGER_COND_CHECK("max_request_time", main_config.max_request_time,
963  (main_config.max_request_time != 0), 100);
964 
965  /*
966  * reject_delay can be zero. OR 1 though 10.
967  */
968  if ((main_config.reject_delay.tv_sec != 0) || (main_config.reject_delay.tv_usec != 0)) {
969  FR_TIMEVAL_BOUND_CHECK("reject_delay", &main_config.reject_delay, >=, 1, 0);
970  }
971  FR_TIMEVAL_BOUND_CHECK("reject_delay", &main_config.reject_delay, <=, 10, 0);
972 
973  FR_INTEGER_BOUND_CHECK("cleanup_delay", main_config.cleanup_delay, <=, 10);
974 
975  FR_TIMEVAL_BOUND_CHECK("reject_delay", &main_config.reject_delay, <=, main_config.cleanup_delay, 0);
976 
977  FR_INTEGER_BOUND_CHECK("resources.talloc_pool_size", main_config.talloc_pool_size, >=, 2 * 1024);
978  FR_INTEGER_BOUND_CHECK("resources.talloc_pool_size", main_config.talloc_pool_size, <=, 1024 * 1024);
979 
980  /*
981  * Set default initial request processing delay to 1/3 of a second.
982  * Will be updated by the lowest response window across all home servers,
983  * if it is less than this.
984  */
985  main_config.init_delay.tv_sec = 0;
986  main_config.init_delay.tv_usec = 2* (1000000 / 3);
987 
988  /*
989  * Free the old configuration items, and replace them
990  * with the new ones.
991  *
992  * Note that where possible, we do atomic switch-overs,
993  * to ensure that the pointers are always valid.
994  */
995  rad_assert(main_config.config == NULL);
996  main_config.config = cs;
998 
999  DEBUG2("%s: #### Loading Realms and Home Servers ####", main_config.name);
1000  if (!realms_init(cs)) {
1001  return -1;
1002  }
1003 
1004  DEBUG2("%s: #### Loading Clients ####", main_config.name);
1005  if (!client_list_parse_section(cs, false)) {
1006  return -1;
1007  }
1008 
1009  /*
1010  * Register the %{config:section.subsection} xlat function.
1011  */
1012  xlat_register(NULL, "config", xlat_config, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN);
1013 
1014  /*
1015  * ...and the client and listen xlats which need to be
1016  * defined before we start parsing the config.
1017  */
1018  xlat_register(NULL, "client", xlat_client, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN);
1019  xlat_register(NULL, "getclient", xlat_getclient, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN);
1020  xlat_register(NULL, "listen", xlat_listen, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN);
1021 
1022  /*
1023  * Ensure cwd is inside the chroot.
1024  */
1025  if (chroot_dir) {
1026  if (chdir(radlog_dir) < 0) {
1027  ERROR("Failed to 'chdir %s' after chroot: %s",
1028  radlog_dir, fr_syserror(errno));
1029  return -1;
1030  }
1031  }
1032 
1033 #ifdef WITH_CONF_WRITE
1034  if (main_config.write_dir) {
1035  cf_section_write(NULL, cs, -1);
1036  }
1037 #endif
1038 
1039  cc = talloc_zero(NULL, cached_config_t);
1040  if (!cc) return -1;
1041 
1042  cc->cs = talloc_steal(cc ,cs);
1043  rad_assert(cs_cache == NULL);
1044  cs_cache = cc;
1045 
1046  /* Clear any unprocessed configuration errors */
1047  (void) fr_strerror();
1048 
1049  return 0;
1050 }
1051 
1052 /*
1053  * Free the configuration. Called only when the server is exiting.
1054  */
1056 {
1057  /*
1058  * Clean up the configuration data
1059  * structures.
1060  */
1061  client_list_free(NULL);
1062  realms_free();
1063  listen_free(&main_config.listen);
1064 
1065  /*
1066  * Frees current config and any previous configs.
1067  */
1068  TALLOC_FREE(cs_cache);
1069  TALLOC_FREE(main_config.dict);
1070 
1071  return 0;
1072 }
1073 
1074 void hup_logfile(void)
1075 {
1076  int fd, old_fd;
1077 
1078  if (default_log.dst != L_DST_FILES) return;
1079 
1080  fd = open(main_config.log_file,
1081  O_WRONLY | O_APPEND | O_CREAT, 0640);
1082  if (fd >= 0) {
1083  /*
1084  * Atomic swap. We'd like to keep the old
1085  * FD around so that callers don't
1086  * suddenly find the FD closed, and the
1087  * writes go nowhere. But that's hard to
1088  * do. So... we have the case where a
1089  * log message *might* be lost on HUP.
1090  */
1091  old_fd = default_log.fd;
1092  default_log.fd = fd;
1093  close(old_fd);
1094  }
1095 }
1096 
1097 static int hup_callback(void *ctx, void *data)
1098 {
1099  CONF_SECTION *modules = ctx;
1100  CONF_SECTION *cs = data;
1101  CONF_SECTION *parent;
1102  char const *name;
1103  module_instance_t *mi;
1104 
1105  /*
1106  * Files may be defined in sub-sections of a module
1107  * config. Walk up the tree until we find the module
1108  * definition.
1109  */
1110  parent = cf_item_parent(cf_section_to_item(cs));
1111  while (parent != modules) {
1112  cs = parent;
1113  parent = cf_item_parent(cf_section_to_item(cs));
1114 
1115  /*
1116  * Something went wrong. Oh well...
1117  */
1118  if (!parent) return 0;
1119  }
1120 
1121  name = cf_section_name2(cs);
1122  if (!name) name = cf_section_name1(cs);
1123 
1124  mi = module_find(modules, name);
1125  if (!mi) return 0;
1126 
1127  if ((mi->entry->module->type & RLM_TYPE_HUP_SAFE) == 0) return 0;
1128 
1129  if (!module_hup_module(mi->cs, mi, time(NULL))) return 0;
1130 
1131  return 0;
1132 }
1133 
1135 {
1136  int rcode;
1137  cached_config_t *cc;
1138  CONF_SECTION *cs;
1139  time_t when;
1140  char buffer[1024];
1141 
1142  static time_t last_hup = 0;
1143 
1144  /*
1145  * Re-open the log file. If we can't, then keep logging
1146  * to the old log file.
1147  *
1148  * The "open log file" code is here rather than in log.c,
1149  * because it makes that function MUCH simpler.
1150  */
1151  hup_logfile();
1152 
1153  /*
1154  * Only check the config files every few seconds.
1155  */
1156  when = time(NULL);
1157  if ((last_hup + 2) >= when) {
1158  INFO("HUP - Last HUP was too recent. Ignoring");
1159  return;
1160  }
1161  last_hup = when;
1162 
1163  rcode = cf_file_changed(cs_cache->cs, hup_callback);
1164  if (rcode == CF_FILE_NONE) {
1165  INFO("HUP - No files changed. Ignoring");
1166  return;
1167  }
1168 
1169  if (rcode == CF_FILE_ERROR) {
1170  INFO("HUP - Cannot read configuration files. Ignoring");
1171  return;
1172  }
1173 
1174  /*
1175  * No config files have changed.
1176  */
1177  if ((rcode & CF_FILE_CONFIG) == 0) {
1178  if ((rcode & CF_FILE_MODULE) != 0) {
1179  INFO("HUP - Files loaded by a module have changed.");
1180 
1181  /*
1182  * FIXME: reload the module.
1183  */
1184 
1185  }
1186  return;
1187  }
1188 
1189  cs = cf_section_alloc(NULL, "main", NULL);
1190  if (!cs) return;
1191 
1192  /* Read the configuration file */
1193  snprintf(buffer, sizeof(buffer), "%.200s/%.50s.conf", radius_dir, main_config.name);
1194 
1195  INFO("HUP - Re-reading configuration files");
1196  if (cf_file_read(cs, buffer) < 0) {
1197  ERROR("Failed to re-read or parse %s", buffer);
1198  talloc_free(cs);
1199  return;
1200  }
1201 
1202  cc = talloc_zero(cs_cache, cached_config_t);
1203  if (!cc) {
1204  ERROR("Out of memory");
1205  return;
1206  }
1207 
1208  /*
1209  * Save the current configuration. Note that we do NOT
1210  * free older ones. We should probably do so at some
1211  * point. Doing so will require us to mark which modules
1212  * are still in use, and which aren't. Modules that
1213  * can't be HUPed always use the original configuration.
1214  * Modules that can be HUPed use one of the newer
1215  * configurations.
1216  */
1217  cc->created = time(NULL);
1218  cc->cs = talloc_steal(cc, cs);
1219  cc->next = cs_cache;
1220  cs_cache = cc;
1221 
1222  INFO("HUP - loading modules");
1223 
1224  /*
1225  * Prefer the new module configuration.
1226  */
1227  modules_hup(cf_section_sub_find(cs, "modules"));
1228 
1229  /*
1230  * Load the new servers.
1231  */
1233 }
static const CONF_PARSER startup_log_config[]
Definition: mainconfig.c:105
void rad_suid_down(void)
Definition: util.c:1474
struct timeval reject_delay
How long to wait before sending an Access-Reject.
Definition: radiusd.h:128
int realms_init(CONF_SECTION *config)
Definition: realms.c:2070
static const CONF_PARSER bootstrap_security_config[]
Definition: mainconfig.c:245
bool proxy_requests
Toggle to enable/disable proxying globally.
Definition: radiusd.h:126
static char const * sbindir
Definition: mainconfig.c:83
static char const * radius_dir
Path to raddb directory.
Definition: mainconfig.c:88
int xlat_register(void *mod_inst, char const *name, xlat_func_t func, xlat_escape_t escape, xlat_instantiate_t instantiate, size_t inst_size, size_t buf_len)
Register an xlat function.
Definition: xlat.c:717
Time value (struct timeval), only for config items.
Definition: radius.h:55
RADCLIENT_LIST * client_list_parse_section(CONF_SECTION *section, bool tls_required)
Main server configuration.
Definition: radiusd.h:108
module_entry_t * entry
Definition: modpriv.h:67
char const * nas_type
Type of client (arbitrary).
Definition: clients.h:47
uint32_t debug_level
Definition: radiusd.h:138
bool event_loop_started
Whether the main event loop has been started yet.
Definition: mainconfig.c:50
int void exec_trigger_set_conf(CONF_SECTION *cs)
Set the global trigger section exec_trigger will search in.
Definition: exec.c:670
bool write_pid
write the PID file
Definition: radiusd.h:167
module_t const * module
Definition: modpriv.h:54
#define INFO(fmt,...)
Definition: log.h:143
static char const * name
uint32_t talloc_pool_size
Size of pool to allocate to hold each REQUEST.
Definition: radiusd.h:155
char const * auth_badpass_msg
Additional text to append to successful auth messages.
Definition: radiusd.h:115
int virtual_servers_init(CONF_SECTION *config)
Definition: modules.c:1577
Log to syslog.
Definition: log.h:60
#define UNUSED
Definition: libradius.h:134
char const * radlog_dir
Definition: radiusd.c:59
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
int fr_set_dumpable_init(void)
Get the current maximum for core files.
Definition: debug.c:513
module_instance_t * module_find(CONF_SECTION *modules, char const *askedname)
Find an existing module instance.
Definition: modules.c:623
int cf_file_read(CONF_SECTION *cs, char const *file)
Definition: conffile.c:3421
static const CONF_PARSER bootstrap_config[]
Definition: mainconfig.c:255
fr_dict_t * dict
Main dictionary.
Definition: radiusd.h:177
RADCLIENT RADCLIENT * client_find(RADCLIENT_LIST const *clients, fr_ipaddr_t const *ipaddr, int proto)
Definition: client.c:431
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:686
#define CF_FILE_ERROR
Definition: conffile.h:370
int modules_hup(CONF_SECTION *modules)
Definition: modules.c:1691
fr_cond_t * debug_condition
Condition used to mark packets up for checking.
Definition: mainconfig.c:48
static bool do_colourise
Definition: mainconfig.c:86
rad_listen_t * listener
The listener that received the request.
Definition: radiusd.h:218
char const * pid_file
Path to write out PID file.
Definition: radiusd.h:123
#define PW_TYPE_DEPRECATED
If a matching CONF_PAIR is found, error out with a deprecated message.
Definition: conffile.h:199
FR_NAME_NUMBER const log_str2dst[]
Definition: log.c:205
fr_log_t default_log
Definition: log.c:216
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
Definition: conffile.h:222
int cf_file_changed(CONF_SECTION *cs, rb_walker_t callback)
Definition: conffile.c:486
char const * name
Name of the daemon, usually 'radiusd'.
Definition: radiusd.h:109
#define XLAT_DEFAULT_BUF_LEN
Definition: xlat.h:89
CONF_SECTION * cs
Definition: modpriv.h:72
#define RLM_TYPE_HUP_SAFE
Will be restarted on HUP.
Definition: modules.h:79
int rad_mkdir(char *directory, mode_t mode, uid_t uid, gid_t gid)
Create possibly many directories.
Definition: util.c:90
void version_init_features(CONF_SECTION *cs)
Initialise core feature flags.
Definition: version.c:313
char const * log_file
Definition: radiusd.h:139
#define PW_TYPE_SUBSECTION
Definition: conffile.h:188
int fr_debug_lvl
Definition: misc.c:40
Defines a CONF_PAIR to C data type mapping.
Definition: conffile.h:267
time_t created
Definition: mainconfig.c:54
int module_hup_module(CONF_SECTION *cs, module_instance_t *node, time_t when)
Definition: modules.c:1624
bool log_stripped_names
Definition: radiusd.c:61
CONF_PAIR * cf_pair_find(CONF_SECTION const *, char const *name)
Definition: conffile.c:3478
char const * cf_pair_value(CONF_PAIR const *pair)
Definition: conffile.c:3506
static const CONF_PARSER resources[]
Definition: mainconfig.c:170
#define DICT_READ_OPTIONAL(_d, _n)
#define FR_TIMEVAL_BOUND_CHECK(_name, _var, _op, _bound_sec, _bound_usec)
Definition: conffile.h:224
main_config_t * root
Pointer to the main config hack to try and deal with hup.
Definition: radiusd.h:267
uint32_t fr_max_attributes
Definition: radius.c:80
uint32_t continuation_timeout
How long to wait before cleaning up state entries.
Definition: radiusd.h:135
#define rad_assert(expr)
Definition: rad_assert.h:38
static const CONF_PARSER security_config[]
Definition: mainconfig.c:159
int fr_str2int(FR_NAME_NUMBER const *table, char const *name, int def)
Definition: token.c:451
static size_t config_escape_func(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
Definition: mainconfig.c:278
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: log.c:238
void cf_file_free(CONF_SECTION *cs)
Definition: conffile.c:3469
int fr_inet_pton(fr_ipaddr_t *out, char const *value, ssize_t inlen, int af, bool resolve, bool mask)
Simple wrapper to decide whether an IP value is v4 or v6 and call the appropriate parser...
Definition: inet.c:564
#define DEBUG(fmt,...)
Definition: log.h:175
static char const * chroot_dir
Definition: mainconfig.c:73
uint32_t max_request_time
How long a request can be processed for before timing out.
Definition: radiusd.h:132
char const * radacct_dir
Definition: radiusd.c:58
uint32_t max_requests
Definition: radiusd.h:136
#define DEBUG2(fmt,...)
Definition: log.h:176
static char const * syslog_facility
Definition: mainconfig.c:85
uint32_t cleanup_delay
How long before cleaning up cached responses.
Definition: radiusd.h:134
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *item)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: conffile.c:181
#define STRINGIFY(x)
Definition: build.h:34
CONF_SECTION * cf_item_parent(CONF_ITEM const *ci)
Definition: conffile.c:3896
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables)
Parse a configuration section into user-supplied variables.
Definition: conffile.c:2234
void void fr_perror(char const *,...) CC_HINT(format(printf
int syslog_facility
Definition: radiusd.h:140
void set_radius_dir(TALLOC_CTX *ctx, char const *path)
Set the global radius config directory.
Definition: mainconfig.c:705
static char const * localstatedir
Definition: mainconfig.c:80
#define RADIUS_DICTIONARY
Definition: conf.h:7
CONF_ITEM * cf_section_to_item(CONF_SECTION const *cs)
Cast a CONF_SECTION to a CONF_ITEM.
Definition: conffile.c:224
Definition: log.h:68
bool fr_dns_lookups
IP -> hostname lookups?
Definition: inet.c:28
int rad_getpwnam(TALLOC_CTX *ctx, struct passwd **out, char const *name)
Resolve a username to a passwd entry.
Definition: util.c:1051
bool log_auth_goodpass
Log failed authentications.
Definition: radiusd.h:114
fr_log_t debug_log
Definition: mainconfig.c:49
CONF_SECTION * cs
CONF_SECTION that was parsed to generate the client.
Definition: clients.h:56
bool cf_item_is_pair(CONF_ITEM const *item)
Definition: conffile.c:3928
A truth value.
Definition: radius.h:56
Configuration AVP similar to a VALUE_PAIR.
Definition: conffile.c:82
CONF_SECTION const * cs
Definition: listen.h:102
bool log_auth
Log authentication attempts.
Definition: radiusd.h:112
32 Bit unsigned integer.
Definition: radius.h:34
ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, char const *fmt, xlat_escape_t escape, void *escape_ctx) CC_HINT(nonnull(1
uint32_t state_seed
magic for proxying
Definition: radiusd.h:165
static int hup_callback(void *ctx, void *data)
Definition: mainconfig.c:1097
char const * fr_strerror(void)
Get the last library error.
Definition: log.c:212
static char const * run_dir
Definition: mainconfig.c:84
#define CLEANUP_DELAY
Definition: radiusd.h:324
void version_init_numbers(CONF_SECTION *cs)
Initialise core version flags.
Definition: version.c:491
CONF_SECTION * cf_section_sub_find(CONF_SECTION const *, char const *name)
Find a sub-section in a section.
Definition: conffile.c:3708
char const * radlib_dir
Path to search for modules in.
Definition: modules.c:36
char const * file
Path to log file.
Definition: log.h:73
void realms_free(void)
Definition: realms.c:256
char const * cf_section_name1(CONF_SECTION const *cs)
Definition: conffile.c:3592
static const CONF_PARSER server_config[]
Definition: mainconfig.c:180
Log to a file on disk.
Definition: log.h:59
Describes a host allowed to send packets to the server.
Definition: clients.h:35
char const * checkrad
Script to use to determine if a user is already connected.
Definition: radiusd.h:144
static bool allow_core_dumps
Definition: mainconfig.c:74
int fr_set_dumpable(bool allow_core_dumps)
Enable or disable core dumps.
Definition: debug.c:528
static char const * prefix
Definition: mainconfig.c:81
static ssize_t xlat_getclient(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Definition: mainconfig.c:408
uint8_t data[]
Definition: eap_pwd.h:625
struct cached_config_t cached_config_t
CONF_SECTION * config
Root of the server config.
Definition: radiusd.h:110
char const * get_radius_dir(void)
Get the global radius config directory.
Definition: mainconfig.c:721
log_lvl_t rad_debug_lvl
Global debugging level.
Definition: log.c:49
void hup_logfile(void)
Definition: mainconfig.c:1074
struct cached_config_t * next
Definition: mainconfig.c:53
int type
One or more of the RLM_TYPE_* constants.
Definition: modules.h:137
bool log_dates_utc
Definition: log.c:214
static char const * radlog_dest
Definition: mainconfig.c:75
#define FR_INTEGER_COND_CHECK(_name, _var, _cond, _new)
Definition: conffile.h:214
CONF_SECTION * cf_section_alloc(CONF_SECTION *parent, char const *name1, char const *name2)
Allocate a CONF_SECTION.
Definition: conffile.c:626
char const * dictionary_dir
Where to load dictionaries from.
Definition: radiusd.h:142
#define CF_FILE_NONE
Definition: conffile.h:369
#define CF_FILE_MODULE
Definition: conffile.h:372
static char const * my_name
Definition: mainconfig.c:82
static const CONF_PARSER startup_server_config[]
Definition: mainconfig.c:120
void listen_free(rad_listen_t **head)
Free a linked list of listeners.
Definition: listen.c:3233
#define REDEBUG(fmt,...)
Definition: log.h:254
struct timeval init_delay
Initial request processing delay.
Definition: radiusd.h:153
static cached_config_t * cs_cache
Definition: mainconfig.c:58
rad_listen_t * listen
Head of a linked list of listeners.
Definition: radiusd.h:147
Discard log messages.
Definition: log.h:63
char const * panic_action
Command to execute if the server receives a fatal signal.
Definition: radiusd.h:150
int main_config_init(void)
Definition: mainconfig.c:731
FR_NAME_NUMBER const syslog_facility_table[]
Syslog facility table.
Definition: log.c:110
void rad_suid_set_down_uid(uid_t uid)
Definition: util.c:1468
CONF_SECTION * cs
Definition: mainconfig.c:55
#define MAX_REQUESTS
Definition: radiusd.h:325
void main_config_hup(void)
Definition: mainconfig.c:1134
bool status_server
Whether to respond to status-server messages.
Definition: radiusd.h:129
bool log_auth_badpass
Log successful authentications.
Definition: radiusd.h:113
void client_list_free(RADCLIENT_LIST *clients)
Definition: client.c:140
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:38
IPv4/6 prefix.
Definition: inet.h:41
bool colourise
Prefix log messages with VT100 escape codes to change text colour.
Definition: log.h:69
#define MAX_REQUEST_TIME
Definition: radiusd.h:323
int main_config_free(void)
Definition: mainconfig.c:1055
static ssize_t xlat_config(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Definition: mainconfig.c:333
log_dst_t dst
Log destination.
Definition: log.h:72
String of printable characters.
Definition: radius.h:33
#define FR_CONF_POINTER(_n, _t, _p)
Definition: conffile.h:172
static const CONF_PARSER log_config[]
Definition: mainconfig.c:139
#define RWDEBUG(fmt,...)
Definition: log.h:251
static ssize_t xlat_client(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Definition: mainconfig.c:375
RADCLIENT * client
The client that originally sent us the request.
Definition: radiusd.h:219
#define RCSID(id)
Definition: build.h:135
void cf_section_add(CONF_SECTION *parent, CONF_SECTION *cs)
Definition: conffile.c:754
#define CF_FILE_CONFIG
Definition: conffile.h:371
char * talloc_typed_strdup(void const *t, char const *p)
Call talloc strdup, setting the type on the new chunk correctly.
Definition: missing.c:588
int fd
File descriptor to write messages to.
Definition: log.h:71
char const * auth_goodpass_msg
Additional text to append to failed auth messages.
Definition: radiusd.h:116
#define RDEBUG(fmt,...)
Definition: log.h:243
#define fr_exit(_x)
Definition: libradius.h:508
#define ERROR(fmt,...)
Definition: log.h:145
static ssize_t xlat_listen(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Definition: mainconfig.c:458
int fr_dict_init(TALLOC_CTX *ctx, fr_dict_t **out, char const *dir, char const *fn, char const *name)
(re)initialize a protocol dictionary
Definition: dict.c:2148
char const * cf_section_name2(CONF_SECTION const *cs)
Definition: conffile.c:3601
char const * shortname
Client nickname.
Definition: clients.h:41
char const * denied_msg
Additional text to append if the user is already logged in (simultaneous use check failed)...
Definition: radiusd.h:118
main_config_t main_config
Main server configuration.
Definition: mainconfig.c:43
CONF_ITEM * cf_reference_item(CONF_SECTION const *parentcs, CONF_SECTION *outercs, char const *ptr)
Definition: conffile.c:906