Define dynamic types (Autz-type foo) etc. before trying to load
[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 typedef struct indexed_modcallable {
34         const           char *server;
35         int             comp;
36         int             idx;
37         modcallable     *modulelist;
38 } indexed_modcallable;
39
40 /*
41  *      For each component, keep an ordered list of ones to call.
42  */
43 static rbtree_t *components;
44
45 static rbtree_t *module_tree = NULL;
46
47 typedef struct section_type_value_t {
48         const char      *section;
49         const char      *typename;
50         int             attr;
51 } section_type_value_t;
52
53
54 /*
55  *      Ordered by component
56  */
57 static const section_type_value_t section_type_value[RLM_COMPONENT_COUNT] = {
58         { "authenticate", "Auth-Type",       PW_AUTH_TYPE },
59         { "authorize",    "Autz-Type",       PW_AUTZ_TYPE },
60         { "preacct",      "Pre-Acct-Type",   PW_PRE_ACCT_TYPE },
61         { "accounting",   "Acct-Type",       PW_ACCT_TYPE },
62         { "session",      "Session-Type",    PW_SESSION_TYPE },
63         { "pre-proxy",    "Pre-Proxy-Type",  PW_PRE_PROXY_TYPE },
64         { "post-proxy",   "Post-Proxy-Type", PW_POST_PROXY_TYPE },
65         { "post-auth",    "Post-Auth-Type",  PW_POST_AUTH_TYPE },
66 };
67
68 static void indexed_modcallable_free(void *data)
69 {
70         indexed_modcallable *c = data;
71
72         modcallable_free(&c->modulelist);
73         free(c);
74 }
75
76 static int indexed_modcallable_cmp(const void *one, const void *two)
77 {
78         int rcode;
79         const indexed_modcallable *a = one;
80         const indexed_modcallable *b = two;
81
82         if (a->server && !b->server) return -1;
83         if (!a->server && b->server) return +1;
84         if (a->server && b->server) {
85                 rcode = strcmp(a->server, b->server);
86                 if (rcode != 0) return rcode;
87         }
88
89         if (a->comp < b->comp) return -1;
90         if (a->comp >  b->comp) return +1;
91
92         return a->idx - b->idx;
93 }
94
95
96 /*
97  *      Free a module instance.
98  */
99 static void module_instance_free(void *data)
100 {
101         module_instance_t *this = data;
102
103         if (this->entry->module->detach)
104                 (this->entry->module->detach)(this->insthandle);
105 #ifdef HAVE_PTHREAD_H
106         if (this->mutex) {
107                 /*
108                  *      FIXME
109                  *      The mutex MIGHT be locked...
110                  *      we'll check for that later, I guess.
111                  */
112                 pthread_mutex_destroy(this->mutex);
113                 free(this->mutex);
114         }
115 #endif
116         free(this);
117 }
118
119
120 /*
121  *      Compare two module entries
122  */
123 static int module_entry_cmp(const void *one, const void *two)
124 {
125         const module_entry_t *a = one;
126         const module_entry_t *b = two;
127
128         return strcmp(a->name, b->name);
129 }
130
131 /*
132  *      Free a module entry.
133  */
134 static void module_entry_free(void *data)
135 {
136         module_entry_t *this = data;
137
138         lt_dlclose(this->handle);       /* ignore any errors */
139         free(this);
140 }
141
142
143 /*
144  *      Remove the module lists.
145  */
146 int detach_modules(void)
147 {
148         rbtree_free(components);
149         rbtree_free(module_tree);
150
151         return 0;
152 }
153
154
155 /*
156  *      Find a module on disk or in memory, and link to it.
157  */
158 static module_entry_t *linkto_module(const char *module_name,
159                                      CONF_SECTION *cs)
160 {
161         module_entry_t myentry;
162         module_entry_t *node;
163         lt_dlhandle handle;
164         char module_struct[256];
165         char *p;
166         const void *module;
167
168         strlcpy(myentry.name, module_name, sizeof(myentry.name));
169         node = rbtree_finddata(module_tree, &myentry);
170         if (node) return node;
171
172         /*
173          *      Keep the handle around so we can dlclose() it.
174          */
175         handle = lt_dlopenext(module_name);
176         if (handle == NULL) {
177                 cf_log_err(cf_sectiontoitem(cs),
178                            "Failed to link to module '%s': %s\n",
179                            module_name, lt_dlerror());
180                 return NULL;
181         }
182
183         /*
184          *      Link to the module's rlm_FOO{} module structure.
185          *
186          *      The module_name variable has the version number
187          *      embedded in it, and we don't want that here.
188          */
189         strcpy(module_struct, module_name);
190         p = strrchr(module_struct, '-');
191         if (p) *p = '\0';
192
193         DEBUG3("    (Loaded %s, checking if it's valid)", module_name);
194
195         /*
196          *      libltld MAY core here, if the handle it gives us contains
197          *      garbage data.
198          */
199         module = lt_dlsym(handle, module_struct);
200         if (!module) {
201                 cf_log_err(cf_sectiontoitem(cs),
202                            "Failed linking to %s structure: %s\n",
203                            module_name, lt_dlerror());
204                 lt_dlclose(handle);
205                 return NULL;
206         }
207         /*
208          *      Before doing anything else, check if it's sane.
209          */
210         if ((*(const uint32_t *) module) != RLM_MODULE_MAGIC_NUMBER) {
211                 lt_dlclose(handle);
212                 cf_log_err(cf_sectiontoitem(cs),
213                            "Invalid version in module '%s'",
214                            module_name);
215                 return NULL;
216
217         }
218
219         /* make room for the module type */
220         node = rad_malloc(sizeof(*node));
221         memset(node, 0, sizeof(*node));
222         strlcpy(node->name, module_name, sizeof(node->name));
223         node->module = module;
224         node->handle = handle;
225
226         DEBUG(" Module: Linked to module %s", module_name);
227
228         /*
229          *      Add the module as "rlm_foo-version" to the configuration
230          *      section.
231          */
232         if (!rbtree_insert(module_tree, node)) {
233                 radlog(L_ERR, "Failed to cache module %s", module_name);
234                 lt_dlclose(handle);
235                 free(node);
236                 return NULL;
237         }
238
239         return node;
240 }
241
242 /*
243  *      Find a module instance.
244  */
245 module_instance_t *find_module_instance(CONF_SECTION *modules,
246                                         const char *instname)
247 {
248         CONF_SECTION *cs;
249         const char *name1, *name2;
250         module_instance_t *node;
251         char module_name[256];
252
253         if (!modules) return NULL;
254
255         /*
256          *      Module instances are declared in the modules{} block
257          *      and referenced later by their name, which is the
258          *      name2 from the config section, or name1 if there was
259          *      no name2.
260          */
261         cs = cf_section_sub_find_name2(modules, NULL, instname);
262         if (cs == NULL) {
263                 radlog(L_ERR, "ERROR: Cannot find a configuration entry for module \"%s\".\n", instname);
264                 return NULL;
265         }
266
267         /*
268          *      If there's already a module instance, return it.
269          */
270         node = cf_data_find(cs, "instance");
271         if (node) return node;
272
273         name1 = cf_section_name1(cs);
274         name2 = cf_section_name2(cs);
275
276         /*
277          *      Found the configuration entry.
278          */
279         node = rad_malloc(sizeof(*node));
280         memset(node, 0, sizeof(*node));
281
282         node->insthandle = NULL;
283
284         /*
285          *      Names in the "modules" section aren't prefixed
286          *      with "rlm_", so we add it here.
287          */
288         snprintf(module_name, sizeof(module_name), "rlm_%s", name1);
289
290         node->entry = linkto_module(module_name, cs);
291         if (!node->entry) {
292                 free(node);
293                 /* linkto_module logs any errors */
294                 return NULL;
295         }
296
297         DEBUG2(" Module: Instantiating %s", instname);
298
299         /*
300          *      Call the module's instantiation routine.
301          */
302         if ((node->entry->module->instantiate) &&
303             ((node->entry->module->instantiate)(cs, &node->insthandle) < 0)) {
304                 cf_log_err(cf_sectiontoitem(cs),
305                            "Instantiation failed for module \"%s\"",
306                            instname);
307                 free(node);
308                 return NULL;
309         }
310
311         /*
312          *      We're done.  Fill in the rest of the data structure,
313          *      and link it to the module instance list.
314          */
315         strlcpy(node->name, instname, sizeof(node->name));
316
317 #ifdef HAVE_PTHREAD_H
318         /*
319          *      If we're threaded, check if the module is thread-safe.
320          *
321          *      If it isn't, we create a mutex.
322          */
323         if ((node->entry->module->type & RLM_TYPE_THREAD_UNSAFE) != 0) {
324                 node->mutex = (pthread_mutex_t *) rad_malloc(sizeof(pthread_mutex_t));
325                 /*
326                  *      Initialize the mutex.
327                  */
328                 pthread_mutex_init(node->mutex, NULL);
329         } else {
330                 /*
331                  *      The module is thread-safe.  Don't give it a mutex.
332                  */
333                 node->mutex = NULL;
334         }
335
336 #endif
337         cf_data_add(cs, "instance", node, module_instance_free);
338
339         return node;
340 }
341
342 static indexed_modcallable *lookup_by_index(const char *server, int comp,
343                                             int idx)
344 {
345         indexed_modcallable myc;
346         
347         myc.comp = comp;
348         myc.idx = idx;
349         myc.server = server;
350
351         return rbtree_finddata(components, &myc);
352 }
353
354 /*
355  *      Create a new sublist.
356  */
357 static indexed_modcallable *new_sublist(const char *server, int comp, int idx)
358 {
359         indexed_modcallable *c;
360
361         c = lookup_by_index(server, comp, idx);
362
363         /* It is an error to try to create a sublist that already
364          * exists. It would almost certainly be caused by accidental
365          * duplication in the config file.
366          *
367          * index 0 is the exception, because it is used when we want
368          * to collect _all_ listed modules under a single index by
369          * default, which is currently the case in all components
370          * except authenticate. */
371         if (c) {
372                 if (idx == 0) {
373                         return c;
374                 }
375                 return NULL;
376         }
377
378         c = rad_malloc(sizeof(*c));
379         c->modulelist = NULL;
380         c->server = server;
381         c->comp = comp;
382         c->idx = idx;
383
384         if (!rbtree_insert(components, c)) {
385                 free(c);
386                 return NULL;
387         }
388
389         return c;
390 }
391
392 static int indexed_modcall(int comp, int idx, REQUEST *request)
393 {
394         int rcode;
395         indexed_modcallable *this;
396         modcallable *list = NULL;
397
398         this = lookup_by_index(request->server, comp, idx);
399         if (!this) {
400                 if (idx != 0) DEBUG2("  WARNING: Unknown value specified for %s.  Cannot perform requested action.",
401                                      section_type_value[comp].typename);
402         } else {
403                 list = this->modulelist;
404         }
405
406         request->component = section_type_value[comp].section;
407
408         rcode = modcall(comp, list, request);
409
410         request->module = "<server-core>";
411         request->component = "<server-core>";
412         return rcode;
413 }
414
415 /*
416  *      Load a sub-module list, as found inside an Auth-Type foo {}
417  *      block
418  */
419 static int load_subcomponent_section(modcallable *parent, CONF_SECTION *cs,
420                                      const char *server, int comp)
421 {
422         indexed_modcallable *subcomp;
423         modcallable *ml;
424         DICT_VALUE *dval;
425         const char *name2 = cf_section_name2(cs);
426
427         rad_assert(comp >= RLM_COMPONENT_AUTH);
428         rad_assert(comp <= RLM_COMPONENT_COUNT);
429
430         /*
431          *      Sanity check.
432          */
433         if (!name2) {
434                 cf_log_err(cf_sectiontoitem(cs),
435                            "No name specified for %s block",
436                            section_type_value[comp].typename);
437                 return 1;
438         }
439
440         /*
441          *      Compile the group.
442          */
443         ml = compile_modgroup(parent, comp, cs);
444         if (!ml) {
445                 return 0;
446         }
447
448         /*
449          *      We must assign a numeric index to this subcomponent.
450          *      It is generated and placed in the dictionary
451          *      automatically.  If it isn't found, it's a serious
452          *      error.
453          */
454         dval = dict_valbyname(section_type_value[comp].attr, name2);
455         if (!dval) {
456                 cf_log_err(cf_sectiontoitem(cs),
457                            "%s %s Not previously configured",
458                            section_type_value[comp].typename, name2);
459                 modcallable_free(&ml);
460                 return 0;
461         }
462
463         subcomp = new_sublist(server, comp, dval->value);
464         if (!subcomp) {
465                 modcallable_free(&ml);
466                 return 1;
467         }
468
469         subcomp->modulelist = ml;
470         return 1;               /* OK */
471 }
472
473 static int define_type(const DICT_ATTR *dattr, const char *name)
474 {
475         uint32_t value;
476         DICT_VALUE *dval;
477
478         /*
479          *      If the value already exists, don't
480          *      create it again.
481          */
482         dval = dict_valbyname(dattr->attr, name);
483         if (dval) return 1;
484
485         /*
486          *      Create a new unique value with a
487          *      meaningless number.  You can't look at
488          *      it from outside of this code, so it
489          *      doesn't matter.  The only requirement
490          *      is that it's unique.
491          */
492         do {
493                 value = lrad_rand() & 0x00ffffff;
494         } while (dict_valbyattr(dattr->attr, value));
495
496         if (dict_addvalue(name, dattr->name, value) < 0) {
497                 radlog(L_ERR, "%s", librad_errstr);
498                 return 0;
499         }
500
501         return 1;
502 }
503
504 static int load_component_section(CONF_SECTION *cs,
505                                   const char *server, int comp)
506 {
507         modcallable *this;
508         CONF_ITEM *modref;
509         int idx;
510         indexed_modcallable *subcomp;
511         const char *modname, *name1;
512         const char *visiblename;
513         const DICT_ATTR *dattr;
514         CONF_PAIR *cp;
515         CONF_SECTION *scs;
516
517         /*
518          *      Find the attribute used to store VALUEs for this section.
519          */
520         dattr = dict_attrbyvalue(section_type_value[comp].attr);
521         if (!dattr) {
522                 cf_log_err(cf_sectiontoitem(cs),
523                            "No such attribute %s",
524                            section_type_value[comp].typename);
525                 return -1;
526         }
527
528         /*
529          *      Define dynamic types, so that others can reference
530          *      them.
531          */
532         for (modref = cf_item_find_next(cs, NULL);
533              modref != NULL;
534              modref = cf_item_find_next(cs, modref)) {
535                 if (!cf_item_is_section(modref)) continue;
536
537                 scs = cf_itemtosection(modref);
538                 name1 = cf_section_name1(scs);
539                 
540                 if (strcmp(name1, section_type_value[comp].typename) == 0) {
541                         if (!define_type(dattr, cf_section_name2(scs))) {
542                                 return -1;
543                         }
544                 }
545         }
546
547
548         /*
549          *      Loop over the entries in the named section, loading
550          *      the sections this time.
551          */
552         for (modref = cf_item_find_next(cs, NULL);
553              modref != NULL;
554              modref = cf_item_find_next(cs, modref)) {
555                 cp = NULL;
556                 scs = NULL;
557
558                 if (cf_item_is_section(modref)) {
559                         scs = cf_itemtosection(modref);
560
561                         name1 = cf_section_name1(scs);
562
563                         if (strcmp(name1,
564                                    section_type_value[comp].typename) == 0) {
565                                 if (!load_subcomponent_section(NULL, scs,
566                                                                server, comp)) {
567                                         return -1; /* FIXME: memleak? */
568                                 }
569                                 continue;
570                         }
571
572                         cp = NULL;
573                 } else if (cf_item_is_pair(modref)) {
574                         cp = cf_itemtopair(modref);
575
576                         /*
577                          *      Create types for simple references
578                          *      only when parsing the authenticate
579                          *      section.
580                          */
581                         if (section_type_value[comp].attr == PW_AUTH_TYPE) {
582                                 if (!define_type(dattr, cf_pair_attr(cp))) {
583                                         return -1;
584                                 }
585                         }
586
587                 } else {
588                         continue; /* ignore it */
589                 }
590
591                 /*
592                  *      Try to compile one entry.
593                  */
594                 this = compile_modsingle(NULL, comp, modref, &modname);
595                 if (!this) {
596                         cf_log_err(cf_sectiontoitem(cs),
597                                    "Errors parsing %s section.\n",
598                                    cf_section_name1(cs));
599                         return -1;
600                 }
601
602                 /*
603                  *      Look for Auth-Type foo {}, which are special
604                  *      cases of named sections, and allowable ONLY
605                  *      at the top-level.
606                  *
607                  *      i.e. They're not allowed in a "group" or "redundant"
608                  *      subsection.
609                  */
610                 if (comp == RLM_COMPONENT_AUTH) {
611                         DICT_VALUE *dval;
612                         const char *modrefname = NULL;
613                         if (cp) {
614                                 modrefname = cf_pair_attr(cp);
615                         } else {
616                                 modrefname = cf_section_name2(scs);
617                                 if (!modrefname) {
618                                         cf_log_err(cf_sectiontoitem(cs),
619                                                    "Errors parsing %s sub-section.\n",
620                                                    cf_section_name1(scs));
621                                         return -1;
622                                 }
623                         }
624
625                         dval = dict_valbyname(PW_AUTH_TYPE, modrefname);
626                         if (!dval) {
627                                 /*
628                                  *      It's a section, but nothing we
629                                  *      recognize.  Die!
630                                  */
631                                 cf_log_err(cf_sectiontoitem(cs),
632                                            "Unknown Auth-Type \"%s\" in %s sub-section.",
633                                            modrefname, section_type_value[comp].section);
634                                 return -1;
635                         }
636                         idx = dval->value;
637                 } else {
638                         /* See the comment in new_sublist() for explanation
639                          * of the special index 0 */
640                         idx = 0;
641                 }
642
643                 subcomp = new_sublist(server, comp, idx);
644                 if (subcomp == NULL) {
645                         modcallable_free(&this);
646                         continue;
647                 }
648
649                 /* If subcomp->modulelist is NULL, add_to_modcallable will
650                  * create it */
651                 visiblename = cf_section_name2(cs);
652                 if (visiblename == NULL)
653                         visiblename = cf_section_name1(cs);
654                 add_to_modcallable(&subcomp->modulelist, this,
655                                    comp, visiblename);
656         }
657
658         return 0;
659 }
660
661 static int load_byserver(CONF_SECTION *cs)
662 {
663         int comp, flag;
664         const char *server = cf_section_name2(cs);
665
666         DEBUG2(" modules {");
667         
668         /*
669          *      Loop over all of the known components, finding their
670          *      configuration section, and loading it.
671          */
672         flag = 0;
673         for (comp = 0; comp < RLM_COMPONENT_COUNT; ++comp) {
674                 CONF_SECTION *subcs;
675
676                 subcs = cf_section_sub_find(cs,
677                                             section_type_value[comp].section);
678                 if (!subcs) continue;
679                         
680                 if (cf_item_find_next(subcs, NULL) == NULL) continue;
681                         
682                 DEBUG2(" Module: Checking %s {...} for more modules to load",
683                        section_type_value[comp].section);
684
685                 if (load_component_section(subcs, server, comp) < 0) {
686                         DEBUG2(" }");
687                         return -1;
688                 }
689                 flag = 1;
690         } /* loop over components */
691
692         /*
693          *      We haven't loaded any of the normal sections.  Maybe we're
694          *      supposed to load the vmps section.
695          *
696          *      This is a bit of a hack...
697          */
698         if (!flag) {
699                 CONF_SECTION *subcs;
700
701                 subcs = cf_section_sub_find(cs, "vmps");
702                 if (subcs) {
703                         DEBUG2(" Module: Checking vmps {...} for more modules to load");                
704                         if (load_component_section(subcs, server,
705                                                    RLM_COMPONENT_POST_AUTH) < 0) {
706                                 return -1;
707                         }
708                         flag = 1;
709                 }
710         }
711
712         DEBUG2(" }");
713
714         if (!flag && server) {
715                 DEBUG("WARNING: Server %s is empty, and will do nothing!",
716                       server);
717         }
718
719         return 0;
720 }
721
722 /*
723  *      Parse the module config sections, and load
724  *      and call each module's init() function.
725  *
726  *      Libtool makes your life a LOT easier, especially with libltdl.
727  *      see: http://www.gnu.org/software/libtool/
728  */
729 int setup_modules(int reload, CONF_SECTION *config)
730 {
731         CONF_SECTION    *cs, *modules;
732         rad_listen_t    *listener;
733         int             null_server = FALSE;
734
735         /*
736          *      If necessary, initialize libltdl.
737          */
738         if (!reload) {
739                 /*
740                  *      Set the default list of preloaded symbols.
741                  *      This is used to initialize libltdl's list of
742                  *      preloaded modules.
743                  *
744                  *      i.e. Static modules.
745                  */
746                 LTDL_SET_PRELOADED_SYMBOLS();
747
748                 if (lt_dlinit() != 0) {
749                         radlog(L_ERR, "Failed to initialize libraries: %s\n",
750                                         lt_dlerror());
751                         return -1;
752                 }
753
754                 /*
755                  *      Set the search path to ONLY our library directory.
756                  *      This prevents the modules from being found from
757                  *      any location on the disk.
758                  */
759                 lt_dlsetsearchpath(radlib_dir);
760
761                 /*
762                  *      Set up the internal module struct.
763                  */
764                 module_tree = rbtree_create(module_entry_cmp,
765                                             module_entry_free, 0);
766                 if (!module_tree) {
767                         radlog(L_ERR, "Failed to initialize modules\n");
768                         return -1;
769                 }
770         } else {
771                 rbtree_free(components);
772         }
773
774         components = rbtree_create(indexed_modcallable_cmp,
775                                    indexed_modcallable_free, 0);
776         if (!components) {
777                 radlog(L_ERR, "Failed to initialize components\n");
778                 return -1;
779         }
780
781         /*
782          *      Remember where the modules were stored.
783          */
784         modules = cf_section_sub_find(config, "modules");
785         if (!modules) {
786                 radlog(L_ERR, "Cannot find a \"modules\" section in the configuration file!");
787                 return -1;
788         }
789
790         DEBUG2("radiusd: #### Instantiating modules ####");
791
792         /*
793          *  Look for the 'instantiate' section, which tells us
794          *  the instantiation order of the modules, and also allows
795          *  us to load modules with no authorize/authenticate/etc.
796          *  sections.
797          */
798         cs = cf_section_sub_find(config, "instantiate");
799         if (cs != NULL) {
800                 CONF_ITEM *ci;
801                 CONF_PAIR *cp;
802                 module_instance_t *module;
803                 const char *name;
804
805                 DEBUG2(" instantiate {");
806
807                 /*
808                  *  Loop over the items in the 'instantiate' section.
809                  */
810                 for (ci=cf_item_find_next(cs, NULL);
811                      ci != NULL;
812                      ci=cf_item_find_next(cs, ci)) {
813
814                         /*
815                          *      Skip sections.  They'll be handled
816                          *      later, if they're referenced at all...
817                          */
818                         if (cf_item_is_section(ci)) {
819                                 continue;
820                         }
821
822                         cp = cf_itemtopair(ci);
823                         name = cf_pair_attr(cp);
824                         module = find_module_instance(modules, name);
825                         if (!module) {
826                                 return -1;
827                         }
828                 } /* loop over items in the subsection */
829
830                 DEBUG2(" }");
831         } /* if there's an 'instantiate' section. */
832
833         /*
834          *      Loop over the listeners, figuring out which sections
835          *      to load.
836          */
837         for (listener = mainconfig.listen;
838              listener != NULL;
839              listener = listener->next) {
840                 char buffer[256];
841
842                 if (listener->type == RAD_LISTEN_PROXY) continue;
843
844                 cs = cf_section_sub_find_name2(config,
845                                                "server", listener->server);
846                 if (!cs && (listener->server != NULL)) {
847                         listener->print(listener, buffer, sizeof(buffer));
848
849                         radlog(L_ERR, "No server has been defined for %s", buffer);
850                         return -1;
851                 }
852         }
853
854         DEBUG2("radiusd: #### Loading Virtual Servers ####");
855
856         /*
857          *      Load all of the virtual servers.
858          */
859         for (cs = cf_subsection_find_next(config, NULL, "server");
860              cs != NULL;
861              cs = cf_subsection_find_next(config, cs, "server")) {
862                 const char *name2 = cf_section_name2(cs);
863
864                 if (name2) {
865                         DEBUG2("server %s {", name2);
866                 } else {
867                         DEBUG2("server {");
868                         null_server = TRUE;
869                 }
870                 if (load_byserver(cs) < 0) {
871                         DEBUG2("}");
872                         return -1;
873                 }
874                 DEBUG2("}");
875         }
876
877         /*
878          *      No empty server defined.  Try to load an old-style
879          *      one for backwards compatibility.
880          */
881         if (!null_server) {
882                 DEBUG2("server {");
883                 if (load_byserver(config) < 0) {
884                         DEBUG2("}");
885                         return -1;
886                 }
887                 DEBUG2("}");
888         }
889
890         return 0;
891 }
892
893 /*
894  *      Call all authorization modules until one returns
895  *      somethings else than RLM_MODULE_OK
896  */
897 int module_authorize(int autz_type, REQUEST *request)
898 {
899         return indexed_modcall(RLM_COMPONENT_AUTZ, autz_type, request);
900 }
901
902 /*
903  *      Authenticate a user/password with various methods.
904  */
905 int module_authenticate(int auth_type, REQUEST *request)
906 {
907         return indexed_modcall(RLM_COMPONENT_AUTH, auth_type, request);
908 }
909
910 /*
911  *      Do pre-accounting for ALL configured sessions
912  */
913 int module_preacct(REQUEST *request)
914 {
915         return indexed_modcall(RLM_COMPONENT_PREACCT, 0, request);
916 }
917
918 /*
919  *      Do accounting for ALL configured sessions
920  */
921 int module_accounting(int acct_type, REQUEST *request)
922 {
923         return indexed_modcall(RLM_COMPONENT_ACCT, acct_type, request);
924 }
925
926 /*
927  *      See if a user is already logged in.
928  *
929  *      Returns: 0 == OK, 1 == double logins, 2 == multilink attempt
930  */
931 int module_checksimul(int sess_type, REQUEST *request, int maxsimul)
932 {
933         int rcode;
934
935         if(!request->username)
936                 return 0;
937
938         request->simul_count = 0;
939         request->simul_max = maxsimul;
940         request->simul_mpp = 1;
941
942         rcode = indexed_modcall(RLM_COMPONENT_SESS, sess_type, request);
943
944         if (rcode != RLM_MODULE_OK) {
945                 /* FIXME: Good spot for a *rate-limited* warning to the log */
946                 return 0;
947         }
948
949         return (request->simul_count < maxsimul) ? 0 : request->simul_mpp;
950 }
951
952 /*
953  *      Do pre-proxying for ALL configured sessions
954  */
955 int module_pre_proxy(int type, REQUEST *request)
956 {
957         return indexed_modcall(RLM_COMPONENT_PRE_PROXY, type, request);
958 }
959
960 /*
961  *      Do post-proxying for ALL configured sessions
962  */
963 int module_post_proxy(int type, REQUEST *request)
964 {
965         return indexed_modcall(RLM_COMPONENT_POST_PROXY, type, request);
966 }
967
968 /*
969  *      Do post-authentication for ALL configured sessions
970  */
971 int module_post_auth(int postauth_type, REQUEST *request)
972 {
973         return indexed_modcall(RLM_COMPONENT_POST_AUTH, postauth_type, request);
974 }