॥ श्री ॥

slapd (OpenLDAP)

Networking 2026-08-28

OpenLDAP is an open-source implementation of the Lightweight Directory Access Protocol (LDAP), used for centralised authentication and directory services. It is pre-installed on Shani OS.

Database files persist in /var/lib/openldap/openldap-data, bind-mounted from /data/varlib/openldap, and survive OS updates.


Setup

Enable the Service

sudo systemctl enable --now slapd

Generate a Password Hash

# Generates a hashed password for use in LDIF files
slappasswd
# Enter your chosen password — copy the {SSHA}... output

Configure the Root DN

OpenLDAP starts empty. Create setup.ldif to set the base DN and admin user:

dn: cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=shanios,dc=local
-
replace: olcRootDN
olcRootDN: cn=Manager,dc=shanios,dc=local
-
replace: olcRootPW
olcRootPW: {SSHA}hashedpasswordhere

Apply using the local UNIX socket (no password needed):

sudo ldapadd -Y EXTERNAL -H ldapi:/// -f setup.ldif

Load Core Schema

# Load standard schemas (required for most LDAP deployments)
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/core.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif

Adding Entries

Base Structure

Create base.ldif:

dn: dc=shanios,dc=local
objectClass: dcObject
objectClass: organization
o: Shani OS Local
dc: shanios

dn: ou=users,dc=shanios,dc=local
objectClass: organizationalUnit
ou: users

dn: ou=groups,dc=shanios,dc=local
objectClass: organizationalUnit
ou: groups
ldapadd -x -H ldap://localhost \
  -D "cn=Manager,dc=shanios,dc=local" \
  -W -f base.ldif

Add a User

dn: uid=alice,ou=users,dc=shanios,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: alice
cn: Alice Smith
sn: Smith
mail: alice@shanios.local
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/alice
loginShell: /bin/bash
userPassword: {SSHA}hashedpasswordhere
ldapadd -x -H ldap://localhost \
  -D "cn=Manager,dc=shanios,dc=local" \
  -W -f user-alice.ldif

Querying

# List all entries under the base DN
ldapsearch -x -H ldap://localhost -b dc=shanios,dc=local

# Search for a specific user
ldapsearch -x -H ldap://localhost \
  -b ou=users,dc=shanios,dc=local \
  "(uid=alice)"

# Authenticated search (as Manager)
ldapsearch -x -H ldap://localhost \
  -D "cn=Manager,dc=shanios,dc=local" \
  -W -b dc=shanios,dc=local

Firewall

sudo firewall-cmd --add-service=ldap --permanent    # port 389 (plain/STARTTLS)
sudo firewall-cmd --add-service=ldaps --permanent   # port 636 (TLS)
sudo firewall-cmd --reload

Troubleshooting

IssueSolution
ldapadd returns No such objectThe parent DN doesn't exist yet — add base structure entries before adding users/groups
Invalid credentialsWrong bind DN or password; the bind DN must match olcRootDN exactly
Can't contact LDAP serverCheck systemctl status slapd; confirm the service is listening: `ss -tlnpgrep 389`
Schema error on ldapaddLoad the required schema LDIFs first (core.ldif, cosine.ldif, inetorgperson.ldif)
View slapd logsjournalctl -u slapd -f

TLS Configuration

Generate a self-signed certificate for internal use (or request one from your CA / Let's Encrypt):

sudo mkdir -p /etc/openldap/tls
sudo openssl req -new -x509 -nodes -days 3650 \
  -keyout /etc/openldap/tls/slapd.key \
  -out /etc/openldap/tls/slapd.crt \
  -subj "/CN=ldap.shanios.local"
sudo chown ldap:ldap /etc/openldap/tls/slapd.key /etc/openldap/tls/slapd.crt
sudo chmod 600 /etc/openldap/tls/slapd.key

Set olcTLSCertificateFile and olcTLSCertificateKeyFile via cn=config:

dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/tls/slapd.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/tls/slapd.key
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f tls.ldif
sudo systemctl restart slapd

Verify with an LDAPS connection (ldaps://, port 636).

Access Control

Replace the default permissive ACLs on the database entry (olcDatabase={1}mdb). Sample policy: anonymous binds may authenticate only, authenticated users may read their own entry, and the Manager has write access:

dn: olcDatabase={1}mdb
changetype: modify
replace: olcAccess
olcAccess: {0}to attrs=userPassword
    by dn.exact="cn=Manager,dc=shanios,dc=local" write
    by self write
    by anonymous auth
    by * none
olcAccess: {1}to dn.subtree="dc=shanios,dc=local"
    by dn.exact="cn=Manager,dc=shanios,dc=local" write
    by self read
    by users read
    by * none
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f acl.ldif

ACL changes take effect immediately — no restart required.

See Also