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