Debian LDAP (Lenny to Squeeze)

I recently upgraded an older install of Debian Lenny to Squeeze. Except for a purge of the MySQL server everything went off pretty well. Except for LDAP authentication.

The old server was using LDAP for authentication and while it seemed to "mostly" work after the install a couple of things were definitely broken. Specifically, the su command was completely broken and sudo was complaining pretty furiously as well. The upgrade warned me about an upgrade to the LDAP packages and suggested moving to the new libpam-ldapd packages.

So, here we go:

First, my basic setup was to rely on files for NSS, so my nsswitch.conf looked like this:

# /etc/nsswitch.conf
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         compat
group:          compat
shadow:         compat

hosts:          files dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis

The main LDAP functionality was provided via PAM for password lookup. To configure an account one would create the basic account locally with the password disabled. Local accounts with passwords would bypass (or ignore) the LDAP lookup and those without passwords would require LDAP to complete the login process. Since I didn't control the enterprise LDAP server, I was forced to continue this setup.

I had previously used a custom PAM configuration, but this time around I allowed aptitude to overwrite my configuration and allowed dpkg and pam-auth-update to configure the pam.d files. The result was /etc/pam.d/common-authentication (comments trimmed out):

# /etc/pam.d/common-auth - authentication settings common to all services
auth    [success=2 default=ignore] nullok_secure
auth    [success=1 default=ignore] minimum_uid=1000 use_first_pass
auth    requisite             
auth    required              

The old lpam-ldap module had its own configuration file that I needed to convert. The newer libpam-ldapd used /etc/nslcd.conf. Here's a look at the file:

# /etc/nslcd.conf
# nslcd configuration file. See nslcd.conf(5)
# for details.

# The user and group nslcd should run as.
uid nslcd
gid nslcd

# The location at which the LDAP server(s) should be reachable.
uri ldaps://

# The search base that will be used for all queries.

# The LDAP protocol version to use.
#ldap_version 3

# SSL options
ssl on
tls_reqcert never

filter passwd (objectClass=person)
filter shadow (objectClass=person)

A few notes here. I ignore the cert error that is thrown by my enterprise's server. Also, they don't use a traditional schema so I needed to specify the filter for the passwd and shadow attributes.

At his point things seemed to be working. I'd been running this with nslcd -d for debugging purposes. I restarted it with the /etc/init.d script and enabled the caching daemon as well. At his point everything seemed to be working pretty well. Unfortunately, I soon started getting long timeouts and delays when authenticating. The helpful message in syslog was:

nslcd[87698]: ldap server timed out

After a significant amount of searching and some troubleshooting this was finally fixed by enforcing an LDAP timeout parameter. It appeared nslcd would stay open longer than our enterprise server liked and then would make a request using an invalid connection. Added the following to /etc/nslcd.conf to fix the problem:

# Idle timelimit. nslcd will close connections if the
# server has not been contacted for the number of seconds.
idle_timelimit 3600

I suppose, all's well that ends well. The configuration has been rock-solid since.