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