Making Linux systems authenticate through LDAP: the roles of NSS, PAM, and SSSD, nslcd configuration, getent and id testing, failover and caching, and troubleshooting.

In episode 17 you saw the concept of PAM and NSS integration at a glance. Episode 19 turns it into practice: how a Linux system really authenticates through LDAP. You'll understand the division of labor between NSS, PAM, and the LDAP client, configure nslcd, test with getent and id, handle failover and caching, and know the common failure points.
Linux authentication through LDAP is not a single component — it's a chain:
files and ldap entries in /etc/nsswitch.conf, getent passwd reads local files first, then LDAP.The division of labor: NSS makes accounts visible, PAM makes logins work. A user account that isn't visible to NSS can't be logged into even if PAM is configured.
On Debian and Ubuntu:
sudo apt install libnss-ldapd libpam-ldapd nslcd ldap-utilsDuring installation the package prompts for the LDAP URI, search base, and which NSS services (passwd, group, shadow) to use. These answers land in /etc/nslcd.conf and /etc/nsswitch.conf.
/etc/nslcd.conf is the heart of the integration:
uid nslcd
gid nslcd
uri ldap://ldap.example.com
base dc=example,dc=com
ldap_version 3
ssl starttls
tls_cacertfile /etc/ssl/certs/ca.crt
binddn cn=admin,dc=example,dc=com
bindpw secret
scope subWith uid nslcd and gid nslcd, the daemon drops privileges after startup. binddn and bindpw are optional — without them, nslcd binds anonymously and relies on the directory's ACL for what it can read.
Important
If the directory requires authenticated binds (for example because olcRequires: authc was set in episode 15), nslcd must have valid credentials in binddn/bindpw — otherwise no account will ever be visible. Don't hardcode a password that rotates; a dedicated service account with read-only ACLs is the least-privilege answer.
/etc/nsswitch.conf decides which source provides which name:
passwd: files ldap
group: files ldap
shadow: files ldap
hosts: files dns
networks: files
protocols: db files
services: db files
ether: files
rpc: files
netgroup: nispasswd, group, and shadow are the services to point at ldap. Order matters: files first keeps local accounts authoritative; a later failure on the LDAP side doesn't break local logins.
On Debian, the package integration already adds the pam_ldap modules to the PAM stack. To verify, look at the common-auth stack files:
auth [success=2 default=ignore] pam_unix.so nullok_secure
auth [success=1 default=ignore] pam_ldap.so use_first_pass
auth requisite pam_deny.so
auth required pam_permit.sopam_unix validates local accounts first; if the user isn't local, pam_ldap handles the LDAP authentication. use_first_pass reuses the password already collected, so the user is asked only once.
After configuration, restart nslcd and test step by step:
sudo systemctl restart nslcd
getent passwd budi
getent group developers
id budi
ssh budi@localhostgetent passwd budi — if the user appears with their LDAP UID, NSS works.getent group developers — checks group resolution.id budi — shows UID, GID, and group membership from LDAP.ssh budi@localhost — tests the full PAM stack through an SSH session.Production systems need more than a single LDAP URI:
uri lines; a failing server fails over to the next.cache_credentials = True in [domain] or [sssd] sections.entry_cache_timeout) controls freshness.[domain/example.com]
ldap_uri = ldap://ldap01.example.com,ldap://ldap02.example.com
ldap_search_base = dc=example,dc=com
cache_credentials = TrueWhen users can't log in:
| Symptom | Likely cause |
|---|---|
getent passwd budi empty | nslcd binding fails, wrong base, or ACL blocks read |
| PAM auth error | wrong binddn/bindpw, or pam_ldap not in the stack |
| LDAP is unreachable | firewall, DNS, or uri typo |
| local users fail too | PAM stack order broken, pam_unix is after pam_ldap |
getent slow | search base too broad or missing indexes |
| SSH login hangs | nslcd is down, or LDAP server unreachable with no cache |
Commands to inspect:
sudo systemctl status nslcd
journalctl -u nslcd -f
sudo -u nslcd /usr/sbin/nslcd -dThe -d flag runs nslcd in the foreground with debug output — the fastest way to see exactly what queries the daemon sends.
In this episode 19 you integrated Linux systems with LDAP: the division of labor between NSS, PAM, nslcd, and SSSD; package installation; nslcd configuration with URI, base, and TLS; nsswitch.conf pointing passwd, group, and shadow at ldap; PAM stack verification; testing with getent, id, and SSH; failover and caching; and troubleshooting with nslcd debug mode.
Key takeaways:
getent first, then id, then SSH.In the next episode, episode 20, we go beyond system authentication: email & address book — how Postfix and Dovecot authenticate users through LDAP, and how clients like Thunderbird and Outlook consume directory data.