krb5 libraries and circular dependencies
raeburn at MIT.EDU
Wed May 26 13:17:33 EDT 2010
On May 25, 2010, at 14:51, ghudson at MIT.EDU wrote:
> So, I'd like to raise the idea of combining all three libraries into
> one. The question here is whether libk5crypto is separate from
> libkrb5 purely due to erstwhile export regulations, or whether we want
> libk5crypto (eventually) be useful independently of libkrb5, like the
> OpenSSL crypto library is.
The krb5-config script currently tells developers to link against the k5crypto library, so actually getting rid of it would be an incompatible ABI change. You could keep a dummy library around, but our symbol versioning uses the library names, too. I'm not sure if there are systems where the symbol name is tied to the actual library name (or soname), but that would be another obstacle.
Whatever you do, be sure to test the new version against old binaries, on a variety of systems, unless you decide you're making a backwards-incompatible ABI change. In which case, there are probably some number of other things that could be cleaned up at the same time.
That said... if the time frame isn't too short, would it make sense to finish up the KIM library support for UNIX and fold that in as well, giving one consistent library for (non-GSSAPI) Kerberos programming? Or fold it in later when it's done?
> 2. Plugins loaded from libkrb5 can make use of libkrb5--this kind of
> circular dependency is allowed when you dynamically load things--and
> they quite often do so.
> There are three directions we can go in here:
> * We can try to make it unnecessary (and disallowed) for plugins to
> directly use libkrb5, by providing them with callbacks. In the
> extreme case, we could provide plugins with a giant vtable
> containing all libkrb5 APIs. Maintaining such a vtable would be a
> bit of a hassle.
I think this sounds best, but I think it can only work well if you actually do provide all the functions that might be desired (i.e., everything exported, or almost everything), and in a form that's easy to use for lots of calls into libkrb5 without lots of code bloat or awkward coding. (Maybe helper functions/macros resembling the real calls, including type checking, but with a library handle argument added, or replacing the context, or something.)
It doesn't have to be quite that hard, if you can programmatically extract the function names and signatures from your header file. I've written such scripts, and some are in the tree; they were intended to work on the header files as they exist now, but you could impose some rules on the addition of new stuff and basically require that it be parseable.
Whether there should be a big, exposed vtable type that changes every time you update the export list, vs a function that takes a string and returns a function pointer a la dlsym (but maybe supporting all the krb5 libraries' public interfaces with one handle), I don't know. There are advantages and disadvantages both ways. The big-vtable approach would need more work than our current 'accessor' stuff, because the accessor is considered internal and subject to change between releases; the big-vtable approach would have to support the ABIs used in previous releases. (Hm, well, unless you specify that the plugin ABI is never going to be compatible across versions.)
> * We can allow plugins to use libkrb5, and create a safety mechanism
> to fail explicitly if a plugin was linked against a different copy
> of libkrb5 than the one which loaded it. To do this, we'd ask
> plugins to call a libkrb5 function which compares the address of a
> global variable or function to one provided to the plugin.
You can't really stop them from using libkrb5 in the general case, if they're careful not to mix versions. (E.g., some internal API using only strings and numbers separates the loading/calling libkrb5 instance from the occasionally-used other libkrb5 instance. Or, for example, the plugin tries to do DNSSEC which loads GSSAPI which.... Though if two libkrb5 instances wind up using the same krb5 support library, it could be bad.) But you could detect mixing of versions, like maybe sticking a pointer field in near the top of the context and checking it on function entry.
More information about the krbdev