[PHP] PHP's ldap_sasl_bind tries to authenticate with KRB5CCNAME other than the one provided by mod_auth_kerb
Hi. I am using Apache-2.2.2 with mod_auth_kerb-5.3, php-5.2.1, openldap-2.3.27 cyrus-sasl-2.1.21 and heindal-0.7.2 on a Linux-from-scratch based system. The problem I'm presenting is probably a PHP issue or an Apache issue, or a mod_auth_kerb issue. I could not understand which one causes the problem. I am trying to connect using SASL and GSSAPI to the LDAP server from a PHP script that runs on the Apache server. The script (in short) does the following: putenv("KRB5CCNAME=" . $_SERVER['KRB5CCNAME']); echo getenv("KRB5CCNAME"); system("klist"); $ldapconn = ldap_connect("ldap://example.org";) || die(...); ldap_sasl_bind($ldapconn, NULL, NULL, "GSSAPI") || die(...); When I run the script manually from a shell that has a proper KRB5CCNAME environment variable, both the system("klist") and the ldap_sasl_bind(...) work as they should. When I run `restart Apache' and then enter to the PHP page for the first time both work as well. The KRB5CCNAME written is /tmp/krb5ccname_apache_ After that, each time I enter the page I get some other KRB5CCNAME (other than the one I got before), the system("klist") command works as it should, but ldap_sasl_bind returns "Local error". In this case I also get an error written to /var/log/auth. This error says that the file /tmp/krb5ccname_apache_ could not be found (this is the same that was written by PHP after I restarted Apache). This means that the authentication process tries to use the previous file-name. I added a debug print to PHP's ldap_sasl_bind function that prints `getenv("KRB5CCNAME")' to Apache's error-log. The KRB5CCNAME written to the error-log is the same as the one PHP outputs. Not the one written to the auth log. Why isn't the KRB5CCNAME variable passed on? Which of the three (PHP, Apache, mod_auth_kerb) keeps the first KRB5CCNAME? How do I cause the new KRB5CCNAME to be used for authentication? Any ideas? Thanks, Gil Ran. P.S. I am not on the list, please cc me. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] PHP's ldap_sasl_bind tries to authenticate with KRB5CCNAME other than the one provided by mod_auth_kerb
On 5/2/07, Richard Lynch <[EMAIL PROTECTED]> wrote: On Wed, May 2, 2007 9:41 am, gil ran wrote: > I am using Apache-2.2.2 with mod_auth_kerb-5.3, php-5.2.1, > openldap-2.3.27 cyrus-sasl-2.1.21 and heindal-0.7.2 on a > Linux-from-scratch based system. > > The problem I'm presenting is probably a PHP issue or an Apache issue, > or a mod_auth_kerb issue. I could not understand which one causes the > problem. > > I am trying to connect using SASL and GSSAPI to the LDAP server from a > PHP script that runs on the Apache server. > > The script (in short) does the following: > putenv("KRB5CCNAME=" . $_SERVER['KRB5CCNAME']); > echo getenv("KRB5CCNAME"); > system("klist"); Always use 'exec' instead, and ALWAYS get the output and the error code and ALWAYS ALWAYS ALWAYS check the error code! This is not the full code. I did check error codes. Lets call this a summery of the code. The "system" command is meant to check if the KRB5CCNAME environment variable is the valid one when used with "system". This proved that the variable was indeed passed in this case. > $ldapconn = ldap_connect("ldap://example.org";) || die(...); > ldap_sasl_bind($ldapconn, NULL, NULL, "GSSAPI") || die(...); > > When I run the script manually from a shell that has a proper > KRB5CCNAME environment variable, both the system("klist") and the > ldap_sasl_bind(...) work as they should. When you run the script manually from a shell, you are probably NOT the same User as PHP runs as, and you are probably NOT using the same shell either, and you therefore almost certainly do NOT have the same environment for your test as for Reality. This is true. I tried from a shell (meaning, running from bash `php ') in order to debug more easily, and found out that it always works this way. This is like stunt-driving a car on a Closed Course with a Professional Driver, and then pretending that it's safe to do that same stunt on a busy city street... :-) 99.9% of the time, this problem boils down to: paths and permissions Use a FULL PATH for any file/program in your exec call: NOT klist /usr/bin/klist /usr/local/bin/klist /sharedhost/example.com/usr/local/i/compiled/it/myself/bin/klist NOT somefile.txt /full/path/to/wherever/it/lives/somefile.txt But klist worked. As I said, the klist was added for debug purpose only. > When I run `restart Apache' and then enter to the PHP page for the > first time both work as well. The KRB5CCNAME written is > /tmp/krb5ccname_apache_ I dunno what klist does, nor what any of the KRB stuff is, but if you want to preserve this KRB thingie from page to page, it looks like you will need to do more than just run 'klist'... I don't want to preserve this KRB thingie from page to page. The opposite is correct: I don't understand why the old file-name is used instead of the new one. OK. I'll give some background about KRB5CCNAME, klist, etc. `klist' is a command that lists the tickets (credentials) that the current kerberos user holds. `KRB5CCNAME' contains the full path to a temporary file that holds the credentials data. This information is passed to the apache by the browser. The file itself is created by Apache (mod_auth_kerb). Apache (mod_auth_kerb) also initializes`KRB5CCNAME'. When using ldap_sasl_bind with the 4th argument set to "GSSAPI" we are trying to bind to the ldap server using sasl and GSSAPI. The GSSAPI ignores any provided username/password (authcid, for those of you who are familiar with sasl). Instead, it uses the information kept in the "credential cache" file. This is the file Apache (mod_auth_kerb) creates. This is the file-name provided by it in $_SERVER['KRB5CCNAME']. When using GSSAPI for authentication it reads the current credentials from the "credential cache" file. It knows where it is according to the environment variable `KRB5CCNAME'. In this case, for some reason, while KRB5CCNAME contains the correct value, GSSAPI is not using it. It is using some other value. You'll need to store the setting somewhere, transmit that storage location through the stateless HTTP protocol (just like GET/POST/COOKIE is used) and then retrieve it if it's already been stored, or make a new one, as appropriate for whatever you are trying to do, which I also don't really understand, but there it is. Not relevant. The problem is not that the data is not stored, it's that the data is stored when I don't want it to be. > After that, each time I enter the page I get some other KRB5CCNAME > (other than the one I got before), the system("klist") command works > as it should, but ldap_sasl_bind returns "Local error". In this case I > also get an error written
Re: [PHP] PHP's ldap_sasl_bind tries to authenticate with KRB5CCNAME other than the one provided by mod_auth_kerb
On 5/3/07, Richard Lynch <[EMAIL PROTECTED]> wrote: On Thu, May 3, 2007 12:33 am, gil ran wrote: >> I dunno what klist does, nor what any of the KRB stuff is, but if >> you >> want to preserve this KRB thingie from page to page, it looks like >> you >> will need to do more than just run 'klist'... > > I don't want to preserve this KRB thingie from page to page. The > opposite is correct: I don't understand why the old file-name is used > instead of the new one. How could GSSAPI know *which* Apache child's environment to check?... I really don't know. I guess that's the main thing I want to find out. I guessed that the environment variable that is set (in the c) code just before calling ldap_sasl_interactive_bind_s would be used, but I was wrong (the auth log showed me that I was wrong). I'm sure that it is consistent. I'm sure of that because the same filename is written to the auth log each time. What you wrote got me to thinking that maybe Apache gets the request (that starts a new session), handles it, and then forks and lets the child to handle the session, although the parent process keeps handling GSSAPI calls. I tried to check this, but I didn't find how to get the ENV of all the httpd processes (I tried /proc//environ, but it seems that it is not updated during runtime - it always contains the initial environment). This would probably tell me where GSSAPI could get the old KRB5CCNAME from. Do you know how to do this? > When using ldap_sasl_bind with the 4th argument set to "GSSAPI" we are > trying to bind to the ldap server using sasl and GSSAPI. The GSSAPI > ignores any provided username/password (authcid, for those of you who > are familiar with sasl). Instead, it uses the information kept in the > "credential cache" file. This is the file Apache (mod_auth_kerb) > creates. This is the file-name provided by it in > $_SERVER['KRB5CCNAME']. If you aren't passing it from Apache to GSSAPI, then it's going to snag whichever env happens to have been set last or... There's a differnt ENV floating around for each Apache child, I think, so how is GSSAPI supposed to know which one to snag? Theoretically, each child has its own environment, and the different environments should not be accessible to the other children. This means that (again, theoretically), the process that created the PHP thread should pass its ENV to PHP that should pass it to ldap that should pass it to sasl that should pass it to GSSAPI. One of them seems to look at the environment of another process (probably the parent). How can this be? Shouldn't the operating system protect the processes? After all, ENV is a block of memory that belongs to a certain process. How come another process is able to access it? The only thing I can think of is that something along the way is created in shared memory, and used from all of the processes. In this case the first process that passed its ENV will "win". This seems to get very far away from PHP. I'm starting to think that I should look for what ever it is that is not working/configured properly somewhere else. Up until now I looked at PHP and Apache. Now I'm starting to think that the source of this problem can be in openldap/cyrus-sasl/heimdal. I'm not sure. Any other ideas will be welcome. In the meantime I will ask the Apache, ldap, sasl and kerb experts as well... Thank, Gil Ran. -- Some people have a "gift" link here. Know what I want? I want you to buy a CD from some indie artist. http://cdbaby.com/browse/from/lynch Yeah, I get a buck. So? -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php