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