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