svn rev #24217: branches/plugins2/ src/lib/krb5/krb/
ghudson@MIT.EDU
ghudson at MIT.EDU
Thu Jul 29 08:40:08 EDT 2010
http://src.mit.edu/fisheye/changelog/krb5/?cs=24217
Commit By: ghudson
Log Message:
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.
Changed Files:
U branches/plugins2/README.BRANCH
U branches/plugins2/src/lib/krb5/krb/plugin.c
Modified: branches/plugins2/README.BRANCH
===================================================================
--- branches/plugins2/README.BRANCH 2010-07-27 16:09:45 UTC (rev 24216)
+++ branches/plugins2/README.BRANCH 2010-07-29 12:40:08 UTC (rev 24217)
@@ -111,11 +111,11 @@
1. Build the branch normally and install it somewhere.
2. cd into the pwqual_combo directory and build it with "make
- -I/path/to/install/include". The Makefile probably only works on
- Linux-based operating systems.
+ INCLUDES=-I/path/to/install/include". The Makefile probably only
+ works on Linux-based operating systems.
3. Go back to the main build directory and run "make testrealm" to
- create a functioning environment.
+ spawn a shell within a functioning environment.
4. Add the following configuration to testdir/krb5.master.conf to make
pwqual_combo discoverable:
@@ -130,23 +130,25 @@
the setting "dict_file = /tmp/dict".
6. Run kadmin.local and create a policy with "addpol -minlength 4
-testpolicy". Associated it with the principal user with "modprinc
--policy testpolicy user".
+ testpolicy". Associated it with the principal user with "modprinc
+ -policy testpolicy user".
7. Inside kadmin.local, try some password change with "cpw user". You
-should be able to see that all three password quality modules are
-functioning: you won't be able to set passwords shorter than four
-characters long (the policy module), or the passwords "books" or
-"sharks" (the dict module), or passwords named "sharksbooks" or
-"bookssharks" (the combo module).
+ should be able to see that all three password quality modules are
+ functioning: you won't be able to set passwords shorter than four
+ characters long (the policy module), or the passwords "books" or
+ "sharks" (the dict module), or passwords named "sharksbooks" or
+ "bookssharks" (the combo module).
8. Quit out of kadmin.local and edit testdir/krb5.master.conf again.
-Play with the filtering rules by adding, alongside the "module"
-directive, one or more assignments for enable_only and/or disable.
-For instance, if you disable the policy module, you should find that
-(upon restarting kadmin.local) you can set passwords shorter than four
-characters again.
+ Play with the filtering rules by adding, alongside the "module"
+ directive, one or more assignments for enable_only and/or disable.
+ For instance, if you disable the policy module, you should find
+ that (upon restarting kadmin.local) you can set passwords shorter
+ than four characters again.
+9. Exit out of the shell to quit out of the test environment.
+
----- What's wrong with this branch -----
The krb5 code on this branch is mostly complete, but as a
@@ -179,8 +181,3 @@
interface. This constraint is probably fine, but if it needs to be
revisited, the framework's data model will need to be made a little
more complicated to allow it.
-
-* Filtering should probably be applied to module mappings before
- dynamic modules are opened, since dlopen() is not always a cheap
- operation. This is an implementation detail of the
- domain-independent plugin framework.
Modified: branches/plugins2/src/lib/krb5/krb/plugin.c
===================================================================
--- branches/plugins2/src/lib/krb5/krb/plugin.c 2010-07-27 16:09:45 UTC (rev 24216)
+++ branches/plugins2/src/lib/krb5/krb/plugin.c 2010-07-29 12:40:08 UTC (rev 24217)
@@ -133,62 +133,6 @@
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 @@
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 @@
}
}
-/* 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 @@
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 @@
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:
More information about the cvs-krb5
mailing list