A filter is a boolean expression that decides which entries a search matches. Filters are written in a fully-parenthesized prefix syntax defined by RFC 4515, which looks unusual at first but is simple once you've seen a few examples.
The simplest filter checks whether an attribute equals a value:
(cn=Jane Doe)cnequalsJane Doe
Every filter is wrapped in parentheses. attribute=value inside those parentheses is an equality match.
Filters combine using prefix operators — the operator comes before its operands, and every operand is itself a fully parenthesized filter:
(&(objectClass=user)(mail=*@example.com))- AND
objectClassequalsusermailmatches*@example.com
&means AND — every child filter must match.|means OR — at least one child filter must match.!means NOT — negates a single child filter.
(|(department=Engineering)(department=Product))- OR
departmentequalsEngineeringdepartmentequalsProduct
(!(accountDisabled=TRUE))- NOT
accountDisabledequalsTRUE
* matches any run of characters, so you can match prefixes, suffixes, or "contains" checks:
(mail=*@example.com)mailmatches*@example.com
(cn=Jane*)cnmatchesJane*
A bare * by itself as the value means "has any value at all" — a presence filter:
(mail=*)mailis present
This is a common way to check "does this entry have this attribute set," regardless of what it's set to.
Besides equality, LDAP filters support ordering comparisons on attributes that have an ordering matching rule (most commonly integers and generalized time):
(&(objectClass=user)(createTimestamp>=20240101000000Z))- AND
objectClassequalsusercreateTimestamp≥20240101000000Z
>= and <= are supported; there is no strict > or < in the LDAP filter grammar.
Because * ( ) \ and the null character are meaningful in filter syntax, any value that might contain them needs to be escaped before it's inserted into a filter string — * becomes \2a, ( becomes \28, and so on. This matters most when a value comes from user input:
Security
Never interpolate untrusted input directly into an LDAP filter string. An unescaped *, (, or ) can change what the filter matches entirely — the same class of bug as SQL injection. See LDAP injection for concrete examples, and always escape with a library function rather than by hand.
Rather than hand-writing nested parentheses, construct and validate filters visually, including correct escaping of any values you type in.
LDAP Filter Builder
Open the LDAP Filter Builder.
Filters determine which entries you find. The next pages cover a specific kind of entry you'll filter for constantly: Users and groups.