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