db8758603c8f6fbf539e7e818de1c91d817c7f41
[freeradius.git] / src / main / radiusd.c
1 /*
2  * radiusd.c    Main loop of the radius server.
3  *
4  * Version:     $Id$
5  *
6  */
7
8 /* don't look here for the version, run radiusd -v or look in version.c */
9 static const char rcsid[] =
10 "$Id$";
11
12 #include        "autoconf.h"
13
14 #include        "radiusd.h"
15
16 #include        <sys/socket.h>
17 #include        <sys/file.h>
18
19 #if HAVE_NETINET_IN_H
20 #include        <netinet/in.h>
21 #endif
22
23 #include        <stdlib.h>
24 #include        <string.h>
25 #include        <netdb.h>
26 #include        <fcntl.h>
27 #include        <ctype.h>
28
29 #if HAVE_UNISTD_H
30 #include        <unistd.h>
31 #endif
32
33 #include        <signal.h>
34
35 #if HAVE_GETOPT_H
36 #include        <getopt.h>
37 #endif
38
39 #if HAVE_SYS_SELECT_H
40 #include        <sys/select.h>
41 #endif
42
43 #if HAVE_SYSLOG_H
44 #include        <syslog.h>
45 #endif
46
47 #if HAVE_SYS_WAIT_H
48 # include <sys/wait.h>
49 #endif
50 #ifndef WEXITSTATUS
51 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
52 #endif
53 #ifndef WIFEXITED
54 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
55 #endif
56
57 #include <assert.h>
58
59 #include        "conffile.h"
60 #include        "modules.h"
61
62 #if WITH_SNMP
63 #include        "radius_snmp.h"
64 #endif
65
66 #include        <sys/resource.h>
67
68 #include        <grp.h>
69 #include        <pwd.h>
70
71 /*
72  *      Global variables.
73  */
74 const char              *progname = NULL;
75 char                    *radius_dir = NULL;
76 char                    *radacct_dir = NULL;
77 char                    *radlog_dir = NULL;
78 const char              *radlib_dir = NULL;
79 int                     log_stripped_names;
80 int                     debug_flag;
81 int                     use_dbm = FALSE;
82 uint32_t                myip = INADDR_ANY;
83 int                     log_auth_detail = FALSE;
84 int                     auth_port = 0;
85 int                     acct_port;
86 int                     proxy_port;
87 int                     proxy_retry_delay = RETRY_DELAY;
88 int                     proxy_retry_count = RETRY_COUNT;
89 int                     proxy_synchronous = TRUE;
90 int                     need_reload = FALSE;
91 struct  main_config_t   mainconfig;
92
93 static int              got_child = FALSE;
94 static int              request_list_busy = FALSE;
95 static int              authfd;
96 static int              acctfd;
97 int                     proxyfd;
98 static int              spawn_flag = TRUE;
99 static pid_t            radius_pid;
100 static struct rlimit    core_limits;
101 static int              proxy_requests = TRUE;
102
103 /*
104  *  We keep the incoming requests in an array, indexed by ID.
105  *
106  *  Each array element contains a linked list of active requests,
107  *  a count of the number of requests, and a time at which the first
108  *  request in the list must be serviced.
109  */
110 typedef struct REQUEST_LIST {
111         REQUEST         *first_request;
112         int             request_count;
113         time_t          last_cleaned_list;
114 } REQUEST_LIST;
115
116 static REQUEST_LIST     request_list[256];
117
118 /*
119  *  Configuration items.
120  */
121 static int              allow_core_dumps = FALSE;
122 static int              max_request_time = MAX_REQUEST_TIME;
123 static int              cleanup_delay = CLEANUP_DELAY;
124 static int              max_requests = MAX_REQUESTS;
125 static int              dont_fork = FALSE;
126 static const char       *pid_file = NULL;
127 static uid_t            server_uid;
128 static gid_t            server_gid;
129 static const char       *uid_name = NULL;
130 static const char       *gid_name = NULL;
131
132 #if !defined(__linux__) && !defined(__GNU_LIBRARY__)
133 extern int      errno;
134 #endif
135
136 static void     usage(void);
137
138 static void     sig_fatal (int);
139 static void     sig_hup (int);
140
141 static void     rad_reject(REQUEST *request);
142 static int      rad_process (REQUEST *, int);
143 static int      rad_clean_list(time_t curtime);
144 static REQUEST  *rad_check_list(REQUEST *);
145 static REQUEST *proxy_check_list(REQUEST *request);
146 static struct timeval *setuptimeout();
147 static void     refresh_request(REQUEST *request, time_t now);
148 #ifndef WITH_THREAD_POOL
149 static int      rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
150 #else
151 extern int      rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
152 #endif
153
154 /*
155  *      A mapping of configuration file names to internal variables
156  */
157 static CONF_PARSER server_config[] = {
158   { "max_request_time",   PW_TYPE_INTEGER,
159     &max_request_time,    Stringify(MAX_REQUEST_TIME) },
160   { "cleanup_delay",      PW_TYPE_INTEGER,
161     &cleanup_delay,       Stringify(CLEANUP_DELAY) },
162   { "max_requests",       PW_TYPE_INTEGER,
163     &max_requests,        Stringify(MAX_REQUESTS) },
164   { "port",               PW_TYPE_INTEGER,
165     &auth_port,           Stringify(PW_AUTH_UDP_PORT) },
166   { "allow_core_dumps",   PW_TYPE_BOOLEAN,    &allow_core_dumps,  "no" },
167   { "log_stripped_names", PW_TYPE_BOOLEAN,    &log_stripped_names,"no" },
168   { "log_auth",           PW_TYPE_BOOLEAN,    &mainconfig.log_auth,   "no" },
169   { "log_auth_badpass",   PW_TYPE_BOOLEAN,    &mainconfig.log_auth_badpass,  "no" },
170   { "log_auth_goodpass",  PW_TYPE_BOOLEAN,    &mainconfig.log_auth_goodpass, "no" },
171   { "pidfile",            PW_TYPE_STRING_PTR, &pid_file,          "${run_dir}/radiusd.pid"},
172   { "bind_address",       PW_TYPE_IPADDR,     &myip,              "*" },
173   { "proxy_requests",     PW_TYPE_BOOLEAN,    &proxy_requests,    "yes" },
174   { "user",           PW_TYPE_STRING_PTR, &uid_name,  NULL},
175   { "group",          PW_TYPE_STRING_PTR, &gid_name,  NULL},
176   { "usercollide",    PW_TYPE_BOOLEAN,    &mainconfig.do_usercollide, "no" },
177   { "lower_user",     PW_TYPE_BOOLEAN,    &mainconfig.do_lower_user, "no" },
178   { "lower_pass",     PW_TYPE_BOOLEAN,    &mainconfig.do_lower_pass, "no" },
179   { "lower_time",     PW_TYPE_STRING_PTR, &mainconfig.lower_time, "before" },
180   { "nospace_user",   PW_TYPE_BOOLEAN,    &mainconfig.do_nospace_user, "no" },
181   { "nospace_pass",   PW_TYPE_BOOLEAN,    &mainconfig.do_nospace_pass, "no" },
182   { "nospace_time",   PW_TYPE_STRING_PTR, &mainconfig.nospace_time, "before" },
183   { NULL, -1, NULL, NULL }
184 };
185
186 /*
187  *      Map the proxy server configuration parameters to variables.
188  */
189 static CONF_PARSER proxy_config[] = {
190   { "retry_delay",  PW_TYPE_INTEGER,
191     &proxy_retry_delay, Stringify(RETRY_DELAY) },
192   { "retry_count",  PW_TYPE_INTEGER,
193     &proxy_retry_count, Stringify(RETRY_COUNT) },
194   { "synchronous",  PW_TYPE_BOOLEAN, &proxy_synchronous, "yes" },
195
196   { NULL, -1, NULL, NULL }
197 };
198
199 /*
200  *      Read config files.
201  */
202 static int reread_config(int reload)
203 {
204         int pid = getpid();
205         CONF_SECTION *cs;
206
207         if (!reload) {
208                 radlog(L_INFO, "Starting - reading configuration files ...");
209         } else if (pid == radius_pid) {
210                 radlog(L_INFO, "Reloading configuration files.");
211         }
212
213         /* First read radiusd.conf */
214         DEBUG2("reread_config:  reading radiusd.conf");
215         if (read_radius_conf_file() < 0) {
216                 radlog(L_ERR|L_CONS, "Errors reading radiusd.conf");
217                 return -1;
218         }
219
220         /*
221          *      And parse the server's configuration values.
222          */
223         cs = cf_section_find(NULL);
224         if (!cs) {
225                 radlog(L_ERR|L_CONS, "No configuration information in radiusd.conf!");
226                 return -1;
227         }
228         cf_section_parse(cs, server_config);
229
230         /*
231          *      Reload the modules.
232          */
233         DEBUG2("read_config_files:  entering modules setup");
234         if (setup_modules() < 0) {
235                 radlog(L_ERR|L_CONS, "Errors setting up modules");
236                 return -1;
237         }
238
239         /*
240          *      Go update our behaviour, based on the configuration
241          *      changes.
242          */
243         if (allow_core_dumps) {
244                 if (setrlimit(RLIMIT_CORE, &core_limits) < 0) {
245                         radlog(L_ERR|L_CONS, "Cannot update core dump limit: %s",
246                             strerror(errno));
247                         exit(1);
248
249                         /*
250                          *      If we're running as a daemon, and core
251                          *      dumps are enabled, log that information.
252                          */
253                 } else if ((core_limits.rlim_cur != 0) && !debug_flag)
254                   radlog(L_INFO, "Core dumps are enabled.");
255
256         } else if (!debug_flag) {
257                 /*
258                  *      Not debugging.  Set the core size to zero, to
259                  *      prevent security breaches.  i.e. People
260                  *      reading passwords from the 'core' file.
261                  */
262                 struct rlimit limits;
263
264                 limits.rlim_cur = 0;
265                 limits.rlim_max = core_limits.rlim_max;
266                 
267                 if (setrlimit(RLIMIT_CORE, &limits) < 0) {
268                         radlog(L_ERR|L_CONS, "Cannot disable core dumps: %s",
269                             strerror(errno));
270                         exit(1);
271                 }
272         }
273
274         /*
275          *      Set the UID and GID, but only if we're NOT running
276          *      in debugging mode.
277          */
278         if (!debug_flag) {
279                 /*
280                  *      Set group.
281                  */
282                 if (gid_name) {
283                         struct group *gr;
284
285                         gr = getgrnam(gid_name);
286                         if (!gr) {
287                                 radlog(L_ERR|L_CONS, "Cannot switch to Group %s: %s", gid_name, strerror(errno));
288                                 exit(1);
289                         }
290                         server_gid = gr->gr_gid;
291                         if (setgid(server_gid) < 0) {
292                                 radlog(L_ERR|L_CONS, "Failed setting Group to %s: %s", gid_name, strerror(errno));
293                                 exit(1);
294                         }
295                 }
296
297                 /*
298                  *      Set UID.
299                  */
300                 if (uid_name) {
301                         struct passwd *pw;
302
303                         pw = getpwnam(uid_name);
304                         if (!pw) {
305                                 radlog(L_ERR|L_CONS, "Cannot switch to User %s: %s", uid_name, strerror(errno));
306                                 exit(1);
307                         }
308                         server_uid = pw->pw_uid;
309                         if (setuid(server_uid) < 0) {
310                                 radlog(L_ERR|L_CONS, "Failed setting User to %s: %s", uid_name, strerror(errno));
311                                 exit(1);
312                         }
313                 }
314         }
315
316
317         /*
318          *      Parse the server's proxy configuration values.
319          */
320         if ((proxy_requests) &&
321             ((cs = cf_section_find("proxy")) != NULL)) {
322                 cf_section_parse(cs, proxy_config);
323         }
324
325         return 0;
326 }
327
328 /*
329  *      Parse a string into a syslog facility level.
330  */
331 static int str2fac(const char *s)
332 {
333 #ifdef LOG_KERN
334         if(!strcmp(s, "kern"))
335                 return LOG_KERN;
336         else
337 #endif
338 #ifdef LOG_USER
339         if(!strcmp(s, "user"))
340                 return LOG_USER;
341         else
342 #endif
343 #ifdef LOG_MAIL
344         if(!strcmp(s, "mail"))
345                 return LOG_MAIL;
346         else
347 #endif
348 #ifdef LOG_DAEMON
349         if(!strcmp(s, "daemon"))
350                 return LOG_DAEMON;
351         else
352 #endif
353 #ifdef LOG_AUTH
354         if(!strcmp(s, "auth"))
355                 return LOG_AUTH;
356         else
357 #endif
358 #ifdef LOG_SYSLOG
359         if(!strcmp(s, "auth"))
360                 return LOG_AUTH;
361         else
362 #endif
363 #ifdef LOG_LPR
364         if(!strcmp(s, "lpr"))
365                 return LOG_LPR;
366         else
367 #endif
368 #ifdef LOG_NEWS
369         if(!strcmp(s, "news"))
370                 return LOG_NEWS;
371         else
372 #endif
373 #ifdef LOG_UUCP
374         if(!strcmp(s, "uucp"))
375                 return LOG_UUCP;
376         else
377 #endif
378 #ifdef LOG_CRON
379         if(!strcmp(s, "cron"))
380                 return LOG_CRON;
381         else
382 #endif
383 #ifdef LOG_AUTHPRIV
384         if(!strcmp(s, "authpriv"))
385                 return LOG_AUTHPRIV;
386         else
387 #endif
388 #ifdef LOG_FTP
389         if(!strcmp(s, "ftp"))
390                 return LOG_FTP;
391         else
392 #endif
393 #ifdef LOG_LOCAL0
394         if(!strcmp(s, "local0"))
395                 return LOG_LOCAL0;
396         else
397 #endif
398 #ifdef LOG_LOCAL1
399         if(!strcmp(s, "local1"))
400                 return LOG_LOCAL1;
401         else
402 #endif
403 #ifdef LOG_LOCAL2
404         if(!strcmp(s, "local2"))
405                 return LOG_LOCAL2;
406         else
407 #endif
408 #ifdef LOG_LOCAL3
409         if(!strcmp(s, "local3"))
410                 return LOG_LOCAL3;
411         else
412 #endif
413 #ifdef LOG_LOCAL4
414         if(!strcmp(s, "local4"))
415                 return LOG_LOCAL4;
416         else
417 #endif
418 #ifdef LOG_LOCAL5
419         if(!strcmp(s, "local5"))
420                 return LOG_LOCAL5;
421         else
422 #endif
423 #ifdef LOG_LOCAL6
424         if(!strcmp(s, "local6"))
425                 return LOG_LOCAL6;
426         else
427 #endif
428 #ifdef LOG_LOCAL7
429         if(!strcmp(s, "local7"))
430                 return LOG_LOCAL7;
431         else
432 #endif
433         {
434                 fprintf(stderr, "%s: Error: Unknown syslog facility: %s\n",
435                         progname, s);
436                 exit(1);
437         }
438         
439         /* this should never be reached */
440         return LOG_DAEMON;
441 }
442
443 int main(int argc, char **argv)
444 {
445         REQUEST                 *request;
446         RADIUS_PACKET           *packet;
447         u_char                  *secret;
448         unsigned char           buffer[4096];
449         struct  sockaddr        salocal;
450         struct  sockaddr_in     *sa;
451         fd_set                  readfds;
452         int                     result;
453         int                     argval;
454         int                     t;
455         int                     pid;
456         int                     i;
457         int                     fd = 0;
458         int                     devnull;
459         int                     status;
460         int                     syslog_facility = LOG_DAEMON;
461         int                     radius_port = 0;
462         struct servent          *svp;
463  
464 #ifdef OSFC2
465         set_auth_parameters(argc,argv);
466 #endif
467
468         /*
469          *      Open /dev/null, and make sure filedescriptors
470          *      0, 1 and 2 are connected to something.
471          */
472         devnull = 0;
473         while (devnull >= 0 && devnull < 3)
474                 devnull = open("/dev/null", O_RDWR);
475
476         if ((progname = strrchr(argv[0], '/')) == NULL)
477                 progname = argv[0];
478         else
479                 progname++;
480
481         debug_flag = 0;
482         spawn_flag = TRUE;
483         radius_dir = strdup(RADIUS_DIR);
484
485         signal(SIGHUP, sig_hup);
486         signal(SIGINT, sig_fatal);
487         signal(SIGQUIT, sig_fatal);
488 #if WITH_SNMP
489         signal(SIGPIPE, SIG_IGN);
490 #endif
491 #ifdef SIGTRAP
492         signal(SIGTRAP, sig_fatal);
493 #endif
494 #ifdef SIGIOT
495         signal(SIGIOT, sig_fatal);
496 #endif
497
498         /*
499          *      Pooled threads and child threads define their own
500          *      signal handler.
501          */
502 #ifndef WITH_THREAD_POOL
503 #ifndef HAVE_PTHREAD_H
504         signal(SIGTERM, sig_fatal);
505 #endif
506 #endif
507         signal(SIGCHLD, sig_cleanup);
508 #if 0
509         signal(SIGFPE, sig_fatal);
510         signal(SIGSEGV, sig_fatal);
511         signal(SIGILL, sig_fatal);
512 #endif
513
514         /*
515          *      Close unused file descriptors.
516          */
517         for (t = 32; t >= 3; t--)
518             if(t!=devnull) close(t);
519
520         /*
521          *      Process the options.
522          */
523         while((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:p:sSvxXyz")) != EOF) {
524
525                 switch(argval) {
526
527                 case 'A':
528                         log_auth_detail = TRUE;
529                         break;
530
531                 case 'a':
532                         if (radacct_dir) free(radacct_dir);
533                         radacct_dir = strdup(optarg);
534                         break;
535                 
536 #if defined(WITH_DBM) || defined(WITH_NDBM)
537                 case 'b':
538                         use_dbm++;
539                         break;
540 #endif
541                 case 'c':
542                         /* ignore for backwards compatibility with Cistron */
543                         break;
544
545                 case 'd':
546                         if (radius_dir) free(radius_dir);
547                         radius_dir = strdup(optarg);
548                         break;
549                 
550                 case 'f':
551                         dont_fork = TRUE;
552                         break;
553
554                 case 'h':
555                         usage();
556                         break;
557
558                 case 'i':
559                         if ((myip = ip_getaddr(optarg)) == INADDR_NONE) {
560                                 fprintf(stderr, "radiusd: %s: host unknown\n",
561                                         optarg);
562                                 exit(1);
563                         }
564                         break;
565                 
566                 case 'l':
567                         if (radlog_dir) free(radlog_dir);
568                         radlog_dir = strdup(optarg);
569                         break;
570                 
571                         /*
572                          *      We should also have this as a configuration
573                          *      file directive.
574                          */
575                 case 'g':
576                         syslog_facility = str2fac(optarg);
577                         break;
578
579                 case 'S':
580                         log_stripped_names++;
581                         break;
582
583                 case 'p':
584                         radius_port = atoi(optarg);
585                         break;
586
587                 case 's':       /* Single process mode */
588                         spawn_flag = FALSE;
589                         break;
590
591                 case 'v':
592                         version();
593                         break;
594
595                         /*
596                          *  BIG debugging mode for users who are
597                          *  TOO LAZY to type '-sfxxyz -l stdout' themselves.
598                          */
599                 case 'X':
600                         spawn_flag = FALSE;
601                         dont_fork = TRUE;
602                         debug_flag = 2;
603                         librad_debug = 2;
604                         mainconfig.log_auth = TRUE;
605                         mainconfig.log_auth_badpass = TRUE;
606                         mainconfig.log_auth_goodpass = TRUE;
607                         radlog_dir = strdup("stdout");
608                         break;
609
610                 case 'x':
611                         debug_flag++;
612                         librad_debug++;
613                         break;
614                 
615                 case 'y':
616                         mainconfig.log_auth = TRUE;
617                         mainconfig.log_auth_badpass = TRUE;
618                         break;
619
620                 case 'z':
621                         mainconfig.log_auth_badpass = TRUE;
622                         mainconfig.log_auth_goodpass = TRUE;
623                         break;
624
625                 default:
626                         usage();
627                         break;
628                 }
629         }
630
631         /*
632          *      Get out PID: the configuration file reader uses it.
633          */
634         radius_pid = getpid();
635
636         /*
637          *      Get the current maximum for core files.
638          */
639         if (getrlimit(RLIMIT_CORE, &core_limits) < 0) {
640                 radlog(L_ERR|L_CONS, "Failed to get current core limit:"
641                     "  %s", strerror(errno));
642                 exit(1);
643         }
644
645         /*
646          *      Read the configuration files, BEFORE doing anything else.
647          */
648         if (reread_config(0) < 0) {
649                 exit(1);
650         }
651
652 #if HAVE_SYSLOG_H
653         /*
654          *      If they asked for syslog, then give it to them.
655          *      Also, initialize the logging facility with the
656          *      configuration that they asked for.
657          */
658         if (!strcmp(radlog_dir, "syslog")) {
659                 openlog(progname, LOG_PID, syslog_facility);
660         }
661         /* Do you want a warning if -g is used without a -l to activate it? */
662 #endif
663
664         /*
665          *      Initialize the request_list[] array.
666          */
667         for (i = 0; i < 256; i++) {
668           request_list[i].first_request = NULL;
669           request_list[i].request_count = 0;
670           request_list[i].last_cleaned_list = 0;
671         }
672
673         /*
674          *      We prefer (in order) the port from the command-line,
675          *      then the port from the configuration file, then
676          *      the port that the system names "radius", then
677          *      1645.
678          */
679         if (radius_port) {
680                 auth_port = radius_port;
681         } /* else auth_port is set from the config file */
682         
683         /*
684          *      Maybe auth_port *wasn't* set from the config file,
685          *      or the config file set it to zero.
686          */
687         acct_port = 0;
688         if (auth_port == 0) {
689                 svp = getservbyname ("radius", "udp");
690                 if (svp != NULL) {
691                         auth_port = ntohs(svp->s_port);
692
693                         /*
694                          *      We're getting auth_port from
695                          *      /etc/services, get acct_port from
696                          *      there, too.
697                          */
698                         svp = getservbyname ("radacct", "udp");
699                         if (svp) acct_port = ntohs(svp->s_port);
700                 } else {
701                         auth_port = PW_AUTH_UDP_PORT;
702                 }
703         }
704
705         /*
706          *      Open Authentication socket.
707          *
708          */
709         authfd = socket (AF_INET, SOCK_DGRAM, 0);
710         if (authfd < 0) {
711                 perror("auth socket");
712                 exit(1);
713         }
714
715         sa = (struct sockaddr_in *) & salocal;
716         memset ((char *) sa, '\0', sizeof (salocal));
717         sa->sin_family = AF_INET;
718         sa->sin_addr.s_addr = myip;
719         sa->sin_port = htons(auth_port);
720
721         result = bind (authfd, & salocal, sizeof (*sa));
722         if (result < 0) {
723                 perror ("auth bind");
724                 exit(1);
725         }
726
727         /*
728          *      Open Accounting Socket.
729          *
730          *      If we haven't already gotten acct_port from /etc/services,
731          *      then make it auth_port + 1.
732          */
733         if (!acct_port) 
734                 acct_port = auth_port + 1;
735         
736         acctfd = socket (AF_INET, SOCK_DGRAM, 0);
737         if (acctfd < 0) {
738                 perror ("acct socket");
739                 exit(1);
740         }
741
742         sa = (struct sockaddr_in *) & salocal;
743         memset ((char *) sa, '\0', sizeof (salocal));
744         sa->sin_family = AF_INET;
745         sa->sin_addr.s_addr = myip;
746         sa->sin_port = htons(acct_port);
747
748         result = bind (acctfd, & salocal, sizeof (*sa));
749         if (result < 0) {
750                 perror ("acct bind");
751                 exit(1);
752         }
753
754         /*
755          *      If we're proxying requests, open the proxy FD.
756          *      Otherwise, don't do anything.
757          */
758         if (proxy_requests) {
759                 /*
760                  *      Open Proxy Socket.
761                  */
762                 proxyfd = socket (AF_INET, SOCK_DGRAM, 0);
763                 if (proxyfd < 0) {
764                         perror ("proxy socket");
765                         exit(1);
766                 }
767                 
768                 sa = (struct sockaddr_in *) & salocal;
769                 memset ((char *) sa, '\0', sizeof (salocal));
770                 sa->sin_family = AF_INET;
771                 sa->sin_addr.s_addr = myip;
772                 
773                 /*
774                  *      Set the proxy port to be one more than the
775                  *      accounting port.
776                  */
777                 for (proxy_port = acct_port + 1; proxy_port < 64000; proxy_port++) {
778                         sa->sin_port = htons(proxy_port);
779                         result = bind (proxyfd, & salocal, sizeof (*sa));
780                         if (result == 0) {
781                                 break;
782                         }
783                 }
784                 
785                 /*
786                  *      Couldn't find a port to which we could bind.
787                  */
788                 if (proxy_port == 64000) {
789                         perror("proxy bind");
790                         exit(1);
791                 }
792
793         } else {
794                 /*
795                  *      NOT proxying requests, set the FD to a bad value.
796                  */
797                 proxyfd = -1;
798                 proxy_port = 0;
799         }
800
801         /*
802          *      Register built-in compare functions.
803          */
804         pair_builtincompare_init();
805
806 #if WITH_SNMP
807         radius_snmp_init();
808 #endif
809
810 #if 0
811         /*
812          *      Connect 0, 1 and 2 to /dev/null.
813          */
814         if (!debug_flag && devnull >= 0) {
815                 dup2(devnull, 0);
816                 if (strcmp(radlog_dir, "stdout") != 0) {
817                   dup2(devnull, 1);
818                 }
819                 dup2(devnull, 2);
820                 if (devnull > 2) close(devnull);
821         }
822 #endif
823
824         /*
825          *      Disconnect from session
826          */
827         if (debug_flag == 0 && dont_fork == 0) {
828                 pid = fork();
829                 if(pid < 0) {
830                         radlog(L_ERR|L_CONS, "Couldn't fork");
831                         exit(1);
832                 }
833
834                 /*
835                  *  The parent exits, so the child can run in the background.
836                  */
837                 if(pid > 0) {
838                         exit(0);
839                 }
840 #if HAVE_SETSID
841                 setsid();
842 #endif
843         }
844
845         /*
846          *      Ensure that we're using the CORRECT pid after forking,
847          *      NOT the one we started with.
848          */
849         radius_pid = getpid();
850
851         /*
852          *      Only write the PID file if we're running as a daemon.
853          *
854          *      And write it AFTER we've forked, so that we write the
855          *      correct PID.
856          */
857         if (dont_fork == FALSE) {
858                 FILE *fp;
859
860                 fp = fopen(pid_file, "w");
861                 if (fp != NULL) {
862                         fprintf(fp, "%d\n", (int) radius_pid);
863                         fclose(fp);
864                 } else {
865                         radlog(L_ERR|L_CONS, "Failed writing process id to file %s: %s\n",
866                             pid_file, strerror(errno));
867                 }
868         }
869
870 #if WITH_THREAD_POOL
871         /*
872          *      If we're spawning children, set up the thread pool.
873          */
874         if (spawn_flag) {
875                 thread_pool_init();
876         }
877 #endif
878
879         /*
880          *      Use linebuffered or unbuffered stdout if
881          *      the debug flag is on.
882          */
883         if (debug_flag) setlinebuf(stdout);
884
885         if (myip == 0) {
886                 strcpy((char *)buffer, "*");
887         } else {
888                 ip_ntoa((char *)buffer, myip);
889         }
890
891         if (proxy_requests) {
892                 radlog(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp, with proxy on %d/udp.",
893                     buffer, auth_port, acct_port, proxy_port);
894         } else {
895                 radlog(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp.",
896                     buffer, auth_port, acct_port);
897         }
898
899         /*
900          *      Note that we NO LONGER fork an accounting process!
901          *      We used to do it for historical reasons, but that
902          *      is no excuse...
903          */
904         radlog(L_INFO, "Ready to process requests.");
905
906         /*
907          *      Receive user requests
908          */
909         for(;;) {
910                 time_t now;
911
912                 if (need_reload) {
913                         if (reread_config(TRUE) < 0) {
914                                 exit(1);
915                         }
916                         need_reload = FALSE;
917                         radlog(L_INFO, "Ready to process requests.");
918                 }
919
920                 FD_ZERO(&readfds);
921                 if (authfd >= 0)
922                         FD_SET(authfd, &readfds);
923                 if (acctfd >= 0)
924                         FD_SET(acctfd, &readfds);
925                 if (proxyfd >= 0)
926                         FD_SET(proxyfd, &readfds);
927 #ifdef WITH_SNMP
928                 if (rad_snmp.smux_fd >= 0)
929                         FD_SET(rad_snmp.smux_fd, &readfds);
930 #endif
931
932                 status = select(32, &readfds, NULL, NULL,
933                                 setuptimeout());
934                 now = time(NULL);
935                 if (status == -1) {
936                         /*
937                          *      On interrupts, we clean up the
938                          *      request list.
939                          */
940                         if (errno == EINTR) {
941                                 rad_clean_list(now);
942                                 continue;
943                         }
944                         radlog(L_ERR, "Unexpected error in select(): %s",
945                             strerror(errno));
946                         sig_fatal(101);
947                 }
948
949                 /*
950                  *      Loop over the open socket FD's, reading any data.
951                  */
952                 for (i = 0; i < 3; i++) {
953
954                         if (i == 0) fd = authfd;
955                         if (i == 1) fd = acctfd;
956                         if (i == 2) fd = proxyfd;
957                         if (fd < 0 || !FD_ISSET(fd, &readfds))
958                                 continue;
959                         /*
960                          *      Receive the packet.
961                          */
962                         packet = rad_recv(fd);
963                         if (packet == NULL) {
964                                 radlog(L_ERR, "%s", librad_errstr);
965                                 continue;
966                         }
967 #if WITH_SNMP
968                         if (fd == acctfd)
969                                 rad_snmp.acct_total_requests++;
970                         if (fd == authfd)
971                                 rad_snmp.auth_total_requests++;
972 #endif
973
974                         /*
975                          *      Check if we know this client for
976                          *      authfd and acctfd.  Check if we know
977                          *      this proxy for proxyfd.
978                          */
979                         if(fd != proxyfd) {
980                                 RADCLIENT    *cl;
981                                 if ((cl = client_find(packet->src_ipaddr)) == NULL) {
982                                       radlog(L_ERR, "Ignoring request from unknown client %s:%d",
983                                         ip_ntoa(buffer, packet->src_ipaddr),
984                                         packet->src_port);
985                                       rad_free(packet);
986                                       continue;
987                                 } else {
988                                       secret = cl->secret;
989                                 }
990                                 
991                         } else {    /* It came in on the proxy port */
992                                 REALM         *rl;
993                                 if ((rl = realm_findbyaddr(packet->src_ipaddr)) == NULL) {
994                                       radlog(L_ERR, "Ignoring request from unknown proxy %s:%d",
995                                         ip_ntoa(buffer, packet->src_ipaddr),
996                                         packet->src_port);
997                                       rad_free(packet);
998                                       continue;
999                                 } else {
1000                                       secret = rl->secret;
1001                                 }
1002                         }      
1003
1004                         /*
1005                          *      Do yet another check, to see if the
1006                          *      packet code is valid.  We only understand
1007                          *      a few, so stripping off obviously invalid
1008                          *      packets here will make our life easier.
1009                          */
1010                         if (packet->code > PW_ACCESS_CHALLENGE) {
1011                                 radlog(L_ERR, "Ignoring request from client %s:%d with unknown code %d", buffer, packet->src_port, packet->code);
1012                                 rad_free(packet);
1013                                 continue;
1014                         }
1015
1016                         if ((request = malloc(sizeof(REQUEST))) == NULL) {
1017                                 radlog(L_ERR|L_CONS, "no memory");
1018                                 exit(1);
1019                         }
1020                         memset(request, 0, sizeof(REQUEST));
1021 #ifndef NDEBUG
1022                         request->magic = REQUEST_MAGIC;
1023 #endif
1024                         request->packet = packet;
1025                         request->proxy = NULL;
1026                         request->reply = NULL;
1027                         request->proxy_reply = NULL;
1028                         request->config_items = NULL;
1029                         request->username = NULL;
1030                         request->password = NULL;
1031                         request->timestamp = now;
1032                         request->child_pid = NO_SUCH_CHILD_PID;
1033                         request->prev = NULL;
1034                         request->next = NULL;
1035                         strNcpy(request->secret, (char *)secret, sizeof(request->secret));
1036                         rad_process(request, spawn_flag);
1037                 } /* loop over authfd, acctfd, proxyfd */
1038
1039                 /*
1040                  *      After processing all new requests,
1041                  *      check if we've got to delete old requests
1042                  *      from the request list.
1043                  */
1044                 rad_clean_list(now);
1045
1046                 /*
1047                  *      When receiving a packet, or timeout,
1048                  *      service the proxy request list.
1049                  */
1050
1051 #if WITH_SNMP
1052                 /*
1053                  *      After handling all authentication/accounting
1054                  *      requests, THEN process any pending SMUX/SNMP
1055                  *      queries.
1056                  *
1057                  *      Note that the handling is done in the main server,
1058                  *      which probably isn't a Good Thing.  It really
1059                  *      should be wrapped, and handled in a thread pool.
1060                  */
1061                 if ((rad_snmp.smux_fd >= 0) &&
1062                     FD_ISSET(rad_snmp.smux_fd, &readfds) &&
1063                     (rad_snmp.smux_event == SMUX_READ)) {
1064                   smux_read();
1065                 }
1066                 
1067                 /*
1068                  *      If we've got to re-connect, then do so now,
1069                  *      before calling select again.
1070                  */
1071                 if (rad_snmp.smux_event == SMUX_CONNECT) {
1072                   smux_connect();
1073                 }
1074 #endif
1075         } /* loop forever */
1076 }
1077
1078
1079 /*
1080  *      Process supported requests:
1081  *
1082  *              PW_AUTHENTICATION_REQUEST - Authentication request from
1083  *                              a client network access server.
1084  *
1085  *              PW_ACCOUNTING_REQUEST - Accounting request from
1086  *                              a client network access server.
1087  *
1088  *              PW_AUTHENTICATION_ACK
1089  *              PW_AUTHENTICATION_REJECT
1090  *              PW_ACCOUNTING_RESPONSE - Reply from a remote Radius server.
1091  *                              Relay reply back to original NAS.
1092  *
1093  */
1094 int rad_process(REQUEST *request, int dospawn)
1095 {
1096         RAD_REQUEST_FUNP fun;
1097
1098         fun = NULL;
1099
1100         assert(request->magic == REQUEST_MAGIC);
1101
1102         switch(request->packet->code) {
1103
1104         case PW_AUTHENTICATION_REQUEST:
1105                 /*
1106                  *      Check for requests sent to the wrong port,
1107                  *      and ignore them, if so.
1108                  */
1109                 if (request->packet->sockfd != authfd) {
1110                   radlog(L_ERR, "Request packet code %d sent to authentication port from "
1111                       "client %s:%d - ID %d : IGNORED",
1112                       request->packet->code,
1113                       client_name(request->packet->src_ipaddr),
1114                       request->packet->src_port,
1115                       request->packet->id);
1116                   request_free(request);
1117                   return -1;
1118                 }
1119                 break;
1120
1121         case PW_ACCOUNTING_REQUEST:
1122                 /*
1123                  *      Check for requests sent to the wrong port,
1124                  *      and ignore them, if so.
1125                  */
1126                 if (request->packet->sockfd != acctfd) {
1127                   radlog(L_ERR, "Request packet code %d sent to accounting port from "
1128                       "client %s:%d - ID %d : IGNORED",
1129                       request->packet->code,
1130                       client_name(request->packet->src_ipaddr),
1131                       request->packet->src_port,
1132                       request->packet->id);
1133                   request_free(request);
1134                   return -1;
1135                 }
1136                 break;
1137
1138         case PW_AUTHENTICATION_ACK:
1139         case PW_AUTHENTICATION_REJECT:
1140         case PW_ACCOUNTING_RESPONSE:
1141                 /*
1142                  *      Replies NOT sent to the proxy port get an
1143                  *      error message logged, and the packet is
1144                  *      dropped.
1145                  */
1146                 if (request->packet->sockfd != proxyfd) {
1147                         radlog(L_ERR, "Reply packet code %d sent to request port from "
1148                             "client %s:%d - ID %d : IGNORED",
1149                             request->packet->code,
1150                             client_name(request->packet->src_ipaddr),
1151                             request->packet->src_port,
1152                             request->packet->id);
1153                         request_free(request);
1154                         return -1;
1155                 }
1156                 break;
1157         }
1158
1159         assert(request->magic == REQUEST_MAGIC);
1160
1161         /*
1162          *      Select the required function and indicate if
1163          *      we need to fork off a child to handle it.
1164          */
1165         switch(request->packet->code) {
1166
1167         case PW_AUTHENTICATION_ACK:
1168         case PW_AUTHENTICATION_REJECT:
1169         case PW_AUTHENTICATION_REQUEST:
1170                 fun = rad_authenticate;
1171                 break;
1172         
1173         case PW_ACCOUNTING_RESPONSE:
1174         case PW_ACCOUNTING_REQUEST:
1175                 fun = rad_accounting;
1176                 break;
1177         
1178         case PW_PASSWORD_REQUEST:
1179                 /*
1180                  *      We don't support this anymore.
1181                  */
1182                 radlog(L_ERR, "Deprecated password change request from client %s:%d "
1183                     "- ID %d : IGNORED",
1184                     client_name(request->packet->src_ipaddr),
1185                     request->packet->src_port,
1186                     request->packet->id);
1187                 request_free(request);
1188                 return -1;
1189                 break;
1190         
1191         default:
1192                 radlog(L_ERR, "Unknown packet type %d from client %s:%d "
1193                     "- ID %d : IGNORED",
1194                     request->packet->code,
1195                     client_name(request->packet->src_ipaddr),
1196                     request->packet->src_port,
1197                     request->packet->id);
1198                 request_free(request);
1199                 return -1;
1200                 break;
1201         }
1202
1203         /*
1204          *      If we did NOT select a function, then exit immediately.
1205          */
1206         if (!fun) {
1207                 request_free(request);
1208                 return 0;
1209         }
1210
1211         /*
1212          *      Check for a duplicate, or error.
1213          *      Throw away the the request if so.
1214          */
1215         request = rad_check_list(request);
1216         if (request == NULL) {
1217                 return 0;
1218         }
1219         
1220         assert(request->magic == REQUEST_MAGIC);
1221
1222         /*
1223          *      The request passes many of our sanity checks.  From
1224          *      here on in, if anything goes wrong, we send a reject
1225          *      message, instead of dropping the packet.
1226          *
1227          *      Build the reply template from the request template.
1228          */
1229         if ((request->reply = rad_alloc(0)) == NULL) {
1230                 fprintf(stderr, "out of memory\n");
1231                 exit(1);
1232         }
1233         request->reply->sockfd     = request->packet->sockfd;
1234         request->reply->dst_ipaddr = request->packet->src_ipaddr;
1235         request->reply->dst_port   = request->packet->src_port;
1236         request->reply->id         = request->packet->id;
1237         request->reply->code       = 0; /* UNKNOWN code */
1238         memcpy(request->reply->vector, request->packet->vector,
1239                sizeof(request->reply->vector));
1240         request->reply->vps = NULL;
1241         request->reply->data = NULL;
1242         
1243         /*
1244          *      If we're spawning a child thread, let it do all of
1245          *      the work of handling a request, and exit.
1246          */
1247         if (dospawn) {
1248                 /*
1249                  *      Maybe the spawn failed.  If so, then we
1250                  *      trivially reject the request (because we can't
1251                  *      handle it), and return.
1252                  */
1253                 if (rad_spawn_child(request, fun) < 0) {
1254                         rad_reject(request);
1255                         request->finished = TRUE;
1256                 }
1257                 return 0;
1258         }
1259
1260         rad_respond(request, fun);
1261         return 0;
1262 }
1263
1264 /*
1265  *      Reject a request, by sending a trivial reply packet.
1266  */
1267 static void rad_reject(REQUEST *request)
1268 {
1269         VALUE_PAIR *vps;
1270         
1271         DEBUG2("Server rejecting request.");
1272         switch (request->packet->code) {
1273                 /*
1274                  *      Accounting requests, etc. get dropped on the floor.
1275                  */
1276         case PW_ACCOUNTING_REQUEST:
1277         default:
1278                 break;
1279
1280                 /*
1281                  *      Authentication requests get their Proxy-State
1282                  *      attributes copied over, and an otherwise blank
1283                  *      reject message sent.
1284                  */
1285         case PW_AUTHENTICATION_REQUEST:
1286                 request->reply->code = PW_AUTHENTICATION_REJECT; 
1287
1288                 /*
1289                  *      Need to copy Proxy-State from request->packet->vps
1290                  */
1291                 vps = paircopy2(request->packet->vps, PW_PROXY_STATE);
1292                 if (vps != NULL)
1293                         pairadd(&(request->reply->vps), vps);
1294                 break;
1295         }
1296         
1297         /*
1298          *      If a reply exists, send it.
1299          */
1300         if (request->reply->code) {
1301                 rad_send(request->reply, request->secret);
1302         }
1303 }
1304
1305 /*
1306  *      Perform any RFC specified cleaning of outgoing replies
1307  */
1308 static void rfc_clean(RADIUS_PACKET *packet)
1309 {
1310         VALUE_PAIR *vps = NULL;
1311         
1312         switch (packet->code) {
1313         default:
1314                 break;
1315                 
1316                 /*
1317                  *      Authentication REJECT's can have only
1318                  *      Reply-Mesaage and Proxy-State.  We delete
1319                  *      everything other than Reply-Message, and
1320                  *      Proxy-State is added below, just before
1321                  *      the reply is sent.
1322                  */
1323         case PW_AUTHENTICATION_REJECT:
1324                 pairmove2(&vps, &(packet->vps), PW_REPLY_MESSAGE);
1325                 pairfree(packet->vps);
1326                 packet->vps = vps;
1327                 break;
1328         }
1329 }
1330
1331 /* 
1332  * FIXME:  The next two functions should all
1333  * be in a module.  But not until we have
1334  * more control over module execution.
1335  * -jcarneal
1336  */
1337
1338 /*
1339  *      Lowercase the string value of a pair.
1340  */
1341 static int rad_lowerpair(REQUEST *request, VALUE_PAIR *vp) {
1342         if (!vp) {
1343                 return -1;
1344         }
1345
1346         rad_lowercase(vp->strvalue);
1347         DEBUG2("rad_lowerpair:  %s now '%s'", vp->name, vp->strvalue);
1348         return 0;
1349 }
1350
1351 /*
1352  *      Remove spaces in a pair.
1353  */
1354 static int rad_rmspace_pair(REQUEST *request, VALUE_PAIR *vp) {
1355         if (!vp) {
1356                 return -1;
1357         }
1358         
1359         rad_rmspace(vp->strvalue);
1360         vp->length = strlen(vp->strvalue);
1361         DEBUG2("rad_rmspace_pair:  %s now '%s'", vp->name, vp->strvalue);
1362         
1363         return 0;
1364 }
1365
1366 /*
1367  *      Respond to a request packet.
1368  *
1369  *      Maybe we reply, maybe we don't.
1370  *      Maybe we proxy the request to another server, or else maybe
1371  *      we replicate it to another server.
1372  */
1373 int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
1374 {
1375         RADIUS_PACKET   *packet, *original;
1376         const char      *secret;
1377         int             finished = FALSE;
1378         int             proxy_sent = 0;
1379         int             reprocess = 0;
1380         
1381         /*
1382          *      Put the decoded packet into it's proper place.
1383          */
1384         if (request->proxy_reply != NULL) {
1385                 packet = request->proxy_reply;
1386                 secret = request->proxysecret;
1387                 original = request->proxy;
1388         } else {
1389                 packet = request->packet;
1390                 secret = request->secret;
1391                 original = NULL;
1392         }
1393
1394         assert(request->magic == REQUEST_MAGIC);
1395         
1396         /*
1397          *      Decode the packet, verifying it's signature,
1398          *      and parsing the attributes into structures.
1399          *
1400          *      Note that we do this CPU-intensive work in
1401          *      a child thread, not the master.  This helps to
1402          *      spread the load a little bit.
1403          */
1404         if (rad_decode(packet, original, secret) != 0) {
1405                 radlog(L_ERR, "%s", librad_errstr);
1406                 rad_reject(request);
1407                 goto finished_request;
1408         }
1409         
1410         /*
1411          *      For proxy replies, remove non-allowed
1412          *      attributes from the list of VP's.
1413          */
1414         if (request->proxy) {
1415                 int replicating;
1416                 replicating = proxy_receive(request);
1417                 if (replicating != 0) {
1418                         goto next_request;
1419                 }
1420         }
1421         
1422         /*
1423          *      We should have a User-Name attribute now.
1424          */
1425         if (request->username == NULL) {
1426                 request->username = pairfind(request->packet->vps,
1427                                              PW_USER_NAME);
1428         }
1429
1430         /*
1431          *      We have the semaphore, and have decoded the packet.
1432          *      Let's process the request.
1433          */
1434         assert(request->magic == REQUEST_MAGIC);
1435
1436         /* 
1437          *      FIXME:  All this lowercase/nospace junk will be moved
1438          *      into a module after module failover is fully in place
1439          *
1440          *      See if we have to lower user/pass before processing
1441          */
1442         if(strcmp(mainconfig.lower_time, "before") == 0) {
1443                 if(mainconfig.do_lower_user)
1444                         rad_lowerpair(request, request->username);
1445                 if(mainconfig.do_lower_pass)
1446                         rad_lowerpair(request, rad_getpass(request));
1447         }
1448         if(strcmp(mainconfig.nospace_time, "before") == 0) {
1449                 if(mainconfig.do_nospace_user)
1450                         rad_rmspace_pair(request, request->username);
1451                 if(mainconfig.do_nospace_pass)
1452                         rad_rmspace_pair(request, rad_getpass(request));
1453         }
1454         (*fun)(request);
1455
1456         /* See if we have to lower user/pass after processing */
1457         if(strcmp(mainconfig.lower_time, "after") == 0) {
1458                 if(mainconfig.do_lower_user)
1459                         rad_lowerpair(request, request->username);
1460                 if(mainconfig.do_lower_pass)
1461                         rad_lowerpair(request, rad_getpass(request));
1462                 reprocess = 1;
1463         }
1464
1465         if(strcmp(mainconfig.nospace_time, "after") == 0) {
1466                 if(mainconfig.do_nospace_user)
1467                         rad_rmspace_pair(request, request->username);
1468                 if(mainconfig.do_nospace_pass)
1469                         rad_rmspace_pair(request, rad_getpass(request));
1470                  reprocess = 1;
1471          }
1472
1473         /* Reprocess if we rejected last time */
1474         if ((fun == rad_authenticate) &&
1475             (request->reply->code == PW_AUTHENTICATION_REJECT) &&
1476             (reprocess)) 
1477                 (*fun)(request);
1478         
1479         /*
1480          *      If we don't already have a proxy
1481          *      packet for this request, we MIGHT have
1482          *      to go proxy it.
1483          */
1484         if (proxy_requests) {
1485                 if (request->proxy == NULL) {
1486                         proxy_sent = proxy_send(request);
1487                         
1488                         /*
1489                          *      sent==1 means it's been proxied.  The child
1490                          *      is done handling the request, but the request
1491                          *      is NOT finished!
1492                          */
1493                         if (proxy_sent == 1) {
1494                                 goto postpone_request;
1495                         }
1496                 }
1497         } else if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
1498                    (request->reply == NULL)) {
1499                 /*
1500                  *      We're not configured to reply to the packet,
1501                  *      and we're not proxying, so the DEFAULT behaviour
1502                  *      is to REJECT the user.
1503                  */
1504                 DEBUG2("There was no response configured: rejecting the user.");
1505                 rad_reject(request);
1506                 goto finished_request;
1507         }
1508
1509         /*
1510          *      If we have a reply to send, copy the Proxy-State
1511          *      attributes from the request to the tail of the reply,
1512          *      and send the packet.
1513          */
1514         assert(request->magic == REQUEST_MAGIC);
1515         if (request->reply->code != 0) {
1516                 VALUE_PAIR *vp = NULL;
1517
1518                 /*
1519                  *      Perform RFC limitations on outgoing replies.
1520                  */
1521                 rfc_clean(request->reply);
1522
1523                 /*
1524                  *      Need to copy Proxy-State from request->packet->vps
1525                  */
1526                 vp = paircopy2(request->packet->vps, PW_PROXY_STATE);
1527                 if (vp != NULL)
1528                         pairadd(&(request->reply->vps), vp);
1529
1530                 rad_send(request->reply, request->secret);
1531         }
1532
1533         /*
1534          *      We're done processing the request, set the
1535          *      request to be finished, clean up as necessary,
1536          *      and forget about the request.
1537          */
1538  finished_request:
1539         /*
1540          *      We're done handling the request.  Free up the linked
1541          *      lists of value pairs.  This might take a long time,
1542          *      so it's more efficient to do it in a child thread,
1543          *      instead of in the main handler when it eventually
1544          *      gets around to deleting the request.
1545          *
1546          *      Also, no one should be using these items after the
1547          *      request is finished, and the reply is sent.  Cleaning
1548          *      them up here ensures that they're not being used again.
1549          *
1550          *      Hmm... cleaning them up in the child thread also seems
1551          *      to make the server run more efficiently!
1552          */
1553
1554         /*      If we proxied this request, it's not safe to delete it until
1555          *      after the proxy reply
1556          */
1557         if (proxy_sent)
1558                 goto postpone_request;
1559
1560         if (request->packet && request->packet->vps) {
1561                 pairfree(request->packet->vps);
1562                 request->packet->vps = NULL;
1563                 request->username = NULL;
1564                 request->password = NULL;
1565         }
1566         if (request->reply && request->reply->vps) {
1567                 pairfree(request->reply->vps);
1568                 request->reply->vps = NULL;
1569         }
1570         if (request->config_items) {
1571                 pairfree(request->config_items);
1572                 request->config_items = NULL;
1573         }
1574
1575         DEBUG2("Finished request");
1576         finished = TRUE;
1577         
1578         /*
1579          *      Go to the next request, without marking
1580          *      the current one as finished.
1581          */
1582  next_request:
1583         DEBUG2("Going to the next request");
1584
1585         /*
1586          *      If this is an accounting request, ensure
1587          *      that we delete it immediately, as there CANNOT be
1588          *      duplicate accounting packets.  If there are, then
1589          *      something else is seriously wrong...
1590          */
1591         if (request->packet->code == PW_ACCOUNTING_REQUEST) {
1592                 request->timestamp = 0;
1593         }
1594
1595 #if WITH_THREAD_POOL
1596         request->child_pid = NO_SUCH_CHILD_PID;
1597 #endif
1598         request->finished = finished; /* do as the LAST thing before exiting */
1599
1600  postpone_request:
1601         return 0;
1602 }
1603
1604 /*
1605  *      Clean up the request list, every so often.
1606  *
1607  *      This is done by walking through ALL of the list, and
1608  *      - marking any requests which are finished, and expired
1609  *      - killing any processes which are NOT finished after a delay
1610  *      - deleting any marked requests.
1611  */
1612 static int rad_clean_list(time_t now)
1613 {
1614         static time_t last_cleaned_list = 0;
1615         int             id;
1616         int             request_count;
1617         int             cleaned = FALSE;
1618
1619         /*
1620          *      Don't bother checking the list if we've done it
1621          *      within the last second.
1622          *
1623          *      However, at LEAST once per second, go through the entire
1624          *      request list again, ensuring that ALL of the request ID's
1625          *      have been processed.
1626          */
1627         if (last_cleaned_list == now) {
1628                 return FALSE;
1629         }
1630         last_cleaned_list = now;
1631
1632 #if WITH_THREAD_POOL
1633         /*
1634          *      Only clean the thread pool if we've spawned child threads.
1635          */
1636         if (spawn_flag) {
1637                 thread_pool_clean(now);
1638         }
1639 #endif
1640         
1641         /*
1642          *      When mucking around with the request list, we block
1643          *      asynchronous access (through the SIGCHLD handler) to
1644          *      the list - equivalent to sigblock(SIGCHLD).
1645          */
1646         request_list_busy = TRUE;
1647         request_count = 0;
1648                 
1649         for (id = 0; id < 256; id++) {
1650                 REQUEST         *curreq;
1651                 REQUEST         **prevptr;
1652                 
1653                 /*
1654                  *      If we've cleaned this entry in the last
1655                  *      second, don't do it now.
1656                  */
1657                 if (request_list[id].last_cleaned_list == now) {
1658                         request_count += request_list[id].request_count;
1659                         continue;
1660                 }
1661                 request_list[id].last_cleaned_list = now;
1662                 
1663                 /*
1664                  *      Set up for looping over the requests
1665                  *      in this list.
1666                  */
1667                 curreq = request_list[id].first_request;
1668                 prevptr = &(request_list[id].first_request);
1669                 
1670                 while (curreq != NULL) {
1671                         assert(curreq->magic == REQUEST_MAGIC);
1672                         
1673                         /*
1674                          *      Handle cleanup_delay, max_request_time,
1675                          *      proxy_retry, for this request.
1676                          */
1677                         refresh_request(curreq, now);
1678                         
1679                         /*
1680                          *      If the request has been marked as deleted,
1681                          *      then remove it from the request list.
1682                          */
1683                         if (curreq->timestamp == 0) {
1684                                 if (request_list[id].request_count == 0) {
1685                                         DEBUG("HORRIBLE ERROR!!!");
1686                                 } else {
1687                                         request_list[id].request_count--;
1688                                 }
1689                                 
1690                                 /*
1691                                  *      Unlink the current request
1692                                  *      from the request queue.
1693                                  */
1694                                 *prevptr = curreq->next;
1695                                 if (curreq->next) {
1696                                         curreq->next->prev = curreq->prev;
1697                                 }
1698                                 request_free(curreq);
1699                                 curreq = *prevptr;
1700                                 
1701                                 /*
1702                                  *      Else the request is still being
1703                                  *      processed.  Skip it.
1704                                  */
1705                         } else {
1706                                 prevptr = &(curreq->next);
1707                                 curreq = curreq->next;
1708                         }
1709                 } /* end of walking the request list for that ID */
1710                 
1711                 request_count += request_list[id].request_count;
1712         } /* for each entry in the request list array */
1713
1714         /*
1715          *      Only print debugging information if anything's changed.
1716          */
1717         if (debug_flag) {
1718                 static int old_request_count = -1;
1719                 
1720                 if (request_count != old_request_count) {
1721                         DEBUG2("%d requests left in the list", request_count);
1722                         old_request_count = request_count;
1723                 }
1724         }
1725
1726         /*
1727          *      We're done playing with the request list.
1728          */
1729         request_list_busy = FALSE;
1730
1731         return cleaned;
1732 }
1733
1734 /*
1735  *      Walk through the request list, cleaning up complete child
1736  *      requests, and verifing that there is only one process
1737  *      responding to each request (duplicate requests are filtered
1738  *      out).
1739  *
1740  *      Also, check if the request is a reply from a request proxied to
1741  *      a remote server.  If so, play games with the request, and return
1742  *      the old one.
1743  */
1744 static REQUEST *rad_check_list(REQUEST *request)
1745 {
1746         REQUEST         *curreq;
1747         REQUEST         *prevreq;
1748         RADIUS_PACKET   *pkt;
1749         int             request_count;
1750         REQUEST_LIST    *request_list_entry;
1751         int             i;
1752         time_t          now;
1753         int             id;
1754
1755         /*
1756          *      If the request has come in on the proxy FD, then
1757          *      it's a proxy reply, so pass it through the proxy
1758          *      code for checking the REQUEST_LIST.
1759          */
1760         if (request->packet->sockfd == proxyfd) {
1761                 return proxy_check_list(request);
1762
1763                 /*
1764                  *      If the request already has a proxy packet,
1765                  *      then it obviously is not a new request, either.
1766                  */
1767         } else if (request->proxy != NULL) {
1768                 return request;
1769         }
1770
1771         request_list_entry = &request_list[request->packet->id];
1772
1773         assert((request_list_entry->first_request == NULL) ||
1774                (request_list_entry->request_count != 0));
1775         assert((request_list_entry->first_request != NULL) ||
1776                (request_list_entry->request_count == 0));
1777
1778         curreq = request_list_entry->first_request;
1779         prevreq = NULL;
1780         pkt = request->packet;
1781         request_count = 0;
1782         now = request->timestamp; /* good enough for our purposes */
1783         id = pkt->id;
1784
1785         /*
1786          *      When mucking around with the request list, we block
1787          *      asynchronous access (through the SIGCHLD handler) to
1788          *      the list - equivalent to sigblock(SIGCHLD).
1789          */
1790         request_list_busy = TRUE;
1791
1792         while (curreq != NULL) {
1793                 /*
1794                  *      The packet ID's MUST be the same, as we're in
1795                  *      request_list[request->packet->id]
1796                  */
1797                 assert(curreq->packet->id == pkt->id);
1798
1799                 /*
1800                  *      Let's see if we received a duplicate of
1801                  *      a packet we already have in our list.
1802                  *
1803                  *      We do this by checking the src IP, src port,
1804                  *      the packet code, and ID.
1805                  */
1806                 if ((curreq->packet->src_ipaddr == pkt->src_ipaddr) &&
1807                     (curreq->packet->src_port == pkt->src_port) &&
1808                     (curreq->packet->code == pkt->code)) {
1809                   /*
1810                    *    We now check the authentication vectors.
1811                    *    If the client has sent us a request with
1812                    *    identical code && ID, but different vector,
1813                    *    then they MUST have gotten our response, so
1814                    *    we can delete the original request, and process
1815                    *    the new one.
1816                    *
1817                    *    If the vectors are the same, then it's a duplicate
1818                    *    request, and we can send a duplicate reply.
1819                    */
1820                   if (memcmp(curreq->packet->vector, pkt->vector,
1821                             sizeof(pkt->vector)) == 0) {
1822                         /*
1823                          *      Maybe we've saved a reply packet.  If so,
1824                          *      re-send it.  Otherwise, just complain.
1825                          */
1826                         if (curreq->reply) {
1827                                 radlog(L_INFO,
1828                                 "Sending duplicate authentication reply"
1829                                 " to client %s:%d - ID: %d",
1830                                 client_name(request->packet->src_ipaddr),
1831                                 request->packet->src_port,
1832                                 request->packet->id);
1833
1834                                 /*
1835                                  *      Use the SOURCE port as the DESTINATION
1836                                  *      port of the duplicate reply.
1837                                  */
1838                                 curreq->reply->dst_port = request->packet->src_port;
1839                                 rad_send(curreq->reply, curreq->secret);
1840                                 
1841                                 /*
1842                                  *      There's no reply, but maybe there's
1843                                  *      an outstanding proxy request.
1844                                  *
1845                                  *      If so, then kick the proxy again.
1846                                  */
1847                         } else if (curreq->proxy != NULL) {
1848                                 if (proxy_synchronous) {
1849                                         DEBUG2("Sending duplicate proxy request to client %s:%d - ID: %d",
1850                                                client_name(curreq->proxy->dst_ipaddr),
1851                                                request->packet->src_port,
1852                                                curreq->proxy->id);
1853
1854                                         curreq->proxy_next_try = request->timestamp + proxy_retry_delay;
1855                                         rad_send(curreq->proxy, curreq->proxysecret);
1856                                 } else {
1857                                         DEBUG2("Ignoring duplicate authentication packet"
1858                                                " from client %s:%d - ID: %d, due to outstanding proxy request.",
1859                                                client_name(request->packet->src_ipaddr),
1860                                                request->packet->src_port,
1861                                                request->packet->id);
1862                                 }
1863                         } else {
1864                                 radlog(L_ERR,
1865                                 "Dropping duplicate authentication packet"
1866                                 " from client %s:%d - ID: %d",
1867                                 client_name(request->packet->src_ipaddr),
1868                                 request->packet->src_port,
1869                                 request->packet->id);
1870                         }
1871
1872                         /*
1873                          *      Delete the duplicate request, and
1874                          *      stop processing the request list.
1875                          */
1876                         request_free(request);
1877                         request = NULL;
1878                         break;
1879                   } else {
1880                           /*
1881                            *    The packet vectors are different, so
1882                            *    we can mark the old request to be
1883                            *    deleted from the list.
1884                            *
1885                            *    Note that we don't actually delete it...
1886                            *    Maybe we should?
1887                            */
1888                           if (curreq->finished) {
1889                                   curreq->timestamp = 0;
1890                           } else {
1891                                   /*
1892                                    *    ??? the client sent us a new request
1893                                    *    with the same ID, while we were
1894                                    *    processing the old one!  What should
1895                                    *    we do?
1896                                    */
1897                                 radlog(L_ERR,
1898                                 "Dropping conflicting authentication packet"
1899                                 " from client %s:%d - ID: %d",
1900                                 client_name(request->packet->src_ipaddr),
1901                                 request->packet->src_port,
1902                                 request->packet->id);
1903                                 request_free(request);
1904                                 request = NULL;
1905                                 break;
1906                           }
1907                   }
1908                 }
1909
1910                 /*
1911                  *      Ugh... duplicated code is bad...
1912                  */
1913
1914                 /*
1915                  *      Delete the current request, if it's
1916                  *      marked as such.  That is, the request
1917                  *      must be finished, there must be no
1918                  *      child associated with that request,
1919                  *      and it's timestamp must be marked to
1920                  *      be deleted.
1921                  */
1922                 if (curreq->finished &&
1923                     (curreq->child_pid == NO_SUCH_CHILD_PID) &&
1924                     (curreq->timestamp + cleanup_delay <= now)) {
1925                                 /*
1926                                  *      Request completed, delete it,
1927                                  *      and unlink it from the
1928                                  *      currently 'alive' list of
1929                                  *      requests.
1930                                  */
1931                         DEBUG2("Cleaning up request ID %d with timestamp %08lx",
1932                                curreq->packet->id,
1933                                (unsigned long)curreq->timestamp);
1934                         prevreq = curreq->prev;
1935                         if (request_list[id].request_count == 0) {
1936                                 DEBUG("HORRIBLE ERROR!!!");
1937                         } else {
1938                                 request_list[id].request_count--;
1939                         }
1940                         
1941                         if (prevreq == NULL) {
1942                                 request_list[id].first_request = curreq->next;
1943                                 request_free(curreq);
1944                                 curreq = request_list[id].first_request;
1945                         } else {
1946                                 prevreq->next = curreq->next;
1947                                 request_free(curreq);
1948                                 curreq = prevreq->next;
1949                         }
1950                         if (curreq)
1951                                 curreq->prev = prevreq;
1952                         
1953                 } else {        /* the request is still alive */
1954                         prevreq = curreq;
1955                         curreq = curreq->next;
1956                         request_count++;
1957                 }
1958         } /* end of walking the request list */
1959         
1960         /*
1961          *      If we've received a duplicate packet, 'request' is NULL.
1962          */
1963         if (request == NULL) {
1964                 request_list_busy = FALSE;
1965                 return NULL;
1966         }
1967
1968         assert(request_list_entry->request_count == request_count);
1969
1970         /*
1971          *      Count the total number of requests, to see if there
1972          *      are too many.  If so, stop counting immediately,
1973          *      and return with an error.
1974          */
1975         if(max_requests) {
1976                 request_count = 0;
1977                 for (i = 0; i < 256; i++) {
1978                         request_count += request_list[i].request_count;
1979
1980                         /*
1981                          *      This is a new request.  Let's see if it
1982                          *      makes us go over our configured bounds.
1983                          */
1984                         if (request_count > max_requests) {
1985                                 radlog(L_ERR, "Dropping request (%d is too many): "
1986                                     "from client %s:%d - ID: %d", request_count, 
1987                                     client_name(request->packet->src_ipaddr),
1988                                     request->packet->src_port,
1989                                     request->packet->id);
1990                                 radlog(L_INFO, "WARNING: Please check the radiusd.conf file.\n\tThe value for 'max_requests' is probably set too low.\n");
1991                                 request_free(request);
1992                                 request_list_busy = FALSE;
1993                                 return NULL;
1994                         }
1995                 }
1996         }
1997
1998         /*
1999          *      Add this request to the list
2000          */
2001         request->prev = prevreq;
2002         request->next = NULL;
2003         request->child_pid = NO_SUCH_CHILD_PID;
2004         request_list_entry->request_count++;
2005
2006         if (prevreq == NULL) {
2007                 assert(request_list_entry->first_request == NULL);
2008                 assert(request_list_entry->request_count == 1);
2009                 request_list_entry->first_request = request;
2010         } else {
2011                 assert(request_list_entry->first_request != NULL);
2012                 prevreq->next = request;
2013         }
2014
2015         /*
2016          *      And return the request to be handled.
2017          */
2018         request_list_busy = FALSE;
2019         return request;
2020 }
2021
2022 #ifndef WITH_THREAD_POOL
2023 #if HAVE_PTHREAD_H
2024 typedef struct spawn_thread_t {
2025   REQUEST *request;
2026   RAD_REQUEST_FUNP fun;
2027 } spawn_thread_t;
2028
2029 /*
2030  *      If the child *thread* gets a termination signal,
2031  *      then exit from the thread.
2032  */
2033 static void sig_term(int sig)
2034 {
2035         sig = sig;                      /* -Wunused */
2036         pthread_exit(NULL);
2037 }
2038
2039 /*
2040  *      Spawn a new child thread to handle this request, and ONLY
2041  *      this request.
2042  */
2043 static void *rad_spawn_thread(void *arg)
2044 {
2045         int replicating;
2046         spawn_thread_t *data = (spawn_thread_t *)arg;
2047         
2048         /*
2049          *      Note that this behaviour only works on Linux.
2050          *
2051          *      It's generally NOT the thing to do, and should
2052          *      be fixed somehow.
2053          *
2054          *      Q: How do we signal a hung thread, and tell it to
2055          *      kill itself?
2056          */
2057         signal(SIGTERM, sig_term);
2058         
2059         /*
2060          *      Keep only allowed attributes in the request.
2061          */
2062         if (data->request->proxy) {
2063                 replicating = proxy_receive(data->request);
2064                 if (replicating != 0) {
2065                         data->request->finished = TRUE;
2066                         free(data);
2067                         return NULL;
2068                 }
2069         }
2070         
2071         rad_respond(data->request, data->fun);
2072         data->request->child_pid = NO_SUCH_CHILD_PID;
2073         free(data);
2074         return NULL;
2075 }
2076 #endif
2077 #endif
2078
2079 /*
2080  *      If we're using the thread pool, then the function in
2081  *      'threads.c' replaces this one.
2082  */
2083 #ifndef WITH_THREAD_POOL
2084 /*
2085  *      Spawns a child process or thread to perform
2086  *      authentication/accounting and respond to RADIUS clients.
2087  */
2088 static int rad_spawn_child(REQUEST *request, RAD_REQUEST_FUNP fun)
2089 {
2090         child_pid_t             child_pid;
2091
2092 #if HAVE_PTHREAD_H
2093         int rcode;
2094         spawn_thread_t *data;
2095
2096         data = (spawn_thread_t *) malloc(sizeof(spawn_thread_t));
2097         memset(data, 0, sizeof(data));
2098         data->request = request;
2099         data->fun = fun;
2100
2101         /*
2102          *      Create a child thread, complaining on error.
2103          */
2104         rcode = pthread_create(&child_pid, NULL, rad_spawn_thread, data);
2105         if (rcode != 0) {
2106                 radlog(L_ERR, "Thread create failed for request from nas %s - ID: %d : %s",
2107                     nas_name2(request->packet),
2108                     request->packet->id,
2109                     strerror(errno));
2110                 return -1;
2111         }
2112
2113         /*
2114          *      Detach it, so it's state is automagically cleaned up on exit.
2115          */
2116         pthread_detach(child_pid);
2117
2118 #else
2119         /*
2120          *      fork our child
2121          */
2122         child_pid = fork();
2123         if (child_pid < 0) {
2124                 radlog(L_ERR, "Fork failed for request from nas %s - ID: %d",
2125                                 nas_name2(request->packet),
2126                                 request->packet->id);
2127                 return -1;
2128         }
2129
2130         if (child_pid == 0) {
2131
2132                 /*
2133                  *      This is the child, it should go ahead and respond
2134                  */
2135                 signal(SIGCHLD, SIG_DFL);
2136                 rad_respond(request, fun);
2137                 exit(0);
2138         }
2139 #endif
2140
2141         /*
2142          *      Register the Child
2143          */
2144         request->child_pid = child_pid;
2145         return 0;
2146 }
2147 #endif /* WITH_THREAD_POOL */
2148
2149 /*ARGSUSED*/
2150 void sig_cleanup(int sig)
2151 {
2152 #ifndef HAVE_PTHREAD_H
2153         int             i;
2154         int             status;
2155         child_pid_t     pid;
2156         REQUEST         *curreq;
2157 #endif
2158
2159         sig = sig; /* -Wunused */
2160  
2161         /*
2162          *      request_list_busy is a lock on the request list
2163          */
2164         if (request_list_busy) {
2165                 got_child = TRUE;
2166                 return;
2167         }
2168         got_child = FALSE;
2169
2170         /*
2171          *      Reset the signal handler, if required.
2172          */
2173         reset_signal(SIGCHLD, sig_cleanup);
2174         
2175         /*
2176          *  If we're using pthreads, then there are NO child processes,
2177          *  so the waitpid() call, and the following code, is useless.
2178          */
2179 #ifndef HAVE_PTHREAD_H
2180         for (;;) {
2181                 pid = waitpid((pid_t)-1, &status, WNOHANG);
2182                 if (pid <= 0)
2183                         return;
2184
2185                 /*
2186                  *      Check to see if the child did a bad thing.
2187                  *      If so, kill ALL processes in the current
2188                  *      process group, to prevent further attacks.
2189                  */
2190                 if (debug_flag && (WIFSIGNALED(status))) {
2191                         radlog(L_ERR|L_CONS, "MASTER: Child PID %d failed to catch signal %d: killing all active servers.\n",
2192                             pid, WTERMSIG(status));
2193                         kill(0, SIGTERM);
2194                         exit(1);
2195                 }
2196
2197                 /*
2198                  *      Service all of the requests in the queues
2199                  */
2200                 for (i = 0; i < 256; i++) {
2201                         curreq = request_list[i].first_request;
2202                         while (curreq != (REQUEST *)NULL) {
2203                                 if (curreq->child_pid == pid) {
2204                                         curreq->child_pid = NO_SUCH_CHILD_PID;
2205                                         break;
2206                                 }
2207                                 curreq = curreq->next;
2208                         }
2209                 }
2210         }
2211 #endif /* !defined HAVE_PTHREAD_H */
2212 }
2213
2214 /*
2215  *      Display the syntax for starting this program.
2216  */
2217 static void usage(void)
2218 {
2219         fprintf(stderr,
2220                 "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-p port] [-"
2221 #if defined(WITH_DBM) || defined(WITH_NDBM)
2222                 "b"
2223 #endif
2224                 "AcfnsSvXxyz]\n", progname);
2225         fprintf(stderr, "Options:\n\n");
2226         fprintf(stderr, "  -a acct_dir     use accounting directory 'acct_dir'.\n");
2227         fprintf(stderr, "  -A              Log auth detail.\n");
2228 #if defined(WITH_DBM) || defined(WITH_NDBM)
2229         fprintf(stderr, "  -b              Use DBM.\n");
2230 #endif
2231         fprintf(stderr, "  -d db_dir       Use database directory 'db_dir'.\n");
2232         fprintf(stderr, "  -f              Run as a foreground process, not a daemon.\n");
2233         fprintf(stderr, "  -h              Print this help message.\n");
2234         fprintf(stderr, "  -i address      Listen only in the given IP address.\n");
2235         fprintf(stderr, "  -l log_dir      Log messages to 'log_dir'.  Special values are:\n");
2236         fprintf(stderr, "                  stdout == log all messages to standard output.\n");
2237         fprintf(stderr, "                  syslog == log all messages to the system logger.\n");
2238         fprintf(stderr, "  -p port         Bind to 'port', and not to the radius/udp, or 1646/udp.\n");
2239         fprintf(stderr, "  -s              Do not spawn child processes to handle requests.\n");
2240         fprintf(stderr, "  -S              Log stripped names.\n");
2241         fprintf(stderr, "  -v              Print server version information.\n");
2242         fprintf(stderr, "  -X              Turn on full debugging. (Means: -sfxxyz -l stdout)\n");
2243         fprintf(stderr, "  -x              Turn on partial debugging. (-xx gives more debugging).\n");
2244         fprintf(stderr, "  -y              Log authentication failures, with password.\n");
2245         fprintf(stderr, "  -z              Log authentication successes, with password.\n");
2246         exit(1);
2247 }
2248
2249
2250 /*
2251  *      We got a fatal signal. Clean up and exit.
2252  */
2253 static void sig_fatal(int sig)
2254 {
2255         const char *me = "MASTER: ";
2256
2257         if (radius_pid != getpid()) {
2258                 me = "CHILD: ";
2259         }
2260
2261         switch(sig) {
2262                 case 100:
2263                         radlog(L_ERR, "%saccounting process died - exit.", me);
2264                         break;
2265                 case 101:
2266                         radlog(L_ERR, "%sfailed in select() - exit.", me);
2267                         break;
2268                 case SIGTERM:
2269                         radlog(L_INFO, "%sexit.", me);
2270                         break;
2271                 default:
2272                         radlog(L_ERR, "%sexit on signal (%d)", me, sig);
2273                         break;
2274         }
2275
2276         /*
2277          *      We're running as a daemon, we're the MASTER daemon,
2278          *      and we got a fatal signal.  Tear the rest of the
2279          *      daemons down, as something absolutely horrible happened.
2280          */
2281         if ((debug_flag == 0) && (dont_fork == 0) &&
2282             (radius_pid == getpid())) {
2283                 /*
2284                  *      Kill all of the processes in the current
2285                  *      process group.
2286                  */
2287                 kill(0, SIGKILL);
2288         }
2289
2290         exit(sig == SIGTERM ? 0 : 1);
2291 }
2292
2293
2294 /*
2295  *      We got the hangup signal.
2296  *      Re-read the configuration files.
2297  */
2298 /*ARGSUSED*/
2299 static void sig_hup(int sig)
2300 {
2301         sig = sig; /* -Wunused */
2302         reset_signal(SIGHUP, sig_hup);
2303
2304         /*
2305          *      Only do the reload if we're the main server, both
2306          *      for processes, and for threads.
2307          */
2308         if (getpid() == radius_pid) {
2309                 need_reload = TRUE;
2310         }
2311 }
2312
2313 /*
2314  *      Do a proxy check of the REQUEST_LIST when using the new proxy code.
2315  *
2316  *      This function and the next two are here because they have to access
2317  *      the REQUEST_LIST structure, which is 'static' to this C file.
2318  */
2319 static REQUEST *proxy_check_list(REQUEST *request)
2320 {
2321         int id;
2322         REQUEST *oldreq;
2323         RADIUS_PACKET *pkt;
2324         
2325         /*
2326          *      Find the original request in the request list
2327          */
2328         oldreq = NULL;
2329         pkt = request->packet;
2330         
2331         for (id = 0; (id < 256) && (oldreq == NULL); id++) {
2332                 for (oldreq = request_list[id].first_request ;
2333                      oldreq != NULL ;
2334                      oldreq = oldreq->next) {
2335                         
2336                         /*
2337                          *      See if this reply packet matches a proxy
2338                          *      packet which we sent.
2339                          */
2340                         if (oldreq->proxy &&
2341                             (oldreq->proxy->dst_ipaddr == pkt->src_ipaddr) &&
2342                             (oldreq->proxy->dst_port == pkt->src_port) &&
2343                             (oldreq->proxy->id == pkt->id)) {
2344                                 /*
2345                                  *      If there is already a reply,
2346                                  *      maybe the new one is a duplicate?
2347                                  */
2348                                 if (oldreq->proxy_reply) {
2349                                         if (memcmp(oldreq->proxy_reply->vector,
2350                                                    request->packet->vector,
2351                                                    sizeof(oldreq->proxy_reply->vector)) == 0) {
2352                                                 DEBUG2("Ignoring duplicate proxy reply");
2353                                                 request_free(request);
2354                                                 return NULL;
2355                                         } else {
2356                                                 /*
2357                                                  *      ??? New reply ???
2358                                                  */
2359                                                 continue;
2360                                         }
2361                                 } /* else no reply, this one must match */
2362
2363                                 /*
2364                                  *      Exit from request list loop
2365                                  *      while oldreq != NULL, which will
2366                                  *      cause the outer loop to stop, too.
2367                                  */
2368                                 break;
2369                         } /* the reply matches a proxied request */
2370                 } /* for all requests in the id request list */
2371         } /* for all 256 id's*/
2372         
2373         /*
2374          *      If we haven't found the old request, complain.
2375          */
2376         if (oldreq == NULL) {
2377                 radlog(L_PROXY, "Unrecognized proxy reply from server %s - ID %d",
2378                     client_name(request->packet->src_ipaddr),
2379                     request->packet->id);
2380                 request_free(request);
2381                 return NULL;
2382         }
2383
2384         /*
2385          *      Refresh the old request, and update it with the proxy reply.
2386          *
2387          *      ??? Can we delete the proxy request here?
2388          *      Is there any more need for it?
2389          */
2390         oldreq->timestamp = request->timestamp;
2391         oldreq->proxy_reply = request->packet;
2392         request->packet = NULL;
2393         request_free(request);
2394         return oldreq;
2395 }
2396
2397 /*
2398  *      Walk through all of the requests, checking cleanup times,
2399  *      proxy retry times, and maximum request times.  We then set the
2400  *      time delay until the server has to service the request queue.
2401  *
2402  *      This time delay is used by the main select() loop, to sleep
2403  *      until either a packet comes in, or until there's some work
2404  *      to be done.
2405  */
2406 static struct timeval *setuptimeout()
2407 {
2408         time_t now = time(NULL);
2409         time_t difference, smallest = 0;
2410         int foundone = FALSE;
2411         int id;
2412         REQUEST *curreq;
2413
2414         /*
2415          *      Static variables, so that we don't do all of this work
2416          *      more than once per second.
2417          *
2418          *      Note that we have 'tv' and 'last_tv'.  'last_tv' is
2419          *      pointed to by 'last_tv_ptr', and depending on the
2420          *      system implementation of select(), it MAY be modified.
2421          *
2422          *      In that was, we want to use the ORIGINAL value, from
2423          *      'tv', and wipe out the (possibly modified) last_tv.
2424          */
2425         static time_t last_setup = 0;
2426         static struct timeval tv, *last_tv_ptr = NULL;
2427         static struct timeval last_tv;
2428
2429         /*
2430          *      If we've already set up the timeout this second,
2431          *      don't do it again.  We simply return the sleep delay
2432          *      from last time.
2433          *
2434          *      Note that if we returned NULL last time, there was nothing
2435          *      to do.  BUT we've been woken up since then, which can only
2436          *      happen if we received a packet.  And if we've received a
2437          *      packet, then there's some work to do in the future.
2438          *
2439          *      FIXME: We can probably use gettimeofday() for finer clock
2440          *      resolution, as the current method will cause it to sleep
2441          *      too long...
2442          */
2443         if ((last_tv_ptr != NULL) &&
2444             (last_setup == now) &&
2445             (tv.tv_sec != 0)) {         
2446                 last_tv = tv;
2447                 DEBUG2("Waking up in %d seconds...",
2448                        (int) last_tv_ptr->tv_sec);
2449                 return last_tv_ptr;
2450         }
2451
2452         last_setup = now;       /* remember when we last set up the sleep timer */
2453
2454         difference = 1;         /* initialize it to a non-zero value */
2455
2456         /*
2457          *      Loop over all of the outstanding requests.
2458          */
2459         for (id = 0; id < 256; id++) {
2460                 for (curreq = request_list[id].first_request; curreq; curreq = curreq->next) {
2461                         /*
2462                          *      The request is marked to be
2463                          *      cleaned up: ignore it.
2464                          */
2465                         if (curreq->timestamp == 0) {
2466                                 continue;
2467                         } else if (curreq->finished) {
2468                                 /*
2469                                  *      The request is finished.
2470                                  *      Wake up when it's time to clean
2471                                  *      it up.
2472                                  */
2473                                 difference = (curreq->timestamp + cleanup_delay) - now;
2474
2475                         } else if (curreq->proxy && !curreq->proxy_reply) {
2476                                 /*
2477                                  *      The request is NOT finished, but there
2478                                  *      is an outstanding proxy request,
2479                                  *      with no matching proxy reply.
2480                                  *
2481                                  *      Wake up when it's time to re-send
2482                                  *      the proxy request.
2483                                  */
2484                                 difference = curreq->proxy_next_try - now;
2485
2486                         } else {
2487                                 /*
2488                                  *      The request is NOT finished.
2489                                  *
2490                                  *      Wake up when it's time to kill
2491                                  *      the errant thread/process.
2492                                  */
2493                                 difference = (curreq->timestamp + max_request_time) - now;
2494                         }
2495
2496                         /*
2497                          *      Found a valid request, with a time at which
2498                          *      we're going to to wake up.
2499                          */
2500                         if (!foundone) {
2501                                 foundone = TRUE;
2502                                 smallest = difference;
2503                         } else {
2504                                 if (difference < smallest)
2505                                         smallest = difference;
2506                         }
2507
2508                         if (difference <= 0) break; /* short-circuit */
2509                 } /* loop over linked list for that ID */
2510
2511                 if (difference <= 0) break; /* short-circuit */
2512         } /* loop over 256 ID's */
2513
2514         /*
2515          *      We haven't found a time at which we need to wake up.
2516          *      Return NULL, so that the select() call will sleep forever.
2517          */
2518         if (!foundone) {
2519                 DEBUG2("Nothing to do.  Sleeping until we see a request.");
2520                 last_tv_ptr = NULL;
2521                 return NULL;
2522         }
2523
2524         /*
2525          *      If the server is CPU starved, then we CAN miss a time
2526          *      for servicing requests.  In which case the 'smallest'
2527          *      value will be negative.  select() doesn't like that,
2528          *      so we fix it.
2529          */
2530         if (smallest < 0) smallest = 0;
2531
2532         /*
2533          *      Set the time (in seconds) for how long we're
2534          *      supposed to sleep.
2535          */
2536         tv.tv_sec = smallest;
2537         tv.tv_usec = 0;
2538         DEBUG2("Waking up in %d seconds...", (int) smallest);
2539
2540         /*
2541          *      Remember how long we should sleep for.
2542          */
2543         last_tv = tv;
2544         last_tv_ptr = &last_tv;
2545         return last_tv_ptr;
2546 }
2547
2548 /*
2549  *      Refresh a request, by using proxy_retry_delay, cleanup_delay,
2550  *      max_request_time, etc.
2551  *
2552  *      When walking over the request list, all of the per-request
2553  *      magic is done here.
2554  */
2555 static void refresh_request(REQUEST *request, time_t now)
2556 {
2557         child_pid_t     child_pid;
2558
2559         /*
2560          *      If the request has finished processing,
2561          *      AND it's child has been cleaned up,
2562          *      AND it's time to clean up the request,
2563          *      THEN, go delete it.
2564          */
2565         if (request->finished &&
2566             (request->child_pid == NO_SUCH_CHILD_PID) &&
2567             (request->timestamp + cleanup_delay <= now)) {
2568                 /*
2569                  *      Request completed, delete it, and unlink it
2570                  *      from the currently 'alive' list of requests.
2571                  */
2572                 DEBUG2("Cleaning up request ID %d with timestamp %08lx",
2573                        request->packet->id,
2574                        (unsigned long)request->timestamp);
2575                 
2576                 /*
2577                  *      Mark the request to be deleted.
2578                  */
2579                 request->timestamp = 0;
2580                 return;
2581                 
2582         }
2583
2584         /*
2585          *      Maybe the child process
2586          *      handling the request has hung:
2587          *      kill it, and continue.
2588          */
2589         if ((request->timestamp + max_request_time) <= now) {
2590                 if (request->child_pid != NO_SUCH_CHILD_PID) {
2591                         /*
2592                          *      This request seems to have hung
2593                          *       - kill it
2594                          */
2595                         child_pid = request->child_pid;
2596                         radlog(L_ERR, "Killing unresponsive child %d",
2597                                child_pid);
2598                         child_kill(child_pid, SIGTERM);
2599                 } /* else no proxy reply, quietly fail */
2600                 
2601                                 /*
2602                                  *      Mark the request as unsalvagable.
2603                                  */
2604                 request->child_pid = NO_SUCH_CHILD_PID;
2605                 request->finished = TRUE;
2606                 request->timestamp = 0;
2607                 return;
2608         }
2609
2610         /*
2611          *      Do any proxy request handling.
2612          *
2613          *      If we're not doing proxy requests, OR if the retry delay
2614          *      is zero (only retry synchronously), then don't bother
2615          *      checking the request for proxy retries.
2616          */
2617         if ((!proxy_requests) ||
2618             (proxy_retry_delay == 0)) {
2619                 return;
2620         }
2621
2622         /*
2623          *      The request is finished, (but it hasn't yet
2624          *      been removed from the list.)
2625          *      OR there is no proxy request,
2626          *      OR we already have seen the reply (so we don't
2627          *      need to send another proxy request),
2628          *      OR the next try is to be done later.
2629          *
2630          *      Skip the try.
2631          *
2632          *      FIXME: These retries should be binned by
2633          *      the next try time, so we don't have to do
2634          *      all of this work on every second.
2635          *
2636          *      That will also get rid of these checks, as
2637          *      a packet can get removed from the bin when
2638          *      the proxy reply is received.
2639          */
2640         if ((request->finished) ||
2641             (!request->proxy) ||
2642             (request->proxy_reply) ||
2643             (request->proxy_next_try > now)) {
2644                 return;
2645         }
2646         
2647         /*
2648          *      If the proxy retry count is zero, then
2649          *      we've sent the last try, and have NOT received
2650          *      a reply from the end server.  In that case,
2651          *      we don't bother trying again, but just mark
2652          *      the request as finished, and go to the next one.
2653          *
2654          *      Note that we do NOT immediately delete the request,
2655          *      on the off chance that the proxy replies before we've
2656          *      thrown the request away.
2657          */
2658         if (request->proxy_try_count == 0) {
2659                 request->finished = TRUE;
2660                 rad_reject(request);
2661                 return;
2662         }
2663
2664         /*
2665          *      We're trying one more time, so count down
2666          *      the tries, and set the next try time.
2667          */
2668         request->proxy_try_count--;
2669         request->proxy_next_try = now + proxy_retry_delay;
2670                 
2671         /* Fix up Acct-Delay-Time */
2672         if (request->proxy->code == PW_ACCOUNTING_REQUEST) {
2673                 VALUE_PAIR *delaypair;
2674                 delaypair = pairfind(request->proxy->vps, PW_ACCT_DELAY_TIME);
2675                 
2676                 if (!delaypair) {
2677                         delaypair = paircreate(PW_ACCT_DELAY_TIME,
2678                                                PW_TYPE_INTEGER);
2679                         if (!delaypair) {
2680                                 radlog(L_ERR|L_CONS, "no memory");
2681                                 exit(1);
2682                         }
2683                         pairadd(&request->proxy->vps, delaypair);
2684                 }
2685                 delaypair->lvalue = now - request->proxy->timestamp;
2686                         
2687                 /* Must recompile the valuepairs to wire format */
2688                 free(request->proxy->data);
2689                 request->proxy->data = NULL;
2690         } /* proxy accounting request */
2691         
2692         /*
2693          *      Send the proxy packet.
2694          */
2695         rad_send(request->proxy, request->proxysecret);
2696 }