porting CCAPI to UNIX
Ken Raeburn
raeburn at MIT.EDU
Fri May 18 00:18:57 EDT 2007
(No wonder I hadn't gotten any feedback on this... it's been sitting
in my "drafts" folder still, unsent. Oops.)
Based on a bunch of comments, it sounds like a process started at
boot time is a good idea, but it should also be able to be started
automatically by user processes.
So, a new proposal:
* krb5.conf entry libdefaults/ccapi_path_template can specify a
pathname template for the mode-700 directory holding the listening
socket for a user. Some substitutions are allowed to get the actual
pathname; say, ${FOO} for environment variables, %u for decimal uid, %
n for user account name, leading ~ for home directory. (Q: Default
to checking some environment variable that could be easily set at
login time, as in Nico's krb5-agent idea?)
* if such a pathname template is provided but the directory doesn't
exist, the socket doesn't exist, or a connection can't be
established, the server process is forked off with options telling it
to run the service using that pathname.
* if a pathname template isn't provided, libdefaults/
ccapi_path_server or a hard-coded value under $prefix or $exec_prefix
indicates a UNIX-domain socket on which a server running as root
should be listening; it gets sent a uid, and returns a pathname or an
error. If it returns a pathname, it's treated as above. (By the
time the pathname is sent, the server has created and is listening on
that socket.)
* if no server is listening on the server socket, it can be
launched from the library. Because it can be launched as the user
and needs root privs for this path, it must be setuid root if used
this way. Which means in the former path, it needs to drop
privileges before doing its work. The socket pathname cannot be set
by the user via $KRB5_CONFIG this way. Possibly the client should be
allowed to indicate the path it's expecting, so the server can just
quit if that doesn't agree with the system config file or compiled-in
path.
When the process is launched, fd 0 is a pipe connected to the parent
process. Closing this pipe indicates to the parent that it's time to
try connecting; either the child process is listening on the UNIX-
domain socket in question, or it's gotten an error, and isn't going
to be able to. So when the pipe gets closed, the parent process
makes only one more attempt to access the UNIX-domain socket before
giving up. The parent could also time out (say, at 20 seconds) in
case the server somehow hangs in launching.
It's a little messy having one server program do both per-user and
monolithic approaches, but it lets us not require extra processes at
boot time if they're not desired, and lets us do testing without root
privileges.
Initially it may be simpler for the monolithic server to spawn
subprocesses per uid instead of keeping everything in one process; I
need to look a little deeper into the existing ccapi code. If so,
this should be transparent to the client, and changing it later
shouldn't affect the protocol. However, the core ccapi server code
is going to eventually have to support multiple client uids not being
able to see each others' credentials; if this support is there by the
time this project is implemented, we can go with a single process.
The intent is that the server looks like it could be one program, and
one process in the monolithic case, but if it's more convenient, it
could first be implemented with multiple programs and processes under
the covers, transparently to the client.
The library will launch processes, but we don't want to mess with
application signal handling, so the library won't catch SIGCHLD. On
Solaris, as Nico suggested, we could use forkx or flags to
posix_spawn to avoid having the signal sent at all -- if we have
forkx; it appears to be a very recent addition, and the Solaris 10
box in my office doesn't have it. Otherwise, the application gets an
extra SIGCHLD, just as it would if it uses popen() or system() etc.
As this would be a separate library from libkrb5, it could be
replaced with something optimized for specific systems (e.g., using
doors on Solaris) using the same ABI.
Ken
More information about the krbdev
mailing list