LDAP Assertion Control – Conditional Operation Execution


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

References

About Terry Gardner

Terry Gardner was a leading directory services architect with experience with many large scale directory services installations and messaging server installations, and was a Subject Matter Expert in the field of Directory Services and Solaris (operating system) performance. Mr. Gardner also participated in the open-source software community. Mr. Gardner passed away in December, 2013.
This entry was posted in computing, Java, LDAP and tagged , , , , , , , . Bookmark the permalink.

Leave a comment