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