Pluggable configuration design choices
ghudson at MIT.EDU
Mon Jul 11 11:19:44 EDT 2011
Thanks for the feedback so far. I've started working on fleshing this
out, and implementation pressures have altered my design ideas a bit.
Right now I'm looking at four major pieces:
1. Add support for vtable-backed profiles.
This piece is fully contained within util/profile. profile.hin gets a
vtable structure (using libprofile coding conventions) with operations
mostly mirroring the libprofile API. There's a new function
profile_init_vtable() to create a profile from a vtable pointer and
callback data, and libprofile functions defer to the vtable for
operations. Most of the vtable methods are optional.
There are a few messy bits. profile_iterator() and
profile_iterator_free() don't take profile arguments (the iterator blob
is expected to contain all of the needed state), so I needed to create
an extra wrapper for iterator blobs. profile_release_string() and
similar functions don't take profile arguments, so I need to copy
results from the vtable into libprofile-allocated memory to preserve the
Finally, I need to handle profile_copy(). krb5_get_profile() uses this
rather than just returning an alias to the context profile. I'm still
mulling over some options here:
* Create a mandatory copy method in the vtable, which accepts a callback
data pointer and produces a new one. The copied profile has the same
vtable as the original and the new data pointer.
* Decide that copied vtable-backed profiles are just reference-counted
aliases to the original.
* Make the copy method optional, and fall back to reference counting
when it isn't defeined.
2. Provide API-level control over the krb5_context profile.
Right now I'm looking at a krb5_init_context_profile(), which takes a
profile argument and a secure flag and outputs a context. I'm mulling
over whether the function should copy the profile (for consistency with
krb5_get_profile()) or just take ownership of it.
3. Support dynamic module loading and system-level module selection.
Of the four options I presented before, I think the best one is where
the first line of krb5.conf (or $KRB5_CONFIG for non-secure contexts)
specifies the module and residual. This is friendly to the test suite
and doesn't add any new environment variables.
There are a couple of different possible shapes for this design.
* I could teach libprofile how to load dynamic modules, and define a
dynamic plugin interface completely in terms of libprofile conventions.
libprofile is linked against libkrb5support already, so it could use
krb5int_open_plugin() for portability.
* I could make libprofile error out with a specific error code if it
sees a module directive. libkrb5 would then re-open the file and parse
out the directive. The dynamic module API would look more like a
standard krb5 plugin API. The pluggable interface would have one
method, mapping a residual string and flags to a profile for the new
I'm currently more fond of the second option, although it requires more
complex interactions between libkrb5 and libprofile.
More information about the krbdev