Difference between revisions of "PHP Extensions"

From stoney cloud
Jump to: navigation, search
[unchecked revision][unchecked revision]
(Requirements)
 
(36 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
Several extensions to the existing PHP LDAP API have been developed to make it more suitable to our needs.
 
Several extensions to the existing PHP LDAP API have been developed to make it more suitable to our needs.
  
== PHP Assertion Control ==
+
== LDAP Controls ==
 +
 
 +
Currently, only the add/modify/replace/delete functions have been patched to accept additional parameters for server and client controls.
 +
 
 +
* [https://github.com/stepping-stone/php-src/tree/ldap-controls Development Branch] (against PHP master)
 +
* [https://github.com/stepping-stone/php-src/tree/ldap-controls-PHP-5.5.10 PHP-5.5.10 Backport Branch] ([https://github.com/stepping-stone/php-src/compare/PHP-5.5.10...ldap-controls-PHP-5.5.10.patch patch for PHP-5.5.10])
 +
* [https://github.com/php/php-src/pull/652 Pull request @upstream] ([https://github.com/php/php-src/pull/652.patch patch for PHP-git-latest])
 +
* [http://marc.info/?l=php-internals&m=139843308032437&w=2 request for comments on php-internals mailinglist]
 +
 
 +
Examples:
 +
 
 +
Single control:
 +
<source lang='php'>
 +
ldap_modify($link, $dn, $entry, $control);
 +
</source>
 +
 
 +
Multiple controls:
 +
<source lang='php'>
 +
ldap_modify($link, $dn, $entry, [$control1, $control2]);
 +
</source>
 +
 
 +
== LDAP Assertion Control ==
 +
 
 +
[https://tools.ietf.org/html/rfc4528 RFC4528]
  
 
To be able to safely change values, the Assertion Control is needed which results in a Compare-and-Set functionality.
 
To be able to safely change values, the Assertion Control is needed which results in a Compare-and-Set functionality.
Line 36: Line 59:
 
* set the new value with the assert that the value must match the previously fetched one
 
* 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
 
* if it succeeds you can safely use the previously set value, if not: repeat the procedure
 +
 +
== LDAP Session Control ==
 +
 +
[https://tools.ietf.org/html/draft-wahl-ldap-session-03 draft-wahl-ldap-session-03]
 +
 +
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:
 +
 +
<source lang='php'>
 +
$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)
 +
</source>
 +
 +
which results in the following log of the ldap (using <code>loglevel stats</code>):
 +
 +
<pre>
 +
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=
 +
</pre>
 +
 +
== LDAP Server Side Sorting Control ==
 +
 +
[https://tools.ietf.org/html/rfc2891 RFC2891]
 +
 +
The server side on OpenLDAP is implemented via an overlay: [http://www.openldap.org/software/man.cgi?query=slapo-sssvlv&apropos=0&sektion=0&manpath=OpenLDAP+2.4-Release&format=html slapo-sssvlv] - Server Side Sorting and Virtual List View overlay for slapd.
 +
 +
'''TODO'''
 +
 +
== LDAP Modify-Increment Extension ==
 +
 +
[https://tools.ietf.org/html/rfc4525 RFC4525]
 +
 +
'''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 ==
 +
 +
[https://tools.ietf.org/html/rfc4527 RFC4527]
 +
 +
'''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 ==
 +
 +
[http://tools.ietf.org/html/draft-armijo-ldap-treedelete-02 draft-armijo-ldap-treedelete-02]
 +
 +
May be really helpful when deleting tree of objects.
 +
 +
== LDAP Scrolling View Browsing of Search Results  ==
 +
 +
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: [http://www.ietf.org/proceedings/55/I-D/draft-ietf-ldapext-ldapv3-vlv-09.txt draft-ietf-ldapext-ldapv3-vlv-09.txt]
 +
 +
This requires [[#LDAP_Server_Side_Sorting_Control | LDAP Server Side Sorting Control]]:
 +
<pre>
 +
5. Client-Server Interaction
 +
  The Virtual List View control extends a regular LDAP Search operation
 +
  which MUST also include a server-side sorting control [SSS].
 +
  [...]
 +
</pre>
 +
 +
A Perl example how to set a LDAP control: http://search.cpan.org/~marschap/perl-ldap-0.62/
 +
 +
The server side on OpenLDAP is implemented via an overlay: [http://www.openldap.org/software/man.cgi?query=slapo-sssvlv&apropos=0&sektion=0&manpath=OpenLDAP+2.4-Release&format=html slapo-sssvlv] - Server Side Sorting and Virtual List View overlay for slapd.
 +
 +
Example Search with server side sorting (ascending):
 +
<pre>
 +
ldapsearch -H ldaps://ldapm.stoney-cloud.org \
 +
  -E sss=uid:integerOrderingMatch \
 +
  -b "ou=people,dc=stoney-cloud,dc=org" \
 +
  -s one \
 +
  -D "cn=Manager,dc=stoney-cloud,dc=org" \
 +
  -z 5 \
 +
  -W -x -LLL \
 +
  "(&(sstBelongsToResellerUID=4000000)(uid=*400*))" o sn givenName sstIsActive
 +
</pre>
 +
 +
Example Search with server side sorting (descending: check the "-" before the attribute uid):
 +
<pre>
 +
ldapsearch -H ldaps://ldapm.stoney-cloud.org \
 +
  -E sss=-uid:integerOrderingMatch \
 +
  -b "ou=people,dc=stoney-cloud,dc=org" \
 +
  -s one \
 +
  -D "cn=Manager,dc=stoney-cloud,dc=org" \
 +
  -z 5 \
 +
  -W -x -LLL \
 +
  "(&(sstBelongsToResellerUID=4000000)(uid=*400*))" o sn givenName sstIsActive
 +
</pre>
 +
 +
== Building the patched LDAP extension ==
 +
 +
=== Requirements ===
 +
 +
* PHP 5.5 (including development tools like <code>phpize</code>)
 +
* OpenLDAP libraries and headers
 +
* libtool
 +
* gcc
 +
* make
 +
* autoconf
 +
* git
 +
* php-ldap extension '''must not be installed''' already, otherwise it will clash with the patched one
 +
 +
=== Building & installation ===
 +
 +
<source lang='bash'>
 +
git clone -b ldap-controls-PHP-5.5.10 --depth=1 https://github.com/stepping-stone/php-src.git
 +
 +
cd php-src/ext/ldap
 +
 +
phpize
 +
aclocal
 +
libtoolize -f
 +
autoheader
 +
autoconf
 +
 +
./configure
 +
make
 +
 +
sudo make install
 +
</source>
 +
 +
=== Activation ===
 +
 +
Add the following line to the relevant <code>php.ini</code>:
 +
<source lang='ini'>
 +
extension=ldap.so
 +
</source>
  
 
[[Category:Documentation]]
 
[[Category:Documentation]]
 
[[Category:PHP]]
 
[[Category:PHP]]
[[Category:LDAP]]
+
[[Category:OpenLDAP directory]]

Latest revision as of 15:56, 12 June 2014

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.

Examples:

Single control:

ldap_modify($link, $dn, $entry, $control);

Multiple controls:

ldap_modify($link, $dn, $entry, [$control1, $control2]);

LDAP Assertion Control

RFC4528

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

draft-wahl-ldap-session-03

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

RFC2891

The server side on OpenLDAP is implemented via an overlay: slapo-sssvlv - Server Side Sorting and Virtual List View overlay for slapd.

TODO

LDAP Modify-Increment Extension

RFC4525

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

RFC4527

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.

LDAP Scrolling View Browsing of Search Results

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):

This requires LDAP Server Side Sorting Control:

5. Client-Server Interaction 
   The Virtual List View control extends a regular LDAP Search operation 
   which MUST also include a server-side sorting control [SSS].
   [...]

A Perl example how to set a LDAP control: http://search.cpan.org/~marschap/perl-ldap-0.62/

The server side on OpenLDAP is implemented via an overlay: slapo-sssvlv - Server Side Sorting and Virtual List View overlay for slapd.

Example Search with server side sorting (ascending):

ldapsearch -H ldaps://ldapm.stoney-cloud.org \
  -E sss=uid:integerOrderingMatch \
  -b "ou=people,dc=stoney-cloud,dc=org" \
  -s one \
  -D "cn=Manager,dc=stoney-cloud,dc=org" \
  -z 5 \
  -W -x -LLL \
  "(&(sstBelongsToResellerUID=4000000)(uid=*400*))" o sn givenName sstIsActive

Example Search with server side sorting (descending: check the "-" before the attribute uid):

ldapsearch -H ldaps://ldapm.stoney-cloud.org \
  -E sss=-uid:integerOrderingMatch \
  -b "ou=people,dc=stoney-cloud,dc=org" \
  -s one \
  -D "cn=Manager,dc=stoney-cloud,dc=org" \
  -z 5 \
  -W -x -LLL \
  "(&(sstBelongsToResellerUID=4000000)(uid=*400*))" o sn givenName sstIsActive

Building the patched LDAP extension

Requirements

  • PHP 5.5 (including development tools like phpize)
  • OpenLDAP libraries and headers
  • libtool
  • gcc
  • make
  • autoconf
  • git
  • php-ldap extension must not be installed already, otherwise it will clash with the patched one

Building & installation

git clone -b ldap-controls-PHP-5.5.10 --depth=1 https://github.com/stepping-stone/php-src.git
 
cd php-src/ext/ldap
 
phpize
aclocal
libtoolize -f
autoheader
autoconf
 
./configure
make
 
sudo make install

Activation

Add the following line to the relevant php.ini:

extension=ldap.so