thread-safe Kerberos libraries

Emily Ratliff ratliff at
Tue Mar 5 20:49:01 EST 2002


Now that you've forgotten what you said:

and I've played with it for a while, I have a few questions and comments.

> The callback functions may only be registered while no locks are held
> (which presumably means before any threads are created and while in
> the main application).  Locks are not held across library calls; they
> are always released.
I agree with both of these items, but the first is the goal of the 
application. I don't see how to enforce this in the library.

> (Question: Should the callback functions be registered through
> separate functions, or one call with extra arguments or a structure
> pointer?)
OpenSSL registers the callback functions individually, but I still prefer 
a structure pointer.

> Each library (each that has data needing protecting, that is) provides
> a set of functions for manipulating these callbacks, based in part on
> the OpenSSL API.
Why allow the capability to have different callbacks for different 
libraries loaded by the same application? In other words, if a single 
application uses more than one library, the app has to register the same 
callbacks with each libary that it uses. OpenSSL only has the thread 
support in one libary, so this issue hasn't shown up for them.

>  We also provide a thread-info function which gives
> the application some info about the thread safety of the library in
> question.
This makes sense that it is per library.

> (Question: Should we consider gssapi thread-safe if it uses locks
> around krb5 calls that can call DNS or C library routines that are not
> known to be thread-safe, or worse, are known not to be thread-safe?)
Sure, but hopefully we will do better.
> Should locks be ref-counted?  
> (What's OpenSSL do?)
OpenSSL does do ref-counting for locks. I'd like to postpone this one til 
later though.

> For each library's prefix "foo" (to be determined for libraries like
> com_err without consistent prefixes), we'd have the following
> functions and macros, with names adjusted accordingly:

> void foo_set_locking_callback (void (*lockfn)(int mode, int locknum,
>                                               const char *file,
>                                               int line));
Why per-library on this one? Why not a global that is shared? It will be 
set the same unless the application is doing something very strange. 

>    Q: What about systems that might have multiple thread packages that
>    *are* known to play nicely together?  If some FooThreads package is
>    provided by the kernel and the pthreads implementation uses
>    FooThreads primitives in a compatible way, the application should
>    be okay even if it doesn't use the same interface as the gss/krb5
>    libraries.  Should that knowledge be in the library or the
>    application?  Should we not bother?  */
> /* Should these be macros or enumerators?  */
> #define FOO_THREADS_WIN32     2
> #define FOO_THREADS_MACOS9    3
> #define FOO_THREADS_MACH      4
The library won't know which thread library and hopefully won't need to 
know, right? It just needs to know whether it has callbacks registered and 
is thread-safe, or it has the threading API compiled in with no callbacks 
registered or doesn't have the threading API compiled in and is unsafe.

> #define LOCKMODE_LOCK   1
> /* Acquire the lock.
>    Q: Support ref-counted locks at this layer?  */
> void fooint_lock (int mode, int locknum, const char *file, int line);
> #define LOCK(N)    fooint_lock(LOCKMODE_LOCK,(N),__FILE__,__LINE__)
> #define UNLOCK(N)  fooint_lock(LOCKMODE_UNLOCK,(N),__FILE__,__LINE__)
LOCKMODE_LOCK and LOCKMODE_UNLOCK can't be private to the library, since 
the library won't know what to pass to the locking callback to get lock 
and unlock capability - this will be defined by the application that 
sets the locking function.

I wrote a proof of concept that is rather different than what is described 
here. I need to rework it to meet in the middle. My proof of concept has 
the library registering the API (it knows the system that it runs on), but 
that makes no sense because you want to avoid the overhead unless the 
application is threaded.

So, I just wanted to double check the advisibility of defining all of this 
per library since that will duplicate the code per library and cause any 
application that links to more than one library to have to set up the 
callbacks per library (more duplicated code). (Do most apps link to only 
one or more than one library?)


Emily Ratliff
IBM, Linux Technology Center, Security Development

More information about the krbdev mailing list