Centralising authentication on an LDAP directory does not remove the credential problem, it moves it: from the /etc/shadow of every host to a single network service and its configuration. Here I look at OpenLDAP 2.2 (the current line, first released in December 2003) as an attack surface, not as a product to adopt.

Context

OpenLDAP is the reference open source implementation of LDAPv3, the protocol defined by RFC 2251 (December 1997) and by the set of documents that RFC 3377 (September 2002) names as the full specification. The code descends from the LDAP server built at the University of Michigan, whose final release dates to 1996; the OpenLDAP project began in 1998 from that source.

The daemon is slapd (Standalone LDAP Daemon). Its shape comes from the Michigan code: a frontend that handles network access and protocol, kept separate from a backend that deals only with storage. That separation weighs on security, because frontend and backend carry different trust models: the frontend talks to untrusted clients, the backend to the local filesystem.

The use case that justifies a directory is reading. A login produces a bind followed by a search; credential changes are rare. On a mixed Linux/FreeBSD/Solaris estate, where Active Directory is absent, slapd becomes the single point against which every service โ€” PAM, mail, web, VPN โ€” verifies identities. A single point also means a single target.

Architecture

The data model is a tree, the DIT (Directory Information Tree). Each entry has a unique DN (Distinguished Name), for instance uid=jsmith,ou=people,dc=example,dc=com. The schema constrains classes and attributes: an inetOrgPerson entry admits cn, mail, userPassword. The schema is extensible, and this is where the first security decision is made: the attributes one chooses to expose, and the ACLs that protect them, define what an anonymous or authenticated client may read.

In OpenLDAP 2.2 the reference transactional backend is BDB, built on Berkeley DB, with transactions and crash recovery; it was already there from 2.1 (June 2002). LDBM and other backends exist, but for an authentication service what matters is consistency after an interruption, not raw speed.

The structural addition in 2.2 is the overlay mechanism: modules that hook into the request pipeline and change slapdโ€™s behaviour without touching the backend. Two overlays have direct security consequences. ppolicy brings password policy inside the directory โ€” expiry, minimum length, lockout after N failed attempts โ€” rather than leaving it to each client. syncrepl handles content replication.

syncrepl takes the place of the older slurpd, the replication daemon inherited from Michigan, which worked in push: the provider pushed changes to the replicas. syncrepl inverts the scheme: the consumer asks, and defines its replica as the result of a search (searchbase, scope, filter, attrs). There are two modes, refreshOnly with periodic polling and refreshAndPersist with a persistent connection that receives updates as they happen. The mechanism is described in the IETF document draft-zeilenga-ldup-sync, at this date still an Internet-Draft and not an RFC.

The critical point

Security is decided in the transport of the bind. A simple bind sends the DN and the password in the clear inside the protocol. If the channel is not encrypted, every login exposes the credential on the wire: anyone intercepting the network segment between client and slapd collects cleartext passwords without having to break anything.

OpenLDAP offers two routes, and they should be kept distinct. TLS encrypts the channel: it starts on port 636 (ldaps) or on 389 through the StartTLS extension of RFC 2830. SASL (RFC 2222) is instead the authentication layer: it opens the door to mechanisms such as DIGEST-MD5, which avoids sending the password in the clear even over an unencrypted channel, or GSSAPI to integrate Kerberos. The two do not exclude each other: SASL EXTERNAL over a TLS channel with a client certificate binds the identity to the certificate verified during the handshake.

The practical consequence is blunt. A simple bind without TLS is not used beyond localhost. Server-side it is enforced with the security directive in slapdโ€™s configuration, which sets a minimum strength โ€” for example refusing bind requests that do not reach a given ssf (security strength factor). Without that constraint the decision stays with each client, and one misconfigured client is enough to bring down the encryption imposed on the others.

Then there are the ACLs. In slapd access control is declarative and ordered: access to ... by ... rules are evaluated in sequence, and the first match decides. The userPassword attribute wants an explicit rule making it readable only by the entry itself (and by administrators) and writable in auth for the bind โ€” never readable by an anonymous client. An anonymous search that manages to read the hashes turns the directory into an offline credential dump.

Implications

Centralising authentication also concentrates the consequence of a mistake. An over-broad ACL on userPassword, a simple bind without TLS, a syncrepl replica travelling in the clear to a consumer at another site: each of these, on its own, exposes the entire credential set, not the credentials of one host. The directory inherits the threat model of every service that leans on it.

In return, the concentration makes a small, well-defined set of things verifiable. The security posture of an OpenLDAP deployment reads off a limited number of points: the TLS* and security directives in the configuration, the access to block for sensitive attributes, the enabled SASL mechanisms, the channel used by syncrepl. They are testable from the outside: an anonymous bind and a search on userPassword say within seconds whether the ACLs hold.

Limits

Here I look at the serverโ€™s configuration, not at the chain of clients. PAM and nss_ldap on the host have their own TLS configuration and their own way of handling a directory that does not respond; a host that falls back to local credentials when slapd is unreachable opens a path the server does not control. The syncrepl part I describe as a content-replication mechanism, without assessing it under active attack on the provider, which is a subject of its own. And the version counts: the above holds for the 2.2 line, and directives and defaults change between one series and the next.


https://www.openldap.org/doc/admin22/guide.html https://www.rfc-editor.org/rfc/rfc2251 https://www.rfc-editor.org/rfc/rfc3377 https://www.rfc-editor.org/rfc/rfc2830 https://tools.ietf.org/html/draft-zeilenga-ldup-sync-05 https://www.openldap.org/pub/umich/guide.pdf https://www.noze.it/en/insights/openldap-open-source/

Cover image: Tree diagram of an LDAP directory with the root node dc=meudomini,dc=org branching into cn=admin, ou=People and ou=Groups, with uidโ€ฆ โ€” diagram by Rferrero, CC BY-SA 4.0 โ€” https://commons.wikimedia.org/wiki/File:EsquemaDominiLDAP.jpg