Removed unused variable
[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;
512         const char *visiblename;
513         const DICT_ATTR *dattr;
514
515         /*
516          *      Find the attribute used to store VALUEs for this section.
517          */
518         dattr = dict_attrbyvalue(section_type_value[comp].attr);
519         if (!dattr) {
520                 cf_log_err(cf_sectiontoitem(cs),
521                            "No such attribute %s",
522                            section_type_value[comp].typename);
523                 return -1;
524         }
525
526         /*
527          *      Loop over the entries in the named section.
528          */
529         for (modref = cf_item_find_next(cs, NULL);
530              modref != NULL;
531              modref = cf_item_find_next(cs, modref)) {
532                 CONF_PAIR *cp = NULL;
533                 CONF_SECTION *scs = NULL;
534
535                 if (cf_item_is_section(modref)) {
536                         const char *name1;
537                         scs = cf_itemtosection(modref);
538
539                         name1 = cf_section_name1(scs);
540
541                         if (strcmp(name1,
542                                    section_type_value[comp].typename) == 0) {
543
544                                 if (!define_type(dattr, cf_section_name2(scs))) {
545                                         return -1;
546                                 }
547
548                                 if (!load_subcomponent_section(NULL, scs,
549                                                                server, comp)) {
550                                         return -1; /* FIXME: memleak? */
551                                 }
552                                 continue;
553                         }
554
555                         cp = NULL;
556                 } else if (cf_item_is_pair(modref)) {
557                         cp = cf_itemtopair(modref);
558
559                         /*
560                          *      Create types for simple references
561                          *      only when parsing the authenticate
562                          *      section.
563                          */
564                         if (section_type_value[comp].attr == PW_AUTH_TYPE) {
565                                 if (!define_type(dattr, cf_pair_attr(cp))) {
566                                         return -1;
567                                 }
568                         }
569
570                 } else {
571                         continue; /* ignore it */
572                 }
573
574                 /*
575                  *      Try to compile one entry.
576                  */
577                 this = compile_modsingle(NULL, comp, modref, &modname);
578                 if (!this) {
579                         cf_log_err(cf_sectiontoitem(cs),
580                                    "Failed to parse %s section.\n",
581                                    cf_section_name1(cs));
582                         return -1;
583                 }
584
585                 /*
586                  *      Look for Auth-Type foo {}, which are special
587                  *      cases of named sections, and allowable ONLY
588                  *      at the top-level.
589                  *
590                  *      i.e. They're not allowed in a "group" or "redundant"
591                  *      subsection.
592                  */
593                 if (comp == RLM_COMPONENT_AUTH) {
594                         DICT_VALUE *dval;
595                         const char *modrefname = NULL;
596                         if (cp) {
597                                 modrefname = cf_pair_attr(cp);
598                         } else {
599                                 modrefname = cf_section_name2(scs);
600                                 if (!modrefname) {
601                                         cf_log_err(cf_sectiontoitem(cs),
602                                                    "Failed to parse %s sub-section.\n",
603                                                    cf_section_name1(scs));
604                                         return -1;
605                                 }
606                         }
607
608                         dval = dict_valbyname(PW_AUTH_TYPE, modrefname);
609                         if (!dval) {
610                                 /*
611                                  *      It's a section, but nothing we
612                                  *      recognize.  Die!
613                                  */
614                                 cf_log_err(cf_sectiontoitem(cs),
615                                            "Unknown Auth-Type \"%s\" in %s sub-section.",
616                                            modrefname, section_type_value[comp].section);
617                                 return -1;
618                         }
619                         idx = dval->value;
620                 } else {
621                         /* See the comment in new_sublist() for explanation
622                          * of the special index 0 */
623                         idx = 0;
624                 }
625
626                 subcomp = new_sublist(server, comp, idx);
627                 if (subcomp == NULL) {
628                         modcallable_free(&this);
629                         continue;
630                 }
631
632                 /* If subcomp->modulelist is NULL, add_to_modcallable will
633                  * create it */
634                 visiblename = cf_section_name2(cs);
635                 if (visiblename == NULL)
636                         visiblename = cf_section_name1(cs);
637                 add_to_modcallable(&subcomp->modulelist, this,
638                                    comp, visiblename);
639         }
640
641         return 0;
642 }
643
644 static int load_byserver(CONF_SECTION *cs, int *do_component)
645 {
646         int comp, flag;
647         const char *server = cf_section_name2(cs);
648
649         DEBUG2(" modules {");
650         
651         /*
652          *      Loop over all of the known components, finding their
653          *      configuration section, and loading it.
654          */
655         flag = 0;
656         for (comp = 0; comp < RLM_COMPONENT_COUNT; ++comp) {
657                 CONF_SECTION *subcs;
658
659                 if (!do_component[comp]) continue;
660
661                 subcs = cf_section_sub_find(cs,
662                                             section_type_value[comp].section);
663                 if (!subcs) continue;
664                         
665                 if (cf_item_find_next(subcs, NULL) == NULL) continue;
666                         
667                 DEBUG2(" Module: Checking %s {...} for more modules to load",
668                        section_type_value[comp].section);
669
670                 if (load_component_section(subcs, server, comp) < 0) {
671                         DEBUG2(" }");
672                         return -1;
673                 }
674                 flag = 1;
675         } /* loop over components */
676
677         /*
678          *      We haven't loaded any of the normal sections.  Maybe we're
679          *      supposed to load the vmps section.
680          *
681          *      This is a bit of a hack...
682          */
683         if (!flag && do_component[RLM_COMPONENT_POST_AUTH]) {
684                 CONF_SECTION *subcs;
685
686                 subcs = cf_section_sub_find(cs, "vmps");
687                 if (subcs) {
688                         DEBUG2(" Module: Checking vmps {...} for more modules to load");                
689                         if (load_component_section(subcs, server,
690                                                    RLM_COMPONENT_POST_AUTH) < 0) {
691                                 return -1;
692                         }
693                         flag = 1;
694                 }
695         }
696
697         DEBUG2(" }");
698
699         if (!flag) {
700                 DEBUG("WARNING: Server %s is empty, and will do nothing!",
701                       server);
702         }
703
704         return 0;
705 }
706
707 /*
708  *      Parse the module config sections, and load
709  *      and call each module's init() function.
710  *
711  *      Libtool makes your life a LOT easier, especially with libltdl.
712  *      see: http://www.gnu.org/software/libtool/
713  */
714 int setup_modules(int reload, CONF_SECTION *config)
715 {
716         int             comp;
717         CONF_SECTION    *cs, *modules;
718         int             do_component[RLM_COMPONENT_COUNT];
719         rad_listen_t    *listener;
720         int             null_server = FALSE;
721
722         /*
723          *      If necessary, initialize libltdl.
724          */
725         if (!reload) {
726                 /*
727                  *      Set the default list of preloaded symbols.
728                  *      This is used to initialize libltdl's list of
729                  *      preloaded modules.
730                  *
731                  *      i.e. Static modules.
732                  */
733                 LTDL_SET_PRELOADED_SYMBOLS();
734
735                 if (lt_dlinit() != 0) {
736                         radlog(L_ERR, "Failed to initialize libraries: %s\n",
737                                         lt_dlerror());
738                         return -1;
739                 }
740
741                 /*
742                  *      Set the search path to ONLY our library directory.
743                  *      This prevents the modules from being found from
744                  *      any location on the disk.
745                  */
746                 lt_dlsetsearchpath(radlib_dir);
747
748                 DEBUG2("radiusd: Library search path is %s",
749                        lt_dlgetsearchpath());
750
751                 /*
752                  *      Set up the internal module struct.
753                  */
754                 module_tree = rbtree_create(module_entry_cmp,
755                                             module_entry_free, 0);
756                 if (!module_tree) {
757                         radlog(L_ERR, "Failed to initialize modules\n");
758                         return -1;
759                 }
760         } else {
761                 rbtree_free(components);
762         }
763
764         components = rbtree_create(indexed_modcallable_cmp,
765                                    indexed_modcallable_free, 0);
766         if (!components) {
767                 radlog(L_ERR, "Failed to initialize components\n");
768                 return -1;
769         }
770
771         /*
772          *      Figure out which sections to load.
773          */
774         memset(do_component, 0, sizeof(do_component));
775         for (listener = mainconfig.listen;
776              listener != NULL;
777              listener = listener->next) {
778                 switch (listener->type) {
779                 case RAD_LISTEN_AUTH:
780                         do_component[RLM_COMPONENT_AUTZ] = 1;
781                         do_component[RLM_COMPONENT_AUTH] = 1;
782                         do_component[RLM_COMPONENT_POST_AUTH] = 1;
783                         do_component[RLM_COMPONENT_SESS] = 1;
784                         break;
785
786                 case RAD_LISTEN_DETAIL: /* just like acct */
787                 case RAD_LISTEN_ACCT:
788                         do_component[RLM_COMPONENT_PREACCT] = 1;
789                         do_component[RLM_COMPONENT_ACCT] = 1;
790                         break;
791
792                 case RAD_LISTEN_PROXY:
793                         do_component[RLM_COMPONENT_PRE_PROXY] = 1;
794                         do_component[RLM_COMPONENT_POST_PROXY] = 1;
795                         break;
796
797                 case RAD_LISTEN_VQP:
798                         do_component[RLM_COMPONENT_POST_AUTH] = 1;
799                         break;
800                         /*
801                          *      Ignore this.
802                          */
803                 case RAD_LISTEN_SNMP:
804                         break;
805
806                 default:
807                         rad_assert(0 == 1);
808                         break;
809                 }
810         }
811
812         for (comp = RLM_COMPONENT_AUTH; comp < RLM_COMPONENT_COUNT; comp++) {
813                 /*
814                  *      Have the debugging messages all in one place.
815                  */
816                 if (!do_component[comp]) {
817                         DEBUG2("modules: Not loading %s{} section",
818                                section_type_value[comp].section);
819                 }
820         }
821
822         /*
823          *      Remember where the modules were stored.
824          */
825         modules = cf_section_sub_find(config, "modules");
826         if (!modules) {
827                 radlog(L_ERR, "Cannot find a \"modules\" section in the configuration file!");
828                 return -1;
829         }
830
831         /*
832          *  Look for the 'instantiate' section, which tells us
833          *  the instantiation order of the modules, and also allows
834          *  us to load modules with no authorize/authenticate/etc.
835          *  sections.
836          */
837         cs = cf_section_sub_find(config, "instantiate");
838         if (cs != NULL) {
839                 CONF_ITEM *ci;
840                 CONF_PAIR *cp;
841                 module_instance_t *module;
842                 const char *name;
843
844                 DEBUG2(" instantiate {");
845
846                 /*
847                  *  Loop over the items in the 'instantiate' section.
848                  */
849                 for (ci=cf_item_find_next(cs, NULL);
850                      ci != NULL;
851                      ci=cf_item_find_next(cs, ci)) {
852
853                         /*
854                          *      Skip sections.  They'll be handled
855                          *      later, if they're referenced at all...
856                          */
857                         if (cf_item_is_section(ci)) {
858                                 continue;
859                         }
860
861                         cp = cf_itemtopair(ci);
862                         name = cf_pair_attr(cp);
863                         module = find_module_instance(modules, name);
864                         if (!module) {
865                                 return -1;
866                         }
867                 } /* loop over items in the subsection */
868
869                 DEBUG2(" }");
870         } /* if there's an 'instantiate' section. */
871
872         /*
873          *      Loop over the listeners, figuring out which sections
874          *      to load.
875          */
876         for (listener = mainconfig.listen;
877              listener != NULL;
878              listener = listener->next) {
879                 char buffer[256];
880
881                 if (listener->type == RAD_LISTEN_PROXY) continue;
882
883                 cs = cf_section_sub_find_name2(config,
884                                                "server", listener->server);
885                 if (!cs && (listener->server != NULL)) {
886                         listener->print(listener, buffer, sizeof(buffer));
887
888                         radlog(L_ERR, "No server has been defined for %s", buffer);
889                         return -1;
890                 }
891         }
892
893         /*
894          *      Load all of the virtual servers.
895          */
896         for (cs = cf_subsection_find_next(config, NULL, "server");
897              cs != NULL;
898              cs = cf_subsection_find_next(config, cs, "server")) {
899                 const char *name2 = cf_section_name2(cs);
900
901                 if (name2) {
902                         DEBUG2("server %s {", name2);
903                 } else {
904                         DEBUG2("server {");
905                         null_server = TRUE;
906                 }
907                 if (load_byserver(cs, do_component) < 0) {
908                         DEBUG2("}");
909                         return -1;
910                 }
911                 DEBUG2("}");
912         }
913
914         /*
915          *      No empty server defined.  Try to load an old-style
916          *      one for backwards compatibility.
917          */
918         if (!null_server) {
919                 DEBUG2("WARNING: Please update your configuration to use virtual servers!");
920                 DEBUG2("server {");
921                 if (load_byserver(config, do_component) < 0) {
922                         DEBUG2("}");
923                         return -1;
924                 }
925                 DEBUG2("}");
926         }
927
928         return 0;
929 }
930
931 /*
932  *      Call all authorization modules until one returns
933  *      somethings else than RLM_MODULE_OK
934  */
935 int module_authorize(int autz_type, REQUEST *request)
936 {
937         return indexed_modcall(RLM_COMPONENT_AUTZ, autz_type, request);
938 }
939
940 /*
941  *      Authenticate a user/password with various methods.
942  */
943 int module_authenticate(int auth_type, REQUEST *request)
944 {
945         return indexed_modcall(RLM_COMPONENT_AUTH, auth_type, request);
946 }
947
948 /*
949  *      Do pre-accounting for ALL configured sessions
950  */
951 int module_preacct(REQUEST *request)
952 {
953         return indexed_modcall(RLM_COMPONENT_PREACCT, 0, request);
954 }
955
956 /*
957  *      Do accounting for ALL configured sessions
958  */
959 int module_accounting(int acct_type, REQUEST *request)
960 {
961         return indexed_modcall(RLM_COMPONENT_ACCT, acct_type, request);
962 }
963
964 /*
965  *      See if a user is already logged in.
966  *
967  *      Returns: 0 == OK, 1 == double logins, 2 == multilink attempt
968  */
969 int module_checksimul(int sess_type, REQUEST *request, int maxsimul)
970 {
971         int rcode;
972
973         if(!request->username)
974                 return 0;
975
976         request->simul_count = 0;
977         request->simul_max = maxsimul;
978         request->simul_mpp = 1;
979
980         rcode = indexed_modcall(RLM_COMPONENT_SESS, sess_type, request);
981
982         if (rcode != RLM_MODULE_OK) {
983                 /* FIXME: Good spot for a *rate-limited* warning to the log */
984                 return 0;
985         }
986
987         return (request->simul_count < maxsimul) ? 0 : request->simul_mpp;
988 }
989
990 /*
991  *      Do pre-proxying for ALL configured sessions
992  */
993 int module_pre_proxy(int type, REQUEST *request)
994 {
995         return indexed_modcall(RLM_COMPONENT_PRE_PROXY, type, request);
996 }
997
998 /*
999  *      Do post-proxying for ALL configured sessions
1000  */
1001 int module_post_proxy(int type, REQUEST *request)
1002 {
1003         return indexed_modcall(RLM_COMPONENT_POST_PROXY, type, request);
1004 }
1005
1006 /*
1007  *      Do post-authentication for ALL configured sessions
1008  */
1009 int module_post_auth(int postauth_type, REQUEST *request)
1010 {
1011         return indexed_modcall(RLM_COMPONENT_POST_AUTH, postauth_type, request);
1012 }