Getting to know the OpenLDAP client tools: ldapsearch, ldapadd, ldapmodify, ldapdelete, ldappasswd, ldapwhoami, and ldapcompare along with their common options, running your first search, and understanding the LDIF format for directory data exchange.

In episode 5 you successfully installed slapd and built the base structure of the dc=example,dc=com domain on your server. The server is now alive and listening on port 389, but nothing is interacting with it yet. Episode 6 shifts the focus to the client side: you'll get to know the LDAP tools one by one, learn the options they share, run your first search both anonymously and authenticated, and understand LDIF — the data exchange language that will accompany you through the rest of this series.
Every LDAP operation introduced in episode 2 has its own tool. The ldap-utils package provides them all at once:
| Tool | Operation | Main function |
|---|---|---|
ldapsearch | Search | Reads and searches entries |
ldapadd | Add | Adds new entries |
ldapmodify | Modify | Changes entry attributes |
ldapdelete | Delete | Deletes entries |
ldappasswd | Password Modify | Changes passwords |
ldapwhoami | Who Am I | Shows the bind identity |
ldapcompare | Compare | Compares an attribute value |
An important note: ldapadd is actually an alias for ldapmodify -a. Meanwhile the ModifyDN operation isn't handled by a tool called ldapmodifydn, but by ldapmodrdn — you'll use it in episode 8.
All the tools above share a nearly identical set of options. Learn one and the rest come naturally:
| Option | Function | Example usage |
|---|---|---|
-H | LDAP server URI | -H ldap://localhost |
-D | Bind DN, the identity used | -D "cn=admin,dc=example,dc=com" |
-w | Password directly in the command | -w secret123 |
-W | Interactive password prompt | -W |
-x | Simple authentication | -x |
-b | Search base DN | -b dc=example,dc=com |
-s | Search scope | -s sub |
-f | Read input from a file | -f entries.ldif |
The base pattern is always the same: tool -x -H server -D binddn -b base followed by tool-specific options. For passwords, get into the habit of using -W rather than -w — with -W the password is requested interactively so it doesn't linger in your shell history. Full details for each tool can be read via ldapsearch -h or the man pages.
Note
Without the -f argument, tools like ldapadd and ldapmodify read input from stdin. The habit of using files makes operations repeatable and reviewable before they're executed — a pattern you'll explore more deeply in episode 7.
Let's start with ldapsearch, the most frequently used tool. The following command searches for all entries within the base dc=example,dc=com:
ldapsearch -x -H ldap://localhost -b dc=example,dc=com "(objectClass=*)"Without -D, the search runs as an anonymous bind. The phrase (objectClass=*) is a filter matching all entries — remember ldapsearch requires a filter at the end of the command. The result shows the DN and all attributes of each entry found, one by one.
Most production directories restrict what anonymous users can see. Searching as admin adds -D and -W:
ldapsearch -x -H ldap://localhost -D "cn=admin,dc=example,dc=com" -W -b dc=example,dc=com "(objectClass=*)"After entering the password, the result will be the same as the anonymous search above — as long as the server grants anonymous users the same read rights. If the ACL rules (episode 10) differ, the results will differ too.
A special entry called the Root DSE sits at the empty DN and contains the server's capabilities, not directory data. You find it using an empty base with a base scope:
ldapsearch -x -H ldap://localhost -b "" -s base "+"The + argument requests operational attributes. From here you can see supportedControl, supportedExtension, supportedSASLMechanisms, and supportedLDAPVersion — this is the quick way to confirm which features your server supports before configuring something that isn't there yet.
LDIF (LDAP Data Interchange Format) is the text representation of LDAP entries, used as the input format for ldapadd and ldapmodify and the output format of ldapsearch. An entry consists of at least a DN followed by attribute-value pairs:
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
dc: example
o: Example IncImportant LDIF rules:
dn: followed by the entry's distinguished name.attribute: value. An attribute can be repeated for multiple values, like objectClass above.# example entry for user budi
dn: uid=budi,ou=People,dc=example,dc=com
description: Example user whose description is long enough
that it has to be continued onto the next line
userCertificate:: Q29udGVudCBCZXJ2YXM=The rules of dn: as the first line, blank-line entry separators, and the attribute: value notation are what you'll keep using in episodes 7 and 8.
Episode 6 equips you with the working tools on the client side: the function of each ldap-utils tool, the shared options -H, -D, -w, -W, -x, -b, -s, and -f, how to run anonymous, authenticated, and Root DSE searches, and the LDIF format rules from entry structure to base64.
Key takeaways:
ldapsearch requires a filter — without one, the command will fail.-W instead of -w so passwords aren't exposed in shell history.dn:, then attribute: value, separate entries with a blank line.In the next episode, episode 7, you'll use all of this to actually populate the directory: building the organizational structure, adding users and groups, up to batch imports — from an empty directory to one that begins to come alive.