Controls¶
Many LDAP users may be unfamiliar with controls. RFC4511 defines controls as “providing a mechanism whereby the semantics and arguments of existing LDAP operations may be extended.” In other words, they can:
- Instruct the server to process a method differently
- Add new arguments to methods to control the altered processing
- Add additional data to the response to a method call
It is important to note that both the server and client must mutually support all controls used. Laurelin will automatically check for server support when using controls.
Using Controls¶
Once controls have been defined, they are very easy to use. Each control has a keyword
and optionally a response_attr
.
The keyword
can be passed as a keyword argument to specific methods. The value type and format is up to the control
implementation. Whatever value the control expects can be wrapped in critical
or optional
to declare
the criticality of the control.
If defined, the response_attr
will be set as an attribute on the object returned from the method call.
For search response controls, the control value will be set on the individual LDAPObject
if it appeared on the
associated search result entry. If it appeared on the search results done message, the control value will be set on the
iterator object.
In the highly unusual case that a response control is set on a search result reference message, the control values will
be inaccessible if fetch_result_refs
is set to True. A warning will be issued in this case.
If fetch_result_refs
is set to False, the response control values will be set on the SearchReferenceHandle
that is yielded from the results iterator.
An LDAPSupportError
will be raised if the control is marked critical and the server does not support it.
Defining Controls¶
Controls must subclass Control. As soon as they are defined as a subclass of Control, they are ready to use. Controls must define at least:
Control.method
, a tuple of method names that this control supports. Current method names are bind, search, compare, add, delete, mod_dn, modify, and ext (extended request). Note that these method names do not necessarily correspond directly toLDAP
method names. Even when they do, other methods may call the base method and pass through control keywords. For example,LDAPObject.find()
ends up passing any control keywords through intoLDAP.search()
(which matches the search method). The bind method is used by bothLDAP.simple_bind()
andLDAP.sasl_bind()
.Control.keyword
, the keyword argument to be used for the request control.Control.REQUEST_OID
the OID of the reuqest control. If the control has criticality, the OID must be listed in the supportedControl attribute of the root DSE of the server at runtime.
If there is an associated response control, also define the following:
Control.response_attr
, the name of the attribute which will be set on objects returned from the method.Control.RESPONSE_OID
the OID of the response control. This may be equal toControl.REQUEST_OID
depending on the spec. This must match the controlType of the response control to be properly set.
Most controls will not need to override methods if only strings are used for request and response values. However, if it
is desirable to use a more complex data structure as a control value, you can override the Control.prepare()
method to accept this structure as its first argument. You will need to process this into a single string for
transmission to the server, and pass it into, and return, the base Control.prepare()
. The second argument is a
boolean describing criticality, and must also be passed into the base method.
To return a more complex value for the response, you can override the Control.handle()
method. This will be
passed the response control value string, and the return will be assigned to the response_attr
attribute on the
returned object.