Difference between revisions of "Projects/Plugin support improvements (first version)"
From K5Wiki
< Projects
(→Current plugins) |
(→Current plugins) |
||
Line 15: | Line 15: | ||
* KDC location: All shared objects from an installation directory are located. A vtable is read from the shared objects. The KDC location framework iterates over each vtable and invokes a lookup function; modules can return success with a location, an error (which halts the location process), or a distinguished error code which passes control along to the next module or the built-in location mechanisms. |
* KDC location: All shared objects from an installation directory are located. A vtable is read from the shared objects. The KDC location framework iterates over each vtable and invokes a lookup function; modules can return success with a location, an error (which halts the location process), or a distinguished error code which passes control along to the next module or the built-in location mechanisms. |
||
− | * GSSAPI |
+ | * GSSAPI: The file /etc/gss/mechs can specify a list of mechanism OIDs and shared object filenames; filenames are taken as relative to $(libdir)/gss. Shared objects implementing mechanisms can export either a function returning a vtable, or can export each GSSAPI interface individually. |
* Serialization (not exposed): Serialization table entries can be registered with krb5_register_serializer. Data objects are matched to table entries by magic number. The registration function is exported by libkrb5 and is named with the krb5_ prefix, but it and its associated structure are declared in k5-int.h rather than krb5.h. It is not used outside of libkrb5. |
* Serialization (not exposed): Serialization table entries can be registered with krb5_register_serializer. Data objects are matched to table entries by magic number. The registration function is exported by libkrb5 and is named with the krb5_ prefix, but it and its associated structure are declared in k5-int.h rather than krb5.h. It is not used outside of libkrb5. |
Revision as of 17:23, 8 February 2010
This is an early stage project for MIT Kerberos. It is being fleshed out by its proponents. Feel free to help flesh out the details of this project. After the project is ready, it will be presented for review and approval.
This page contains some notes about improving the plugin infrastructure, but does not make a specific proposal yet.
Current plugins
We currently have the following plugins:
- Preauth: All shared objects from profile-specified or installation directory are loaded. Two vtables are read from the shared objects, one for libkrb5 and one for the KDC. The preauth framework iterates over the module list invoking functions to generate or handle preauth data. Preauth vtable functions receive a callback function and data object which allow it to request information such as the expected enctype or FAST armor key for the request.
- Authdata: Very similar to the preauth framework.
- KDB: The profile specifies a database library name for each realm. Shared objects matching the library name are loaded from a profile-specified and installation directory; the first matching object with an appropriately-named vtable data object is used, and the rest are ignored. libkdb5 contains wrappers which invoke functions in the library's vtable, or (for some optional functions) default implementations if the vtable left the function pointer as NULL.
- KDC location: All shared objects from an installation directory are located. A vtable is read from the shared objects. The KDC location framework iterates over each vtable and invokes a lookup function; modules can return success with a location, an error (which halts the location process), or a distinguished error code which passes control along to the next module or the built-in location mechanisms.
- GSSAPI: The file /etc/gss/mechs can specify a list of mechanism OIDs and shared object filenames; filenames are taken as relative to $(libdir)/gss. Shared objects implementing mechanisms can export either a function returning a vtable, or can export each GSSAPI interface individually.
- Serialization (not exposed): Serialization table entries can be registered with krb5_register_serializer. Data objects are matched to table entries by magic number. The registration function is exported by libkrb5 and is named with the krb5_ prefix, but it and its associated structure are declared in k5-int.h rather than krb5.h. It is not used outside of libkrb5.
- ccache (not exposed): Very similar to serialization, except that ccache implementations are selected using a URL-style prefix in the ccache name.
- keytab (not exposed): Very similar to ccache, except that the keytab registration function is used outside of libkrb5 to register a "KDB keytab", which is used by kadmind to serve GSSRPC without requiring a keytab file containing the kadmin keys.
- Replay cache (not exposed): Very similar to ccache, except that the replay cache registration function is not used anywhere (even inside libkrb5).
Plugin frameworks which are "not exposed" may still be productively used by vendor forks of the krb5 tree.
Future plugins
The following areas are candidates for future plugin support:
- PRNG
- profile / configuration
- DNS / host-realm mapping
- password quality policy
- lockout
- audit
- password synchronization
Current support infrastructure
In libkrb5support, we have functions to facilitate loading plugins from shared objects. There is a set of functions to load individual plugins from named files and mechglue; these are currently used by the HDB bridge and GSS mechglue:
- krb5int_open_plugin - Create a plugin handle from a filename
- krb5int_close_plugin - Close a plugin handle
- krb5int_get_plugin_data - Retrieve a data object from a plugin handle by symbol name
- krb5int_get_plugin_func - Retrieve a function object from a plugin handle by symbol name
There is another set of functions to scan a list of directories for plugins:
- krb5int_open_plugin_dirs - Create a plugin dir handle from a list of directories and (optionally) filebases
- krb5int_close_plugin_dirs - Close a plugin dir handle
- krb5int_get_plugin_dir_data - Retrieve a list of data objects from a plugin dir handle by symbol name
- krb5int_get_plugin_dir_func - Retrieve a list of function objects from a plugin dir handle by symbol name
- krb5int_free_plugin_dir_data - Free a list of data objects returned by krb5int_get_plugin_dir_data
- krb5int_free_plugin_dir_func - Free a list of function objects returned by krb5int_get_plugin_dir_func
Problem areas
- Every caller of krb5int_open_plugin_dirs specifies either no filebases (e.g. preauth plugins) or a single filebase (KDB plugins). Accepting and processing a list of filebases is probably needless complexity.
- Callers of krb5int_open_plugin_dirs have to know what directories to supply, which means they need to know the krb5 install root as well as the magic plugin area for OS X, and they need logic for reading a profile variable to determine the alternate plugin directory for the test suite (currently only implemented for KDB and preauth plugins).
- In most uses of plugins, we read a data object containing a list of function pointers. This makes it mostly impossible to supply a plugin which works with multiple versions of krb5. If we instead read a function object which we invoked with a version number to retrieve the vtable, it would be possible (though perhaps awkward) to create a shared object which works with multiple versions.
- We are somewhat schizophrenic about how plugins can access krb5 library functionality, and in particular internal symbols. Sometimes we call functions directly, sometimes we make use of a vtable passed into the plugin (e.g. the preauth_get_client_data_proc function), sometimes we use the accessor to invoke internal functions, and sometimes we call APIs or internal functions directly. Ideally we should have a consistent policy with a sound justification.
- When measuring code coverage with gcov, we cannot use shared libraries; this means we need to link in-tree plugins statically into the libraries or programs which load them. We have an ad-hoc method to do this with KDB plugins, but not with other plugin types.
- Administrators have an easier time writing scripts than creating linkable shared objects. In some cases it might yield a better administrator experience to create plugin interfaces via subprocesses than loading shared objects, although in many cases this might not be feasible.
- In some scenarios such as embedded environments, it may be more useful to allow applications to supply plugin vtables via an API (as we do for keytabs and ccaches, though those APIs are not public) than to load them from shared objects in the filesystem.