Browse learn

Common LDAP Filter Examples

Explore practical LDAP filters for users, groups, attributes, nested logic, and directory-specific cases, with notes on escaping and performance.

On this page

Why Understanding LDAP Filters Matters

LDAP filter strings are the core mechanism for searching and retrieving directory entries in systems like Active Directory and OpenLDAP. Whether you’re authenticating users, syncing groups, or integrating single sign-on, writing correct and effective LDAP filters is essential for precise, performant, and secure directory operations. For developers and identity practitioners, fluency with LDAP filter syntax lets you construct reliable queries, safely implement directory lookups, and avoid subtle bugs that can cause authentication failures or excessive search loads.

The most useful filter patterns combine standard assertion and logical syntax with schema-specific attributes. Active Directory and other LDAP servers may require different object classes or matching rules.

LDAP Filter Syntax: The Building Blocks (RFC 4515)

The string representation of an LDAP filter is specified by RFC 4515, which mandates a formal grammar based on parentheses and prefix logic operators. A filter is always a parenthesized expression, composed of one or more clauses about attributes and their values. These may be combined using logical operators for complex queries.

The fundamental structure is:

  • Single clause: (attribute=value)
  • Compound logic: (&(...)(...)) (AND), (|(...)(...)) (OR), (!(...)) (NOT)
  • Presence check: (attribute=*)

Examples:

  • (cn=Alice) // Entries with cn equal to Alice
  • (&(objectClass=user)(mail=*)) // Users with any email set

Each sub-clause or logical operation is itself fully parenthesized. Filters cannot omit parentheses or write logic operators in infix style.

Presence, Equality, and Substring Filters: Practical Examples

LDAP filters can assert the existence or value of attributes using specific syntaxes:

Presence Filters

Match entries where an attribute exists:

  • Generic: (mail=*) — All entries with a mail attribute set
  • Universal (match all): (objectClass=*) — All directory entries

Equality Filters

Match entries where an attribute equals a given value:

  • (cn=John Doe) — Entries with cn (common name) equal to “John Doe”
  • (uid=jsmith) — Entries with uid equal to “jsmith”

Substring/Wildcard Filters

Use * as a wildcard for zero or more characters, only within substring filters:

  • (cn=J*) — cn starts with “J” (e.g., “John”, “Jane”)
  • (mail=*example.com) — mail ends with “example.com”
  • (sn=*mit*) — surname contains “mit”

A common misconception is that * can express presence outside of substring form—presence is strictly (attribute=*).

Compound and Logical Filters: AND, OR, NOT in Practice

To build queries with multiple conditions, LDAP filters use prefix logical operators:

AND: All Conditions Must Match

& combines multiple clauses—all must be true:

  • (&(objectClass=person)(mail=*))
    • Matches entries with objectClass of “person” and an email address

OR: Any Condition Can Match

| combines clauses where any may match:

  • (|(sn=Smith)(sn=Jones))
    • Entries with surname Smith or Jones

NOT: Negation

! negates a single clause:

  • (!(cn=Guest))
    • Entries whose cn is NOT “Guest”

Compound filters require all components—each clause, including the logic operator and its children—to be within their own parentheses. For example, to find users with email and title both present:

  • (&(mail=*)(title=*))

Nested filters allow for sophisticated queries, but every level must be properly parenthesized.

Escaping Special Characters: Preventing Filter Errors

Certain characters in filter values have special meanings and must be escaped according to RFC 4515:

CharacterMust Be Escaped AsExample Use
*\2a(cn=Smith\2aJohn) for “Smith*John”
(\28(cn=John\28Dev\29) for “John(Dev)”
)\29
\\5c(cn=O\'Connor) becomes (cn=O\5c'Connor)
NUL\00

Failure to properly escape these characters can cause filters to be rejected or return no results. The escape is a backslash (\) followed by the two-digit hexadecimal code of the character.

For example:

  • To search for a user whose cn is “Smith, John”, use (cn=Smith\2c John) because the comma does not need escaping, but if searching for an asterisk, it must be escaped.

Most-Used LDAP Filter Examples (Reference Table)

The following examples distinguish between generic LDAP and common Active Directory attributes.

PurposeGeneric LDAP ExampleActive Directory ExampleNotes
All entries(objectClass=*)SameUniversal match
All users(objectClass=person)(objectCategory=person)<br>or<br>(objectClass=user)AD often uses both objectCategory and objectClass
All groups(objectClass=groupOfNames)<br>or<br>(objectClass=group)(objectCategory=group)AD typically uses objectCategory=group
Users with email(&(objectClass=person)(mail=*))(&(objectCategory=person)(mail=*))Email presence
User by username(uid=jsmith)(sAMAccountName=jsmith)AD uses sAMAccountName
User by email(mail=j.doe@example.com)SameCase-insensitive in most directories
Users with missing title(!(title=*))SameInverse presence
Groups by partial name(cn=*admins*)SameWildcard substring
User is member of group (by DN)(memberOf=CN=Admins,OU=Groups,DC=example,DC=com)Same (AD only)memberOf is not always populated outside AD
Members of a group (group entry search)(member=uid=jsmith,ou=People,dc=example,dc=com)(member=CN=John Smith,CN=Users,DC=example,DC=com)Querying group entry for presence of user DN
Disabled usersn/a(&(objectCategory=person)(userAccountControl:1.2.840.113556.1.4.803:=2))AD only—uses bitwise match filter for userAccountControl

Note: Not every server or schema supports every attribute. For example, memberOf is reliably available only in Active Directory, while member is generic but used differently in AD and other LDAP servers.

Active Directory vs Generic LDAP: Key Differences

While core LDAP filter syntax is consistent (per RFC 4515), attribute names and object classes can differ, especially in Microsoft Active Directory:

  • User accounts:
    • AD: objectCategory=person and objectClass=user
    • Generic LDAP: often just objectClass=person
  • Group membership:
    • AD: memberOf attribute on user objects (auto-populated)
    • Generic LDAP: typically, groups reference members by member attributes (group entry points to user DN)
  • Account enabled/disabled state:
    • AD uses the userAccountControl attribute with bitwise filtering (not a standard LDAP feature)
  • Case handling:
    • Most LDAP servers treat attribute matching as case-insensitive (per specification), but this can vary.

When writing filters, ensure attribute names and logic fit your target directory’s schema.

Common Mistakes and Troubleshooting Tips

Common Errors

  • Missing or mismatched parentheses: Every clause, logical operator, and filter must be properly parenthesized. Omitting parentheses is invalid.
  • Incorrect use of wildcards: * as a wildcard is valid only within substring expressions, not as a universal replacement for values.
  • Unescaped special characters: Failing to escape special characters (*, (, ), \, NUL) in values can break the filter.
  • Typographical errors in attribute names: Directory schemas vary; misspelling or assuming the presence of attributes (memberOf, mail) can result in no matches.
  • Compound filters without a logical operator: All compound expressions must be wrapped by a single logic operator, e.g., (&(a=1)(b=2)), not simply (a=1)(b=2).

Troubleshooting Suggestions

  • If a filter returns no results, check for:
    • Proper parentheses and full encapsulation
    • Correct attribute names for your directory platform
    • Proper escaping of any filter value special characters
    • Appropriate use of wildcards only in substring filters
  • Test incrementally by simplifying filters and adding complexity one clause at a time.
  • When in doubt, consult your directory’s schema or documentation to confirm supported attributes and their expected usage in filters.

Sources