Created and use virtual_server_t structure
[freeradius.git] / src / main / modules.c
1 /*
2  * modules.c    Radius module support.
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2003,2006  The FreeRADIUS server project
21  * Copyright 2000  Alan DeKok <aland@ox.org>
22  * Copyright 2000  Alan Curry <pacman@world.std.com>
23  */
24
25 #include <freeradius-devel/ident.h>
26 RCSID("$Id$")
27
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/modpriv.h>
30 #include <freeradius-devel/modcall.h>
31 #include <freeradius-devel/rad_assert.h>
32
33 extern int check_config;
34
35 typedef struct indexed_modcallable {
36         int             comp;
37         int             idx;
38         modcallable     *modulelist;
39 } indexed_modcallable;
40
41 typedef struct virtual_server_t {
42         const char      *name;
43         CONF_SECTION    *cs;
44         rbtree_t        *components;
45         struct virtual_server_t *next;
46 } virtual_server_t;
47
48 /*
49  *      Keep a hash of virtual servers, so that we can reload them.
50  */
51 #define VIRTUAL_SERVER_HASH_SIZE (256)
52 static virtual_server_t *virtual_servers[VIRTUAL_SERVER_HASH_SIZE];
53
54 static rbtree_t *module_tree = NULL;
55
56 static rbtree_t *instance_tree = NULL;
57
58 typedef struct section_type_value_t {
59         const char      *section;
60         const char      *typename;
61         int             attr;
62 } section_type_value_t;
63
64 struct fr_module_hup_t {
65         module_instance_t       *mi;
66         time_t                  when;
67         void                    *insthandle;
68         fr_module_hup_t         *next;
69 };
70
71
72 /*
73  *      Ordered by component
74  */
75 static const section_type_value_t section_type_value[RLM_COMPONENT_COUNT] = {
76         { "authenticate", "Auth-Type",       PW_AUTH_TYPE },
77         { "authorize",    "Autz-Type",       PW_AUTZ_TYPE },
78         { "preacct",      "Pre-Acct-Type",   PW_PRE_ACCT_TYPE },
79         { "accounting",   "Acct-Type",       PW_ACCT_TYPE },
80         { "session",      "Session-Type",    PW_SESSION_TYPE },
81         { "pre-proxy",    "Pre-Proxy-Type",  PW_PRE_PROXY_TYPE },
82         { "post-proxy",   "Post-Proxy-Type", PW_POST_PROXY_TYPE },
83         { "post-auth",    "Post-Auth-Type",  PW_POST_AUTH_TYPE },
84 };
85
86
87 #ifdef WITHOUT_LIBLTDL
88 typedef struct lt_dlmodule_t {
89   const char    *name;
90   void          *ref;
91 } lt_dlmodule_t;
92
93 /*
94  *      Define modules here.
95  */
96 extern module_t rlm_pap;
97 extern module_t rlm_chap;
98 extern module_t rlm_eap;
99
100 /*
101  *      EAP structures are defined elsewhere.
102  */
103 typedef struct eap_type_t EAP_TYPE;
104
105 /*
106  *      And so on for other EAP types.
107  */
108 extern EAP_TYPE rlm_eap_md5;
109
110 static const lt_dlmodule_t lt_dlmodules[] = {
111         { "rlm_pap", &rlm_pap },
112         { "rlm_chap", &rlm_chap },
113         { "rlm_eap", &rlm_eap },
114         { "rlm_eap_md5", &rlm_eap_md5 },
115         
116         /*
117          *      Add other modules here.
118          */
119                 
120         { NULL, NULL }
121 };
122
123
124 lt_dlhandle lt_dlopenext(const char *name)
125 {
126         int i;
127
128         for (i = 0; lt_dlmodules[i].name != NULL; i++) {
129                 if (strcmp(name, lt_dlmodules[i].name) == 0) {
130                         return lt_dlmodules[i].ref;
131                 }
132         }
133
134         return NULL;
135 }
136
137 void *lt_dlsym(lt_dlhandle handle, UNUSED const char *symbol)
138 {
139         return handle;
140 }
141 #endif /* WITHOUT_LIBLTDL */
142
143 static int virtual_server_idx(const char *name)
144 {
145         uint32_t hash;
146
147         if (!name) return 0;
148
149         hash = fr_hash_string(name);
150                 
151         return hash & (VIRTUAL_SERVER_HASH_SIZE - 1);
152 }
153
154 static void virtual_server_free(virtual_server_t *server)
155 {
156         if (server->components) rbtree_free(server->components);
157         server->components = NULL;
158
159         free(server);
160 }
161
162 static void indexed_modcallable_free(void *data)
163 {
164         indexed_modcallable *c = data;
165
166         modcallable_free(&c->modulelist);
167         free(c);
168 }
169
170 static int indexed_modcallable_cmp(const void *one, const void *two)
171 {
172         const indexed_modcallable *a = one;
173         const indexed_modcallable *b = two;
174
175         if (a->comp < b->comp) return -1;
176         if (a->comp >  b->comp) return +1;
177
178         return a->idx - b->idx;
179 }
180
181
182 /*
183  *      Compare two module entries
184  */
185 static int module_instance_cmp(const void *one, const void *two)
186 {
187         const module_instance_t *a = one;
188         const module_instance_t *b = two;
189
190         return strcmp(a->name, b->name);
191 }
192
193
194 static void module_instance_free_old(CONF_SECTION *cs, module_instance_t *node,
195                                      time_t when)
196 {
197         fr_module_hup_t *mh, **last;
198
199         /*
200          *      Walk the list, freeing up old instances.
201          */
202         last = &(node->mh);
203         while (*last) {
204                 mh = *last;
205
206                 /*
207                  *      Free only every 60 seconds.
208                  */
209                 if ((when - mh->when) < 60) {
210                         last = &(mh->next);
211                         continue;
212                 }
213
214                 cf_section_parse_free(cs, mh->insthandle);
215                 
216                 if (node->entry->module->detach) {
217                         (node->entry->module->detach)(mh->insthandle);
218                 } else {
219                         free(mh->insthandle);
220                 }
221
222                 *last = mh->next;
223                 free(mh);
224         }
225 }
226
227
228 /*
229  *      Free a module instance.
230  */
231 static void module_instance_free(void *data)
232 {
233         module_instance_t *this = data;
234
235         module_instance_free_old(this->cs, this, time(NULL) + 100);
236
237         if (this->entry->module->detach) {
238                 (this->entry->module->detach)(this->insthandle);
239         }
240
241 #ifdef HAVE_PTHREAD_H
242         if (this->mutex) {
243                 /*
244                  *      FIXME
245                  *      The mutex MIGHT be locked...
246                  *      we'll check for that later, I guess.
247                  */
248                 pthread_mutex_destroy(this->mutex);
249                 free(this->mutex);
250         }
251 #endif
252         memset(this, 0, sizeof(*this));
253         free(this);
254 }
255
256
257 /*
258  *      Compare two module entries
259  */
260 static int module_entry_cmp(const void *one, const void *two)
261 {
262         const module_entry_t *a = one;
263         const module_entry_t *b = two;
264
265         return strcmp(a->name, b->name);
266 }
267
268 /*
269  *      Free a module entry.
270  */
271 static void module_entry_free(void *data)
272 {
273         module_entry_t *this = data;
274
275         lt_dlclose(this->handle);       /* ignore any errors */
276         memset(this, 0, sizeof(*this));
277         free(this);
278 }
279
280
281 /*
282  *      Remove the module lists.
283  */
284 int detach_modules(void)
285 {
286         int i;
287
288         for (i = 0; i < VIRTUAL_SERVER_HASH_SIZE; i++) {
289                 virtual_server_t *server, *next;
290
291                 for (server = virtual_servers[i];
292                      server != NULL;
293                      server = next) {
294                         next = server->next;
295                         virtual_server_free(server);
296                 }
297         }
298
299         rbtree_free(instance_tree);
300         rbtree_free(module_tree);
301
302         lt_dlexit();
303
304         return 0;
305 }
306
307
308 /*
309  *      Find a module on disk or in memory, and link to it.
310  */
311 static module_entry_t *linkto_module(const char *module_name,
312                                      CONF_SECTION *cs)
313 {
314         module_entry_t myentry;
315         module_entry_t *node;
316         lt_dlhandle handle;
317         char module_struct[256];
318         char *p;
319         const module_t *module;
320
321         strlcpy(myentry.name, module_name, sizeof(myentry.name));
322         node = rbtree_finddata(module_tree, &myentry);
323         if (node) return node;
324
325         /*
326          *      Keep the handle around so we can dlclose() it.
327          */
328         handle = lt_dlopenext(module_name);
329         if (handle == NULL) {
330                 cf_log_err(cf_sectiontoitem(cs),
331                            "Failed to link to module '%s': %s\n",
332                            module_name, lt_dlerror());
333                 return NULL;
334         }
335
336         /*
337          *      Link to the module's rlm_FOO{} module structure.
338          *
339          *      The module_name variable has the version number
340          *      embedded in it, and we don't want that here.
341          */
342         strcpy(module_struct, module_name);
343         p = strrchr(module_struct, '-');
344         if (p) *p = '\0';
345
346         DEBUG3("    (Loaded %s, checking if it's valid)", module_name);
347
348         /*
349          *      libltld MAY core here, if the handle it gives us contains
350          *      garbage data.
351          */
352         module = lt_dlsym(handle, module_struct);
353         if (!module) {
354                 cf_log_err(cf_sectiontoitem(cs),
355                            "Failed linking to %s structure: %s\n",
356                            module_name, lt_dlerror());
357                 lt_dlclose(handle);
358                 return NULL;
359         }
360         /*
361          *      Before doing anything else, check if it's sane.
362          */
363         if (module->magic != RLM_MODULE_MAGIC_NUMBER) {
364                 lt_dlclose(handle);
365                 cf_log_err(cf_sectiontoitem(cs),
366                            "Invalid version in module '%s'",
367                            module_name);
368                 return NULL;
369
370         }
371
372         /* make room for the module type */
373         node = rad_malloc(sizeof(*node));
374         memset(node, 0, sizeof(*node));
375         strlcpy(node->name, module_name, sizeof(node->name));
376         node->module = module;
377         node->handle = handle;
378
379         cf_log_module(cs, "Linked to module %s", module_name);
380
381         /*
382          *      Add the module as "rlm_foo-version" to the configuration
383          *      section.
384          */
385         if (!rbtree_insert(module_tree, node)) {
386                 radlog(L_ERR, "Failed to cache module %s", module_name);
387                 lt_dlclose(handle);
388                 free(node);
389                 return NULL;
390         }
391
392         return node;
393 }
394
395 /*
396  *      Find a module instance.
397  */
398 module_instance_t *find_module_instance(CONF_SECTION *modules,
399                                         const char *instname, int do_link)
400 {
401         int check_config_safe = FALSE;
402         CONF_SECTION *cs;
403         const char *name1, *name2;
404         module_instance_t *node, myNode;
405         char module_name[256];
406
407         if (!modules) return NULL;
408
409         /*
410          *      Module instances are declared in the modules{} block
411          *      and referenced later by their name, which is the
412          *      name2 from the config section, or name1 if there was
413          *      no name2.
414          */
415         cs = cf_section_sub_find_name2(modules, NULL, instname);
416         if (cs == NULL) {
417                 radlog(L_ERR, "ERROR: Cannot find a configuration entry for module \"%s\".\n", instname);
418                 return NULL;
419         }
420
421         /*
422          *      If there's already a module instance, return it.
423          */
424         strlcpy(myNode.name, instname, sizeof(myNode.name));
425         node = rbtree_finddata(instance_tree, &myNode);
426         if (node) return node;
427
428         if (!do_link) return NULL;
429
430         name1 = cf_section_name1(cs);
431         name2 = cf_section_name2(cs);
432
433         /*
434          *      Found the configuration entry.
435          */
436         node = rad_malloc(sizeof(*node));
437         memset(node, 0, sizeof(*node));
438
439         node->insthandle = NULL;
440         node->cs = cs;
441
442         /*
443          *      Names in the "modules" section aren't prefixed
444          *      with "rlm_", so we add it here.
445          */
446         snprintf(module_name, sizeof(module_name), "rlm_%s", name1);
447
448         node->entry = linkto_module(module_name, cs);
449         if (!node->entry) {
450                 free(node);
451                 /* linkto_module logs any errors */
452                 return NULL;
453         }
454
455         if (check_config && (node->entry->module->instantiate) &&
456             (node->entry->module->type & RLM_TYPE_CHECK_CONFIG_SAFE) == 0) {
457                 const char *value = NULL;
458                 CONF_PAIR *cp;
459
460                 cp = cf_pair_find(cs, "force_check_config");
461                 if (cp) value = cf_pair_value(cp);
462
463                 if (value && (strcmp(value, "yes") == 0)) goto print_inst;
464
465                 cf_log_module(cs, "Skipping instantiation of %s", instname);
466         } else {
467         print_inst:
468                 check_config_safe = TRUE;
469                 cf_log_module(cs, "Instantiating %s", instname);
470         }
471
472         /*
473          *      Call the module's instantiation routine.
474          */
475         if ((node->entry->module->instantiate) &&
476             (!check_config || check_config_safe) &&
477             ((node->entry->module->instantiate)(cs, &node->insthandle) < 0)) {
478                 cf_log_err(cf_sectiontoitem(cs),
479                            "Instantiation failed for module \"%s\"",
480                            instname);
481                 free(node);
482                 return NULL;
483         }
484
485         /*
486          *      We're done.  Fill in the rest of the data structure,
487          *      and link it to the module instance list.
488          */
489         strlcpy(node->name, instname, sizeof(node->name));
490
491 #ifdef HAVE_PTHREAD_H
492         /*
493          *      If we're threaded, check if the module is thread-safe.
494          *
495          *      If it isn't, we create a mutex.
496          */
497         if ((node->entry->module->type & RLM_TYPE_THREAD_UNSAFE) != 0) {
498                 node->mutex = (pthread_mutex_t *) rad_malloc(sizeof(pthread_mutex_t));
499                 /*
500                  *      Initialize the mutex.
501                  */
502                 pthread_mutex_init(node->mutex, NULL);
503         } else {
504                 /*
505                  *      The module is thread-safe.  Don't give it a mutex.
506                  */
507                 node->mutex = NULL;
508         }
509
510 #endif
511         rbtree_insert(instance_tree, node);
512
513         return node;
514 }
515
516 static indexed_modcallable *lookup_by_index(rbtree_t *components,
517                                             int comp, int idx)
518 {
519         indexed_modcallable myc;
520         
521         myc.comp = comp;
522         myc.idx = idx;
523
524         return rbtree_finddata(components, &myc);
525 }
526
527 /*
528  *      Create a new sublist.
529  */
530 static indexed_modcallable *new_sublist(rbtree_t *components, int comp, int idx)
531 {
532         indexed_modcallable *c;
533
534         c = lookup_by_index(components, comp, idx);
535
536         /* It is an error to try to create a sublist that already
537          * exists. It would almost certainly be caused by accidental
538          * duplication in the config file.
539          *
540          * index 0 is the exception, because it is used when we want
541          * to collect _all_ listed modules under a single index by
542          * default, which is currently the case in all components
543          * except authenticate. */
544         if (c) {
545                 if (idx == 0) {
546                         return c;
547                 }
548                 return NULL;
549         }
550
551         c = rad_malloc(sizeof(*c));
552         c->modulelist = NULL;
553         c->comp = comp;
554         c->idx = idx;
555
556         if (!rbtree_insert(components, c)) {
557                 free(c);
558                 return NULL;
559         }
560
561         return c;
562 }
563
564 int indexed_modcall(int comp, int idx, REQUEST *request)
565 {
566         int rcode;
567         indexed_modcallable *this;
568         modcallable *list = NULL;
569         virtual_server_t *server;
570
571         rcode = virtual_server_idx(request->server);
572         for (server = virtual_servers[rcode];
573              server != NULL;
574              server = server->next) {
575                 if (!request->server && !server->name) break;
576
577                 if ((request->server && server->name) &&
578                     (strcmp(request->server, server->name) == 0)) break;
579         }
580
581         if (!server) {
582                 RDEBUG("No such virtual server %s", request->server);
583                 return RLM_MODULE_FAIL;
584         }
585
586         this = lookup_by_index(server->components, comp, idx);
587         if (!this) {
588                 if (idx != 0) DEBUG2("  WARNING: Unknown value specified for %s.  Cannot perform requested action.",
589                                      section_type_value[comp].typename);
590         } else {
591                 list = this->modulelist;
592         }
593
594         request->component = section_type_value[comp].section;
595
596         rcode = modcall(comp, list, request);
597
598         request->module = "";
599         request->component = "";
600         return rcode;
601 }
602
603 /*
604  *      Load a sub-module list, as found inside an Auth-Type foo {}
605  *      block
606  */
607 static int load_subcomponent_section(modcallable *parent, CONF_SECTION *cs,
608                                      rbtree_t *components, int attr, int comp)
609 {
610         indexed_modcallable *subcomp;
611         modcallable *ml;
612         DICT_VALUE *dval;
613         const char *name2 = cf_section_name2(cs);
614
615         rad_assert(comp >= RLM_COMPONENT_AUTH);
616         rad_assert(comp < RLM_COMPONENT_COUNT);
617
618         /*
619          *      Sanity check.
620          */
621         if (!name2) {
622                 cf_log_err(cf_sectiontoitem(cs),
623                            "No name specified for %s block",
624                            section_type_value[comp].typename);
625                 return 1;
626         }
627
628         /*
629          *      Compile the group.
630          */
631         ml = compile_modgroup(parent, comp, cs);
632         if (!ml) {
633                 return 0;
634         }
635
636         /*
637          *      We must assign a numeric index to this subcomponent.
638          *      It is generated and placed in the dictionary
639          *      automatically.  If it isn't found, it's a serious
640          *      error.
641          */
642         dval = dict_valbyname(attr, name2);
643         if (!dval) {
644                 cf_log_err(cf_sectiontoitem(cs),
645                            "%s %s Not previously configured",
646                            section_type_value[comp].typename, name2);
647                 modcallable_free(&ml);
648                 return 0;
649         }
650
651         subcomp = new_sublist(components, comp, dval->value);
652         if (!subcomp) {
653                 modcallable_free(&ml);
654                 return 1;
655         }
656
657         subcomp->modulelist = ml;
658         return 1;               /* OK */
659 }
660
661 static int define_type(const DICT_ATTR *dattr, const char *name)
662 {
663         uint32_t value;
664         DICT_VALUE *dval;
665
666         /*
667          *      If the value already exists, don't
668          *      create it again.
669          */
670         dval = dict_valbyname(dattr->attr, name);
671         if (dval) return 1;
672
673         /*
674          *      Create a new unique value with a
675          *      meaningless number.  You can't look at
676          *      it from outside of this code, so it
677          *      doesn't matter.  The only requirement
678          *      is that it's unique.
679          */
680         do {
681                 value = fr_rand() & 0x00ffffff;
682         } while (dict_valbyattr(dattr->attr, value));
683
684         if (dict_addvalue(name, dattr->name, value) < 0) {
685                 radlog(L_ERR, "%s", fr_strerror());
686                 return 0;
687         }
688
689         return 1;
690 }
691
692 static int load_component_section(CONF_SECTION *cs,
693                                   rbtree_t *components, int comp)
694 {
695         modcallable *this;
696         CONF_ITEM *modref;
697         int idx;
698         indexed_modcallable *subcomp;
699         const char *modname;
700         const char *visiblename;
701         const DICT_ATTR *dattr;
702
703         /*
704          *      Find the attribute used to store VALUEs for this section.
705          */
706         dattr = dict_attrbyvalue(section_type_value[comp].attr);
707         if (!dattr) {
708                 cf_log_err(cf_sectiontoitem(cs),
709                            "No such attribute %s",
710                            section_type_value[comp].typename);
711                 return -1;
712         }
713
714         /*
715          *      Loop over the entries in the named section, loading
716          *      the sections this time.
717          */
718         for (modref = cf_item_find_next(cs, NULL);
719              modref != NULL;
720              modref = cf_item_find_next(cs, modref)) {
721                 const char *name1;
722                 CONF_PAIR *cp = NULL;
723                 CONF_SECTION *scs = NULL;
724
725                 if (cf_item_is_section(modref)) {
726                         scs = cf_itemtosection(modref);
727
728                         name1 = cf_section_name1(scs);
729
730                         if (strcmp(name1,
731                                    section_type_value[comp].typename) == 0) {
732                                 if (!load_subcomponent_section(NULL, scs,
733                                                                components,
734                                                                dattr->attr,
735                                                                comp)) {
736                                         return -1; /* FIXME: memleak? */
737                                 }
738                                 continue;
739                         }
740
741                         cp = NULL;
742
743                 } else if (cf_item_is_pair(modref)) {
744                         cp = cf_itemtopair(modref);
745
746                 } else {
747                         continue; /* ignore it */
748                 }
749
750                 /*
751                  *      Try to compile one entry.
752                  */
753                 this = compile_modsingle(NULL, comp, modref, &modname);
754                 if (!this) {
755                         cf_log_err(cf_sectiontoitem(cs),
756                                    "Errors parsing %s section.\n",
757                                    cf_section_name1(cs));
758                         return -1;
759                 }
760
761                 /*
762                  *      Look for Auth-Type foo {}, which are special
763                  *      cases of named sections, and allowable ONLY
764                  *      at the top-level.
765                  *
766                  *      i.e. They're not allowed in a "group" or "redundant"
767                  *      subsection.
768                  */
769                 if (comp == RLM_COMPONENT_AUTH) {
770                         DICT_VALUE *dval;
771                         const char *modrefname = NULL;
772                         if (cp) {
773                                 modrefname = cf_pair_attr(cp);
774                         } else {
775                                 modrefname = cf_section_name2(scs);
776                                 if (!modrefname) {
777                                         modcallable_free(&this);
778                                         cf_log_err(cf_sectiontoitem(cs),
779                                                    "Errors parsing %s sub-section.\n",
780                                                    cf_section_name1(scs));
781                                         return -1;
782                                 }
783                         }
784
785                         dval = dict_valbyname(PW_AUTH_TYPE, modrefname);
786                         if (!dval) {
787                                 /*
788                                  *      It's a section, but nothing we
789                                  *      recognize.  Die!
790                                  */
791                                 modcallable_free(&this);
792                                 cf_log_err(cf_sectiontoitem(cs),
793                                            "Unknown Auth-Type \"%s\" in %s sub-section.",
794                                            modrefname, section_type_value[comp].section);
795                                 return -1;
796                         }
797                         idx = dval->value;
798                 } else {
799                         /* See the comment in new_sublist() for explanation
800                          * of the special index 0 */
801                         idx = 0;
802                 }
803
804                 subcomp = new_sublist(components, comp, idx);
805                 if (subcomp == NULL) {
806                         modcallable_free(&this);
807                         continue;
808                 }
809
810                 /* If subcomp->modulelist is NULL, add_to_modcallable will
811                  * create it */
812                 visiblename = cf_section_name2(cs);
813                 if (visiblename == NULL)
814                         visiblename = cf_section_name1(cs);
815                 add_to_modcallable(&subcomp->modulelist, this,
816                                    comp, visiblename);
817         }
818
819         return 0;
820 }
821
822 static int load_byserver(CONF_SECTION *cs)
823 {
824         int comp, flag;
825         const char *name = cf_section_name2(cs);
826         rbtree_t *components;
827         virtual_server_t *server;
828
829         cf_log_info(cs, " modules {");
830
831         components = rbtree_create(indexed_modcallable_cmp,
832                                    indexed_modcallable_free, 0);
833         if (!components) {
834                 radlog(L_ERR, "Failed to initialize components\n");
835                 return -1;
836         }
837
838         server = rad_malloc(sizeof(*server));
839         memset(server, 0, sizeof(*server));
840
841         server->name = name;
842         server->cs = cs;
843         server->components = components;
844
845         /*
846          *      Define types first.
847          */
848         for (comp = 0; comp < RLM_COMPONENT_COUNT; ++comp) {
849                 CONF_SECTION *subcs;
850                 CONF_ITEM *modref;
851                 DICT_ATTR *dattr;
852
853                 subcs = cf_section_sub_find(cs,
854                                             section_type_value[comp].section);
855                 if (!subcs) continue;
856                         
857                 if (cf_item_find_next(subcs, NULL) == NULL) continue;
858
859                 /*
860                  *      Find the attribute used to store VALUEs for this section.
861                  */
862                 dattr = dict_attrbyvalue(section_type_value[comp].attr);
863                 if (!dattr) {
864                         cf_log_err(cf_sectiontoitem(subcs),
865                                    "No such attribute %s",
866                                    section_type_value[comp].typename);
867                         cf_log_info(cs, " }");
868                 error:
869                         virtual_server_free(server);
870                         return -1;
871                 }
872
873                 /*
874                  *      Define dynamic types, so that others can reference
875                  *      them.
876                  */
877                 for (modref = cf_item_find_next(subcs, NULL);
878                      modref != NULL;
879                      modref = cf_item_find_next(subcs, modref)) {
880                         const char *name1;
881                         CONF_SECTION *subsubcs;
882
883                         /*
884                          *      Create types for simple references
885                          *      only when parsing the authenticate
886                          *      section.
887                          */
888                         if ((section_type_value[comp].attr == PW_AUTH_TYPE) &&
889                             cf_item_is_pair(modref)) {
890                                 CONF_PAIR *cp = cf_itemtopair(modref);
891                                 if (!define_type(dattr, cf_pair_attr(cp))) {
892                                         goto error;
893                                 }
894
895                                 continue;
896                         }
897
898                         if (!cf_item_is_section(modref)) continue;
899                         
900                         subsubcs = cf_itemtosection(modref);
901                         name1 = cf_section_name1(subsubcs);
902                 
903                         if (strcmp(name1, section_type_value[comp].typename) == 0) {
904                                 if (!define_type(dattr,
905                                                  cf_section_name2(subsubcs))) {
906                                         cf_log_info(cs, " }");
907                                         goto error;
908                                 }
909                         }
910                 }
911         } /* loop over components */
912
913         /*
914          *      Loop over all of the known components, finding their
915          *      configuration section, and loading it.
916          */
917         flag = 0;
918         for (comp = 0; comp < RLM_COMPONENT_COUNT; ++comp) {
919                 CONF_SECTION *subcs;
920
921                 subcs = cf_section_sub_find(cs,
922                                             section_type_value[comp].section);
923                 if (!subcs) continue;
924                         
925                 if (cf_item_find_next(subcs, NULL) == NULL) continue;
926                         
927                 cf_log_module(cs, "Checking %s {...} for more modules to load",
928                        section_type_value[comp].section);
929
930 #ifdef WITH_PROXY
931                 /*
932                  *      Skip pre/post-proxy sections if we're not
933                  *      proxying.
934                  */
935                 if (!mainconfig.proxy_requests &&
936                     ((comp == PW_PRE_PROXY_TYPE) ||
937                      (comp == PW_PRE_PROXY_TYPE))) {
938                         continue;
939                 }
940 #endif
941
942                 if (load_component_section(subcs, components, comp) < 0) {
943                         cf_log_info(cs, " }");
944                         goto error;
945                 }
946                 flag = 1;
947         } /* loop over components */
948
949         /*
950          *      We haven't loaded any of the normal sections.  Maybe we're
951          *      supposed to load the vmps section.
952          *
953          *      This is a bit of a hack...
954          */
955         if (!flag) {
956                 CONF_SECTION *subcs;
957
958                 subcs = cf_section_sub_find(cs, "vmps");
959                 if (subcs) {
960                         cf_log_module(cs, "Checking vmps {...} for more modules to load");              
961                         if (load_component_section(subcs, components,
962                                                    RLM_COMPONENT_POST_AUTH) < 0) {
963                                 goto error;
964                         }
965                         flag = 1;
966                 }
967
968 #ifdef WITH_DHCP
969                 if (!flag) {
970                         const DICT_ATTR *dattr;
971
972                         dattr = dict_attrbyname("DHCP-Message-Type");
973                         if (!dattr) {
974                                 radlog(L_ERR, "No DHCP-Message-Type attribute");
975                                 goto error;
976                         }
977
978                         /*
979                          *      Handle each DHCP Message type separately.
980                          */
981                         for (subcs = cf_subsection_find_next(cs, NULL,
982                                                              "dhcp");
983                              subcs != NULL;
984                              subcs = cf_subsection_find_next(cs, subcs,
985                                                              "dhcp")) {
986                                 const char *name2 = cf_section_name2(subcs);
987
988                                 DEBUG2(" Module: Checking dhcp %s {...} for more modules to load", name2);
989                                 if (!load_subcomponent_section(NULL, subcs,
990                                                                components,
991                                                                dattr->attr,
992                                                                RLM_COMPONENT_POST_AUTH)) {
993                                         goto error; /* FIXME: memleak? */
994                                 }
995                                 flag = 1;
996                         }
997                 }
998 #endif
999         }
1000
1001         cf_log_info(cs, " }");
1002
1003         if (!flag && name) {
1004                 DEBUG("WARNING: Server %s is empty, and will do nothing!",
1005                       name);
1006         }
1007
1008         /*
1009          *      Now that it is OK, insert it into the list.
1010          *
1011          *      This is thread-safe...
1012          */
1013         comp = virtual_server_idx(name);
1014         server->next = virtual_servers[comp];
1015         virtual_servers[comp] = server;
1016
1017         return 0;
1018 }
1019
1020
1021 /*
1022  *      Load all of the virtual servers.
1023  */
1024 int virtual_server_load(CONF_SECTION *config)
1025 {
1026         int null_server = FALSE;
1027         CONF_SECTION *cs;
1028
1029         DEBUG2("%s: #### Loading Virtual Servers ####", mainconfig.name);
1030
1031         /*
1032          *      Load all of the virtual servers.
1033          */
1034         for (cs = cf_subsection_find_next(config, NULL, "server");
1035              cs != NULL;
1036              cs = cf_subsection_find_next(config, cs, "server")) {
1037                 const char *name2 = cf_section_name2(cs);
1038
1039                 if (name2) {
1040                         cf_log_info(cs, "server %s {", name2);
1041                 } else {
1042                         cf_log_info(cs, "server {");
1043                         null_server = TRUE;
1044                 }
1045                 if (load_byserver(cs) < 0) {
1046                         cf_log_info(cs, "}");
1047                         return -1;
1048                 }
1049                 cf_log_info(cs, "}");
1050                 if (debug_flag == 0) {
1051                         radlog(L_INFO, "Loaded virtual server %s", name2);
1052                 }
1053         }
1054
1055         /*
1056          *      No empty server defined.  Try to load an old-style
1057          *      one for backwards compatibility.
1058          */
1059         if (!null_server) {
1060                 cf_log_info(cs, "server {");
1061                 if (load_byserver(config) < 0) {
1062                         cf_log_info(cs, "}");
1063                         return -1;
1064                 }
1065                 cf_log_info(cs, "}");
1066         }
1067
1068         return 0;
1069 }
1070
1071
1072 int module_hup_module(CONF_SECTION *cs, module_instance_t *node, time_t when)
1073 {
1074         void *insthandle = NULL;
1075         fr_module_hup_t *mh;
1076
1077         if (!node ||
1078             !node->entry->module->instantiate ||
1079             ((node->entry->module->type & RLM_TYPE_HUP_SAFE) == 0)) {
1080                 return 1;
1081         }
1082
1083         cf_log_module(cs, "Trying to reload module \"%s\"", node->name);
1084         
1085         if ((node->entry->module->instantiate)(cs, &insthandle) < 0) {
1086                 cf_log_err(cf_sectiontoitem(cs),
1087                            "HUP failed for module \"%s\".  Using old configuration.",
1088                            node->name);
1089                 return 0;
1090         }
1091
1092         radlog(L_INFO, " Module: Reloaded module \"%s\"", node->name);
1093
1094         module_instance_free_old(cs, node, when);
1095
1096         /*
1097          *      Save the old instance handle for later deletion.
1098          */
1099         mh = rad_malloc(sizeof(*mh));
1100         mh->mi = node;
1101         mh->when = when;
1102         mh->insthandle = node->insthandle;
1103         mh->next = node->mh;
1104         node->mh = mh;
1105
1106         node->insthandle = insthandle;
1107         
1108         /*
1109          *      FIXME: Set a timeout to come back in 60s, so that
1110          *      we can pro-actively clean up the old instances.
1111          */
1112
1113         return 1;
1114 }
1115
1116
1117 int module_hup(CONF_SECTION *modules)
1118 {
1119         time_t when;
1120         CONF_ITEM *ci;
1121         CONF_SECTION *cs;
1122         module_instance_t *node;
1123
1124         if (!modules) return 0;
1125
1126         when = time(NULL);
1127
1128         /*
1129          *      Loop over the modules
1130          */
1131         for (ci=cf_item_find_next(modules, NULL);
1132              ci != NULL;
1133              ci=cf_item_find_next(modules, ci)) {
1134                 const char *instname;
1135                 module_instance_t myNode;
1136
1137                 /*
1138                  *      If it's not a section, ignore it.
1139                  */
1140                 if (!cf_item_is_section(ci)) continue;
1141
1142                 cs = cf_itemtosection(ci);
1143                 instname = cf_section_name2(cs);
1144                 if (!instname) instname = cf_section_name1(cs);
1145
1146                 strlcpy(myNode.name, instname, sizeof(myNode.name));
1147                 node = rbtree_finddata(instance_tree, &myNode);
1148
1149                 module_hup_module(cs, node, when);
1150         }
1151
1152         return 1;
1153 }
1154
1155
1156 /*
1157  *      Parse the module config sections, and load
1158  *      and call each module's init() function.
1159  *
1160  *      Libtool makes your life a LOT easier, especially with libltdl.
1161  *      see: http://www.gnu.org/software/libtool/
1162  */
1163 int setup_modules(int reload, CONF_SECTION *config)
1164 {
1165         CONF_SECTION    *cs, *modules;
1166         rad_listen_t    *listener;
1167
1168         if (reload) return 0;
1169
1170         /*
1171          *      If necessary, initialize libltdl.
1172          */
1173         if (!reload) {
1174                 /*
1175                  *      Set the default list of preloaded symbols.
1176                  *      This is used to initialize libltdl's list of
1177                  *      preloaded modules.
1178                  *
1179                  *      i.e. Static modules.
1180                  */
1181                 LTDL_SET_PRELOADED_SYMBOLS();
1182
1183                 if (lt_dlinit() != 0) {
1184                         radlog(L_ERR, "Failed to initialize libraries: %s\n",
1185                                         lt_dlerror());
1186                         return -1;
1187                 }
1188
1189                 /*
1190                  *      Set the search path to ONLY our library directory.
1191                  *      This prevents the modules from being found from
1192                  *      any location on the disk.
1193                  */
1194                 lt_dlsetsearchpath(radlib_dir);
1195
1196                 /*
1197                  *      Set up the internal module struct.
1198                  */
1199                 module_tree = rbtree_create(module_entry_cmp,
1200                                             module_entry_free, 0);
1201                 if (!module_tree) {
1202                         radlog(L_ERR, "Failed to initialize modules\n");
1203                         return -1;
1204                 }
1205
1206                 instance_tree = rbtree_create(module_instance_cmp,
1207                                               module_instance_free, 0);
1208                 if (!instance_tree) {
1209                         radlog(L_ERR, "Failed to initialize modules\n");
1210                         return -1;
1211                 }
1212         }
1213
1214         memset(virtual_servers, 0, sizeof(virtual_servers));
1215
1216         /*
1217          *      Remember where the modules were stored.
1218          */
1219         modules = cf_section_sub_find(config, "modules");
1220         if (!modules) {
1221                 radlog(L_ERR, "Cannot find a \"modules\" section in the configuration file!");
1222                 return -1;
1223         }
1224
1225         DEBUG2("%s: #### Instantiating modules ####", mainconfig.name);
1226
1227         /*
1228          *  Look for the 'instantiate' section, which tells us
1229          *  the instantiation order of the modules, and also allows
1230          *  us to load modules with no authorize/authenticate/etc.
1231          *  sections.
1232          */
1233         cs = cf_section_sub_find(config, "instantiate");
1234         if (cs != NULL) {
1235                 CONF_ITEM *ci;
1236                 CONF_PAIR *cp;
1237                 module_instance_t *module;
1238                 const char *name;
1239
1240                 cf_log_info(cs, " instantiate {");
1241
1242                 /*
1243                  *  Loop over the items in the 'instantiate' section.
1244                  */
1245                 for (ci=cf_item_find_next(cs, NULL);
1246                      ci != NULL;
1247                      ci=cf_item_find_next(cs, ci)) {
1248
1249                         /*
1250                          *      Skip sections and "other" stuff.
1251                          *      Sections will be handled later, if
1252                          *      they're referenced at all...
1253                          */
1254                         if (!cf_item_is_pair(ci)) {
1255                                 continue;
1256                         }
1257
1258                         cp = cf_itemtopair(ci);
1259                         name = cf_pair_attr(cp);
1260                         module = find_module_instance(modules, name, 1);
1261                         if (!module) {
1262                                 return -1;
1263                         }
1264                 } /* loop over items in the subsection */
1265
1266                 cf_log_info(cs, " }");
1267         } /* if there's an 'instantiate' section. */
1268
1269         /*
1270          *      Loop over the listeners, figuring out which sections
1271          *      to load.
1272          */
1273         for (listener = mainconfig.listen;
1274              listener != NULL;
1275              listener = listener->next) {
1276                 char buffer[256];
1277
1278                 if (listener->type == RAD_LISTEN_PROXY) continue;
1279
1280                 cs = cf_section_sub_find_name2(config,
1281                                                "server", listener->server);
1282                 if (!cs && (listener->server != NULL)) {
1283                         listener->print(listener, buffer, sizeof(buffer));
1284
1285                         radlog(L_ERR, "No server has been defined for %s", buffer);
1286                         return -1;
1287                 }
1288         }
1289
1290         if (virtual_server_load(config) < 0) return -1;
1291
1292         return 0;
1293 }
1294
1295 /*
1296  *      Call all authorization modules until one returns
1297  *      somethings else than RLM_MODULE_OK
1298  */
1299 int module_authorize(int autz_type, REQUEST *request)
1300 {
1301         return indexed_modcall(RLM_COMPONENT_AUTZ, autz_type, request);
1302 }
1303
1304 /*
1305  *      Authenticate a user/password with various methods.
1306  */
1307 int module_authenticate(int auth_type, REQUEST *request)
1308 {
1309         return indexed_modcall(RLM_COMPONENT_AUTH, auth_type, request);
1310 }
1311
1312 #ifdef WITH_ACCOUNTING
1313 /*
1314  *      Do pre-accounting for ALL configured sessions
1315  */
1316 int module_preacct(REQUEST *request)
1317 {
1318         return indexed_modcall(RLM_COMPONENT_PREACCT, 0, request);
1319 }
1320
1321 /*
1322  *      Do accounting for ALL configured sessions
1323  */
1324 int module_accounting(int acct_type, REQUEST *request)
1325 {
1326         return indexed_modcall(RLM_COMPONENT_ACCT, acct_type, request);
1327 }
1328 #endif
1329
1330 #ifdef WITH_SESSION_MGMT
1331 /*
1332  *      See if a user is already logged in.
1333  *
1334  *      Returns: 0 == OK, 1 == double logins, 2 == multilink attempt
1335  */
1336 int module_checksimul(int sess_type, REQUEST *request, int maxsimul)
1337 {
1338         int rcode;
1339
1340         if(!request->username)
1341                 return 0;
1342
1343         request->simul_count = 0;
1344         request->simul_max = maxsimul;
1345         request->simul_mpp = 1;
1346
1347         rcode = indexed_modcall(RLM_COMPONENT_SESS, sess_type, request);
1348
1349         if (rcode != RLM_MODULE_OK) {
1350                 /* FIXME: Good spot for a *rate-limited* warning to the log */
1351                 return 0;
1352         }
1353
1354         return (request->simul_count < maxsimul) ? 0 : request->simul_mpp;
1355 }
1356 #endif
1357
1358 #ifdef WITH_PROXY
1359 /*
1360  *      Do pre-proxying for ALL configured sessions
1361  */
1362 int module_pre_proxy(int type, REQUEST *request)
1363 {
1364         return indexed_modcall(RLM_COMPONENT_PRE_PROXY, type, request);
1365 }
1366
1367 /*
1368  *      Do post-proxying for ALL configured sessions
1369  */
1370 int module_post_proxy(int type, REQUEST *request)
1371 {
1372         return indexed_modcall(RLM_COMPONENT_POST_PROXY, type, request);
1373 }
1374 #endif
1375
1376 /*
1377  *      Do post-authentication for ALL configured sessions
1378  */
1379 int module_post_auth(int postauth_type, REQUEST *request)
1380 {
1381         return indexed_modcall(RLM_COMPONENT_POST_AUTH, postauth_type, request);
1382 }