IMAP and kerberos

From: Date: Tue, 06 Nov 2001 19:20:24 +0000
Subject: IMAP and kerberos
Groups: php.general 
Request: Send a blank email to php-general+get-73641@lists.php.net to get a copy of this message
I apologize for the length of this, but I thought it would be good to get it all out. If anyone has anything to add, I'd love to hear it. Or if anyone knows if my work has been worthless, and there's a way around this without tweaking code, I would be very pleased. I've been having a lot of fun with PHP, c-client, and kerberos v5 lately. What I wanted to do was have a user authenticate via a homegrown apache module which did kerberos authentication, creating a TGT which is stashed in /var/tmp/tkt/<username's first character>/<username>. Then the user would access a PHP page which sets the environment KRB5CCNAME, so that the proper ticket could be found and used with an IMAP session. Much to my surprise (initially), even with --with-kerberos flags for PHP, there was no attempted GSSAPI authentication over the IMAP connection. So in the ext/imap/php_imap.c file, I added the line auth_link(&auth_gss); right before auth_link(&auth_log); So then it tries to do GSSAPI authentication upon establishing an IMAP connection. But I discover that despite my setting of the KRB5CCNAME variable (using putenv), the only place that PHP looks for the ticket is in /tmp/krb5cc_<server uid>. So with some trussing I discover that when apache starts up and auth_link(&auth_gss) is called, a function is called that initializes a kerberos context, sets KRB5CCNAME (with whatever KRB5CCNAME is currently set to, or just the default), yadda yadda, etc etc. This apparently sets some static flags and variables which indicate to kerberos/gssapi that it doesn't ever need to read the KRB5CCNAME environment variable again. This really sucks when you want to do a putenv for every individual user so you can find their TGT. I wrote to the author of c-client and told him what I was trying to do - that is, use c-client in a single process to serve multiple users. To paraphrase his response, "You're trying to do what? It wasn't meant to be used that way." I was somewhat surprised, since I had thought this was sort of the intent behind including kerberos support for IMAP in PHP. Huh. So there are a few things that can be done, a few of which I tried. 1) mangle the c-client auth_link function so that it doesn't initialize some gssapi/kerberos stuff, so that in your PHP script you can use the KRB5CCNAME environment variable (but only once). Then set up apache so that each forked process only services one request. I determined that this was not too pretty of a solution, especially since I'd be using it for an application that already gets around 10 hits a second at peak load, and I want to keep things fast. 2) Let all the tickets go into the default file. But we have over 25,000 users, so the file would end up being huge, and it would take a long time to find a TGT for a particular user. 3) find a gssapi function, hack the PHP source a little more, and force a deletion of the gssapi context each time, so the KRB5CCNAME environment variable is read on each open of an IMAP connection. So this is what I am currently doing, although it's not in production yet. Note: this is all with krb5-1.2.2 apache 1.3.20 php 4.0.6 imap-2001a.RELEASE-CANDIDATE.1 Solaris 8 The changes I made were all to php-4.0.6/ext/imap/php_imap.c Here's what I did: Added auth_link(&auth_gss); as I said before. Added #include <gssapi/gssapi.h> at the top of the file. In void imap_do_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) I added the declaration OM_uint32 minor_status; Then, as the first line of code in this function after declarations , I called gss_krb5_ccache_name(&minor_status, NULL, NULL); That's it. Hopefully this will be of benefit to someone. -Blaise

« previous php.general (#73641) next »