rlm_eap: add eap_chbind.c to build
[freeradius.git] / src / main / modules.c
1 /*
2  * modules.c    Radius module support.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2003,2006  The FreeRADIUS server project
21  * Copyright 2000  Alan DeKok <aland@ox.org>
22  * Copyright 2000  Alan Curry <pacman@world.std.com>
23  */
24
25 #include <freeradius-devel/ident.h>
26 RCSID("$Id$")
27
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/modpriv.h>
30 #include <freeradius-devel/modcall.h>
31 #include <freeradius-devel/rad_assert.h>
32
33 extern int check_config;
34
35 typedef struct indexed_modcallable {
36         int             comp;
37         int             idx;
38         modcallable     *modulelist;
39 } indexed_modcallable;
40
41 typedef struct virtual_server_t {
42         const char      *name;
43         time_t          created;
44         int             can_free;
45         CONF_SECTION    *cs;
46         rbtree_t        *components;
47         modcallable     *mc[RLM_COMPONENT_COUNT];
48         CONF_SECTION    *subcs[RLM_COMPONENT_COUNT];
49         struct virtual_server_t *next;
50 } virtual_server_t;
51
52 /*
53  *      Keep a hash of virtual servers, so that we can reload them.
54  */
55 #define VIRTUAL_SERVER_HASH_SIZE (256)
56 static virtual_server_t *virtual_servers[VIRTUAL_SERVER_HASH_SIZE];
57
58 static rbtree_t *module_tree = NULL;
59
60 static rbtree_t *instance_tree = NULL;
61
62 struct fr_module_hup_t {
63         module_instance_t       *mi;
64         time_t                  when;
65         void                    *insthandle;
66         fr_module_hup_t         *next;
67 };
68
69 /*
70  *      Ordered by component
71  */
72 const section_type_value_t section_type_value[RLM_COMPONENT_COUNT] = {
73         { "authenticate", "Auth-Type",       PW_AUTH_TYPE },
74         { "authorize",    "Autz-Type",       PW_AUTZ_TYPE },
75         { "preacct",      "Pre-Acct-Type",   PW_PRE_ACCT_TYPE },
76         { "accounting",   "Acct-Type",       PW_ACCT_TYPE },
77         { "session",      "Session-Type",    PW_SESSION_TYPE },
78         { "pre-proxy",    "Pre-Proxy-Type",  PW_PRE_PROXY_TYPE },
79         { "post-proxy",   "Post-Proxy-Type", PW_POST_PROXY_TYPE },
80         { "post-auth",    "Post-Auth-Type",  PW_POST_AUTH_TYPE }
81 #ifdef WITH_COA
82         ,
83         { "recv-coa",     "Recv-CoA-Type",   PW_RECV_COA_TYPE },
84         { "send-coa",     "Send-CoA-Type",   PW_SEND_COA_TYPE }
85 #endif
86 };
87
88
89 #ifdef WITHOUT_LIBLTDL
90 #ifdef WITH_DLOPEN
91 #include <dlfcn.h>
92
93 #ifndef RTLD_NOW
94 #define RTLD_NOW (0)
95 #endif
96 #ifndef RTLD_LOCAL
97 #define RTLD_LOCAL (0)
98 #endif
99
100 #define fr_dlopenext lt_dlopenext
101 #ifndef LT_SHREXT
102 #ifdef __APPLE__
103 #define LT_SHREXT ".dylib"
104 #define LD_LIBRARY_PATH "DYLD_FALLBACK_LIBRARY_PATH"
105 #elif defined (WIN32)
106 #define LT_SHREXT ".dll"
107 #else
108 #define LT_SHREXT ".so"
109 #define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
110 #endif
111 #endif
112
113 int lt_dlinit(void)
114 {
115         char *p, *val;
116         char buffer[1024];
117
118         /*
119          *      This doesn't really do anything...
120          */
121         p = getenv(LD_LIBRARY_PATH);
122         if (p) {
123                 snprintf(buffer, sizeof(buffer), "%s:%s", p, radlib_dir);
124                 val = buffer;
125         } else {
126                 val = radlib_dir;
127         }
128
129         return setenv(LD_LIBRARY_PATH, val, 1);
130 }
131
132 lt_dlhandle lt_dlopenext(const char *name)
133 {
134         void *handle;
135         char buffer[2048];
136
137         /*
138          *      Prefer loading our libraries by absolute path.
139          */
140         snprintf(buffer, sizeof(buffer), "%s/%s%s", radlib_dir, name, LT_SHREXT);
141         handle = dlopen(buffer, RTLD_NOW | RTLD_LOCAL);
142         if (handle) return handle;
143
144         strlcpy(buffer, name, sizeof(buffer));
145
146         /*
147          *      FIXME: Make this configurable...
148          */
149         strlcat(buffer, LT_SHREXT, sizeof(buffer));
150
151         return dlopen(buffer, RTLD_NOW | RTLD_LOCAL);
152 }
153
154 void *lt_dlsym(lt_dlhandle handle, UNUSED const char *symbol)
155 {
156         return dlsym(handle, symbol);
157 }
158
159 int lt_dlclose(lt_dlhandle handle)
160 {
161         if (!handle) return 0;
162
163         return dlclose(handle);
164 }
165
166 const char *lt_dlerror(void)
167 {
168         return dlerror();
169 }
170
171
172 #else  /* without dlopen */
173 typedef struct lt_dlmodule_t {
174   const char    *name;
175   void          *ref;
176 } lt_dlmodule_t;
177
178 typedef struct eap_type_t EAP_TYPE;
179 typedef struct rlm_sql_module_t rlm_sql_module_t;
180
181 /*
182  *      FIXME: Write hackery to auto-generate this data.
183  *      We only need to do this on systems that don't have dlopen.
184  */
185 extern module_t rlm_pap;
186 extern module_t rlm_chap;
187 extern module_t rlm_eap;
188 extern module_t rlm_sql;
189 /* and so on ... */
190
191 extern EAP_TYPE rlm_eap_md5;
192 extern rlm_sql_module_t rlm_sql_mysql;
193 /* and so on ... */
194
195 static const lt_dlmodule_t lt_dlmodules[] = {
196         { "rlm_pap", &rlm_pap },
197         { "rlm_chap", &rlm_chap },
198         { "rlm_eap", &rlm_eap },
199         /* and so on ... */
200
201         { "rlm_eap_md5", &rlm_eap_md5 },
202         /* and so on ... */
203                 
204         { "rlm_sql_mysql", &rlm_sql_mysql },
205         /* and so on ... */
206                 
207         { NULL, NULL }
208 };
209
210 #define fr_dlopenext lt_dlopenext
211 lt_dlhandle lt_dlopenext(const char *name)
212 {
213         int i;
214
215         for (i = 0; lt_dlmodules[i].name != NULL; i++) {
216                 if (strcmp(name, lt_dlmodules[i].name) == 0) {
217                         return lt_dlmodules[i].ref;
218                 }
219         }
220
221         return NULL;
222 }
223
224 void *lt_dlsym(lt_dlhandle handle, UNUSED const char *symbol)
225 {
226         return handle;
227 }
228
229 int lt_dlclose(lt_dlhandle handle)
230 {
231         return 0;
232 }
233
234 const char *lt_dlerror(void)
235 {
236         return "Unspecified error";
237 }
238
239 #endif  /* WITH_DLOPEN */
240 #else   /* WITHOUT_LIBLTDL */
241
242 /*
243  *      Solve the issues of libraries linking to other libraries
244  *      by using a newer libltdl API.
245  */
246 #ifndef HAVE_LT_DLADVISE_INIT
247 #define fr_dlopenext lt_dlopenext
248 #else
249 static lt_dlhandle fr_dlopenext(const char *filename)
250 {
251         lt_dlhandle handle = 0;
252         lt_dladvise advise;
253
254         if (!lt_dladvise_init (&advise) &&
255             !lt_dladvise_ext (&advise) &&
256             !lt_dladvise_global (&advise)) {
257                 handle = lt_dlopenadvise (filename, advise);
258         }
259
260         lt_dladvise_destroy (&advise);
261
262         return handle;
263 }
264 #endif  /* HAVE_LT_DLADVISE_INIT */
265 #endif /* WITHOUT_LIBLTDL */
266
267 static int virtual_server_idx(const char *name)
268 {
269         uint32_t hash;
270
271         if (!name) return 0;
272
273         hash = fr_hash_string(name);
274                 
275         return hash & (VIRTUAL_SERVER_HASH_SIZE - 1);
276 }
277
278 static virtual_server_t *virtual_server_find(const char *name)
279 {
280         int rcode;
281         virtual_server_t *server;
282
283         rcode = virtual_server_idx(name);
284         for (server = virtual_servers[rcode];
285              server != NULL;
286              server = server->next) {
287                 if (!name && !server->name) break;
288
289                 if ((name && server->name) &&
290                     (strcmp(name, server->name) == 0)) break;
291         }
292
293         return server;
294 }
295
296 static void virtual_server_free(virtual_server_t *server)
297 {
298         if (!server) return;
299
300         if (server->components) rbtree_free(server->components);
301         server->components = NULL;
302
303         free(server);
304 }
305
306 void virtual_servers_free(time_t when)
307 {
308         int i;
309         virtual_server_t **last;
310         
311         for (i = 0; i < VIRTUAL_SERVER_HASH_SIZE; i++) {
312                 virtual_server_t *server, *next;
313
314                 last = &virtual_servers[i];
315                 for (server = virtual_servers[i];
316                      server != NULL;
317                      server = next) {
318                         next = server->next;
319
320                         /*
321                          *      If we delete it, fix the links so that
322                          *      we don't orphan anything.  Also,
323                          *      delete it if it's old, AND a newer one
324                          *      was defined.
325                          *
326                          *      Otherwise, the last pointer gets set to
327                          *      the one we didn't delete.
328                          */
329                         if ((when == 0) ||
330                             ((server->created < when) && server->can_free)) {
331                                 *last = server->next;
332                                 virtual_server_free(server);
333                         } else {
334                                 last = &(server->next);
335                         }
336                 }
337         }
338 }
339
340 static void indexed_modcallable_free(void *data)
341 {
342         indexed_modcallable *c = data;
343
344         modcallable_free(&c->modulelist);
345         free(c);
346 }
347
348 static int indexed_modcallable_cmp(const void *one, const void *two)
349 {
350         const indexed_modcallable *a = one;
351         const indexed_modcallable *b = two;
352
353         if (a->comp < b->comp) return -1;
354         if (a->comp >  b->comp) return +1;
355
356         return a->idx - b->idx;
357 }
358
359
360 /*
361  *      Compare two module entries
362  */
363 static int module_instance_cmp(const void *one, const void *two)
364 {
365         const module_instance_t *a = one;
366         const module_instance_t *b = two;
367
368         return strcmp(a->name, b->name);
369 }
370
371
372 static void module_instance_free_old(CONF_SECTION *cs, module_instance_t *node,
373                                      time_t when)
374 {
375         fr_module_hup_t *mh, **last;
376
377         /*
378          *      Walk the list, freeing up old instances.
379          */
380         last = &(node->mh);
381         while (*last) {
382                 mh = *last;
383
384                 /*
385                  *      Free only every 60 seconds.
386                  */
387                 if ((when - mh->when) < 60) {
388                         last = &(mh->next);
389                         continue;
390                 }
391
392                 cf_section_parse_free(cs, mh->insthandle);
393                 
394                 if (node->entry->module->detach) {
395                         (node->entry->module->detach)(mh->insthandle);
396                 } else {
397                         free(mh->insthandle);
398                 }
399
400                 *last = mh->next;
401                 free(mh);
402         }
403 }
404
405
406 /*
407  *      Free a module instance.
408  */
409 static void module_instance_free(void *data)
410 {
411         module_instance_t *this = data;
412
413         module_instance_free_old(this->cs, this, time(NULL) + 100);
414
415         if (this->entry->module->detach) {
416                 (this->entry->module->detach)(this->insthandle);
417         }
418
419 #ifdef HAVE_PTHREAD_H
420         if (this->mutex) {
421                 /*
422                  *      FIXME
423                  *      The mutex MIGHT be locked...
424                  *      we'll check for that later, I guess.
425                  */
426                 pthread_mutex_destroy(this->mutex);
427                 free(this->mutex);
428         }
429 #endif
430         memset(this, 0, sizeof(*this));
431         free(this);
432 }
433
434
435 /*
436  *      Compare two module entries
437  */
438 static int module_entry_cmp(const void *one, const void *two)
439 {
440         const module_entry_t *a = one;
441         const module_entry_t *b = two;
442
443         return strcmp(a->name, b->name);
444 }
445
446 /*
447  *      Free a module entry.
448  */
449 static void module_entry_free(void *data)
450 {
451         module_entry_t *this = data;
452
453         lt_dlclose(this->handle);       /* ignore any errors */
454         memset(this, 0, sizeof(*this));
455         free(this);
456 }
457
458
459 /*
460  *      Remove the module lists.
461  */
462 int detach_modules(void)
463 {
464         rbtree_free(instance_tree);
465         rbtree_free(module_tree);
466
467         lt_dlexit();
468
469         return 0;
470 }
471
472
473 /*
474  *      Find a module on disk or in memory, and link to it.
475  */
476 static module_entry_t *linkto_module(const char *module_name,
477                                      CONF_SECTION *cs)
478 {
479         module_entry_t myentry;
480         module_entry_t *node;
481         lt_dlhandle handle = NULL;
482         char module_struct[256];
483         char *p;
484         const module_t *module;
485
486         strlcpy(myentry.name, module_name, sizeof(myentry.name));
487         node = rbtree_finddata(module_tree, &myentry);
488         if (node) return node;
489
490         /*
491          *      Link to the module's rlm_FOO{} module structure.
492          *
493          *      The module_name variable has the version number
494          *      embedded in it, and we don't want that here.
495          */
496         strcpy(module_struct, module_name);
497         p = strrchr(module_struct, '-');
498         if (p) *p = '\0';
499
500 #if defined(WITHOUT_LIBLTDL) && defined (WITH_DLOPEN) && defined(RTLD_SELF)
501         module = lt_dlsym(RTLD_SELF, module_struct);
502         if (module) goto open_self;
503 #endif
504
505         /*
506          *      Keep the handle around so we can dlclose() it.
507          */
508         handle = fr_dlopenext(module_name);
509         if (handle == NULL) {
510                 cf_log_err(cf_sectiontoitem(cs),
511                            "Failed to link to module '%s': %s\n",
512                            module_name, lt_dlerror());
513                 return NULL;
514         }
515
516         DEBUG3("    (Loaded %s, checking if it's valid)", module_name);
517
518         /*
519          *      libltld MAY core here, if the handle it gives us contains
520          *      garbage data.
521          */
522         module = lt_dlsym(handle, module_struct);
523         if (!module) {
524                 cf_log_err(cf_sectiontoitem(cs),
525                            "Failed linking to %s structure: %s\n",
526                            module_name, lt_dlerror());
527                 lt_dlclose(handle);
528                 return NULL;
529         }
530
531 #if defined(WITHOUT_LIBLTDL) && defined (WITH_DLOPEN) && defined(RTLD_SELF)
532  open_self:
533 #endif
534         /*
535          *      Before doing anything else, check if it's sane.
536          */
537         if (module->magic != RLM_MODULE_MAGIC_NUMBER) {
538                 lt_dlclose(handle);
539                 cf_log_err(cf_sectiontoitem(cs),
540                            "Invalid version in module '%s'",
541                            module_name);
542                 return NULL;
543
544         }
545
546         /* make room for the module type */
547         node = rad_malloc(sizeof(*node));
548         memset(node, 0, sizeof(*node));
549         strlcpy(node->name, module_name, sizeof(node->name));
550         node->module = module;
551         node->handle = handle;
552
553         cf_log_module(cs, "Linked to module %s", module_name);
554
555         /*
556          *      Add the module as "rlm_foo-version" to the configuration
557          *      section.
558          */
559         if (!rbtree_insert(module_tree, node)) {
560                 radlog(L_ERR, "Failed to cache module %s", module_name);
561                 lt_dlclose(handle);
562                 free(node);
563                 return NULL;
564         }
565
566         return node;
567 }
568
569 /*
570  *      Find a module instance.
571  */
572 module_instance_t *find_module_instance(CONF_SECTION *modules,
573                                         const char *instname, int do_link)
574 {
575         int check_config_safe = FALSE;
576         CONF_SECTION *cs;
577         const char *name1;
578         module_instance_t *node, myNode;
579         char module_name[256];
580
581         if (!modules) return NULL;
582
583         /*
584          *      Module instances are declared in the modules{} block
585          *      and referenced later by their name, which is the
586          *      name2 from the config section, or name1 if there was
587          *      no name2.
588          */
589         cs = cf_section_sub_find_name2(modules, NULL, instname);
590         if (cs == NULL) {
591                 radlog(L_ERR, "ERROR: Cannot find a configuration entry for module \"%s\".\n", instname);
592                 return NULL;
593         }
594
595         /*
596          *      If there's already a module instance, return it.
597          */
598         strlcpy(myNode.name, instname, sizeof(myNode.name));
599         node = rbtree_finddata(instance_tree, &myNode);
600         if (node) return node;
601
602         if (!do_link) return NULL;
603
604         name1 = cf_section_name1(cs);
605
606         /*
607          *      Found the configuration entry.
608          */
609         node = rad_malloc(sizeof(*node));
610         memset(node, 0, sizeof(*node));
611
612         node->insthandle = NULL;
613         node->cs = cs;
614
615         /*
616          *      Names in the "modules" section aren't prefixed
617          *      with "rlm_", so we add it here.
618          */
619         snprintf(module_name, sizeof(module_name), "rlm_%s", name1);
620
621         node->entry = linkto_module(module_name, cs);
622         if (!node->entry) {
623                 free(node);
624                 /* linkto_module logs any errors */
625                 return NULL;
626         }
627
628         if (check_config && (node->entry->module->instantiate) &&
629             (node->entry->module->type & RLM_TYPE_CHECK_CONFIG_SAFE) == 0) {
630                 const char *value = NULL;
631                 CONF_PAIR *cp;
632
633                 cp = cf_pair_find(cs, "force_check_config");
634                 if (cp) value = cf_pair_value(cp);
635
636                 if (value && (strcmp(value, "yes") == 0)) goto print_inst;
637
638                 cf_log_module(cs, "Skipping instantiation of %s", instname);
639         } else {
640         print_inst:
641                 check_config_safe = TRUE;
642                 cf_log_module(cs, "Instantiating module \"%s\" from file %s",
643                               instname, cf_section_filename(cs));
644         }
645
646         /*
647          *      Call the module's instantiation routine.
648          */
649         if ((node->entry->module->instantiate) &&
650             (!check_config || check_config_safe) &&
651             ((node->entry->module->instantiate)(cs, &node->insthandle) < 0)) {
652                 cf_log_err(cf_sectiontoitem(cs),
653                            "Instantiation failed for module \"%s\"",
654                            instname);
655                 free(node);
656                 return NULL;
657         }
658
659         /*
660          *      We're done.  Fill in the rest of the data structure,
661          *      and link it to the module instance list.
662          */
663         strlcpy(node->name, instname, sizeof(node->name));
664
665 #ifdef HAVE_PTHREAD_H
666         /*
667          *      If we're threaded, check if the module is thread-safe.
668          *
669          *      If it isn't, we create a mutex.
670          */
671         if ((node->entry->module->type & RLM_TYPE_THREAD_UNSAFE) != 0) {
672                 node->mutex = (pthread_mutex_t *) rad_malloc(sizeof(pthread_mutex_t));
673                 /*
674                  *      Initialize the mutex.
675                  */
676                 pthread_mutex_init(node->mutex, NULL);
677         } else {
678                 /*
679                  *      The module is thread-safe.  Don't give it a mutex.
680                  */
681                 node->mutex = NULL;
682         }
683
684 #endif
685         rbtree_insert(instance_tree, node);
686
687         return node;
688 }
689
690 static indexed_modcallable *lookup_by_index(rbtree_t *components,
691                                             int comp, int idx)
692 {
693         indexed_modcallable myc;
694         
695         myc.comp = comp;
696         myc.idx = idx;
697
698         return rbtree_finddata(components, &myc);
699 }
700
701 /*
702  *      Create a new sublist.
703  */
704 static indexed_modcallable *new_sublist(rbtree_t *components, int comp, int idx)
705 {
706         indexed_modcallable *c;
707
708         c = lookup_by_index(components, comp, idx);
709
710         /* It is an error to try to create a sublist that already
711          * exists. It would almost certainly be caused by accidental
712          * duplication in the config file.
713          *
714          * index 0 is the exception, because it is used when we want
715          * to collect _all_ listed modules under a single index by
716          * default, which is currently the case in all components
717          * except authenticate. */
718         if (c) {
719                 if (idx == 0) {
720                         return c;
721                 }
722                 return NULL;
723         }
724
725         c = rad_malloc(sizeof(*c));
726         c->modulelist = NULL;
727         c->comp = comp;
728         c->idx = idx;
729
730         if (!rbtree_insert(components, c)) {
731                 free(c);
732                 return NULL;
733         }
734
735         return c;
736 }
737
738 int indexed_modcall(int comp, int idx, REQUEST *request)
739 {
740         int rcode;
741         modcallable *list = NULL;
742         virtual_server_t *server;
743
744         /*
745          *      Hack to find the correct virtual server.
746          */
747         server = virtual_server_find(request->server);
748         if (!server) {
749                 RDEBUG("No such virtual server \"%s\"", request->server);
750                 return RLM_MODULE_FAIL;
751         }
752
753         if (idx == 0) {
754                 list = server->mc[comp];
755                 if (!list) RDEBUG2("  WARNING: Empty %s section.  Using default return values.", section_type_value[comp].section);
756
757         } else {
758                 indexed_modcallable *this;
759
760                 this = lookup_by_index(server->components, comp, idx);
761                 if (this) {
762                         list = this->modulelist;
763                 } else {
764                         RDEBUG2("  WARNING: Unknown value specified for %s.  Cannot perform requested action.",
765                                 section_type_value[comp].typename);
766                 }
767         }
768         
769         if (server->subcs[comp]) {
770                 if (idx == 0) {
771                         RDEBUG("# Executing section %s from file %s",
772                                section_type_value[comp].section,
773                                cf_section_filename(server->subcs[comp]));
774                 } else {
775                         RDEBUG("# Executing group from file %s",
776                                cf_section_filename(server->subcs[comp]));
777                 }
778         }
779         request->component = section_type_value[comp].section;
780
781         rcode = modcall(comp, list, request);
782
783         request->module = "";
784         request->component = "<core>";
785         return rcode;
786 }
787
788 /*
789  *      Load a sub-module list, as found inside an Auth-Type foo {}
790  *      block
791  */
792 static int load_subcomponent_section(modcallable *parent, CONF_SECTION *cs,
793                                      rbtree_t *components,
794                                      const DICT_ATTR *dattr, int comp)
795 {
796         indexed_modcallable *subcomp;
797         modcallable *ml;
798         DICT_VALUE *dval;
799         const char *name2 = cf_section_name2(cs);
800
801         rad_assert(comp >= RLM_COMPONENT_AUTH);
802         rad_assert(comp < RLM_COMPONENT_COUNT);
803
804         /*
805          *      Sanity check.
806          */
807         if (!name2) {
808                 cf_log_err(cf_sectiontoitem(cs),
809                            "No name specified for %s block",
810                            section_type_value[comp].typename);
811                 return 1;
812         }
813
814         /*
815          *      Compile the group.
816          */
817         ml = compile_modgroup(parent, comp, cs);
818         if (!ml) {
819                 return 0;
820         }
821
822         /*
823          *      We must assign a numeric index to this subcomponent.
824          *      It is generated and placed in the dictionary
825          *      automatically.  If it isn't found, it's a serious
826          *      error.
827          */
828         dval = dict_valbyname(dattr->attr, dattr->vendor, name2);
829         if (!dval) {
830                 cf_log_err(cf_sectiontoitem(cs),
831                            "%s %s Not previously configured",
832                            section_type_value[comp].typename, name2);
833                 modcallable_free(&ml);
834                 return 0;
835         }
836
837         subcomp = new_sublist(components, comp, dval->value);
838         if (!subcomp) {
839                 modcallable_free(&ml);
840                 return 1;
841         }
842
843         subcomp->modulelist = ml;
844         return 1;               /* OK */
845 }
846
847 static int define_type(const DICT_ATTR *dattr, const char *name)
848 {
849         uint32_t value;
850         DICT_VALUE *dval;
851
852         /*
853          *      If the value already exists, don't
854          *      create it again.
855          */
856         dval = dict_valbyname(dattr->attr, dattr->vendor, name);
857         if (dval) return 1;
858
859         /*
860          *      Create a new unique value with a
861          *      meaningless number.  You can't look at
862          *      it from outside of this code, so it
863          *      doesn't matter.  The only requirement
864          *      is that it's unique.
865          */
866         do {
867                 value = fr_rand() & 0x00ffffff;
868         } while (dict_valbyattr(dattr->attr, dattr->vendor, value));
869
870         DEBUG2("  Module: Creating %s = %s", dattr->name, name);
871         if (dict_addvalue(name, dattr->name, value) < 0) {
872                 radlog(L_ERR, "%s", fr_strerror());
873                 return 0;
874         }
875
876         return 1;
877 }
878
879 static int load_component_section(CONF_SECTION *cs,
880                                   rbtree_t *components, int comp)
881 {
882         modcallable *this;
883         CONF_ITEM *modref;
884         int idx;
885         indexed_modcallable *subcomp;
886         const char *modname;
887         const char *visiblename;
888         const DICT_ATTR *dattr;
889
890         /*
891          *      Find the attribute used to store VALUEs for this section.
892          */
893         dattr = dict_attrbyvalue(section_type_value[comp].attr, 0);
894         if (!dattr) {
895                 cf_log_err(cf_sectiontoitem(cs),
896                            "No such attribute %s",
897                            section_type_value[comp].typename);
898                 return -1;
899         }
900
901         /*
902          *      Loop over the entries in the named section, loading
903          *      the sections this time.
904          */
905         for (modref = cf_item_find_next(cs, NULL);
906              modref != NULL;
907              modref = cf_item_find_next(cs, modref)) {
908                 const char *name1;
909                 CONF_PAIR *cp = NULL;
910                 CONF_SECTION *scs = NULL;
911
912                 if (cf_item_is_section(modref)) {
913                         scs = cf_itemtosection(modref);
914
915                         name1 = cf_section_name1(scs);
916
917                         if (strcmp(name1,
918                                    section_type_value[comp].typename) == 0) {
919                                 if (!load_subcomponent_section(NULL, scs,
920                                                                components,
921                                                                dattr,
922                                                                comp)) {
923                                         return -1; /* FIXME: memleak? */
924                                 }
925                                 continue;
926                         }
927
928                         cp = NULL;
929
930                 } else if (cf_item_is_pair(modref)) {
931                         cp = cf_itemtopair(modref);
932
933                 } else {
934                         continue; /* ignore it */
935                 }
936
937                 /*
938                  *      Try to compile one entry.
939                  */
940                 this = compile_modsingle(NULL, comp, modref, &modname);
941                 if (!this) {
942                         cf_log_err(cf_sectiontoitem(cs),
943                                    "Errors parsing %s section.\n",
944                                    cf_section_name1(cs));
945                         return -1;
946                 }
947
948                 /*
949                  *      Look for Auth-Type foo {}, which are special
950                  *      cases of named sections, and allowable ONLY
951                  *      at the top-level.
952                  *
953                  *      i.e. They're not allowed in a "group" or "redundant"
954                  *      subsection.
955                  */
956                 if (comp == RLM_COMPONENT_AUTH) {
957                         DICT_VALUE *dval;
958                         const char *modrefname = NULL;
959                         if (cp) {
960                                 modrefname = cf_pair_attr(cp);
961                         } else {
962                                 modrefname = cf_section_name2(scs);
963                                 if (!modrefname) {
964                                         modcallable_free(&this);
965                                         cf_log_err(cf_sectiontoitem(cs),
966                                                    "Errors parsing %s sub-section.\n",
967                                                    cf_section_name1(scs));
968                                         return -1;
969                                 }
970                         }
971
972                         dval = dict_valbyname(PW_AUTH_TYPE, 0, modrefname);
973                         if (!dval) {
974                                 /*
975                                  *      It's a section, but nothing we
976                                  *      recognize.  Die!
977                                  */
978                                 modcallable_free(&this);
979                                 cf_log_err(cf_sectiontoitem(cs),
980                                            "Unknown Auth-Type \"%s\" in %s sub-section.",
981                                            modrefname, section_type_value[comp].section);
982                                 return -1;
983                         }
984                         idx = dval->value;
985                 } else {
986                         /* See the comment in new_sublist() for explanation
987                          * of the special index 0 */
988                         idx = 0;
989                 }
990
991                 subcomp = new_sublist(components, comp, idx);
992                 if (subcomp == NULL) {
993                         modcallable_free(&this);
994                         continue;
995                 }
996
997                 /* If subcomp->modulelist is NULL, add_to_modcallable will
998                  * create it */
999                 visiblename = cf_section_name2(cs);
1000                 if (visiblename == NULL)
1001                         visiblename = cf_section_name1(cs);
1002                 add_to_modcallable(&subcomp->modulelist, this,
1003                                    comp, visiblename);
1004         }
1005
1006         return 0;
1007 }
1008
1009 static int load_byserver(CONF_SECTION *cs)
1010 {
1011         int comp, flag;
1012         const char *name = cf_section_name2(cs);
1013         rbtree_t *components;
1014         virtual_server_t *server = NULL;
1015         indexed_modcallable *c;
1016
1017         if (name) {
1018                 cf_log_info(cs, "server %s { # from file %s",
1019                             name, cf_section_filename(cs));
1020         } else {
1021                 cf_log_info(cs, "server { # from file %s",
1022                             cf_section_filename(cs));
1023         }
1024
1025         cf_log_info(cs, " modules {");
1026
1027         components = rbtree_create(indexed_modcallable_cmp,
1028                                    indexed_modcallable_free, 0);
1029         if (!components) {
1030                 radlog(L_ERR, "Failed to initialize components\n");
1031                 goto error;
1032         }
1033
1034         server = rad_malloc(sizeof(*server));
1035         memset(server, 0, sizeof(*server));
1036
1037         server->name = name;
1038         server->created = time(NULL);
1039         server->cs = cs;
1040         server->components = components;
1041
1042         /*
1043          *      Define types first.
1044          */
1045         for (comp = 0; comp < RLM_COMPONENT_COUNT; ++comp) {
1046                 CONF_SECTION *subcs;
1047                 CONF_ITEM *modref;
1048                 DICT_ATTR *dattr;
1049
1050                 subcs = cf_section_sub_find(cs,
1051                                             section_type_value[comp].section);
1052                 if (!subcs) continue;
1053
1054                 if (cf_item_find_next(subcs, NULL) == NULL) continue;
1055
1056                 /*
1057                  *      Find the attribute used to store VALUEs for this section.
1058                  */
1059                 dattr = dict_attrbyvalue(section_type_value[comp].attr, 0);
1060                 if (!dattr) {
1061                         cf_log_err(cf_sectiontoitem(subcs),
1062                                    "No such attribute %s",
1063                                    section_type_value[comp].typename);
1064                 error:
1065                         if (debug_flag == 0) {
1066                                 radlog(L_ERR, "Failed to load virtual server %s",
1067                                        (name != NULL) ? name : "<default>");
1068                         }
1069                         virtual_server_free(server);
1070                         return -1;
1071                 }
1072
1073                 /*
1074                  *      Define dynamic types, so that others can reference
1075                  *      them.
1076                  */
1077                 for (modref = cf_item_find_next(subcs, NULL);
1078                      modref != NULL;
1079                      modref = cf_item_find_next(subcs, modref)) {
1080                         const char *name1;
1081                         CONF_SECTION *subsubcs;
1082
1083                         /*
1084                          *      Create types for simple references
1085                          *      only when parsing the authenticate
1086                          *      section.
1087                          */
1088                         if ((section_type_value[comp].attr == PW_AUTH_TYPE) &&
1089                             cf_item_is_pair(modref)) {
1090                                 CONF_PAIR *cp = cf_itemtopair(modref);
1091                                 if (!define_type(dattr, cf_pair_attr(cp))) {
1092                                         goto error;
1093                                 }
1094
1095                                 continue;
1096                         }
1097
1098                         if (!cf_item_is_section(modref)) continue;
1099                         
1100                         subsubcs = cf_itemtosection(modref);
1101                         name1 = cf_section_name1(subsubcs);
1102
1103                         if (strcmp(name1, section_type_value[comp].typename) == 0) {
1104                                 if (!define_type(dattr,
1105                                                  cf_section_name2(subsubcs))) {
1106                                         goto error;
1107                                 }
1108                         }
1109                 }
1110         } /* loop over components */
1111
1112         /*
1113          *      Loop over all of the known components, finding their
1114          *      configuration section, and loading it.
1115          */
1116         flag = 0;
1117         for (comp = 0; comp < RLM_COMPONENT_COUNT; ++comp) {
1118                 CONF_SECTION *subcs;
1119
1120                 subcs = cf_section_sub_find(cs,
1121                                             section_type_value[comp].section);
1122                 if (!subcs) continue;
1123                         
1124                 if (cf_item_find_next(subcs, NULL) == NULL) continue;
1125                         
1126                 cf_log_module(cs, "Checking %s {...} for more modules to load",
1127                        section_type_value[comp].section);
1128
1129                 /*
1130                  *      Skip pre/post-proxy sections if we're not
1131                  *      proxying.
1132                  */
1133                 if (
1134 #ifdef WITH_PROXY
1135                     !mainconfig.proxy_requests &&
1136 #endif
1137                     ((comp == RLM_COMPONENT_PRE_PROXY) ||
1138                      (comp == RLM_COMPONENT_POST_PROXY))) {
1139                         continue;
1140                 }
1141
1142 #ifndef WITH_ACCOUNTING
1143                 if (comp == RLM_COMPONENT_ACCT) continue;
1144 #endif
1145
1146 #ifndef WITH_SESSION_MGMT
1147                 if (comp == RLM_COMPONENT_SESS) continue;
1148 #endif
1149
1150                 if (load_component_section(subcs, components, comp) < 0) {
1151                         goto error;
1152                 }
1153
1154                 /*
1155                  *      Cache a default, if it exists.  Some people
1156                  *      put empty sections for some reason...
1157                  */
1158                 c = lookup_by_index(components, comp, 0);
1159                 if (c) server->mc[comp] = c->modulelist;
1160
1161                 server->subcs[comp] = subcs;
1162
1163                 flag = 1;
1164         } /* loop over components */
1165
1166         /*
1167          *      We haven't loaded any of the normal sections.  Maybe we're
1168          *      supposed to load the vmps section.
1169          *
1170          *      This is a bit of a hack...
1171          */
1172         if (!flag) {
1173                 CONF_SECTION *subcs;
1174
1175                 subcs = cf_section_sub_find(cs, "vmps");
1176                 if (subcs) {
1177                         cf_log_module(cs, "Checking vmps {...} for more modules to load");              
1178                         if (load_component_section(subcs, components,
1179                                                    RLM_COMPONENT_POST_AUTH) < 0) {
1180                                 goto error;
1181                         }
1182                         c = lookup_by_index(components,
1183                                             RLM_COMPONENT_POST_AUTH, 0);
1184                         if (c) server->mc[RLM_COMPONENT_POST_AUTH] = c->modulelist;
1185                         flag = 1;
1186                 }
1187
1188 #ifdef WITH_DHCP
1189                 if (!flag) {
1190                         const DICT_ATTR *dattr;
1191
1192                         dattr = dict_attrbyname("DHCP-Message-Type");
1193
1194                         /*
1195                          *      Handle each DHCP Message type separately.
1196                          */
1197                         if (dattr) for (subcs = cf_subsection_find_next(cs, NULL, "dhcp");
1198                                         subcs != NULL;
1199                                         subcs = cf_subsection_find_next(cs, subcs,
1200                                                                         "dhcp")) {
1201                                 const char *name2 = cf_section_name2(subcs);
1202
1203                                 DEBUG2(" Module: Checking dhcp %s {...} for more modules to load", name2);
1204                                 if (!load_subcomponent_section(NULL, subcs,
1205                                                                components,
1206                                                                dattr,
1207                                                                RLM_COMPONENT_POST_AUTH)) {
1208                                         goto error; /* FIXME: memleak? */
1209                                 }
1210                                 c = lookup_by_index(components,
1211                                                     RLM_COMPONENT_POST_AUTH, 0);
1212                                 if (c) server->mc[RLM_COMPONENT_POST_AUTH] = c->modulelist;
1213                                 flag = 1;
1214                         }
1215                 }
1216 #endif
1217         }
1218
1219         cf_log_info(cs, " } # modules");
1220         cf_log_info(cs, "} # server");
1221
1222         if (!flag && name) {
1223                 DEBUG("WARNING: Server %s is empty, and will do nothing!",
1224                       name);
1225         }
1226
1227         if (debug_flag == 0) {
1228                 radlog(L_INFO, "Loaded virtual server %s",
1229                        (name != NULL) ? name : "<default>");
1230         }
1231
1232         /*
1233          *      Now that it is OK, insert it into the list.
1234          *
1235          *      This is thread-safe...
1236          */
1237         comp = virtual_server_idx(name);
1238         server->next = virtual_servers[comp];
1239         virtual_servers[comp] = server;
1240
1241         /*
1242          *      Mark OLDER ones of the same name as being unused.
1243          */
1244         server = server->next;
1245         while (server) {
1246                 if ((!name && !server->name) ||
1247                     (name && server->name &&
1248                      (strcmp(server->name, name) == 0))) {
1249                         server->can_free = TRUE;
1250                         break;
1251                 }
1252                 server = server->next;
1253         }
1254
1255         return 0;
1256 }
1257
1258
1259 /*
1260  *      Load all of the virtual servers.
1261  */
1262 int virtual_servers_load(CONF_SECTION *config)
1263 {
1264         CONF_SECTION *cs;
1265         static int first_time = TRUE;
1266
1267         DEBUG2("%s: #### Loading Virtual Servers ####", mainconfig.name);
1268
1269         /*
1270          *      If we have "server { ...}", then there SHOULD NOT be
1271          *      bare "authorize", etc. sections.  if there is no such
1272          *      server, then try to load the old-style sections first.
1273          *
1274          *      In either case, load the "default" virtual server first.
1275          *      this matches better iwth users expectations.
1276          */
1277         cs = cf_section_find_name2(cf_subsection_find_next(config, NULL,
1278                                                            "server"),
1279                                    "server", NULL);
1280         if (cs) {
1281                 if (load_byserver(cs) < 0) {
1282                         return -1;
1283                 }
1284         } else {
1285                 if (load_byserver(config) < 0) {
1286                         return -1;
1287                 }
1288         }
1289
1290         /*
1291          *      Load all of the virtual servers.
1292          */
1293         for (cs = cf_subsection_find_next(config, NULL, "server");
1294              cs != NULL;
1295              cs = cf_subsection_find_next(config, cs, "server")) {
1296                 const char *name2;
1297                 virtual_server_t *server;
1298
1299                 name2 = cf_section_name2(cs);
1300                 if (!name2) continue; /* handled above */
1301
1302                 server = virtual_server_find(name2);
1303                 if (server &&
1304                     (cf_top_section(server->cs) == config)) {
1305                         radlog(L_ERR, "Duplicate virtual server \"%s\" in file %s:%d and file %s:%d",
1306                                server->name,
1307                                cf_section_filename(server->cs),
1308                                cf_section_lineno(server->cs),
1309                                cf_section_filename(cs),
1310                                cf_section_lineno(cs));
1311                         return -1;
1312                 }
1313
1314                 if (load_byserver(cs) < 0) {
1315                         /*
1316                          *      Once we successfully started once,
1317                          *      continue loading the OTHER servers,
1318                          *      even if one fails.
1319                          */
1320                         if (!first_time) continue;
1321                         return -1;
1322                 }
1323         }
1324
1325         /*
1326          *      If we succeed the first time around, remember that.
1327          */
1328         first_time = FALSE;
1329
1330         return 0;
1331 }
1332
1333 int module_hup_module(CONF_SECTION *cs, module_instance_t *node, time_t when)
1334 {
1335         void *insthandle = NULL;
1336         fr_module_hup_t *mh;
1337
1338         if (!node ||
1339             !node->entry->module->instantiate ||
1340             ((node->entry->module->type & RLM_TYPE_HUP_SAFE) == 0)) {
1341                 return 1;
1342         }
1343
1344         cf_log_module(cs, "Trying to reload module \"%s\"", node->name);
1345         
1346         if ((node->entry->module->instantiate)(cs, &insthandle) < 0) {
1347                 cf_log_err(cf_sectiontoitem(cs),
1348                            "HUP failed for module \"%s\".  Using old configuration.",
1349                            node->name);
1350                 return 0;
1351         }
1352
1353         radlog(L_INFO, " Module: Reloaded module \"%s\"", node->name);
1354
1355         module_instance_free_old(cs, node, when);
1356
1357         /*
1358          *      Save the old instance handle for later deletion.
1359          */
1360         mh = rad_malloc(sizeof(*mh));
1361         mh->mi = node;
1362         mh->when = when;
1363         mh->insthandle = node->insthandle;
1364         mh->next = node->mh;
1365         node->mh = mh;
1366
1367         node->insthandle = insthandle;
1368         
1369         /*
1370          *      FIXME: Set a timeout to come back in 60s, so that
1371          *      we can pro-actively clean up the old instances.
1372          */
1373
1374         return 1;
1375 }
1376
1377
1378 int module_hup(CONF_SECTION *modules)
1379 {
1380         time_t when;
1381         CONF_ITEM *ci;
1382         CONF_SECTION *cs;
1383         module_instance_t *node;
1384
1385         if (!modules) return 0;
1386
1387         when = time(NULL);
1388
1389         /*
1390          *      Loop over the modules
1391          */
1392         for (ci=cf_item_find_next(modules, NULL);
1393              ci != NULL;
1394              ci=cf_item_find_next(modules, ci)) {
1395                 const char *instname;
1396                 module_instance_t myNode;
1397
1398                 /*
1399                  *      If it's not a section, ignore it.
1400                  */
1401                 if (!cf_item_is_section(ci)) continue;
1402
1403                 cs = cf_itemtosection(ci);
1404                 instname = cf_section_name2(cs);
1405                 if (!instname) instname = cf_section_name1(cs);
1406
1407                 strlcpy(myNode.name, instname, sizeof(myNode.name));
1408                 node = rbtree_finddata(instance_tree, &myNode);
1409
1410                 module_hup_module(cs, node, when);
1411         }
1412
1413         return 1;
1414 }
1415
1416
1417 /*
1418  *      Parse the module config sections, and load
1419  *      and call each module's init() function.
1420  *
1421  *      Libtool makes your life a LOT easier, especially with libltdl.
1422  *      see: http://www.gnu.org/software/libtool/
1423  */
1424 int setup_modules(int reload, CONF_SECTION *config)
1425 {
1426         CONF_ITEM       *ci, *next;
1427         CONF_SECTION    *cs, *modules;
1428         rad_listen_t    *listener;
1429
1430         if (reload) return 0;
1431
1432         /*
1433          *      If necessary, initialize libltdl.
1434          */
1435         if (!reload) {
1436                 /*
1437                  *      This line works around a completely
1438                  *
1439                  *              RIDICULOUS INSANE IDIOTIC
1440                  *
1441                  *      bug in libltdl on certain systems.  The "set
1442                  *      preloaded symbols" macro below ends up
1443                  *      referencing this name, but it isn't defined
1444                  *      anywhere in the libltdl source.  As a result,
1445                  *      any program STUPID enough to rely on libltdl
1446                  *      fails to link, because the symbol isn't
1447                  *      defined anywhere.
1448                  *
1449                  *      It's like libtool and libltdl are some kind
1450                  *      of sick joke.
1451                  */
1452 #ifdef IE_LIBTOOL_DIE
1453 #define lt__PROGRAM__LTX_preloaded_symbols lt_libltdl_LTX_preloaded_symbols
1454 #endif
1455
1456                 /*
1457                  *      Set the default list of preloaded symbols.
1458                  *      This is used to initialize libltdl's list of
1459                  *      preloaded modules.
1460                  *
1461                  *      i.e. Static modules.
1462                  */
1463                 LTDL_SET_PRELOADED_SYMBOLS();
1464
1465                 if (lt_dlinit() != 0) {
1466                         radlog(L_ERR, "Failed to initialize libraries: %s\n",
1467                                         lt_dlerror());
1468                         return -1;
1469                 }
1470
1471                 /*
1472                  *      Set the search path to ONLY our library directory.
1473                  *      This prevents the modules from being found from
1474                  *      any location on the disk.
1475                  */
1476                 lt_dlsetsearchpath(radlib_dir);
1477
1478                 /*
1479                  *      Set up the internal module struct.
1480                  */
1481                 module_tree = rbtree_create(module_entry_cmp,
1482                                             module_entry_free, 0);
1483                 if (!module_tree) {
1484                         radlog(L_ERR, "Failed to initialize modules\n");
1485                         return -1;
1486                 }
1487
1488                 instance_tree = rbtree_create(module_instance_cmp,
1489                                               module_instance_free, 0);
1490                 if (!instance_tree) {
1491                         radlog(L_ERR, "Failed to initialize modules\n");
1492                         return -1;
1493                 }
1494         }
1495
1496         memset(virtual_servers, 0, sizeof(virtual_servers));
1497
1498         /*
1499          *      Remember where the modules were stored.
1500          */
1501         modules = cf_section_sub_find(config, "modules");
1502         if (!modules) {
1503                 radlog(L_INFO, "WARNING: Cannot find a \"modules\" section in the configuration file!");
1504         }
1505
1506         DEBUG2("%s: #### Instantiating modules ####", mainconfig.name);
1507
1508         /*
1509          *      Loop over module definitions, looking for duplicates.
1510          *
1511          *      This is O(N^2) in the number of modules, but most
1512          *      systems should have less than 100 modules.
1513          */
1514         for (ci=cf_item_find_next(modules, NULL);
1515              ci != NULL;
1516              ci=next) {
1517                 const char *name1, *name2;
1518                 CONF_SECTION *subcs, *duplicate;
1519
1520                 next = cf_item_find_next(modules, ci);
1521
1522                 if (!cf_item_is_section(ci)) continue;
1523
1524                 if (!next || !cf_item_is_section(next)) continue;
1525
1526                 subcs = cf_itemtosection(ci);
1527                 name1 = cf_section_name1(subcs);
1528                 name2 = cf_section_name2(subcs);
1529
1530                 duplicate = cf_section_find_name2(cf_itemtosection(next),
1531                                                   name1, name2);
1532                 if (!duplicate) continue;
1533
1534                 if (!name2) name2 = "";
1535
1536                 radlog(L_ERR, "Duplicate module \"%s %s\", in file %s:%d and file %s:%d",
1537                        name1, name2,
1538                        cf_section_filename(subcs),
1539                        cf_section_lineno(subcs),
1540                        cf_section_filename(duplicate),
1541                        cf_section_lineno(duplicate));
1542                 return -1;
1543         }
1544
1545         /*
1546          *  Look for the 'instantiate' section, which tells us
1547          *  the instantiation order of the modules, and also allows
1548          *  us to load modules with no authorize/authenticate/etc.
1549          *  sections.
1550          */
1551         cs = cf_section_sub_find(config, "instantiate");
1552         if (cs != NULL) {
1553                 CONF_PAIR *cp;
1554                 module_instance_t *module;
1555                 const char *name;
1556
1557                 cf_log_info(cs, " instantiate {");
1558
1559                 /*
1560                  *  Loop over the items in the 'instantiate' section.
1561                  */
1562                 for (ci=cf_item_find_next(cs, NULL);
1563                      ci != NULL;
1564                      ci=cf_item_find_next(cs, ci)) {
1565
1566                         /*
1567                          *      Skip sections and "other" stuff.
1568                          *      Sections will be handled later, if
1569                          *      they're referenced at all...
1570                          */
1571                         if (!cf_item_is_pair(ci)) {
1572                                 continue;
1573                         }
1574
1575                         cp = cf_itemtopair(ci);
1576                         name = cf_pair_attr(cp);
1577                         module = find_module_instance(modules, name, 1);
1578                         if (!module) {
1579                                 return -1;
1580                         }
1581                 } /* loop over items in the subsection */
1582
1583                 cf_log_info(cs, " }");
1584         } /* if there's an 'instantiate' section. */
1585
1586         /*
1587          *      Loop over the listeners, figuring out which sections
1588          *      to load.
1589          */
1590         for (listener = mainconfig.listen;
1591              listener != NULL;
1592              listener = listener->next) {
1593                 char buffer[256];
1594
1595 #ifdef WITH_PROXY
1596                 if (listener->type == RAD_LISTEN_PROXY) continue;
1597 #endif
1598
1599                 cs = cf_section_sub_find_name2(config,
1600                                                "server", listener->server);
1601                 if (!cs && (listener->server != NULL)) {
1602                         listener->print(listener, buffer, sizeof(buffer));
1603
1604                         radlog(L_ERR, "No server has been defined for %s", buffer);
1605                         return -1;
1606                 }
1607         }
1608
1609         if (virtual_servers_load(config) < 0) return -1;
1610
1611         return 0;
1612 }
1613
1614 /*
1615  *      Call all authorization modules until one returns
1616  *      somethings else than RLM_MODULE_OK
1617  */
1618 int module_authorize(int autz_type, REQUEST *request)
1619 {
1620         return indexed_modcall(RLM_COMPONENT_AUTZ, autz_type, request);
1621 }
1622
1623 /*
1624  *      Authenticate a user/password with various methods.
1625  */
1626 int module_authenticate(int auth_type, REQUEST *request)
1627 {
1628         return indexed_modcall(RLM_COMPONENT_AUTH, auth_type, request);
1629 }
1630
1631 #ifdef WITH_ACCOUNTING
1632 /*
1633  *      Do pre-accounting for ALL configured sessions
1634  */
1635 int module_preacct(REQUEST *request)
1636 {
1637         return indexed_modcall(RLM_COMPONENT_PREACCT, 0, request);
1638 }
1639
1640 /*
1641  *      Do accounting for ALL configured sessions
1642  */
1643 int module_accounting(int acct_type, REQUEST *request)
1644 {
1645         return indexed_modcall(RLM_COMPONENT_ACCT, acct_type, request);
1646 }
1647 #endif
1648
1649 #ifdef WITH_SESSION_MGMT
1650 /*
1651  *      See if a user is already logged in.
1652  *
1653  *      Returns: 0 == OK, 1 == double logins, 2 == multilink attempt
1654  */
1655 int module_checksimul(int sess_type, REQUEST *request, int maxsimul)
1656 {
1657         int rcode;
1658
1659         if(!request->username)
1660                 return 0;
1661
1662         request->simul_count = 0;
1663         request->simul_max = maxsimul;
1664         request->simul_mpp = 1;
1665
1666         rcode = indexed_modcall(RLM_COMPONENT_SESS, sess_type, request);
1667
1668         if (rcode != RLM_MODULE_OK) {
1669                 /* FIXME: Good spot for a *rate-limited* warning to the log */
1670                 return 0;
1671         }
1672
1673         return (request->simul_count < maxsimul) ? 0 : request->simul_mpp;
1674 }
1675 #endif
1676
1677 #ifdef WITH_PROXY
1678 /*
1679  *      Do pre-proxying for ALL configured sessions
1680  */
1681 int module_pre_proxy(int type, REQUEST *request)
1682 {
1683         return indexed_modcall(RLM_COMPONENT_PRE_PROXY, type, request);
1684 }
1685
1686 /*
1687  *      Do post-proxying for ALL configured sessions
1688  */
1689 int module_post_proxy(int type, REQUEST *request)
1690 {
1691         return indexed_modcall(RLM_COMPONENT_POST_PROXY, type, request);
1692 }
1693 #endif
1694
1695 /*
1696  *      Do post-authentication for ALL configured sessions
1697  */
1698 int module_post_auth(int postauth_type, REQUEST *request)
1699 {
1700         return indexed_modcall(RLM_COMPONENT_POST_AUTH, postauth_type, request);
1701 }
1702
1703 #ifdef WITH_COA
1704 int module_recv_coa(int recv_coa_type, REQUEST *request)
1705 {
1706         return indexed_modcall(RLM_COMPONENT_RECV_COA, recv_coa_type, request);
1707 }
1708
1709 int module_send_coa(int send_coa_type, REQUEST *request)
1710 {
1711         return indexed_modcall(RLM_COMPONENT_SEND_COA, send_coa_type, request);
1712 }
1713 #endif