Several extensions to the existing PHP LDAP API have been developed to make it more suitable to our needs.
LDAP Controls
Currently, only the add/modify/replace/delete functions have been patched to accept additional parameters for server and client controls.
- Development Branch (against PHP master)
- PHP-5.5.10 Backport Branch (patch for PHP-5.5.10)
- Pull request @upstream (patch for PHP-git-latest)
- request for comments on php-internals mailinglist
Examples:
Single control:
ldap_modify($link, $dn, $entry, $control);
Multiple controls:
ldap_modify($link, $dn, $entry, [$control1, $control2]);
LDAP Assertion Control
To be able to safely change values, the Assertion Control is needed which results in a Compare-and-Set functionality.
Example (taken from ext/ldap/tests/ldap_control_assertion_basic.phpt
):
$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version); $entry = array( "objectClass" => array( "top", "dcObject", "organization"), "dc" => "stoney-cloud", "o" => "stoney-cloud", "description" => "stoney cloud root object", ); ldap_modify($link, "dc=stoney-cloud,dc=org", $entry); $assertion_string = "(description=stoney cloud root object)"; $control = ldap_control_assertion($link, $assertion_string); // the following fails if the description has been changed in the meantime ldap_modify($link, "dc=my-domain,dc=com", $entry, $control);
This can be used to safely increment variables, reserve IP addresses without race conditions.
Given a field in the LDAP which contains the the next free id or IP address:
- get the current value
- increment the value
- set the new value with the assert that the value must match the previously fetched one
- if it succeeds you can safely use the previously set value, if not: repeat the procedure
LDAP Session Control
The implementation of the control creation is complete, but controls can currently only be passed to the add/modify/replace/delete functions. To be useful, we must pass this control to almost every PHP LDAP call.
The idea of this control is the possibility of tracking the queries made in the LDAP for a given session in the application:
$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version); $entry = array( "objectClass" => array( "top", "dcObject", "organization"), "dc" => "my-domain", "o" => "my-domain", "description" => "Domain description", ); $sessionSourceIp = "192.168.1.10"; $sessionSourceName = "api.stoney-cloud.org"; $sessionTrackingIdentifier = "tmueller"; // username $control = ldap_control_session_tracking($link, $sessionSourceIp, $sessionSourceName, LDAP_CONTROL_X_SESSION_TRACKING_USERNAME, $sessionTrackingIdentifier); ldap_modify($link, "dc=my-domain,dc=com", $entry, $control)
which results in the following log of the ldap (using loglevel stats
):
Apr 25 14:59:32 testmachine slapd[4208]: conn=1014 op=5 [IP=192.168.1.10 NAME=api.stoney-cloud.org USERNAME=tmueller] MOD dn="dc=my-domain,dc=com" Apr 25 14:59:32 testmachine slapd[4208]: conn=1014 op=5 [IP=192.168.1.10 NAME=api.stoney-cloud.org USERNAME=tmueller] MOD attr=objectClass dc o description Apr 25 14:59:32 testmachine slapd[4208]: conn=1014 op=5 [IP=192.168.1.10 NAME=api.stoney-cloud.org USERNAME=tmueller] RESULT tag=103 err=0 text=
LDAP Server Side Sorting Control
TODO
LDAP Simple Paged Results Control
TODO
LDAP Modify-Increment Extension
TODO (this isn't a control but a specific type of modification)
Together with the Pre Read Control this presents a more elegant way on getting unique monotonic increasing IDs (our UIDs) since this would allow to increment the UID and getting the previous value in the same call.
LDAP Read Entry Controls
TODO This may be harder to get into upstream PHP since this requires that the functions pass back the message object such that the caller can get the response control out of it (which contains the entries of the query).
LDAP Tree Delete Control
draft-armijo-ldap-treedelete-02
May be really helpful when deleting tree of objects.
Notes on Server Side Sorting and Virtual List View (Simple Paging)
To achieve server side sorting with proper paging, the Server Side Sorting and Virtual List View overlay on the OpenLDAP server needs to be installed (this overlay replaces the built in simple paging mechanism):
- Internet-Draft: draft-ietf-ldapext-ldapv3-vlv-09.txt
- OpenLDAP Overlay: slapo-sssvlv - Server Side Sorting and Virtual List View overlay for slapd.
A Perl example how to set a LDAP control: http://search.cpan.org/~marschap/perl-ldap-0.62/