Identity and access
LDAP and directories
One central tree of people and groups, which every server asks at login instead of keeping its own accounts.
A directory holds entries, each named by a DN that spells its place in the tree
(uid=alice,ou=people,dc=office,dc=lab) and made of attributes whose object classes say which are allowed
(posixAccount for a Unix login, posixGroup for a group). Clients search from a base DN with a filter
((&(objectClass=posixGroup)(memberUid=alice))) and bind to prove who they are; a simple bind sends the DN and
the password itself, so on plain LDAP (TCP 389) it is readable on the wire unless StartTLS or LDAPS (TCP 636)
wraps it. Servers use the directory for logins through PAM (pam_ldap, sssd) and for user names through NSS:
a password or group changed once applies everywhere, and a removed person can log in nowhere. Microsoft's Active
Directory is an LDAP directory with Kerberos beside it.
How an LDAP login works, step by step
In the LDAP lab the directory (10.0.1.10, OpenLDAP slapd) holds the tree
dc=office,dc=lab. The fileServer (.11) and buildServer (.12) keep no passwords; alice logs in from the
laptop (.13). LDAP v3 is RFC 4511, over TCP 389.
- sshd hands the password to PAM.
/etc/pam.d/sshdstarts withauth sufficient pam_ldap.so, so the directory is asked first and a yes is enough. - nslcd finds the entry. It searches from the base
dc=office,dc=labfor(uid=alice)and gets the DNuid=alice,ou=people,dc=office,dc=lab. - It binds as alice. A BindRequest with that DN and the password (a simple bind, RFC 4513). The server
compares it with the entry's
userPassword, a salted{SSHA}hash, and answers BindResponse result 0 (success) or 49 (invalidCredentials). A server never needs the password itself, and no server has a copy. - The account step checks authorization. On buildServer a
pam_authz_searchfilter(&(objectClass=posixGroup)(cn=builders)(memberUid=$username))must find an entry, or PAM's account step says no, even with the right password. - NSS supplies the Unix identity. The uid number, group and home come from the entry's
posixAccountattributes, soidon the server showsuid=2001(alice).
Change alice's password or delete carol's entry once, in the directory, and every server follows on the next login.
Plain LDAP sends a simple bind readable on the wire; StartTLS (extended operation OID 1.3.6.1.4.1.1466.20037)
upgrades port 389 to TLS first, and LDAPS uses TLS from the start on TCP 636 (TLS).
What it looks like on a Linux machine
ldapsearch reads the tree. -x is a simple bind (anonymous here), -LLL prints plain LDIF:
$ ldapsearch -x -LLL -H ldap://directory.lab -b ou=people,dc=office,dc=lab '(objectClass=posixAccount)' uid cn uidNumber
dn: uid=alice,ou=people,dc=office,dc=lab
uid: alice
cn: Alice Archer
uidNumber: 2001
ldapwhoami binds and asks who the server thinks you are:
$ ldapwhoami -x -H ldap://directory.lab
anonymous
$ ldapwhoami -x -H ldap://directory.lab -D uid=alice,ou=people,dc=office,dc=lab -w correct-horse
dn:uid=alice,ou=people,dc=office,dc=lab
$ ldapwhoami -x -H ldap://directory.lab -D uid=alice,ou=people,dc=office,dc=lab -w letmein
ldap_bind: Invalid credentials (49)
Access control decides what each identity may do. Alice may not delete carol's entry:
$ ldapdelete -x -H ldap://directory.lab -D uid=alice,ou=people,dc=office,dc=lab -w tidy-lantern-77 uid=carol,ou=people,dc=office,dc=lab
ldap_delete: Insufficient access (50)
additional info: no write access to parent
slapd's log (-d stats) records each bind with its security strength factor, ssf=0 for plain LDAP and
ssf=256 over StartTLS or LDAPS:
conn=1003 op=0 BIND dn="uid=alice,ou=people,dc=office,dc=lab" mech=SIMPLE bind_ssf=0 ssf=0
What goes wrong, and how you see it
Wrong password, or wrong DN. ldap_bind: Invalid credentials (49). LDAP gives the same answer for a wrong
password and a DN that does not exist, so check the DN with an anonymous search first.
The server is unreachable. ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1), exit 255. Every
directory login on every server fails at once; check the address, port 389 or 636, and the firewall.
A search finds nothing. No such object (32) with a Matched DN: line means the base DN is wrong; the
matched part is how far the server got down the tree.
Right password, still refused. sshd logs Access denied for user bob by PAM account configuration and nslcd
logs found no matches: authentication passed, the group filter did not
(authentication vs authorization). Add the user to the group in the
directory.
Passwords on the wire. A capture on port 389 shows the bind password in clear. Use -ZZ (StartTLS, required)
or ldaps://; a server without TLS set up answers StartTLS with Protocol error (2).
Questions people ask
What port does LDAP use? TCP 389 for LDAP and StartTLS, TCP 636 for LDAPS. Active Directory adds the global catalog on 3268 and 3269.
LDAP vs Active Directory? LDAP is the protocol; Active Directory is Microsoft's directory service, which speaks LDAP for searches and binds and uses Kerberos for logins. OpenLDAP is a directory server too.
LDAP vs Kerberos? LDAP stores who people are and which groups they are in, and can check a password by binding. Kerberos proves identity with tickets, so the password is not sent to each server. Many networks use both, as AD does; single sign-on builds on them.