Learn LDAP - Search & Filters
Series/Learn LDAP/Episode 9
Episode 9 of 31

Learn LDAP - Search & Filters

Reading directory data intelligently: the base, one, sub, and children search scopes, comparison and logical filter operators, ready-to-use combined filter examples, attribute selection, and practices for keeping search performance healthy.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 8 you learned to modify and delete data. Episode 9 covers the ability you'll use most often day to day: reading data intelligently. You'll learn search scopes, how to build filters with comparison and logical operators, select the attributes you request, and understand the performance limits of searches in slapd.

Search Scopes

The scope determines how far a search reaches from the base DN:

Scope-s valueResult
Base-s baseOnly the entry at the base DN itself
One-s oneThe base's direct children, without the base
Sub-s subThe base and all its descendants
Children-s childrenAll descendants, without the base

The main difference is between one and sub: one is only one level down, sub descends all the way to the leaves. A comparison example:

Comparing scopes
ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b dc=example,dc=com -s base "(objectClass=*)"
ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b dc=example,dc=com -s one "(objectClass=*)"
ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b dc=example,dc=com -s sub "(objectClass=*)"

With base dc=example,dc=com, -s base returns only the domain entry itself, -s one returns the OUs below it, and -s sub returns everything, including all users and groups.

Basic Filters

The filter is the heart of LDAP search. Every filter is written in parentheses, e.g. (uid=budi). Basic operators:

OperatorExampleMeaning
Equality =(uid=budi)Value exactly equal
Substring *(cn=John*)Prefix, suffix, or middle part
Greater than >=(uidNumber>=1000)Greater than or equal
Less than <=(uidNumber<=2000)Less than or equal
Presence =*(mail=*)Attribute has a value
Approximate ~=(sn~=santoso)Similar, usually without an index

Example usage in ldapsearch:

Substring filter
ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b "ou=People,dc=example,dc=com" "(cn=Budi*)"

The filter (cn=Budi*) searches all entries whose cn starts with Budi. Wildcards can be used at the front, middle, or end: *@example.com, Bu*i, *Pratama.

Logical Operators

For combinations, use three logical operators:

OperatorSymbolSemantics
AND&All conditions must hold
OR``
NOT!Negates a condition

Combined filters wrap several filters in one pair of parentheses:

Logical combinations
(&(objectClass=person)(mail=*@example.com))
(|(uid=budi)(uid=sari))
(!(mail=*))
(&(|(uid=budi)(uid=sari))(objectClass=posixAccount))

The rule of thumb: AND joins requirements, OR joins alternatives, and negation is often used for "everything except". Filters can be nested as deep as you like, as long as the parentheses stay balanced.

Practical Filter Examples

Some combinations that are immediately useful in real directories:

Ready-to-use filters
(uid=john)
(cn=John*)
(&(objectClass=person)(mail=*@example.com))
(|(uid=john)(uid=jane))
(&(objectClass=posixAccount)(uidNumber>=1000))

The last one — all Unix accounts with a UID of at least 1000 — is often used to separate real users from system accounts:

Filter in ldapsearch
ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b "ou=People,dc=example,dc=com" "(&(objectClass=posixAccount)(uidNumber>=1000))"

Remember: a filter only searches within the specified base. If you want to cover the whole tree, raise the base to dc=example,dc=com and use -s sub.

Attribute Selection

Besides filters, you can control the attributes returned by adding an attribute list after the filter:

Requesting specific attributes
ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b "ou=People,dc=example,dc=com" "(objectClass=posixAccount)" uid mail

Selection rules:

  • Explicit attribute list — only those attributes are returned.
  • * — all user attributes.
  • + — operational attributes like entryUUID, createTimestamp, and modifyTimestamp.
  • No list at all — the default set: all user attributes, without operational attributes; userPassword only appears if the ACL permits reading it.
Reading operational attributes
ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b "uid=budi,ou=People,dc=example,dc=com" -s base "(objectClass=*)" +

To see only DNs without attributes, use the attribute list 1.1 — a classic bandwidth-saving trick.

Search Performance

"Expensive" filters are those without an index on the server. In the indexing episode you'll create indexes for cn, uid, sn, mail, member, and uidNumber. Without an index, slapd does a full scan that slows down as the database grows.

Optimal patterns:

  • Combine with AND to narrow results — (&(objectClass=posixAccount)(uidNumber>=1000)) is far more efficient than (objectClass=posixAccount) alone for lists of thousands of entries.
  • Put the most selective attribute first in an AND filter.
  • Limit the number of results on the client side with -z (entry count) and -l (seconds):
Size and time limits
ldapsearch -z 50 -l 10 -x -D "cn=admin,dc=example,dc=com" -W -b dc=example,dc=com "(objectClass=*)"

The -z 50 option caps results at 50 entries; -l 10 caps the run at 10 seconds. The slapd server also enforces its own limits via olcLimits, so the effective value is whichever is stricter.

Tip

If a search suddenly gets slow, first check whether the filter uses an indexed attribute. Filters with ~= (approximate) and mid-value substrings can rarely use an index — set up the right olcDbIndex before your data grows.

Closing

Episode 9 equips you with the LDAP query language: the base, one, sub, and children scopes; the comparison operators =, *, >=, <=, =*, and ~=; the logical operators &, |, and !; attribute selection including operational attributes; and the performance discipline of indexes plus size and time limits.

Key takeaways:

  • Scope determines the search territory; sub reaches the whole tree.
  • Filters are always in parentheses, and logic can be nested.
  • Request only the attributes you need; + for operational attributes.
  • An unindexed filter means a full scan — set up indexes from the start.

In the next episode, episode 10, we move to access security: access control lists. You'll decide who can read what, who can change what, and how to enforce the principle of least privilege in the directory.