[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: Kerberos and simple binds using same password database?



Aleksandar Milivojevic wrote:
I've managed to configure slapd to use Kerberos for authentication (using SASL/GSSAPI). This works great if user holds a valid ticket, and if (s)he is using Kerberos aware client such as ldapsearch.

However, if user isn't using Kerberos aware client, (s)he will be authenticated using the password stored in userPassword attribute (using passwords instead of Kerberos tickets is OK in my case, as long as connection is over TLS).

Now, the question. Is it possible to configure slapd not to use userPassword attribute in this case, but rather attempt to check user's password against Kerberos? Something "saslauthd -a kerberos5" is doing. Or (more general) to use saslauthd to perform password checking (which can check it against Kerberos database).

I guess for this to work, an opposite of sasl-regexp option would need to exist (to map LDAP entity to Kerberos user@realm type of entity), but I couldn't find anything like that. Which makes me to believe it might not be possible to do.

By searching around I found some questions/answers about using LDAP as store for Kerberos. While implementing something like that (if possible) might solve a problem of having slapd and Kerberos use same passwords, in this case I can't take that route. Kerberos realms (plural) that users are in are part of several Active Directory domains, so technically, passwords are already stored in AD's LDAP database and they need to stay there.

I've finally got all of this up and working, with help from several people on this and Cyrus SASL mailing lists. I'll post this short summary in case somebody has same problems as I did, and stumble onto this thread in list's archive.


The problem was to have LDAP server (slapd) authenticate against more than one Kerberos realm. Some of the realms were MIT implementation, some where Microsoft implementations (used by Active Directory). The host where LDAP runs belongs to one of MIT realms. For simplicity, I'll use two realms and call them MIT and WINDOWS.

The first obstacle was specifying against which realm the user's password should be verified. This one was simple to solve by placing value {SASL}user@REALM in userPassword attribute (many thanks to Fredriksson on that one). In addition to that, slapd.conf file in /usr/sasl2/lib must be created with single line "pwcheck_method: saslauthd". Saslauthd should be started with -a kerberos5 and -r options in addition to standard ones. "-r" option is important not to skip, or things will not work.

The second obstacle was getting saslauthd to actually perform password verification against realm the host doesn't belong to. It wasn't as simple as defining additional realms in /etc/krb5.conf file, but at the end it wasn't that complicated either.

First of all, host/ldap.host.com@REALM principals must be created and keys must be generated and placed into /etc/krb5.keytab file for all realms (MIT and WINDOWS) that passwords will be checked against. Second, in all realms, only dec-cbc-crc keys must be generated for host and ldap principals. Otherwise, things will fail since Windows implementation doesn't support 3DES. Saslauthd used 3DES with MIT side it belongs into (if there's such host key), but then attempts to use it again when verifying TGT against Windows side. This one was hard to debug, but revield itself after tcpdump session. On MIT side, use -e "des-cbc-crc:normal" when creating host principal and adding key to the keytab file (addprinc and ktadd commands). Principals created on Windows side (using ktpass.exe) will have only des-cbc-crc by default.

So, on MIT side it looks something like this:
# kadmin
kadmin> addprinc -randkey -e "des-cbc-crc:normal" host/ldap.host.com
kadmin> ktadd -k /etc/krb5.keytab -e "des-cbc-crc:normal"
        host/ldap.host.com

(the second line is single line, I broke it into two for readability, type as one line)

On Windows side, user h-ldaphost (or whatever name, not important) should be created, and this command executed from command line:

ktpass -princ host/ldap.host.com@WINDOWS -mapuser h-ldaphost
       -pass something_random -out h-ldaphost.keytab

(again, as single line, I broke it into two for readability)

h-ldaphost.keytab should be copied over to LDAP server and key added to /etc/krb5.keytab.

If SASL is to be used by LDAP server, ldap/ldap.host.com@REALM principals and keys should be created, and keys placed into /etc/openldap/ldap.keytab, and slapd started with KRB5_KTNAME environment variable set to point to that file (/etc/krb5.keytab can't be used, it is readable only by root, so another file readable only by user slapd runs under should be created, owner root, group whatever slapd runs under, mode 640). Same restriction for encryption types as for host/* principals. Also, for each Kerberos realm, something like this should be placed into slapd.conf:

sasl-regexp
   uid=(.*),cn=realm,cn=.*,cn=auth
   ldap://ou=people,dc=your,dc=domain??sub?(uid=$1)

(replace "realm" in second line with realm name, case is not important, "mit" or "windows" or whatever your realms are called). This will work as long as usernames on Windows domain and Unix side (as defined in LDAP database) are the same.

After this, things like ldapsearch -Y GSSAPI (after kinit) and/or ldapsearch -Y PLAIN will also work. DIGEST-MD5 will not work (I guess because passwords are stored inside Kerberos, so SASL libraries do not have access to plain text password). If you don't need this, skip it (as well as creating ldap/* principals/keys).

Second thing that needs to be done is to define one-way trust between realm that LDAP server belongs (MIT), and all other realms. On MIT realm, principal krbtgt/MIT@WINDOWS should be created using addprinc:

# kadmin
kadmin> addprinc krbtgt/MIT@WINDOWS

On Windows side, one-way trust (MIT trusts WINDOWS) should be defined (Domains and Trusts, right-click on domain, preferences, trust, add MIT to list of "domains that trust this domain"). Passwords for krbtgt/MIT@WINDOWS and the one used for defining trust on Windows side must be the same! This password can be long random string, you'll never have to enter it again. The only way to change them once entered, is to delete principal (on MIT side) and remove trust (on Windows) side, and recerate them (or at least I wasn't able to find any other method of changing them).

If all is well, after this things should simply work.

--
Aleksandar Milivojevic <amilivojevic@pbl.ca>    Pollard Banknote Limited
Systems Administrator                           1499 Buffalo Place
Tel: (204) 474-2323 ext 276                     Winnipeg, MB  R3T 1L7