Don't allow radius_dir to be globally writable
[freeradius.git] / src / main / mainconfig.c
1 /*
2  * mainconf.c   Handle the server's configuration.
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Copyright 2002  The FreeRADIUS server project
21  * Copyright 2002  Alan DeKok <aland@ox.org>
22  */
23
24 #include "autoconf.h"
25 #include "libradius.h"
26
27 #include <stdlib.h>
28 #include <string.h>
29
30 #ifdef HAVE_NETINET_IN_H
31 #include <netinet/in.h>
32 #endif
33
34 #ifdef HAVE_ARPA_INET_H
35 #include <arpa/inet.h>
36 #endif
37
38 #include "radiusd.h"
39 #include "rad_assert.h"
40 #include "conffile.h"
41 #include "token.h"
42
43 #include <sys/resource.h>
44 #include <unistd.h>
45 #include <sys/types.h>
46 #include <sys/socket.h>
47 #include <netdb.h>
48 #include <sys/stat.h>
49 #include <grp.h>
50 #include <pwd.h>
51
52 #ifdef HAVE_SYS_PRCTL_H
53 #include <sys/prctl.h>
54 #endif
55
56 #ifdef WITH_UDPFROMTO
57 #include "udpfromto.h"
58 #endif
59
60
61 struct main_config_t mainconfig;
62
63 /*
64  *  Local variables for stuff.
65  */
66 static uid_t server_uid;
67 static gid_t server_gid;
68
69 /*
70  *      These are not used anywhere else..
71  */
72 static const char *localstatedir = NULL;
73 static const char *prefix = NULL;
74 static int auth_port = 0;
75
76 /*
77  *  Map the proxy server configuration parameters to variables.
78  */
79 static CONF_PARSER proxy_config[] = {
80         { "retry_delay",  PW_TYPE_INTEGER, 0, &mainconfig.proxy_retry_delay, Stringify(RETRY_DELAY) },
81         { "retry_count",  PW_TYPE_INTEGER, 0, &mainconfig.proxy_retry_count, Stringify(RETRY_COUNT) },
82         { "synchronous",  PW_TYPE_BOOLEAN, 0, &mainconfig.proxy_synchronous, "no" },
83         { "default_fallback", PW_TYPE_BOOLEAN, 0, &mainconfig.proxy_fallback, "no" },
84         { "dead_time",    PW_TYPE_INTEGER, 0, &mainconfig.proxy_dead_time, Stringify(DEAD_TIME) },
85         { "post_proxy_authorize", PW_TYPE_BOOLEAN, 0, &mainconfig.post_proxy_authorize, "yes" },
86         { "wake_all_if_all_dead", PW_TYPE_BOOLEAN, 0, &mainconfig.wake_all_if_all_dead, "no" },
87         { NULL, -1, 0, NULL, NULL }
88 };
89
90 /*
91  *  Security configuration for the server.
92  */
93 static CONF_PARSER security_config[] = {
94         { "max_attributes",  PW_TYPE_INTEGER, 0, &librad_max_attributes, Stringify(0) },
95         { "reject_delay",  PW_TYPE_INTEGER, 0, &mainconfig.reject_delay, Stringify(0) },
96         { "status_server", PW_TYPE_BOOLEAN, 0, &mainconfig.status_server, "no"},
97         { NULL, -1, 0, NULL, NULL }
98 };
99
100 /*
101  *  A mapping of configuration file names to internal variables
102  */
103 static CONF_PARSER server_config[] = {
104         /*
105          *      FIXME: 'prefix' is the ONLY one which should be
106          *      configured at compile time.  Hard-coding it here is
107          *      bad.  It will be cleaned up once we clean up the
108          *      hard-coded defines for the locations of the various
109          *      files.
110          */
111         { "prefix",             PW_TYPE_STRING_PTR, 0, &prefix,            "/usr/local"},
112         { "localstatedir",      PW_TYPE_STRING_PTR, 0, &localstatedir,     "${prefix}/var"},
113         { "logdir",             PW_TYPE_STRING_PTR, 0, &radlog_dir,        "${localstatedir}/log"},
114         { "libdir",             PW_TYPE_STRING_PTR, 0, &radlib_dir,        "${prefix}/lib"},
115         { "radacctdir",         PW_TYPE_STRING_PTR, 0, &radacct_dir,       "${logdir}/radacct" },
116         { "hostname_lookups",   PW_TYPE_BOOLEAN,    0, &librad_dodns,      "no" },
117 #ifdef WITH_SNMP
118         { "snmp",               PW_TYPE_BOOLEAN,    0, &mainconfig.do_snmp,      "no" },
119 #endif
120         { "max_request_time", PW_TYPE_INTEGER, 0, &mainconfig.max_request_time, Stringify(MAX_REQUEST_TIME) },
121         { "cleanup_delay", PW_TYPE_INTEGER, 0, &mainconfig.cleanup_delay, Stringify(CLEANUP_DELAY) },
122         { "max_requests", PW_TYPE_INTEGER, 0, &mainconfig.max_requests, Stringify(MAX_REQUESTS) },
123         { "delete_blocked_requests", PW_TYPE_INTEGER, 0, &mainconfig.kill_unresponsive_children, Stringify(FALSE) },
124         { "port", PW_TYPE_INTEGER, 0, &auth_port, Stringify(PW_AUTH_UDP_PORT) },
125         { "allow_core_dumps", PW_TYPE_BOOLEAN, 0, &mainconfig.allow_core_dumps, "no" },
126         { "log_stripped_names", PW_TYPE_BOOLEAN, 0, &log_stripped_names,"no" },
127         { "log_file", PW_TYPE_STRING_PTR, -1, &mainconfig.log_file, "${logdir}/radius.log" },
128         { "log_auth", PW_TYPE_BOOLEAN, -1, &mainconfig.log_auth, "no" },
129         { "log_auth_badpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_badpass, "no" },
130         { "log_auth_goodpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_goodpass, "no" },
131         { "pidfile", PW_TYPE_STRING_PTR, 0, &mainconfig.pid_file, "${run_dir}/radiusd.pid"},
132         { "bind_address", PW_TYPE_IPADDR, 0, &mainconfig.myip, "*" },
133         { "user", PW_TYPE_STRING_PTR, 0, &mainconfig.uid_name, NULL},
134         { "group", PW_TYPE_STRING_PTR, 0, &mainconfig.gid_name, NULL},
135         { "usercollide", PW_TYPE_BOOLEAN, 0, &mainconfig.do_usercollide,  "no" },
136         { "lower_user", PW_TYPE_STRING_PTR, 0, &mainconfig.do_lower_user, "no" },
137         { "lower_pass", PW_TYPE_STRING_PTR, 0, &mainconfig.do_lower_pass, "no" },
138         { "nospace_user", PW_TYPE_STRING_PTR, 0, &mainconfig.do_nospace_user, "no" },
139         { "nospace_pass", PW_TYPE_STRING_PTR, 0, &mainconfig.do_nospace_pass, "no" },
140         { "checkrad", PW_TYPE_STRING_PTR, 0, &mainconfig.checkrad, "${sbindir}/checkrad" },
141         { "proxy_requests", PW_TYPE_BOOLEAN, 0, &mainconfig.proxy_requests, "yes" },
142         { "proxy", PW_TYPE_SUBSECTION, 0, proxy_config, NULL },
143         { "security", PW_TYPE_SUBSECTION, 0, security_config, NULL },
144         { "debug_level", PW_TYPE_INTEGER, 0, &mainconfig.debug_level, "0"},
145         { NULL, -1, 0, NULL, NULL }
146 };
147
148 /*
149  *      Xlat for %{config:section.subsection.attribute}
150  */
151 static int xlat_config(void *instance, REQUEST *request,
152                        char *fmt, char *out,
153                        size_t outlen,
154                        RADIUS_ESCAPE_STRING func)
155 {
156         CONF_SECTION *cs;
157         CONF_PAIR *cp;
158         char buffer[1024];
159         char *p, *value;
160         const char *start = fmt;
161
162         request = request;      /* -Wunused */
163         instance = instance;    /* -Wunused */
164
165         cp = NULL;
166         cs = NULL;
167
168         while (cp == NULL) {
169                 /*
170                  *      Find the next section.
171                  */
172                 for (p = buffer; (*fmt != 0) && (*fmt != '.'); p++, fmt++) {
173                         *p = *fmt;
174                 }
175                 *p = '\0';
176
177                 /*
178                  *  The character is a '.', find a section (as the user
179                  *  has given us a subsection to find)
180                  */
181                 if (*fmt == '.') {
182                         CONF_SECTION *next;
183
184                         fmt++;  /* skip the period */
185
186                         if (cs == NULL) {
187                           next = cf_section_find(buffer);
188                         } else {
189                           next = cf_subsection_find_next(cs, NULL, buffer);
190                         }
191                         if (next == NULL) {
192                                 radlog(L_ERR, "config: No such section %s in format string %s", buffer, start);
193                                 return 0;
194                         }
195                         cs = next;
196
197                 } else {        /* no period, must be a conf-part */
198                         cp = cf_pair_find(cs, buffer);
199
200                         if (cp == NULL) {
201                                 radlog(L_ERR, "config: No such section %s in format string %s", buffer, start);
202                                 return 0;
203                         }
204                 }
205         } /* until cp is non-NULL */
206
207         /*
208          *  Ensure that we only copy what's necessary.
209          *
210          *  If 'outlen' is too small, then the output is chopped to fit.
211          */
212         value = cf_pair_value(cp);
213         if (value) {
214                 if (outlen > strlen(value)) {
215                         outlen = strlen(value) + 1;
216                 }
217         }
218
219         return func(out, outlen, value);
220 }
221
222
223 /*
224  *      Recursively make directories.
225  */
226 static int r_mkdir(const char *part)
227 {
228         char *ptr, parentdir[500];
229         struct stat st;
230
231         if (stat(part, &st) == 0)
232                 return(0);
233
234         ptr = strrchr(part, '/');
235
236         if (ptr == part)
237                 return(0);
238
239         snprintf(parentdir, (ptr - part)+1, "%s", part);
240
241         if (r_mkdir(parentdir) != 0)
242                 return(1);
243
244         if (mkdir(part, 0770) != 0) {
245                 fprintf(stderr, "mkdir(%s) error: %s\n", part, strerror(errno));
246                 return(1);
247         }
248
249         return(0);
250 }
251
252 /*
253  *      Checks if the log directory is writeable by a particular user.
254  */
255 static int radlogdir_iswritable(const char *effectiveuser)
256 {
257         struct passwd *pwent;
258
259         if (radlog_dir[0] != '/')
260                 return(0);
261
262         if (r_mkdir(radlog_dir) != 0)
263                 return(1);
264
265         /* FIXME: do we have this function? */
266         if (strstr(radlog_dir, "radius") == NULL)
267                 return(0);
268
269         /* we have a logdir that mentions 'radius', so it's probably
270          * safe to chown the immediate directory to be owned by the normal
271          * process owner. we gotta do it before we give up root.  -chad
272          */
273
274         if (!effectiveuser) {
275                 return 1;
276         }
277
278         pwent = getpwnam(effectiveuser);
279
280         if (pwent == NULL) /* uh oh! */
281                 return(1);
282
283         if (chown(radlog_dir, pwent->pw_uid, -1) != 0)
284                 return(1);
285
286         return(0);
287 }
288
289
290 /*
291  *  Switch UID and GID to what is specified in the config file
292  */
293 static int switch_users(void)
294 {
295         /*  Set GID.  */
296         if (mainconfig.gid_name != NULL) {
297                 struct group *gr;
298
299                 gr = getgrnam(mainconfig.gid_name);
300                 if (gr == NULL) {
301                         if (errno == ENOMEM) {
302                                 radlog(L_ERR|L_CONS, "Cannot switch to Group %s: out of memory", mainconfig.gid_name);
303                         } else {
304                                 radlog(L_ERR|L_CONS, "Cannot switch group; %s doesn't exist", mainconfig.gid_name);
305                         }
306                         exit(1);
307                 }
308                 server_gid = gr->gr_gid;
309                 if (setgid(server_gid) < 0) {
310                         radlog(L_ERR|L_CONS, "Failed setting Group to %s: %s",
311                                mainconfig.gid_name, strerror(errno));
312                         exit(1);
313                 }
314         } else {
315                 server_gid = getgid();
316         }
317
318         /*  Set UID.  */
319         if (mainconfig.uid_name != NULL) {
320                 struct passwd *pw;
321
322                 pw = getpwnam(mainconfig.uid_name);
323                 if (pw == NULL) {
324                         if (errno == ENOMEM) {
325                                 radlog(L_ERR|L_CONS, "Cannot switch to User %s: out of memory", mainconfig.uid_name);
326                         } else {
327                                 radlog(L_ERR|L_CONS, "Cannot switch user; %s doesn't exist", mainconfig.uid_name);
328                         }
329                         exit(1);
330                 }
331                 server_uid = pw->pw_uid;
332 #ifdef HAVE_INITGROUPS
333                 if (initgroups(mainconfig.uid_name, server_gid) < 0) {
334                         if (errno != EPERM) {
335                                 radlog(L_ERR|L_CONS, "Failed setting supplementary groups for User %s: %s", mainconfig.uid_name, strerror(errno));
336                                 exit(1);
337                         }
338                 }
339 #endif
340                 if (setuid(server_uid) < 0) {
341                         radlog(L_ERR|L_CONS, "Failed setting User to %s: %s", mainconfig.uid_name, strerror(errno));
342                         exit(1);
343                 }
344         }
345         return(0);
346 }
347
348
349 /*
350  * Create the linked list of realms from the new configuration type
351  * This way we don't have to change to much in the other source-files
352  */
353 static int generate_realms(const char *filename)
354 {
355         CONF_SECTION *cs;
356         REALM *my_realms = NULL;
357         REALM *c, **tail;
358         char *s, *t, *authhost, *accthost;
359         char *name2;
360
361         tail = &my_realms;
362         for (cs = cf_subsection_find_next(mainconfig.config, NULL, "realm");
363              cs != NULL;
364              cs = cf_subsection_find_next(mainconfig.config, cs, "realm")) {
365                 name2 = cf_section_name2(cs);
366                 if (!name2) {
367                         radlog(L_CONS|L_ERR, "%s[%d]: Missing realm name",
368                                filename, cf_section_lineno(cs));
369                         return -1;
370                 }
371                 /*
372                  * We've found a realm, allocate space for it
373                  */
374                 c = rad_malloc(sizeof(REALM));
375                 memset(c, 0, sizeof(REALM));
376
377                 c->secret[0] = '\0';
378
379                 /*
380                  *      No authhost means LOCAL.
381                  */
382                 if ((authhost = cf_section_value_find(cs, "authhost")) == NULL) {
383                         c->ipaddr = htonl(INADDR_NONE);
384                         c->auth_port = 0;
385                 } else {
386                         if ((s = strchr(authhost, ':')) != NULL) {
387                                 *s++ = 0;
388                                 c->auth_port = atoi(s);
389                         } else {
390                                 c->auth_port = PW_AUTH_UDP_PORT;
391                         }
392                         if (strcmp(authhost, "LOCAL") == 0) {
393                                 /*
394                                  *      Local realms don't have an IP address,
395                                  *      secret, or port.
396                                  */
397                                 c->ipaddr = htonl(INADDR_NONE);
398                                 c->auth_port = 0;
399                         } else {
400                                 c->ipaddr = ip_getaddr(authhost);
401                                 if (c->ipaddr == htonl(INADDR_NONE)) {
402                                         radlog(L_ERR, "%s[%d]: Host %s not found",
403                                                filename, cf_section_lineno(cs),
404                                                authhost);
405                                         return -1;
406                                 }
407                         }
408
409                         /*
410                          * Double check length, just to be sure!
411                          */
412                         if (strlen(authhost) >= sizeof(c->server)) {
413                                 radlog(L_ERR, "%s[%d]: Server name of length %d is greater than allowed: %d",
414                                        filename, cf_section_lineno(cs),
415                                        (int) strlen(authhost),
416                                        (int) sizeof(c->server) - 1);
417                                 return -1;
418                         }
419                 }
420
421                 /*
422                  *      No accthost means LOCAL
423                  */
424                 if ((accthost = cf_section_value_find(cs, "accthost")) == NULL) {
425                         c->acct_ipaddr = htonl(INADDR_NONE);
426                         c->acct_port = 0;
427                 } else {
428                         if ((s = strchr(accthost, ':')) != NULL) {
429                                 *s++ = 0;
430                                 c->acct_port = atoi(s);
431                         } else {
432                                 c->acct_port = PW_ACCT_UDP_PORT;
433                         }
434                         if (strcmp(accthost, "LOCAL") == 0) {
435                                 /*
436                                  *      Local realms don't have an IP address,
437                                  *      secret, or port.
438                                  */
439                                 c->acct_ipaddr = htonl(INADDR_NONE);
440                                 c->acct_port = 0;
441                         } else {
442                                 c->acct_ipaddr = ip_getaddr(accthost);
443                                 if (c->acct_ipaddr == htonl(INADDR_NONE)) {
444                                         radlog(L_ERR, "%s[%d]: Host %s not found",
445                                                filename, cf_section_lineno(cs),
446                                                accthost);
447                                         return -1;
448                                 }
449                         }
450
451                         if (strlen(accthost) >= sizeof(c->acct_server)) {
452                                 radlog(L_ERR, "%s[%d]: Server name of length %d is greater than allowed: %d",
453                                        filename, cf_section_lineno(cs),
454                                        (int) strlen(accthost),
455                                        (int) sizeof(c->acct_server) - 1);
456                                 return -1;
457                         }
458                 }
459
460                 if (strlen(name2) >= sizeof(c->realm)) {
461                         radlog(L_ERR, "%s[%d]: Realm name of length %d is greater than allowed %d",
462                                filename, cf_section_lineno(cs),
463                                (int) strlen(name2),
464                                (int) sizeof(c->server) - 1);
465                         return -1;
466                 }
467
468                 strcpy(c->realm, name2);
469                 if (authhost) strcpy(c->server, authhost);
470                 if (accthost) strcpy(c->acct_server, accthost);
471
472                 /*
473                  *      If one or the other of authentication/accounting
474                  *      servers is set to LOCALHOST, then don't require
475                  *      a shared secret.
476                  */
477                 if ((c->ipaddr != htonl(INADDR_NONE)) ||
478                     (c->acct_ipaddr != htonl(INADDR_NONE))) {
479                         if ((s = cf_section_value_find(cs, "secret")) == NULL ) {
480                                 radlog(L_ERR, "%s[%d]: No shared secret supplied for realm: %s",
481                                        filename, cf_section_lineno(cs), name2);
482                                 return -1;
483                         }
484
485                         if (strlen(s) >= sizeof(c->secret)) {
486                                 radlog(L_ERR, "%s[%d]: Secret of length %u is greater than the allowed maximum of %u.",
487                                        filename, cf_section_lineno(cs),
488                                        strlen(s), sizeof(c->secret) - 1);
489                                 return -1;
490                         }
491                         strNcpy((char *)c->secret, s, sizeof(c->secret));
492                 }
493
494                 c->striprealm = 1;
495
496                 if ((cf_section_value_find(cs, "nostrip")) != NULL)
497                         c->striprealm = 0;
498                 if ((cf_section_value_find(cs, "noacct")) != NULL)
499                         c->acct_port = 0;
500                 if ((cf_section_value_find(cs, "trusted")) != NULL)
501                         c->trusted = 1;
502                 if ((cf_section_value_find(cs, "notrealm")) != NULL)
503                         c->notrealm = 1;
504                 if ((cf_section_value_find(cs, "notsuffix")) != NULL)
505                         c->notrealm = 1;
506                 if ((t = cf_section_value_find(cs,"ldflag")) != NULL) {
507                         static const LRAD_NAME_NUMBER ldflags[] = {
508                                 { "fail_over",   0 },
509                                 { "round_robin", 1 },
510                                 { NULL, 0 }
511                         };
512
513                         c->ldflag = lrad_str2int(ldflags, t, -1);
514                         if (c->ldflag == -1) {
515                                 radlog(L_ERR, "%s[%d]: Unknown value \"%s\" for ldflag",
516                                        filename, cf_section_lineno(cs),
517                                        t);
518                                 return -1;
519                         }
520
521                 } else {
522                         c->ldflag = 0; /* non, make it fail-over */
523                 }
524                 c->active = TRUE;
525                 c->acct_active = TRUE;
526
527                 c->next = NULL;
528                 *tail = c;
529                 tail = &c->next;
530         }
531
532         /*
533          *      And make these realms preferred over the ones
534          *      in the 'realms' file.
535          */
536         *tail = mainconfig.realms;
537         mainconfig.realms = my_realms;
538
539         /*
540          *  Ensure that all of the flags agree for the realms.
541          *
542          *      Yeah, it's O(N^2), but it's only once, and the
543          *      maximum number of realms is small.
544          */
545         for(c = mainconfig.realms; c != NULL; c = c->next) {
546                 REALM *this;
547
548                 /*
549                  *      Check that we cannot load balance to LOCAL
550                  *      realms, as that doesn't make any sense.
551                  */
552                 if ((c->ldflag == 1) &&
553                     ((c->ipaddr == htonl(INADDR_NONE)) ||
554                      (c->acct_ipaddr == htonl(INADDR_NONE)))) {
555                         radlog(L_ERR | L_CONS, "ERROR: Realm %s cannot be load balanced to LOCAL",
556                                c->realm);
557                         exit(1);
558                 }
559
560                 /*
561                  *      Compare this realm to all others, to ensure
562                  *      that the configuration is consistent.
563                  */
564                 for (this = c->next; this != NULL; this = this->next) {
565                         if (strcasecmp(c->realm, this->realm) != 0) {
566                                 continue;
567                         }
568
569                         /*
570                          *      Same realm: Different load balancing
571                          *      flag: die.
572                          */
573                         if (c->ldflag != this->ldflag) {
574                                 radlog(L_ERR | L_CONS, "ERROR: Inconsistent value in realm %s for load balancing 'ldflag' attribute",
575                                        c->realm);
576                                 exit(1);
577                         }
578                 }
579         }
580
581         return 0;
582 }
583
584
585 /*
586  *      Create the linked list of realms from the new configuration
587  *      type.  This way we don't have to change too much in the other
588  *      source-files.
589  */
590 static RADCLIENT *generate_clients(const char *filename, CONF_SECTION *section)
591 {
592         CONF_SECTION    *cs;
593         RADCLIENT       *list, *c;
594         char            *hostnm, *secret, *shortnm, *netmask;
595         char            *nastype, *login, *password;
596         char            *name2;
597
598         list = NULL;
599         for (cs = cf_subsection_find_next(section, NULL, "client");
600              cs != NULL;
601              cs = cf_subsection_find_next(section, cs, "client")) {
602
603                 name2 = cf_section_name2(cs);
604                 if (!name2) {
605                         radlog(L_CONS|L_ERR, "%s[%d]: Missing client name",
606                                filename, cf_section_lineno(cs));
607                         clients_free(list);
608                         return NULL;
609                 }
610                 /*
611                  * Check the lengths, we don't want any core dumps
612                  */
613                 hostnm = name2;
614
615                 if((secret = cf_section_value_find(cs, "secret")) == NULL) {
616                         radlog(L_ERR, "%s[%d]: Missing secret for client: %s",
617                                 filename, cf_section_lineno(cs), name2);
618                         clients_free(list);
619                         return NULL;
620                 }
621
622                 if((shortnm = cf_section_value_find(cs, "shortname")) == NULL) {
623                         radlog(L_ERR, "%s[%d]: Missing shortname for client: %s",
624                                 filename, cf_section_lineno(cs), name2);
625                         clients_free(list);
626                         return NULL;
627                 }
628
629                 netmask = strchr(hostnm, '/');
630
631                 if (strlen(secret) >= sizeof(c->secret)) {
632                         radlog(L_ERR, "%s[%d]: Secret of length %u is greater than the allowed maximum of %u.",
633                                 filename, cf_section_lineno(cs),
634                                 strlen(secret), sizeof(c->secret) - 1);
635                         clients_free(list);
636                         return NULL;
637                 }
638
639                 if (strlen(shortnm) > sizeof(c->shortname)) {
640                         radlog(L_ERR, "%s[%d]: Client short name of length %u is greater than the allowed maximum of %u.",
641                                         filename, cf_section_lineno(cs),
642                                strlen(shortnm), sizeof(c->shortname) - 1);
643                         clients_free(list);
644                         return NULL;
645                 }
646
647                 if((nastype = cf_section_value_find(cs, "nastype")) != NULL) {
648                         if(strlen(nastype) >= sizeof(c->nastype)) {
649                                radlog(L_ERR, "%s[%d]: nastype of length %u longer than the allowed maximum of %u",
650                                       filename, cf_section_lineno(cs),
651                                       strlen(nastype), sizeof(c->nastype) - 1);
652                                clients_free(list);
653                                return NULL;
654                         }
655                 }
656
657                 if((login = cf_section_value_find(cs, "login")) != NULL) {
658                         if(strlen(login) >= sizeof(c->login)) {
659                                radlog(L_ERR, "%s[%d]: login of length %u longer than the allowed maximum of %u",
660                                       filename, cf_section_lineno(cs),
661                                       strlen(login), sizeof(c->login) - 1);
662                                clients_free(list);
663                                return NULL;
664                         }
665                 }
666
667                 if((password = cf_section_value_find(cs, "password")) != NULL) {
668                         if(strlen(password) >= sizeof(c->password)) {
669                                radlog(L_ERR, "%s[%d]: password of length %u longer than the allowed maximum of %u",
670                                       filename, cf_section_lineno(cs),
671                                       strlen(password), sizeof(c->password) - 1);
672                                clients_free(list);
673                                return NULL;
674                         }
675                 }
676
677                 /*
678                  * The size is fine.. Let's create the buffer
679                  */
680                 c = rad_malloc(sizeof(RADCLIENT));
681                 memset(c, 0, sizeof(RADCLIENT));
682
683                 /*
684                  *      Look for netmasks.
685                  */
686                 c->netmask = ~0;
687                 if (netmask) {
688                         int mask_length;
689
690                         mask_length = atoi(netmask + 1);
691                         if ((mask_length < 0) || (mask_length > 32)) {
692                                 radlog(L_ERR, "%s[%d]: Invalid value '%s' for IP network mask.",
693                                                 filename, cf_section_lineno(cs), netmask + 1);
694                                 clients_free(list);
695                                 return NULL;
696                         }
697
698                         if (mask_length == 0) {
699                                 c->netmask = 0;
700                         } else {
701                                 c->netmask = ~0 << (32 - mask_length);
702                         }
703
704                         *netmask = '\0';
705                         c->netmask = htonl(c->netmask);
706                 }
707
708                 c->ipaddr = ip_getaddr(hostnm);
709                 if (c->ipaddr == INADDR_NONE) {
710                         radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
711                                         filename, cf_section_lineno(cs), hostnm);
712                         clients_free(list);
713                         return NULL;
714                 }
715
716                 /*
717                  *      Update the client name again...
718                  */
719                 if (netmask) {
720                         *netmask = '/';
721                         c->ipaddr &= c->netmask;
722                         strcpy(c->longname, hostnm);
723                 } else {
724                         ip_hostname(c->longname, sizeof(c->longname),
725                                         c->ipaddr);
726                 }
727
728                 strcpy((char *)c->secret, secret);
729                 strcpy(c->shortname, shortnm);
730                 if(nastype != NULL)
731                         strcpy(c->nastype, nastype);
732                 if(login != NULL)
733                         strcpy(c->login, login);
734                 if(password != NULL)
735                         strcpy(c->password, password);
736
737                 c->next = list;
738                 list = c;
739         }
740
741         return list;
742 }
743
744
745 /*
746  *      Code for handling listening on multiple ports.
747  */
748 static rad_listen_t listen_inst;
749 static const char *listen_type = NULL;
750
751 static const CONF_PARSER listen_config[] = {
752         { "ipaddr", PW_TYPE_IPADDR,
753           offsetof(rad_listen_t,ipaddr), NULL, "0.0.0.0" },
754
755         { "port", PW_TYPE_INTEGER,
756           offsetof(rad_listen_t,port), NULL, "0" },
757
758         { "type", PW_TYPE_STRING_PTR,
759           0, &listen_type, "" },
760
761         { NULL, -1, 0, NULL, NULL }             /* end the list */
762 };
763
764 static const LRAD_NAME_NUMBER listen_compare[] = {
765         { "auth",       RAD_LISTEN_AUTH },
766         { "acct",       RAD_LISTEN_ACCT },
767         { NULL, 0 },
768 };
769
770
771 /*
772  *      Free a linked list of listeners;
773  */
774 static void listen_free(rad_listen_t *list)
775 {
776         while (list) {
777                 rad_listen_t *next = list->next;
778                 
779                 /*
780                  *      The code below may have eaten the FD.
781                  */
782                 if (list->fd >= 0) close(list->fd);
783                 free(list);
784                 
785                 list = next;
786         }
787 }
788
789 /*
790  *      Binds a listener to a socket.
791  */
792 static int listen_bind(rad_listen_t *this)
793 {
794         struct sockaddr salocal;
795         struct sockaddr_in *sa;
796
797         rad_listen_t    **last;
798
799         /*
800          *      If the port is zero, then it means the appropriate
801          *      thing from /etc/services.
802          */
803         if (this->port == 0) {
804                 struct servent  *svp;
805
806                 switch (this->type) {
807                 case RAD_LISTEN_AUTH:
808                         svp = getservbyname ("radius", "udp");
809                         if (svp != NULL) {
810                                 this->port = ntohs(svp->s_port);
811                         } else {
812                                 this->port = PW_AUTH_UDP_PORT;
813                         }
814                         break;
815
816                 case RAD_LISTEN_ACCT:
817                         svp = getservbyname ("radacct", "udp");
818                         if (svp != NULL) {
819                                 this->port = ntohs(svp->s_port);
820                         } else {
821                                 this->port = PW_ACCT_UDP_PORT;
822                         }
823                         break;
824
825                 default:
826                         radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
827                         return -1;
828                 }
829         }
830
831         /*
832          *      Find it in the old list, AFTER updating the port.  If
833          *      it's there, use that, rather than creating a new
834          *      socket.  This allows HUP's to re-use the old sockets,
835          *      which means that packets waiting in the socket queue
836          *      don't get lost.  */
837         for (last = &mainconfig.listen;
838              *last != NULL;
839              last = &((*last)->next)) {
840                 if ((this->ipaddr == (*last)->ipaddr) &&
841                     (this->type == (*last)->type) &&
842                     (this->port == (*last)->port)) {
843                         this->fd = (*last)->fd;
844                         (*last)->fd = -1;
845                         return 0;
846                 }
847         }
848
849         /*
850          *      Create the socket.
851          */
852         this->fd = socket(AF_INET, SOCK_DGRAM, 0);
853         if (this->fd < 0) {
854                 return -1;
855         }
856         
857
858 #ifdef WITH_UDPFROMTO
859         /*
860          *      Initialize udpfromto for all sockets.
861          */
862         if (udpfromto_init(this->fd) != 0) {
863                 radlog(L_ERR|L_CONS, "ERROR: udpfromto init failed.");
864         }
865 #endif
866
867         sa = (struct sockaddr_in *) &salocal;
868         memset ((char *) sa, '\0', sizeof(salocal));
869         sa->sin_family = AF_INET;
870         sa->sin_addr.s_addr = this->ipaddr;
871         sa->sin_port = htons(this->port);
872         
873         if (bind(this->fd, &salocal, sizeof(*sa)) < 0) {
874                 close(this->fd);
875                 this->fd = -1;
876                 return -1;
877         }
878
879         return 0;
880 }
881
882
883 static int last_proxy_port = 0;
884
885 /*
886  *      Externally visible function for creating a new proxy LISTENER.
887  *
888  *      For now, don't take ipaddr or port.
889  */
890 int proxy_new_listener(void)
891 {
892         int port;
893         rad_listen_t *this;
894
895         this = rad_malloc(sizeof(*this));
896
897         memset(this, 0, sizeof(*this));
898
899         this->ipaddr = mainconfig.myip;
900         this->type = RAD_LISTEN_PROXY;
901
902         /*
903          *      Proxying was not previously defined: die.
904          */
905         if (last_proxy_port == 0) return -1;
906
907         /*
908          *      Keep going until we find an unused port.
909          */
910         for (port = last_proxy_port + 1; port < 64000; port++) {
911                 this->port = port;
912                 if (listen_bind(this) == 0) {
913                         rad_listen_t **last;
914
915                         last_proxy_port = port;
916
917                         /*
918                          *      Add the new listener to the list of
919                          *      listeners.
920                          */
921                         for (last = &mainconfig.listen;
922                              *last != NULL;
923                              last = &((*last)->next)) {
924                                 /* do nothing */
925                         }
926
927                         *last = this;
928                         return this->fd;
929                 }
930         }
931
932         return -1;
933 }
934
935
936 /*
937  *      Generate a list of listeners.  Takes an input list of
938  *      listeners, too, so we don't close sockets with waiting packets.
939  */
940 static int listen_init(const char *filename, rad_listen_t **head)
941 {
942         CONF_SECTION    *cs;
943         rad_listen_t    **last;
944         char            buffer[32];
945         rad_listen_t    *this;
946
947         /*
948          *      Add to the end of the list.
949          */
950         for (last = head; *last != NULL; last = &((*last)->next)) {
951                 /* do nothing */
952         }
953
954         /*
955          *      Find the first one (if any).
956          */
957         for (cs = cf_subsection_find_next(mainconfig.config,
958                                           NULL, "listen");
959              cs != NULL;
960              cs = cf_subsection_find_next(mainconfig.config,
961                                           cs, "listen")) {
962                 memset(&listen_inst, 0, sizeof(listen_inst));
963                 
964                 /*
965                  *      Fix errors for later.
966                  */
967                 if (cf_section_parse(cs, &listen_inst, listen_config) < 0) {
968                         radlog(L_CONS|L_ERR, "%s[%d]: Error parsing listen section.",
969                                filename, cf_section_lineno(cs));
970                         return -1;
971                 }
972
973                 if (listen_type) {
974                         listen_inst.type = lrad_str2int(listen_compare,
975                                                         listen_type, 0);
976                 }
977                 if (listen_inst.type == RAD_LISTEN_NONE) {
978                         radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
979                                filename, cf_section_lineno(cs));
980                         return -1;
981                 }
982
983                 this = rad_malloc(sizeof(*this));
984                 memcpy(this, &listen_inst, sizeof(*this));
985                 
986                 /*
987                  *      And bind it to the port.
988                  */
989                 if (listen_bind(this) < 0) {
990                         radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s:%d",
991                                filename, cf_section_lineno(cs),
992                                ip_ntoa(buffer, this->ipaddr), this->port);
993                         free(this);
994                         return -1;
995                 }
996
997                 *last = this;
998                 last = &(this->next);           
999         }
1000
1001         /*
1002          *      If we're proxying requests, open the proxy FD.
1003          *      Otherwise, don't do anything.
1004          */
1005         if (mainconfig.proxy_requests == TRUE) {
1006                 int             port = -1;
1007                 rad_listen_t    *auth;
1008                 int             num_realms = 0;
1009                 int             localhost = 0;
1010                 int             otherhost = 0;
1011                 REALM           *realm;
1012                 uint32_t        proxy_ip;
1013                 uint32_t        ipaddr;
1014
1015                 /*
1016                  *      If there are no realms configured, don't
1017                  *      open the proxy port.
1018                  */
1019                 for (realm = mainconfig.realms;
1020                      realm != NULL;
1021                      realm = realm->next) {
1022                         /*
1023                          *      Ignore LOCAL realms.
1024                          */
1025                         if ((realm->ipaddr == htonl(INADDR_NONE)) &&
1026                             (realm->acct_ipaddr == htonl(INADDR_NONE))) {
1027                                 continue;
1028                         }
1029                         num_realms++;
1030
1031                         /*
1032                          *      Loopback addresses
1033                          */
1034                         if (realm->ipaddr == htonl(INADDR_LOOPBACK)) {
1035                                 localhost = 1;
1036                         } else {
1037                                 otherhost = 1;
1038                         }
1039                         if (realm->acct_ipaddr == htonl(INADDR_LOOPBACK)) {
1040                                 localhost = 1;
1041                         } else {
1042                                 otherhost = 1;
1043                         }
1044                 }
1045
1046                 /*
1047                  *      No external realms.  Don't open another port.
1048                  */
1049                 if (num_realms == 0) {
1050                         return 0;
1051                 }
1052
1053                 /*
1054                  *      All of the realms are localhost, don't open
1055                  *      an external port.
1056                  */
1057                 if (localhost && !otherhost) {
1058                         proxy_ip = htonl(INADDR_LOOPBACK);
1059                 } else {
1060                         /*
1061                          *      Multiple external realms, listen
1062                          *      on any address that will send packets.
1063                          */
1064                         proxy_ip = htonl(INADDR_NONE);
1065                 }
1066
1067                 /*
1068                  *      Find the first authentication port,
1069                  *      and use it
1070                  */
1071                 ipaddr = htonl(INADDR_NONE);
1072                 for (auth = *head; auth != NULL; auth = auth->next) {
1073                         /*
1074                          *      Listening on ANY, use that.
1075                          */
1076                         if (ipaddr != htonl(INADDR_ANY)) {
1077                                 /*
1078                                  *      Not set.  Pick the first one.
1079                                  *      Or, ANY, pick that.
1080                                  */
1081                                 if ((ipaddr == htonl(INADDR_NONE)) ||
1082                                     (auth->ipaddr == htonl(INADDR_ANY))) {
1083                                         ipaddr = auth->ipaddr;
1084
1085                                         /*
1086                                          *      Else listening on multiple
1087                                          *      IP's, use ANY for proxying.
1088                                          */
1089                                 } else if (ipaddr != auth->ipaddr) {
1090                                         ipaddr = htonl(INADDR_ANY);
1091                                 }
1092                         }
1093                         if (auth->type == RAD_LISTEN_AUTH) {
1094                                 port = auth->port + 2;
1095                                 break;
1096                         }
1097                 }
1098
1099                 /*
1100                  *      Not found, pick an accounting port.
1101                  */
1102                 if (port < 0) for (auth = *head; auth != NULL; auth = auth->next) {
1103                         if (auth->type == RAD_LISTEN_ACCT) {
1104                                 port = auth->port + 1;
1105                                 break;
1106                         }
1107                 }
1108
1109                 /*
1110                  *      Still no port.  Don't do anything.
1111                  */
1112                 if (port < 0) {
1113                         return 0;
1114                 }
1115
1116                 this = rad_malloc(sizeof(*this));
1117                 memset(this, 0, sizeof(*this));
1118
1119                 /*
1120                  *      More checks to do the right thing.
1121                  */
1122                 if (proxy_ip == htonl(INADDR_NONE)) {
1123                         proxy_ip = ipaddr;
1124                 }
1125                 
1126                 /*
1127                  *      Create the proxy socket.
1128                  */
1129                 this->ipaddr = proxy_ip;
1130                 this->type = RAD_LISTEN_PROXY;
1131
1132                 /*
1133                  *      Try to find a proxy port (value doesn't matter)
1134                  */
1135                 for (this->port = port;
1136                      this->port < 64000;
1137                      this->port++) {
1138                         if (listen_bind(this) == 0) {
1139                                 last_proxy_port = this->port;
1140                                 *last = this;
1141                                 return 0;
1142                         }
1143                 }
1144
1145                 radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
1146                 free(this);
1147                 return -1;
1148         }
1149
1150         return 0;
1151 }
1152
1153
1154 /*
1155  *      Hack the OLD way of listening on a socket.
1156  */
1157 static int old_listen_init(rad_listen_t **head)
1158 {
1159         CONF_PAIR       *cp;
1160         rad_listen_t    *this, **last;
1161
1162         /*
1163          *      No "bind_address": all listen directives
1164          *      are in the "listen" clauses.
1165          */
1166         cp = cf_pair_find(mainconfig.config, "bind_address");
1167         if (!cp) return 0;
1168         
1169         last = head;
1170
1171         this = rad_malloc(sizeof(*this));
1172         memset(this, 0, sizeof(*this));
1173
1174         /*
1175          *      Create the authentication socket.
1176          */
1177         this->ipaddr = mainconfig.myip;
1178         this->type = RAD_LISTEN_AUTH;
1179         this->port = auth_port;
1180
1181         if (listen_bind(this) < 0) {
1182                 radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", this->port);
1183                 free(this);
1184                 return -1;
1185         }
1186         auth_port = this->port; /* may have been updated in listen_bind */
1187         *last = this;
1188         last = &(this->next);
1189
1190         /*
1191          *  Open Accounting Socket.
1192          *
1193          *  If we haven't already gotten acct_port from /etc/services,
1194          *  then make it auth_port + 1.
1195          */
1196         this = rad_malloc(sizeof(*this));
1197         memset(this, 0, sizeof(*this));
1198
1199         /*
1200          *      Create the accounting socket.
1201          *
1202          *      The accounting port is always the authentication port + 1
1203          */
1204         this->ipaddr = mainconfig.myip;
1205         this->type = RAD_LISTEN_ACCT;
1206         this->port = auth_port + 1;
1207
1208         if (listen_bind(this) < 0) {
1209                 radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", this->port);
1210                 free(this);
1211                 return -1;
1212         }
1213         *last = this;
1214
1215         return 0;
1216 }
1217
1218
1219 #ifndef RADIUS_CONFIG
1220 #define RADIUS_CONFIG "radiusd.conf"
1221 #endif
1222
1223 CONF_SECTION *read_radius_conf_file(void)
1224 {
1225         char buffer[256];
1226         CONF_SECTION *cs;
1227         struct stat statbuf;
1228
1229         if (stat(radius_dir, &statbuf) < 0) {
1230                 radlog(L_ERR|L_CONS, "Errors reading %s: %s",
1231                        radius_dir, strerror(errno));
1232                 return NULL;
1233         }
1234
1235         if ((statbuf.st_mode & S_IWOTH) != 0) {
1236                 radlog(L_ERR|L_CONS, "Configuration directory %s is globally writable.  Refusing to start due to insecure configuration.",
1237                        radius_dir);
1238           return NULL;
1239         }
1240
1241
1242         if (0 && (statbuf.st_mode & S_IROTH) != 0) {
1243                 radlog(L_ERR|L_CONS, "Configuration directory %s is globally readable.  Refusing to start due to insecure configuration.",
1244                        radius_dir);
1245                 return NULL;
1246         }
1247
1248         /* Lets go look for the new configuration files */
1249         snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CONFIG);
1250         if ((cs = conf_read(NULL, 0, buffer, NULL)) == NULL) {
1251                 return NULL;
1252         }
1253
1254         /*
1255          *      This allows us to figure out where, relative to
1256          *      radiusd.conf, the other configuration files exist.
1257          */
1258         cf_section_parse(cs, NULL, server_config);
1259
1260         /* Initialize the dictionary */
1261         DEBUG2("read_config_files:  reading dictionary");
1262         if (dict_init(radius_dir, RADIUS_DICTIONARY) != 0) {
1263                 radlog(L_ERR|L_CONS, "Errors reading dictionary: %s",
1264                                 librad_errstr);
1265                 cf_section_free(&cs);
1266                 return NULL;
1267         }
1268
1269         return cs;
1270 }
1271
1272
1273 /*
1274  *      Read config files.
1275  *
1276  *      This function can ONLY be called from the main server process.
1277  */
1278 int read_mainconfig(int reload)
1279 {
1280         struct rlimit core_limits;
1281         static int old_debug_level = -1;
1282         char buffer[1024];
1283         CONF_SECTION *cs, *oldcs;
1284         rad_listen_t *listener;
1285         RADCLIENT *c, *tail;
1286
1287         if (!reload) {
1288                 radlog(L_INFO, "Starting - reading configuration files ...");
1289         } else {
1290                 radlog(L_INFO, "Reloading configuration files.");
1291         }
1292
1293         /* First read radiusd.conf */
1294         DEBUG2("reread_config:  reading radiusd.conf");
1295         if ((cs = read_radius_conf_file()) == NULL) {
1296                 if (debug_flag ||
1297                     (radlog_dir == NULL)) {
1298                         radlog(L_ERR|L_CONS, "Errors reading radiusd.conf");
1299                 } else {
1300                         radlog(L_ERR|L_CONS, "Errors reading %s/radiusd.conf: For more information, please read the tail end of %s", radius_dir, mainconfig.log_file);
1301                 }
1302                 return -1;
1303         }
1304
1305         /*
1306          *      Free the old configuration items, and replace them
1307          *      with the new ones.
1308          *
1309          *      Note that where possible, we do atomic switch-overs,
1310          *      to ensure that the pointers are always valid.
1311          */
1312         oldcs = mainconfig.config;
1313         mainconfig.config = cs;
1314         cf_section_free(&oldcs);
1315
1316         /* old-style naslist file */
1317         snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_NASLIST);
1318         DEBUG2("read_config_files:  reading naslist");
1319         if (read_naslist_file(buffer) < 0) {
1320                 radlog(L_ERR|L_CONS, "Errors reading naslist");
1321                 return -1;
1322         }
1323         /* old-style clients file */
1324         snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CLIENTS);
1325         DEBUG2("read_config_files:  reading clients");
1326         if (read_clients_file(buffer) < 0) {
1327                 radlog(L_ERR|L_CONS, "Errors reading clients");
1328                 return -1;
1329         }
1330
1331         /*
1332          *      Add to that, the *new* list of clients.
1333          */
1334         snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CONFIG);
1335         c = generate_clients(buffer, mainconfig.config);
1336         if (!c) {
1337                 return -1;
1338         }
1339
1340         /*
1341          *      The new list of clients takes precedence over the old one.
1342          */
1343         for (tail = c; tail->next != NULL; tail = tail->next) {
1344           /* do nothing */
1345         }
1346         tail->next = mainconfig.clients;
1347         mainconfig.clients = c;
1348         
1349         /* old-style realms file */
1350         snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_REALMS);
1351         DEBUG2("read_config_files:  reading realms");
1352         if (read_realms_file(buffer) < 0) {
1353                 radlog(L_ERR|L_CONS, "Errors reading realms");
1354                 return -1;
1355         }
1356
1357         /*
1358          *      If there isn't any realms it isn't fatal..
1359          */
1360         snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CONFIG);
1361         if (generate_realms(buffer) < 0) {
1362                 return -1;
1363         }
1364
1365         /*
1366          *  Register the %{config:section.subsection} xlat function.
1367          */
1368         xlat_register("config", xlat_config, NULL);
1369
1370         /*
1371          *      Set the libraries debugging flag to whatever the main
1372          *      flag is.  Note that on a SIGHUP, to turn the debugging
1373          *      off, we do other magic.
1374          *
1375          *      Increase the debug level, if the configuration file
1376          *      says to, OR, if we're decreasing the debug from what it
1377          *      was before, allow that, too.
1378          */
1379         if ((mainconfig.debug_level > debug_flag) ||
1380             (mainconfig.debug_level <= old_debug_level)) {
1381           debug_flag = mainconfig.debug_level;
1382         }
1383         librad_debug = debug_flag;
1384         old_debug_level = mainconfig.debug_level;
1385
1386         /*
1387          *  Go update our behaviour, based on the configuration
1388          *  changes.
1389          */
1390
1391         /*  Get the current maximum for core files.  */
1392         if (getrlimit(RLIMIT_CORE, &core_limits) < 0) {
1393                 radlog(L_ERR|L_CONS, "Failed to get current core limit:  %s", strerror(errno));
1394                 exit(1);
1395         }
1396
1397         if (mainconfig.allow_core_dumps) {
1398                 if (setrlimit(RLIMIT_CORE, &core_limits) < 0) {
1399                         radlog(L_ERR|L_CONS, "Cannot update core dump limit: %s",
1400                                         strerror(errno));
1401                         exit(1);
1402
1403                         /*
1404                          *  If we're running as a daemon, and core
1405                          *  dumps are enabled, log that information.
1406                          */
1407                 } else if ((core_limits.rlim_cur != 0) && !debug_flag)
1408                         radlog(L_INFO|L_CONS, "Core dumps are enabled.");
1409
1410         } else if (!debug_flag) {
1411                 /*
1412                  *  Not debugging.  Set the core size to zero, to
1413                  *  prevent security breaches.  i.e. People
1414                  *  reading passwords from the 'core' file.
1415                  */
1416                 struct rlimit limits;
1417
1418                 limits.rlim_cur = 0;
1419                 limits.rlim_max = core_limits.rlim_max;
1420
1421                 if (setrlimit(RLIMIT_CORE, &limits) < 0) {
1422                         radlog(L_ERR|L_CONS, "Cannot disable core dumps: %s",
1423                                         strerror(errno));
1424                         exit(1);
1425                 }
1426         }
1427
1428         /*
1429          *      The first time around, ensure that we can write to the
1430          *      log directory.
1431          */
1432         if (!reload) {
1433                 /*
1434                  *      We need root to do mkdir() and chown(), so we
1435                  *      do this before giving up root.
1436                  */
1437                 radlogdir_iswritable(mainconfig.uid_name);
1438         }
1439         switch_users();
1440
1441 #ifdef HAVE_SYS_PRCTL_H
1442 #ifdef HAVE_PR_SET_DUMPABLE
1443         if (mainconfig.allow_core_dumps) {
1444                 if (prctl(PR_SET_DUMPABLE, 1) < 0) {
1445                         radlog(L_ERR|L_CONS,"Cannot enable core dumps: prctl(PR_SET_DUMPABLE) failed: '%s'",
1446                                strerror(errno));
1447                 }
1448         }
1449 #endif
1450 #endif
1451
1452         /*
1453          *      Sanity check the configuration for internal
1454          *      consistency.
1455          */
1456         if (mainconfig.reject_delay > mainconfig.cleanup_delay) {
1457                 mainconfig.reject_delay = mainconfig.cleanup_delay;
1458         }
1459
1460         /*
1461          *      Initialize the old "bind_address" and "port", first.
1462          */
1463         listener = NULL;
1464         if (old_listen_init(&listener) < 0) {
1465                 exit(1);
1466         }
1467
1468         /*
1469          *      Read the list of listeners.
1470          */
1471         snprintf(buffer, sizeof(buffer), "%.200s/radiusd.conf", radius_dir);
1472         if (listen_init(buffer, &listener) < 0) {
1473                 exit(1);
1474         }
1475
1476         if (!listener) {
1477                 radlog(L_ERR|L_CONS, "Server is not configured to listen on any ports.  Exiting.");
1478                 exit(1);
1479         }
1480
1481         listen_free(mainconfig.listen);
1482         mainconfig.listen = listener;
1483
1484         return 0;
1485 }
1486
1487 /*
1488  *      Free the configuration.
1489  */
1490 int free_mainconfig(void)
1491 {
1492         /*
1493          *      Clean up the configuration data
1494          *      structures.
1495          */
1496         cf_section_free(&mainconfig.config);
1497         realm_free(mainconfig.realms);
1498         clients_free(mainconfig.clients);
1499
1500         return 0;
1501 }