The OpenLDAP client libraries can use a SASL EXTERNAL mechanism to bind to the directory. The client needs an SSL certificate with (e.g.) a common name (CN) and a mail address (Email). Quoting verbatim from the OpenLDAP Admin Guide chapter on Using TLS: “The server must request a client certificate in order to use the SASL EXTERNAL authentication mechanism with a TLS session. As such, a non-default TLSVerifyClient setting must be configured before SASL EXTERNAL authentication may be attempted, and the SASL EXTERNAL mechanism will only be offered to the client if a valid client certificate was received“.
# slapd.conf TLSVerifyClient allow
The OpenLDAP slapd must furthermore be configured to accept the EXTERNAL mechanism:
# /usr/lib/sasl2/slapd.conf mech_list: DIGEST-MD5 EXTERNAL
A sample certificate created with OpenSSL is:
Subject: OU=SSLcerts, CN=My Name/Email=me@example.com
X509v3 Subject Alternative Name:
email:me@example.com
X509v3 Key Usage:
Digital Signature, Key Encipherment, Key Agreement
My slapd.conf contains the following regular expression which will map the subject of the certificate onto an LDAP DN, searching for it in the directory. The second expression maps the subject of a different certificate right onto the manager’s DN
sasl-regexp email=(.+@.+),cn=(.+),ou=sslcerts ldap:///dc=example,dc=com??sub?(cn=$2) sasl-regexp email=myname@example.com,cn=My Name,ou=Admins cn=manager,dc=example,dc=com
The EXTENDED mechanism is only used on a connection which is initiated over SSL. I’ll set up my environment first:
export LDAPCONF=/home/user export LDAPRC=ldap.rc
The ldap.rc is then read by the OpenLDAP client libraries. Its content is
URI ldaps://ldap.example.com:636/ BASE dc=example,dc=com SASL_MECH EXTERNAL TLS_CERT /home/user/ssl/me.crt TLS_KEY /home/user/ssl/me.key
Now check that the server actually offers the EXTERNAL mechanism:
$ ldapsearch -H ldaps://ldap.example.com -x -b '' -s base + ... supportedLDAPVersion: 3 supportedSASLMechanisms: DIGEST-MD5 supportedSASLMechanisms: EXTERNAL ...
The LDIF for this “person” doesn’t require a userPassword attribute type:
dn: cn=me,dc=example,dc=com sn: Name cn: My Name objectClass: person
If all goes well, an ldapwhoami would show
$ ldapwhoami SASL/EXTERNAL authentication started SASL username: emailAddress=me@example.com,CN=My Name,OU=SSLcerts SASL SSF: 0 dn:cn=me,dc=example,dc=com
The EXTERNAL mechanism can also be used from Perl
I have two identical servers which return the supportedSASLMechanisms in a different order. It seems that the clients attempt to use the authentication mechanisms in the order of the returned attribute type. The only workaround I’ve found, is to force the client libraries to use GSSAPI (the mechanism I want to use) by either
export LDAPSASL_MECH=gssapi
or by creating a ~/.ldaprc containing
SASL_MECH GSSAPI