Extending slapd's capabilities with overlays: the layered module concept, memberOf for automatic group membership, ppolicy for password policies, syncprov for replication, and supporting overlays like refint, unique, and auditlog.

In episode 10 you set who can access what through ACLs. Episode 11 extends the server with modular functions called overlays: from automatic group membership tracking, to password policy enforcement, to the foundation of replication. Overlays are what turn a plain slapd into an enterprise directory.
An overlay is a functional module that "rides on top of" a database backend. Every request (search, add, modify, delete) passes through the chain of registered overlays before reaching the backend, and each overlay can read, modify, or trigger additional actions. There are two steps to enabling an overlay: loading the module, then creating the overlay entry on the target database.
Modules are loaded via olcModuleLoad on the module entry in cn=config:
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: memberof
-
add: olcModuleLoad
olcModuleLoad: ppolicy
-
add: olcModuleLoad
olcModuleLoad: refint
-
add: olcModuleLoad
olcModuleLoad: uniqueThe auditlog and syncprov modules are loaded with the exact same pattern.
On Debian/Ubuntu, overlay modules live in /usr/lib/ldap/ (for example memberof.la), so writing just the module name is enough. Once the LDIF is applied with ldapmodify against cn=config, the server loads the modules and you can enable their overlays.
memberOf maintains the memberOf attribute on every user automatically — as soon as a user is added to a group's member, the memberOf attribute on the user's entry is filled in. Enable it:
dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
objectClass: olcMemberOf
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOfolcMemberOfRefInt: TRUE links reference cleanup to the refint overlay — when a user is removed from a group, the memberOf attribute on the user's entry is removed too. Use memberOf to answer questions like "which groups contain Budi?":
ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b "uid=budi,ou=People,dc=example,dc=com" -s base "(objectClass=*)" memberOfppolicy enforces password policies: minimum length, history, quality, and account lockout. Enable the overlay, then point it at a default policy:
dn: olcOverlay={0}ppolicy,olcDatabase={1}mdb,cn=config
objectClass: olcPPolicyConfig
olcOverlay: ppolicy
olcPPolicyDefault: cn=default,ou=Policies,dc=example,dc=com
olcPPolicyHashCleartext: FALSE
olcPPolicyUseLockout: TRUEMake sure the ppolicy schema is loaded — on Debian/Ubuntu its file is at /etc/ldap/schema/ppolicy.schema. Then create the policy entry:
dn: cn=default,ou=Policies,dc=example,dc=com
objectClass: pwdPolicy
objectClass: person
cn: default
sn: Default password policy
pwdAttribute: userPassword
pwdMinLength: 12
pwdMaxAge: 7776000
pwdInHistory: 5
pwdCheckQuality: 2
pwdMaxFailure: 3
pwdLockout: TRUE
pwdLockoutDuration: 300
pwdGraceAuthNLimit: 2A few key attributes:
| Attribute | Meaning |
|---|---|
pwdMinLength | Minimum password length |
pwdMaxAge | Maximum password age in seconds (90 days = 7776000) |
pwdInHistory | Number of old passwords that can't be reused |
pwdCheckQuality | Quality checking level, from 0 to 2 |
pwdMaxFailure | Failed login attempt limit |
pwdLockout | Enable account lockout after pwdMaxFailure |
pwdLockoutDuration | Lockout duration in seconds |
pwdGraceAuthNLimit | Number of grace logins after expiration |
The full details of ppolicy — including hashing and external validation — will be covered in episode 12.
syncprov turns a server into a replication provider: it tracks changes (contextCSN) and provides synchronization for consumers. Configuration on the provider side:
dn: olcOverlay={0}syncprov,olcDatabase={1}mdb,cn=config
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpCheckpoint: 100 10
olcSpSessionlog: 100olcSpCheckpoint tells the provider to write a sync marker every 100 operations or 10 minutes; olcSpSessionlog sets the session log size for delta-sync. The consumer side uses the syncrepl directive on its own database — covered fully in the replication episode. Combining syncprov with accesslog enables delta-sync: consumers receive only changes, not the entire database contents.
Besides the big three above, there are overlays that round out a production directory:
| Overlay | Main function |
|---|---|
refint | Keeps DN references consistent when entries are deleted or renamed |
unique | Enforces uniqueness of certain attributes within a scope |
constraint | Restricts attribute values to allowed patterns or lists |
auditlog | Writes change logs to an LDIF file for audit |
accesslog | Records changes for delta-sync and history |
dynlist | Creates dynamic lists from a query via memberURL |
valsort | Automatically sorts multi-valued attribute values |
unique, for example, prevents two users from using the same uidNumber — a problem we touched on in episode 7:
dn: olcOverlay={0}unique,olcDatabase={1}mdb,cn=config
objectClass: olcUniqueConfig
olcOverlay: unique
olcUniqueURI: ldap:///?uidNumber?sub?(objectClass=posixAccount)auditlog writes every modification to a file that can be reviewed:
dn: olcOverlay={0}auditlog,olcDatabase={1}mdb,cn=config
objectClass: olcAuditLogConfig
olcOverlay: auditlog
olcAuditlogFile: /var/log/ldap/audit.logSeveral things to keep in mind:
memberOf should be active before refint so reference cleanup can follow; validating overlays like constraint are usually placed earlier so invalid requests are rejected before being processed further.auditlog, accesslog) can fill the disk — set up log rotation from the start.olcOverlay prefixed with index 0, 1, 2, and so on) so their order is clear when read via slapcat.Tip
After changing the cn=config configuration, check its consistency with slapcat -n 0 -l /tmp/config.ldif and make sure the service restarts cleanly via systemctl status slapd. Errors in overlay entries usually only surface at restart, not when the LDIF is applied.
Episode 11 introduces OpenLDAP's overlay architecture: the layered module concept, the two-step process of loading modules with olcModuleLoad, the three main overlays memberOf, ppolicy, and syncprov, seven supporting overlays like refint, unique, and auditlog, and the discipline of ordering and overhead when configuring them.
Key takeaways:
memberOf automatically maintains membership; pair it with refint.ppolicy is the gatekeeper of password policies, syncprov the foundation of replication.In the next episode, episode 12, we dive into password policy in full: policy attributes, hashing from SSHA to Argon2, external validation, and how to properly test lockout, expiration, and grace logins.