#include <freeradius-devel/parser.h>
#include <freeradius-devel/rad_assert.h>
+/** Path to search for modules in
+ *
+ */
+char const *radlib_dir = NULL;
+
typedef struct indexed_modcallable {
rlm_components_t comp;
int idx;
return 0;
}
-lt_dlhandle lt_dlopenext(char const *name)
+fr_dlhandle fr_dlopenext(char const *name)
{
- int flags = RTLD_NOW;
- void *handle;
- char buffer[2048];
- char *env;
-
+ int flags = RTLD_NOW;
+ void *handle;
+ char buffer[2048];
+ char *env;
+ char const *search_path;
#ifdef RTLD_GLOBAL
if (strcmp(name, "rlm_perl") == 0) {
flags |= RTLD_GLOBAL;
*/
flags |= RTLD_NOW;
#endif
+
+ /*
+ * Apple removed support for DYLD_LIBRARY_PATH in rootless mode.
+ */
+ env = getenv("FR_LIBRARY_PATH");
+ if (env) {
+ DEBUG3("Ignoring libdir as FR_LIBRARY_PATH set. Module search path will be: %s", env);
+ search_path = env;
+ } else {
+ search_path = radlib_dir;
+ }
+
/*
* Prefer loading our libraries by absolute path.
*/
- if (radlib_dir) {
+ if (search_path) {
char *error;
+ char *ctx, *paths, *path;
+ char *p;
- snprintf(buffer, sizeof(buffer), "%s/%s%s", radlib_dir, name, LT_SHREXT);
+ fr_strerror();
- DEBUG4("Loading library using absolute path \"%s\"", buffer);
+ ctx = paths = talloc_strdup(NULL, search_path);
+ while ((path = strsep(&paths, ":")) != NULL) {
+ /*
+ * Trim the trailing slash
+ */
+ p = strrchr(path, '/');
+ if (p && ((p[1] == '\0') || (p[1] == ':'))) *p = '\0';
- handle = dlopen(buffer, flags);
- if (handle) return handle;
- error = dlerror();
+ path = talloc_asprintf(ctx, "%s/%s%s", path, name, LT_SHREXT);
- fr_strerror_printf("%s", error);
- DEBUG4("Failed with error: %s", error);
+ DEBUG4("Loading %s with path: %s", name, path);
- /*
- * Because dlopen (on OSX at least) produces really
- * shitty and inaccurate error messages
- */
- if (access(buffer, R_OK) < 0) {
- switch (errno) {
- case EACCES:
- WARN("Library file found, but we don't have permission to read it");
- break;
-
- case ENOENT:
- DEBUG4("Library file not found");
- break;
-
- default:
- DEBUG4("Issue accessing library file: %s", fr_syserror(errno));
- break;
+ handle = dlopen(path, flags);
+ if (handle) {
+ talloc_free(ctx);
+ return handle;
}
+ error = dlerror();
+
+ fr_strerror_printf("%s%s\n", fr_strerror(), error);
+ DEBUG4("Loading %s failed: %s - %s", name, error,
+ (access(path, R_OK) < 0) ? fr_syserror(errno) : "No access errors");
+ talloc_free(path);
}
+ talloc_free(ctx);
}
DEBUG4("Loading library using linker search path(s)");
return handle;
}
-void *lt_dlsym(lt_dlhandle handle, char const *symbol)
+void *fr_dlsym(fr_dlhandle handle, char const *symbol)
{
return dlsym(handle, symbol);
}
-int lt_dlclose(lt_dlhandle handle)
+int fr_dlclose(fr_dlhandle handle)
{
if (!handle) return 0;
return dlclose(handle);
}
-char const *lt_dlerror(void)
+char const *fr_dlerror(void)
{
return dlerror();
}
}
#endif
- /*
- * Remove any registered paircompares.
- */
- paircompare_unregister_instance(module->insthandle);
-
xlat_unregister(module->name, NULL, module->insthandle);
+
/*
* Remove all xlat's registered to module instance.
*/
- if (module->insthandle) xlat_unregister_module(module->insthandle);
+ if (module->insthandle) {
+ /*
+ * Remove any registered paircompares.
+ */
+ paircompare_unregister_instance(module->insthandle);
+
+ xlat_unregister_module(module->insthandle);
+ }
talloc_free(module);
}
/*
* Keep the handle around so we can dlclose() it.
*/
- handle = lt_dlopenext(module_name);
+ handle = fr_dlopenext(module_name);
if (!handle) {
cf_log_err_cs(cs, "Failed to link to module '%s': %s", module_name, fr_strerror());
return NULL;
*/
if (node->entry->module->inst_size) {
*handle = talloc_zero_array(node, uint8_t, node->entry->module->inst_size);
- rad_assert(handle);
+ rad_assert(*handle);
talloc_set_name(*handle, "rlm_%s_t",
node->entry->module->name ? node->entry->module->name : "config");
* section. If the CS is free'd the instance will be
* free'd, too.
*/
- node = talloc_zero(cs, module_instance_t);
+ node = talloc_zero(instance_tree, module_instance_t);
node->cs = cs;
strlcpy(node->name, name2, sizeof(node->name));
if (idx == 0) {
list = server->mc[comp];
- if (!list) RDEBUG3("Empty %s section. Using default return values.", section_type_value[comp].section);
-
+ if (!list) {
+ if (server->name) {
+ RDEBUG3("Empty %s section in virtual server \"%s\". Using default return values.",
+ section_type_value[comp].section, server->name);
+ } else {
+ RDEBUG3("Empty %s section. Using default return values.", section_type_value[comp].section);
+ }
+ }
} else {
indexed_modcallable *this;
static int load_byserver(CONF_SECTION *cs)
{
- rlm_components_t comp, found;
+ rlm_components_t comp;
+ bool found;
char const *name = cf_section_name2(cs);
rbtree_t *components;
virtual_server_t *server = NULL;
* Loop over all of the known components, finding their
* configuration section, and loading it.
*/
- found = 0;
+ found = false;
for (comp = 0; comp < MOD_COUNT; ++comp) {
CONF_SECTION *subcs;
server->subcs[comp] = subcs;
- found = 1;
+ found = true;
} /* loop over components */
/*
* Loop over all of the components
*/
for (comp = 0; comp < MOD_COUNT; ++comp) {
- CONF_SECTION *subcs;
- CONF_ITEM *modref;
+ CONF_SECTION *subcs, *type_cs;
DICT_ATTR const *da;
subcs = cf_section_sub_find(cs,
/*
* Define dynamic types, so that others can reference
* them.
+ *
+ * First, bare modules for 'authenticate'.
+ * Second, Auth-Type, etc.
*/
- for (modref = cf_item_find_next(subcs, NULL);
- modref != NULL;
- modref = cf_item_find_next(subcs, modref)) {
- char const *name1;
- CONF_SECTION *subsubcs;
+ if (section_type_value[comp].attr == PW_AUTH_TYPE) {
+ CONF_ITEM *modref;
- /*
- * Create types for simple references
- * only when parsing the authenticate
- * section.
- */
- if ((section_type_value[comp].attr == PW_AUTH_TYPE) &&
- cf_item_is_pair(modref)) {
- CONF_PAIR *cp = cf_item_to_pair(modref);
+ for (modref = cf_item_find_next(subcs, NULL);
+ modref != NULL;
+ modref = cf_item_find_next(subcs, modref)) {
+ CONF_PAIR *cp;
+
+ if (!cf_item_is_pair(modref)) continue;
+
+ cp = cf_item_to_pair(modref);
if (!define_type(cs, da, cf_pair_attr(cp))) {
return false;
}
- continue;
+ /*
+ * Check for duplicates
+ */
+ if (rad_debug_lvl) {
+ CONF_PAIR *cp2;
+ CONF_SECTION *cs2;
+
+ cp2 = cf_pair_find(subcs, cf_pair_attr(cp));
+ rad_assert(cp2 != NULL);
+ if (cp2 != cp) {
+ WARN("%s[%d]: Duplicate module '%s'",
+ cf_pair_filename(cp2),
+ cf_pair_lineno(cp2),
+ cf_pair_attr(cp));
+ }
+
+ cs2 = cf_section_sub_find_name2(subcs, section_type_value[comp].typename, cf_pair_attr(cp));
+ if (cs2) {
+ WARN("%s[%d]: Duplicate Auth-Type '%s'",
+ cf_section_filename(cs2),
+ cf_section_lineno(cs2),
+ cf_pair_attr(cp));
+ }
+ }
+
}
+ }
- if (!cf_item_is_section(modref)) continue;
+ /*
+ * And loop over the type names
+ */
+ for (type_cs = cf_subsection_find_next(subcs, NULL, section_type_value[comp].typename);
+ type_cs != NULL;
+ type_cs = cf_subsection_find_next(subcs, type_cs, section_type_value[comp].typename)) {
+ if (!define_type(cs, da, cf_section_name2(type_cs))) {
+ return false;
+ }
- subsubcs = cf_item_to_section(modref);
- name1 = cf_section_name1(subsubcs);
+ if (rad_debug_lvl) {
+ CONF_SECTION *cs2;
- if (strcmp(name1, section_type_value[comp].typename) == 0) {
- if (!define_type(cs, da,
- cf_section_name2(subsubcs))) {
- return false;
- }
+ cs2 = cf_section_sub_find_name2(subcs, section_type_value[comp].typename, cf_section_name2(type_cs));
+ rad_assert(cs2 != NULL);
+ if (cs2 != type_cs) {
+ WARN("%s[%d]: Duplicate Auth-Type '%s'",
+ cf_section_filename(cs2),
+ cf_section_lineno(cs2),
+ cf_section_name2(cs2));
+ }
}
}
} /* loop over components */
for (cs = cf_subsection_find_next(config, NULL, "server");
cs != NULL;
cs = cf_subsection_find_next(config, cs, "server")) {
+#if defined(WITH_DHCP) || defined(WITH_VMPS)
CONF_SECTION *subcs;
DICT_ATTR const *da;
+#endif
#ifdef WITH_VMPS
/*
DEBUG2("%s: #### Instantiating modules ####", main_config.name);
+ cf_log_info(config, " modules {");
+
/*
* Loop over module definitions, looking for duplicates.
*
module_instance_t *module;
char const *name;
- cf_log_info(cs, " instantiate {");
+ cf_log_info(cs, " instantiate {");
/*
* Loop over the items in the 'instantiate' section.
} /* handle subsections */
} /* loop over the "instantiate" section */
- cf_log_info(cs, " }");
+ cf_log_info(cs, " }");
} /* if there's an 'instantiate' section. */
/*
* because we've now split up the modules into
* mods-enabled.
*/
- cf_log_info(cs, " modules {");
for (ci=cf_item_find_next(modules, NULL);
ci != NULL;
ci=next) {
module = module_instantiate(modules, name);
if (!module) return -1;
}
- cf_log_info(cs, " } # modules");
+ cf_log_info(config, " } # modules");
if (virtual_servers_load(config) < 0) return -1;