I'm setting up OpenLDAP slapd
on Ubuntu 14.04 Trusty Tahr. I want certain instances (replication etc.) that aren't users to be able to login via SASL
using DIGEST-MD5
mechanism.
Unlike users, they are not supposed to have a corresponding DN (along with the password) in the directory tree. Instead, their credentials are supposed to be stored externally, hence SASL
.
I'm using saslauthd
right now (this is not a hard requirement if it can be made to work with direct access to the sasldb, for instance) and it works fine using mechanisms PLAIN
and LOGIN
while it fails using mechanisms DIGEST-MD5
and CRAM-MD5
.
What am I missing or doing wrong? How can I get it to work with DIGEST-MD5
?
OpenLDAP is configured for SASL
in /etc/ldap/sasl2/slapd.conf
like this:
mech_list: EXTERNAL DIGEST-MD5 CRAM-MD5 PLAIN LOGIN
pwcheck_method: saslauthd
saslauthd_path: /var/run/saslauthd/mux
The interesting (changed) options in /etc/default/saslauthd
are:
START=yes
MECHANISMS="sasldb"
They result in saslauthd
being started like so:
/usr/sbin/saslauthd -a sasldb -c -m /var/run/saslauthd -n 5
I reproduce the failing case with DIGEST-MD5
like this:
# ldapsearch -U replication -ZZ -Y DIGEST-MD5 -H ldap://ldap-master.example.com/ -b "dc=example,dc=com" "(objectClass=*)"
SASL/DIGEST-MD5 authentication started
Please enter your password:
ldap_sasl_interactive_bind_s: Invalid credentials (49)
additional info: SASL(-13): user not found: no secret in database
The part in the slapd log where it seems to fail (logging is on any
) looks like this:
slapd[23330]: [rw] authid: "uid=replication,cn=digest-md5,cn=auth" -> "uid=replication,cn=digest-md5,cn=auth"
slapd[23330]: slap_parseURI: parsing uid=replication,cn=digest-md5,cn=auth
slapd[23330]: >>> dnNormalize: <uid=replication,cn=digest-md5,cn=auth>
slapd[23330]: <<< dnNormalize: <uid=replication,cn=digest-md5,cn=auth>
slapd[23330]: <==slap_sasl2dn: Converted SASL name to uid=replication,cn=digest-md5,cn=auth
slapd[23330]: slap_sasl_getdn: dn:id converted to uid=replication,cn=digest-md5,cn=auth
slapd[23330]: SASL Canonicalize [conn=1002]: slapAuthcDN="uid=replication,cn=digest-md5,cn=auth"
slapd[23330]: SASL [conn=1002] Failure: no secret in database
slapd[23330]: SASL [conn=1002] Debug: DIGEST-MD5 common mech dispose
slapd[23330]: send_ldap_result: conn=1002 op=2 p=3
slapd[23330]: send_ldap_result: err=49 matched="" text="SASL(-13): user not found: no secret in database"
slapd[23330]: send_ldap_response: msgid=3 tag=97 err=49
There's nothing in /var/log/auth.log
nor in the debug output of saslauthd
when I run it manually, which likely indicates that slapd
didn't even get as far as handing off the authentication to saslauthd
(in contrast with the working case, see below).
I reproduce the working case with PLAIN
or LOGIN
like this:
# ldapsearch -U replication -ZZ -Y PLAIN -H ldap://ldap-master.example.com/ -b "dc=example,dc=com" "(objectClass=*)"
SASL/PLAIN authentication started
Please enter your password:
SASL username: replication
SASL SSF: 0
# extended LDIF
…
The corresponding part in the slapd
log that indicated failure for the case above now looks like this:
slapd[23330]: [rw] authid: "uid=replication,cn=plain,cn=auth" -> "uid=replication,cn=plain,cn=auth"
slapd[23330]: slap_parseURI: parsing uid=replication,cn=plain,cn=auth
slapd[23330]: >>> dnNormalize: <uid=replication,cn=plain,cn=auth>
slapd[23330]: <<< dnNormalize: <uid=replication,cn=plain,cn=auth>
slapd[23330]: <==slap_sasl2dn: Converted SASL name to uid=replication,cn=plain,cn=auth
slapd[23330]: slap_sasl_getdn: dn:id converted to uid=replication,cn=plain,cn=auth
slapd[23330]: SASL Canonicalize [conn=1006]: slapAuthcDN="uid=replication,cn=plain,cn=auth"
slapd[23330]: daemon: activity on 1 descriptor
slapd[23330]: daemon: activity on:
slapd[23330]:
slapd[23330]: daemon: epoll: listen=8 active_threads=0 tvp=zero
slapd[23330]: daemon: epoll: listen=9 active_threads=0 tvp=zero
slapd[23330]: daemon: epoll: listen=10 active_threads=0 tvp=zero
slapd[23330]: SASL proxy authorize [conn=1006]: authcid="replication" authzid="replication"
slapd[23330]: conn=1006 op=1 BIND authcid="replication" authzid="replication"
slapd[23330]: SASL Authorize [conn=1006]: proxy authorization allowed authzDN=""
slapd[23330]: send_ldap_sasl: err=0 len=-1
slapd[23330]: conn=1006 op=1 BIND dn="uid=replication,cn=plain,cn=auth" mech=PLAIN sasl_ssf=0 ssf=128
slapd[23330]: do_bind: SASL/PLAIN bind: dn="uid=replication,cn=plain,cn=auth" sasl_ssf=0
slapd[23330]: send_ldap_response: msgid=2 tag=97 err=0
Both /var/log/auth.log
and the debug output from saslauthd
now contain this:
saslauthd[23354]: rel_accept_lock : released accept lock
saslauthd[23358]: get_accept_lock : acquired accept lock
saslauthd[23354]: cache_get_rlock : attempting a read lock on slot: 458
saslauthd[23354]: cache_lookup : [login=replication] [service=] [realm=ldap]: not found, update pending
saslauthd[23354]: cache_un_lock : attempting to release lock on slot: 458
saslauthd[23354]: cache_get_wlock : attempting a write lock on slot: 458
saslauthd[23354]: cache_commit : lookup committed
saslauthd[23354]: cache_un_lock : attempting to release lock on slot: 458
saslauthd[23354]: do_auth : auth success: [user=replication] [service=ldap] [realm=] [mech=sasldb]
saslauthd[23354]: do_request : response: OK
Apparently, there must be some difference in how it works with PLAIN
and LOGIN
vs. DIGEST-MD5
and CRAM-MD5
.
Update and clarification:
The DNs used for authorizing access to the tree are uid=replication,cn=digest-md5,cn=auth
and uid=replication,cn=plain,cn=auth
respectively and according to section 15.2.5 of http://www.openldap.org/doc/admin24/sasl.html those DNs don't need to actually exist in the tree (which must be true at least for PLAIN
and LOGIN
as it is working fine there).
For testing purposes I'm currently using olcAccess: to * by dn.regex="replication" read by * break
to ensure the replication login gets at least read access to everything (yes, I know that's not secure and I will give it proper permissions for production) in the master LDAP tree.
The credentials are in /etc/sasldb2
and they are successfully checked against when using PLAIN
or LOGIN
(see above). For reference, it looks like that:
# sasldblistusers2
replication@ldap-master: userPassword
…
# db_dump -p /etc/sasldb2
VERSION=3
format=print
type=hash
h_nelem=4
db_pagesize=4096
HEADER=END
replication\00ldap-master\00userPassword
PasswordCensored
…
However, in the case of DIGEST-MD5
and CRAM-MD5
it doesn't seem to contact saslauthd
at all (due to me missing something or doing something wrong, possibly), so the database is likely not consulted, either.