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