RFC 4528 defines the request control called the LDAP Assertion Control (OID 1.3.6.1.1.12
). The LDAP Assertion Control provides clients with a mechanism wherein an LDAP request is executed conditionally based on whether a client-supplied filter matches an attribute in the entry with target distinguished name (DN) supplied with the operation. Matching rules are used to match values, as always in LDAP and code that uses language-based matching instead of matching rules could fail spectacularly. Should the filter not match the target, the operation is not executed, and the assertion failed result code (decimal 122) must be returned to the client. As with any filter, the attributes used in the assertion filter should be indexed.
To determine whether your directory server supports the LDAP Assertion Control, query the root DSE for the supportedControl
attribute whose value is 1.3.6.1.1.12
:
# ldapsearch example: /usr/bin/ldapsearch -h localhost -p 1389 \ -x -b '' -s base '(&)' supportedControl | \ perl -lane 'print if /1.3.6.1.1.12/' supportedControl: 1.3.6.1.1.12
For information about the root DSE, see “LDAP: The root DSE”.
AssertionRequestControlDemo.java provides a demonstration of how to use the LDAP Asssertion Control in Java.
Applicability
The LDAP Assertion Control is applicable to the following operations:
- ADD – the target is the entry field
- COMPARE – the target is the entry field
- DELETE – the target is the del request type
- MODIFY – the target is the object field
- MODIFY DN – the target is the entry field
- SEARCH – the target is the base object or base DN
The LDAP Assertion Control is not applicable to the following operations:
- BIND
- UNBIND
- STARTTLS
- ABANDON
The LDAP Assertion Control should be protected by access control, and since the supplied filter might contain sensitive information, the transmission should be conducted via an encrypted channel, preferably SSL or TLS. in this way, only trusted authentication identities can use the LDAP Assertion Control and the transmission is protected. Further, access controls should be in place to limit the authenticated identities that may use the LDAP Assertion Control.
Demonstration of the LDAP Assertion Control
There is an example written in Java called AssertionRequestControlDemo.java (click the filename to download).
The following examples use the following entry, take note of the case of the l
attribute and the value of the st
attribute:
dn: uid=user.0,ou=people,dc=example,dc=com objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: shadowAccount postalAddress: Aaren Atp$91327 Broadway Street$Las Vegas, UT 08103 postalCode: 08103 userPassword:: e1NTSEF9VG1QbzAwRXJHK05EN2R0SG1RSGJDVGJhUHBneXVpa01ZMEQ2Rmc9PQ= = employeeNumber: 20 initials: AWA givenName: Aaren pager: +1 214 214 4195 mobile: +1 947 007 3231 cn: Aaren Atp telephoneNumber: +1 089 907 9947 sn: Atp street: 91327 Broadway Street homePhone: +1 457 787 9183 l: Las Vegas mail: user.0@example.com st: UT description: description 2 description: description 3 uid: user.0
There follows an example of a search request and a modify request.
SEARCH
Use the older OpenLDAP client and include the LDAP Assertion Control with a search request:
/usr/bin/ldapsearch -h localhost -p 1389 \ -D 'cn=directory manager' -W -LLL -x \ -b uid=user.0,ou=people,dc=example,dc=com \ -s sub -e assert='(l=las vegas)' '(uid=user.0)' cn Enter LDAP Password: dn: uid=user.0,ou=people,dc=example,dc=com cn: Aaren Atp
The parameters of the successful search request included the LDAP Assertion Control (-e assert='(l=las vegas)'
), requesting the cn
attribute. Since this is a search request, the target is the base object uid=user.0,ou=people,dc=example,dc=com
. Since the assertion filter matches the base object, the cn
is returned. Note that the case of the l
attribute is ignored when matching the base object. If the case must be matched, use an extensible match filter:
/usr/bin/ldapsearch -h localhost -p 1389 \ -D 'cn=directory manager' -W -LLL -x \ -b uid=user.0,ou=people,dc=example,dc=com \ -s sub -e assert='(l:caseExactMatch:=las vegas)' \ '(uid=user.0)' cn Enter LDAP Password: Assertion Failed (122) Additional information: The search request cannot be processed because it contains an LDAP assertion control and the assertion filter did not match the contents of the base entry
In the above example "las vegas"
does not match "Las Vegas"
, therefore, the search operation was not processed. The "Assertion Failed (122)"
shows that the directory server correctly set the response code because there was no match.
MODIFY
The above example will attempt to set the st
attribute to NV
but will fail because of the supplied filter '(l:caseExactMatch:=las vegas)'
. Use the modern ldapmodify
client.
ldapmodify --hostname localhost --port 1389 \ --bindDn 'cn=directory manager' \ --bindPasswordFile ~/.pwdFile \ --assertionFilter '(l:caseExactMatch:=las vegas)' dn: uid=user.0,ou=people,dc=example,dc=com changetype: modify replace: st st: NV # Processing MODIFY request for uid=user.0,ou=people,dc=example,dc=com Entry uid=user.0,ou=people,dc=example,dc=com \ cannot be modified because the request contained \ an LDAP assertion control and the associated \ filter did not match the contents of the that entry Result Code: 122 (Assertion Failed) Diagnostic Message: Entry uid=user.0,ou=people,dc=example,dc=com\ cannot be modified because the request contained an LDAP assertion control and the associated filter did not match the contents of the that entry
Remove the extensible match filter and try again. Add the post-read control to verify the attribute was changed:
ldapmodify --hostname localhost --port 1389 \ --bindDn 'cn=directory manager' --bindPasswordFile ~/.pwdFile \ --assertionFilter '(l=las vegas)' --postReadAttributes st dn: uid=user.0,ou=people,dc=example,dc=com changetype: modify replace: st st: NV # Processing MODIFY request for uid=user.0,ou=people,dc=example,dc=com # MODIFY operation successful for DN uid=user.0,ou=people,dc=example,dc=com # Target entry after the operation: # dn: uid=user.0,ou=people,dc=example,dc=com # st: NV