Pluggable configuration design choices

Greg Hudson 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
malloc/free barrier.

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 mailing list