Last modified: March 23, 2026
This article is written in: 🇺🇸
LDAP is a protocol used to access and manage directory information over an IP network. It is open, vendor-neutral, and an industry standard. LDAP is commonly used for centralized authentication, where user credentials and permissions are managed in a single directory and applied across multiple systems and applications.
uid=jdoe,ou=users,dc=example,dc=com represents a specific entry under the "users" organizational unit in the "example.com" domain.
| Component | Description |
uid=jdoe |
User ID |
ou=users |
Organizational Unit |
dc=example,dc=com |
Domain Components representing example.com |
The network topology illustrates how the LDAP server interacts with multiple client hosts across the network.
| LDAP Server |
| (ldap.example.com) |
+----------+---------+
|
---------------------------------
| | |
+-------+-----+ +-----+-------+ +---+-------+
| | | | | |
+------v------+ +----v-----+ +-----v----+ +----v-----+
| Client Host | | Client | | Client | | Client |
| (Web) | | Host | | Host | | Host |
| | | (Email) | | (SSH) | | (FTP) |
+-------------+ +----------+ +----------+ +----------+
LDAP directories are organized hierarchically in a structure known as the Directory Information Tree (DIT).
Visual Representation of a DIT:
(Root)
|
+----------+----------+
| |
dc=com dc=org
| |
+-----+-----+ |
| | |
dc=example dc=company ...
|
+---+---+
| |
ou=users ou=groups
| |
| +----------------+
| |
+--+--+ +---+---+
| | | |
uid=alice uid=bob cn=admins cn=users
dc=example,dc=com corresponds to the domain example.com.ou=users for user accounts or ou=groups for different group classifications.uid=alice for a user named Alice.cn=admins for an administrators group.User Client Host LDAP Server
| | |
|---Login Request------>| |
| |---Authenticate------>|
| | |
| |<--Authentication-----|
|<--Access Granted------| |
LDAP defines a set of operations that clients can perform on the directory.
Example Command:
ldapwhoami -x -D "uid=jdoe,ou=users,dc=example,dc=com" -W
Options:
| Option | Description |
-x |
Use simple authentication. |
-D |
Bind DN (the user's distinguished name). |
-W |
Prompt for the password. |
Expected Output:
Enter LDAP Password:
dn:uid=jdoe,ou=users,dc=example,dc=com
Example Search Command:
ldapsearch -x -b "dc=example,dc=com" "(uid=jdoe)"
| Option | Description |
-x |
Use simple authentication. |
-b |
Base DN to search. |
"(uid=jdoe)" |
Search filter. |
Expected Output:
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: (uid=jdoe)
# requesting: ALL
#
# jdoe, users, example.com
dn: uid=jdoe,ou=users,dc=example,dc=com
uid: jdoe
cn: John Doe
sn: Doe
mail: jdoe@example.com
...
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Example Add Command:
ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f new_user.ldif
Example Delete Command:
ldapdelete -x -D "cn=admin,dc=example,dc=com" -W "uid=jdoe,ou=users,dc=example,dc=com"
Search filters control what entries are returned in a search operation.
Syntax:
(attribute=value): Equality match.(&(filter1)(filter2)): AND operation.(|(filter1)(filter2)): OR operation.(!(filter)): NOT operation.Examples:
Find users with uid 'jdoe':
(uid=jdoe)
Find entries that are persons and have an email:
(&(objectClass=person)(mail=*))
Find users not in the 'admins' group:
(!(memberOf=cn=admins,ou=groups,dc=example,dc=com))
ldapsearch -x -b "dc=example,dc=com" "(objectClass=*)"
ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f entry.ldif
ldapdelete -x -D "cn=admin,dc=example,dc=com" -W "uid=jdoe,ou=users,dc=example,dc=com"
ldapwhoami -x -D "uid=jdoe,ou=users,dc=example,dc=com" -W
Centralized authentication via LDAP allows multiple servers and applications to use a single directory for user authentication and authorization.
Prerequisites:
Install OpenLDAP and Utilities:
sudo apt-get update
sudo apt-get install slapd ldap-utils
Configure slapd:
During installation, you may not be prompted for configuration. Run the following to reconfigure:
sudo dpkg-reconfigure slapd
Configuration Prompts:
| Setting | Value |
| Omit OpenLDAP server configuration? | No |
| DNS domain name | example.com |
| Organization name | Example Company |
| Administrator password | [Set a strong password] |
| Database backend | MDB |
| Remove the database when slapd is purged? | No |
| Move old database? | Yes |
Create Base LDIF File (base.ldif):
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Example Company
dc: example
dn: ou=users,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: users
dn: ou=groups,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: groups
Load the Schema into LDAP:
sudo ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f base.ldif
Expected Output:
adding new entry "dc=example,dc=com"
adding new entry "ou=users,dc=example,dc=com"
adding new entry "ou=groups,dc=example,dc=com"
Create User LDIF File (user.ldif):
dn: uid=jdoe,ou=users,dc=example,dc=com
objectClass: inetOrgPerson
uid: jdoe
cn: John Doe
sn: Doe
givenName: John
mail: jdoe@example.com
userPassword: {SSHA}encrypted_password_here
Note: Use slappasswd to generate an encrypted password.
slappasswd
| Step | Action |
| Enter Password | [Type password] |
| Re-enter Password | [Retype password] |
| Output | {SSHA}encrypted_password_here |
Load the User into LDAP:
sudo ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f user.ldif
adding new entry "uid=jdoe,ou=users,dc=example,dc=com"
Install Required Packages:
sudo apt-get install libnss-ldap libpam-ldap ldap-utils nscd
Configuration Prompts:
| Setting | Value |
| LDAP server URI | ldap://ldapserver.example.com |
| Distinguished name of the search base | dc=example,dc=com |
| LDAP version | 3 |
| Make local root Database admin | Yes |
| Does the LDAP database require login? | No |
| LDAP account for root | cn=admin,dc=example,dc=com |
| LDAP root account password | [Enter admin password] |
Configure NSS to Use LDAP:
Edit /etc/nsswitch.conf:
passwd: compat systemd ldap
group: compat systemd ldap
shadow: compat ldap
Configure PAM for LDAP Authentication:
Ensure that /etc/pam.d/common-auth includes:
auth sufficient pam_ldap.so
auth required pam_unix.so nullok_secure try_first_pass
Restart NSS Service:
sudo service nscd restart
Install libpam-mkhomedir:
sudo apt-get install libpam-mkhomedir
Configure PAM to create home directories:
Edit /etc/pam.d/common-session and add:
session required pam_mkhomedir.so skel=/etc/skel umask=077
Test LDAP Lookup:
getent passwd jdoe
Expected Output:
jdoe:x:10000:10000:John Doe:/home/jdoe:/bin/bash
Test Login as LDAP User:
Use SSH or local terminal:
ssh jdoe@localhost
Verify that the LDAP service is listening and reachable:
ldapwhoami -x -H ldap://localhost
Expected output for an anonymous bind:
For an authenticated bind, supply credentials:
ldapwhoami -x -D "cn=admin,dc=example,dc=com" -W -H ldap://localhost
Expected output:
dn:cn=admin,dc=example,dc=com
Search for all user entries to confirm the directory is populated:
ldapsearch -x -b "ou=users,dc=example,dc=com" -H ldap://localhost "(objectClass=inetOrgPerson)" uid cn
Verify a specific group:
ldapsearch -x -b "ou=groups,dc=example,dc=com" -H ldap://localhost "(cn=developers)"
Create a temporary test user (testuser.ldif):
dn: uid=testuser,ou=users,dc=example,dc=com
objectClass: inetOrgPerson
uid: testuser
cn: Test User
sn: User
userPassword: testpass
Add, verify, and then remove the test entry:
sudo ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f testuser.ldif
ldapsearch -x -b "dc=example,dc=com" "(uid=testuser)" uid cn
sudo ldapdelete -x -D "cn=admin,dc=example,dc=com" -W "uid=testuser,ou=users,dc=example,dc=com"
After configuring NSS, verify that the system can resolve LDAP users and groups:
getent passwd # should list LDAP users alongside local users
getent group # should list LDAP groups
id jdoe # should show uid, gid, and groups from LDAP
LDAP supports several methods for authenticating clients to the directory server.
Simple authentication sends a DN and password to the server. It should always be used over an encrypted connection to prevent credentials from being transmitted in clear text.
ldapwhoami -x -D "uid=jdoe,ou=users,dc=example,dc=com" -W -H ldap://localhost
Transport Layer Security (TLS) encrypts the communication channel between the client and the server.
I. Generate or obtain a TLS certificate and key for the LDAP server.
II. Configure slapd to use TLS by creating an LDIF file (tls.ldif):
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/ca-certificates.crt
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/ssl/ldap-server.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap-server.key
Apply the configuration:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f tls.ldif
III. Configure clients to require TLS by adding to /etc/ldap/ldap.conf:
TLS_CACERT /etc/ssl/certs/ca-certificates.crt
TLS_REQCERT demand
IV. Test a TLS connection:
ldapwhoami -x -ZZ -D "uid=jdoe,ou=users,dc=example,dc=com" -W -H ldap://localhost
The -ZZ flag enforces StartTLS and fails if encryption cannot be established.
OpenLDAP supports password policies through the ppolicy overlay, which allows administrators to enforce rules like minimum length, expiration, and lockout after failed attempts.
Load the password policy module and schema:
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif
Create a default password policy entry (ppolicy_default.ldif):
dn: cn=default,ou=policies,dc=example,dc=com
objectClass: pwdPolicy
objectClass: person
cn: default
sn: default
pwdAttribute: userPassword
pwdMaxAge: 7776000
pwdMinLength: 8
pwdMaxFailure: 5
pwdLockout: TRUE
pwdLockoutDuration: 900
pwdMustChange: TRUE
Add the policy:
sudo ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f ppolicy_default.ldif
For development or testing purposes, you can run both the LDAP server and client on the same host. Follow the server installation steps above, then configure the client to connect to localhost:
I. Install client libraries:
sudo apt-get install libnss-ldap libpam-ldap ldap-utils nscd
When prompted for the LDAP server URI, enter ldap://127.0.0.1.
II. Edit /etc/nsswitch.conf to add ldap:
passwd: compat systemd ldap
group: compat systemd ldap
shadow: compat ldap
III. Restart services and test:
sudo service nscd restart
getent passwd jdoe
Because both the server and client processes share the same machine, no network configuration is required beyond verifying that slapd listens on 127.0.0.1:389.
Create LDIF File for New User (user2.ldif):
dn: uid=asmith,ou=users,dc=example,dc=com
objectClass: inetOrgPerson
uid: asmith
cn: Alice Smith
sn: Smith
givenName: Alice
mail: asmith@example.com
userPassword: {SSHA}encrypted_password_here
Add User to LDAP:
sudo ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f user2.ldif
Create Modify LDIF File (modify_jdoe.ldif):
dn: uid=jdoe,ou=users,dc=example,dc=com
changetype: modify
replace: mail
mail: john.doe@example.com
Apply Changes:
sudo ldapmodify -x -D "cn=admin,dc=example,dc=com" -W -f modify_jdoe.ldif
Delete User Entry:
sudo ldapdelete -x -D "cn=admin,dc=example,dc=com" -W "uid=jdoe,ou=users,dc=example,dc=com"
ldapsearch command to perform various queries on the LDAP directory. Try to search for specific users, groups, and other entities based on different attributes.