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