Plugin project proposal
Nicolas.Williams at oracle.com
Thu Jul 15 13:43:56 EDT 2010
On Thu, Jul 15, 2010 at 12:59:01PM -0400, Zhanna Tsitkova wrote:
> The main participants in the new architecture are:
I've never seen a plugin interface as complex as this.
- PAM? Much simpler.
- GSS-API? Much simpler.
- SASL? Much simpler.
- Device drivers? Much simpler.
I could list many more plugin APIs where either I'm familiar with an
implementation, or where I've reviewed or influenced the design.
> Plugin related configuration and registration happen at run time,
> during the krb5 context creation. At this time PM registers all
At krb5 context creation time?! What if a plugin isn't needed? Must
the caller still load it?
Besides being a disaster for performance, this is also inviting DLL
hell (I'm thinking of OpenSSL getting loaded unnecessarily by
unnecessarily loading the PKINIT pre-auth plugin).
> From now on, to invoke the desired plugin interface, the caller
> obtains the plugin handle for the desired plugin module and uses its
> functionality. For example:
> plugin_manager_get_service(ctx->pl_manager, PWD_QLTY,
> PWD_QLTY_KRB, &plugin_handle);
> plugin_pwd_qlty_check(plugin_handle, srv_handle, password,
> use_policy, pol, principal);
> where PWD_QLTY is plugin interface id and PWD_QLTY_KRB is its
> implementation id.
Is this whenever you need to call a particular plugin? Or when you need
to call a plugin but don't care which it is? For the former I think
this is overkill, for the latter I think this is over-overkill.
For services like PAM, where the caller shouldn't care what the plugin
is (think KDB) there's really no need to have a plugin type and
"implementation ID". Having them at all makes the API unnecessarily
hard to use. (Yes, PAM involves calling potentially more than one
plugin, whereas the KDB involves calling no more than one plugin, still,
PAM is closer to the KDB here than, say, the GSS-API.)
For services like the GSS-API, where the caller needs to identify a
specific "mechanism" (think pre-auth) there's still no need to indicate
the plugin type, though there is a need to indicate "implementation ID".
Basically, I object to the plugin_manager_get_service() part.
> Now let me bring to your attention some updates.
> 1. 1. For those who followed the proposal since it was first
> introduced (I guess, in April): we decided to remove Abstract
> Interface for plugin manager. The initial motivation for having this
> abstraction was to allow multiple implementations of plugin managers.
Why "allow multiple implementations of plugin managers"?? Who's going
to re-implement this?
I can see having one implementation that uses dynamic object
linking/loading, and one designed for static linking. But I'd just
implement a dlopen()/dlsym()/dlclose() shim for use in the static
linking case so as to cut down on code duplication.
> It thought to be useful for such cases as hardcoded configuration (as
> for embedded devices), configuration that excludes the default
> location search for dynamic plugins, or for asynchronous processing
> model etc. However, since we do not have any immediate use-cases in
> hands, for now we will implement only one plugin manager and reserve
> the possibility of adding the abstraction later if needed.
I don't follow.
> 2. 2. It was suggested to use hash tables for the plugin
> interfaces in lieu of C structures. This would provide better plugin
> impl. version control and interface extensibility.
See Russ' and my other replies.
> 3. 3. Another interesting suggestion is for plugin interface to be
> more generic and follow a request-response paradigm:
See Russ' and my other replies.
> 4. 4. Notion of the plugin properties configuration attribute. It
> was introduced in the project to allow the administrator to pass some
> additional information to the plugin manager. For example, to be
> initialized, Plugin_A requires Plugin_B to be initialized first.
> Plugin manager now would arrange the proper init order or pass the
> desired parameters to the plugin module.
How is init order established?
I don't think plugin designs should be as complex as you guys are making
this one, nor should they take very long to produce. Simplify.
Start with existing plugin systems whose paradigms match the ones needed
internally in libkrb5. Examples are given above.
I'm not saying "do what libpam and/or libgss do", but I'm saying that
what they do is far, far simpler than what you're proposing, and it
works, and there's no reason to think that something simpler wouldn't
More information about the krbdev