mit krb5 and threads - api
raeburn at MIT.EDU
Wed Mar 3 02:26:52 EST 2004
Quick recap from previous discussions: Shim layer - yes. Callbacks -
gone. Dynamic loading - mustn't leak resources at unload. Thread
cancellation - undecided. File locking issues - undecided.
So there's still a bunch of stuff to be worked out, but I think some
of the basics can be mapped out right now, like which objects we want
to be safe to manipulate in multiple threads at once, and some initial
I've written up some ideas, but it's still a bit rough. Comments on
what I've got so far are welcome.
Skimming through krb5.h, I think I'd break things down this way:
Safe for simultaneous use in multiple threads: krb5_ccache,
krb5_rcache, krb5_keytab, profile. Everything using these must
lock them within the library.
Unsafe: krb5_context, krb5_auth_context, kdc/ap message
structures. (These can be changed by the library when we're
trying to retrieve information, decode messages, etc.)
Applications must manage locks if objects are used in multiple
Safe for read-only access: ccache/rcache/keytab iteration cursors
and entry structures, get/verify_init_creds options, authenticator
data, credentials, principal names, krb5_data, addresses, crypto
stuff, trivial integral and pointer types. Iteration cursors
aren't safe if the container referenced is being modified.
All created objects (e.g., from krb5_copy_principal) are effectively
independent of the other objects in use at their creation.
(Effectively = we could in theory use locks and ref counts under the
covers, but the application should behave as if it's a completely new
I'm still a bit tempted to move krb5_context into the "safe" list, and
keep just one krb5_context for the GSSAPI mechanism, since most of the
per-association data is in the auth context, but it would be a lot of
work, and I'm not sure it could work anyways.
For GSSAPI (though we should probably handle this through the IETF):
Safe: names, credential handles, OIDs and OID sets and buffer
descriptors when not being modified.
Unsafe: context ids, OID sets (for output), buffer descriptors
(for modification), channel bindings, credential info, etc.
If we wind up having to prioritize, probably keytabs would be the
first to punt, then possibly credentials caches.
Anyone familiar with the use of GSSAPI in threaded programs? (Any
OpenLDAP people listening?) What's most urgent to make thread-safe on
the GSSAPI side?
As for the internal shim layer interface, I'm thinking about this so
far, based loosely on the pthread API:
#include "k5-thread.h" /* not installed */
k5_mutex_t foo_mutex = K5_MUTEX_INITIALIZER;
int k5_mutex_init(k5_mutex_t *);
int k5_mutex_destroy(k5_mutex_t *); /* void? */
int k5_mutex_lock(k5_mutex_t *);
int k5_mutex_unlock(k5_mutex_t *); /* void? */
int k5_key_create(k5_key_t *, void (*destructor)(void *));
/* or maybe a fixed number of predefined key values? */
int k5_setspecific(k5_key_t, const void *);
... something to call at library termination ...
Mutexes would be simple -- a thread isn't allowed to lock a mutex it
already has locked.
Error returns would be system error codes, which so far we've always
been assuming would be compatible enough with the com_err error code
handling that we can just get away with treating the former as a
subset of the latter. So strerror() and error_message() should both
give something useful back.
Most of these will be defined as macros. Implementation data and
non-trivial functions, when (not "if") they're needed, will be in a
separate support library, and would use krb5int_ as the prefix for all
exported symbol names. (I used k5_ above because I just get tired of
typing krb5int_ a lot.)
I'm almost ready to check in a header file and a few other changes to
the CVS repository, but they're in the preliminary stages. No weak
symbol support, no support for anything but POSIX threads, never
enabled by default (except maybe some debug code to test the
lock/unlock pairing even without the pthread support), only the basic
mutex code and a couple of locks. But it's a starting point.
More information about the krbdev