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