diff options
author | Greg Hudson <ghudson@mit.edu> | 2010-07-29 12:40:08 +0000 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2010-07-29 12:40:08 +0000 |
commit | 49fdc3dc52b9a9c69632e288773a74e4489fa2a0 (patch) | |
tree | f1e5ba536544217d57d186319db799258847da62 /src | |
parent | 72af6413340470b62156a9620137de33ac23d9aa (diff) | |
download | krb5-49fdc3dc52b9a9c69632e288773a74e4489fa2a0.zip krb5-49fdc3dc52b9a9c69632e288773a74e4489fa2a0.tar.gz krb5-49fdc3dc52b9a9c69632e288773a74e4489fa2a0.tar.bz2 |
On the plugins2 branch, improve the generic plugin support so that it
does not dlopen/dlsym modules which would later be filtered out. Also
edit README.BRANCH a little.
git-svn-id: svn://anonsvn.mit.edu/krb5/branches/plugins2@24217 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/krb5/krb/plugin.c | 144 |
1 files changed, 64 insertions, 80 deletions
diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c index ad045c1..77861e3 100644 --- a/src/lib/krb5/krb/plugin.c +++ b/src/lib/krb5/krb/plugin.c @@ -133,62 +133,6 @@ parse_modstr(krb5_context context, const char *modstr, return 0; } -/* Open a dynamic object at modpath, look up symname within it, and register - * the resulting init function as modname. */ -static krb5_error_code -open_and_register(krb5_context context, struct plugin_interface *interface, - const char *modname, const char *modpath, - const char *symname) -{ - krb5_error_code ret; - struct plugin_file_handle *handle; - void (*initvt_fn)(); - - ret = krb5int_open_plugin(modpath, &handle, &context->err); - if (ret != 0) - return ret; - - ret = krb5int_get_plugin_func(handle, symname, &initvt_fn, &context->err); - if (ret != 0) { - krb5int_close_plugin(handle); - return ret; - } - - ret = register_module(context, interface, modname, - (krb5_plugin_initvt_fn)initvt_fn, handle); - if (ret != 0) - krb5int_close_plugin(handle); - return ret; -} - -/* Register the plugins given by the profile strings in modules. */ -static krb5_error_code -register_dyn_modules(krb5_context context, struct plugin_interface *interface, - const char *iname, char **modules) -{ - krb5_error_code ret; - char *modname = NULL, *modpath = NULL, *symname = NULL; - - for (; *modules != NULL; modules++) { - ret = parse_modstr(context, *modules, &modname, &modpath); - if (ret != 0) - return ret; - if (asprintf(&symname, "%s_%s_initvt", iname, modname) < 0) { - free(modname); - free(modpath); - return ENOMEM; - } - /* XXX should errors here be fatal, or just ignore the module? */ - ret = open_and_register(context, interface, modname, modpath, symname); - free(modname); - free(modpath); - free(symname); - if (ret != 0) - return ret; - } - return 0; -} - /* Return true if value is found in list. */ static krb5_boolean find_in_list(char **list, const char *value) @@ -200,17 +144,25 @@ find_in_list(char **list, const char *value) return FALSE; } -/* Remove any registered modules whose names are not present in enable. */ +/* Return true if module is not filtered out by enable or disable lists. */ +static krb5_boolean +module_enabled(const char *modname, char **enable, char **disable) +{ + return ((enable == NULL || find_in_list(enable, modname)) && + (disable == NULL || !find_in_list(disable, modname))); +} + +/* Remove any registered modules whose names are filtered out. */ static void -filter_enable(krb5_context context, struct plugin_interface *interface, - char **enable) +filter_builtins(krb5_context context, struct plugin_interface *interface, + char **enable, char **disable) { struct plugin_mapping *map, **pmap; pmap = &interface->modules; while (*pmap != NULL) { map = *pmap; - if (!find_in_list(enable, map->modname)) { + if (!module_enabled(map->modname, enable, disable)) { *pmap = map->next; free_plugin_mapping(map); } else @@ -218,22 +170,53 @@ filter_enable(krb5_context context, struct plugin_interface *interface, } } -/* Remove any registered modules whose names are present in disable. */ -static void -filter_disable(krb5_context context, struct plugin_interface *interface, - char **disable) +/* Register the plugin module given by the profile string mod. */ +static krb5_error_code +register_dyn_module(krb5_context context, struct plugin_interface *interface, + const char *iname, const char *modstr, char **enable, + char **disable) { - struct plugin_mapping *map, **pmap; + krb5_error_code ret; + char *modname = NULL, *modpath = NULL, *symname = NULL; + struct plugin_file_handle *handle = NULL; + void (*initvt_fn)(); - pmap = &interface->modules; - while (*pmap != NULL) { - map = *pmap; - if (find_in_list(disable, map->modname)) { - *pmap = map->next; - free_plugin_mapping(map); - } else - pmap = &map->next; + /* Parse out the module name and path, and make sure it is enabled. */ + ret = parse_modstr(context, modstr, &modname, &modpath); + if (ret != 0) + goto cleanup; + if (!module_enabled(modname, enable, disable)) + goto cleanup; + + /* Construct the initvt symbol name for this interface and module. */ + if (asprintf(&symname, "%s_%s_initvt", iname, modname) < 0) { + symname = NULL; + ret = ENOMEM; + goto cleanup; } + + /* Open the plugin and resolve the initvt symbol. */ + ret = krb5int_open_plugin(modpath, &handle, &context->err); + if (ret != 0) + goto cleanup; + ret = krb5int_get_plugin_func(handle, symname, &initvt_fn, &context->err); + if (ret != 0) + goto cleanup; + + /* Create a mapping for the module. */ + ret = register_module(context, interface, modname, + (krb5_plugin_initvt_fn)initvt_fn, handle); + if (ret != 0) + goto cleanup; + handle = NULL; /* Now owned by the module mapping. */ + +cleanup: + free(modname); + free(modpath); + free(symname); + if (handle != NULL) + krb5int_close_plugin(handle); + return ret; } /* Ensure that a plugin interface is configured. id is assumed to be valid. */ @@ -243,7 +226,7 @@ configure_interface(krb5_context context, int id) krb5_error_code ret; struct plugin_interface *interface = &context->plugins[id]; const char *iname = interface_names[id]; - char **modules = NULL, **enable = NULL, **disable = NULL; + char **modules = NULL, **enable = NULL, **disable = NULL, **mod; static const char *path[4]; if (interface->configured) @@ -266,15 +249,16 @@ configure_interface(krb5_context context, int id) if (ret != 0 && ret != PROF_NO_RELATION) goto cleanup; - if (modules != NULL) { - ret = register_dyn_modules(context, interface, iname, modules); + /* Remove built-in modules which are filtered out by configuration. */ + filter_builtins(context, interface, enable, disable); + + /* Create mappings for dynamic modules which aren't filtered out. */ + for (mod = modules; mod && *mod; mod++) { + ret = register_dyn_module(context, interface, iname, *mod, + enable, disable); if (ret != 0) return ret; } - if (enable != NULL) - filter_enable(context, interface, enable); - if (disable != NULL) - filter_disable(context, interface, disable); ret = 0; cleanup: |