Hi all.

Following the lines of my initial posting "LDAP controls in response"
<http://news.php.net/php.internals/19927>, I got to the point I
implemented specific API calls for known controls encoding, and generic
and well-known controls decoding from operation results. I also
implemented extended operations API calls for generic as well as
well-known extended operations. I think this area really needs to be
improved, because many controls are now part of the standard track and are
getting used more and more. A clear and broadly useful example in many
PHP applications dealing with LDAP-based authentication is related to
password handling: passwords can be set by the user using the password
modify extended operation (RFC 3062), and the use of the controls defined
in <draft-behera-ldap-password-policy> may enable applications to present
information about authentication failures dictated by password policies
enforced at the DSA side.


currently, in the LDAP extension, controls are set by means of the
ldap_set_option() call that attaches them to the LDAP handle. This
solution is not optimal because in principle it requires a call to set the
controls and one to remove them after the operation completed, otherwise
the same controls would apply to all subsequent operations; this may or
may not be harmful, but in general it indicates a poor design. The
favored LDAP API makes use of the *_ext() operations, which take the
client-side and server-side controls as arguments. I didn't consider
changing this well-established behavior in the PHP LDAP API, although I
think little use of controls in PHP's LDAP extension occurred so far,
given the relatively poor and incomplete API.

ldap_parse_result() now allows parsing of control responses

For well-known controls I chose the naming convention


For example:

ldap_ctrl_paged_results() encode the request
ldap_ctrl_paged_results_resp() extract the cookie and estimated number
of entries yet to be returned

Currently, I have implemented:
- manageDSAit RFC 3296
- pagedResults RFC 2696
- ppolicy (incomplete) <draft-behera-ldap-password-policy>
- No-op <draft-zeilenga-ldap-noop>
- manageDIT (OpenLDAP; undocumented)
- permissiveModify (MS Active Directory)

I plan to add:
- proxyAuthz <draft-weltman-ldapv3-proxy>
- subentries RFC 3672
- vlv RFC 3876
- assert <draft-zeilenga-ldap-assert>
- preread/postread <draft-zeilenga-ldap-readentry>
- sort RFC 2891
- valsort (OpenLDAP; undocumented)
- sync <draft-zeilenga-ldup-sync>
- chaining <draft-sermersheim-ldap-chaining>; expired
- ... (suggestions?)

The encoding calls for well-known controls may operate in two ways: if a
valid LDAP handler is provided, the control is registered using the
LDAP-level ldap_set_option() call; otherwise, if a NULL is passed, an
array containing the OID, the criticality flag if true and the control
value, if any, is returned. This can be assembled with other control
arrays in a PHP array of arrays, and set altogether by means of the
PHP-level ldap_set_option() call.

Extended operations:

an API call is implemented for the generic exop and for each of the
well-known exops; the API call allows the response args to be optional; in
case they are not passed, a handler to the response is returned, so that
it can be queried with the specialized response parsing call to extract
specific data, and with ldap_parse_result() to extract generic data like
controls, referrals, the error code, the error text, and the matched DN.

I note that this behavior may be redundant, since additional response info
could be obtained directly from the LDAP handler by means of separate
ldap_get_option() calls; honestly, I favor the ldap_parse_result() +
ldap_parse_exop() approach, so I chose to give the user this flexibility.

ldap_exop() sends an already encoded exop
ldap_parse_exop() decodes the response of an exop

For well-known exops I chose the naming convention ldap_exop_<name>() and
ldap_parse_exop_<name>(). Here "decoding" means that the relevant data is
extracted from the result; based on each exop specs, an optional OID and
some optional ber-encoded data may be returned.

ldap_parse_exop_whoami() decode the returned identity

ldap_parse_exop_passwd() decode the server generated password

Note that ldap_start_tls() is actually an exop, so it should be renamed
ldap_exop_start_tls(); no ldap_parse_exop_start_tls() is required since
nothing specific can be returned (actually, it could; but users are
discouraged from making any use of it).

There is no need to implement the "cancel" exop, since PHP does not make
use of asynchronous calls.

If anybody is interested in discussing this extension to the LDAP API,
please feel free to jump in. I hope it complies enough with the naming
and coding standards of PHP. I'm in the process of refining and
completing this preliminary patch. I'd like to submit it and get some
feedback before I get to coding all the remaining controls


Ing. Pierangelo Masarati
Responsabile Open Solution

SysNet s.n.c.
Via Dossi, 8 - 27100 Pavia - ITALIA
Office: +39.02.23998309
Mobile: +39.333.4963172
Email: pierangelo.masarati@sys-net.it

Search Discussions

  • Pierangelo Masarati at Dec 10, 2005 at 3:35 pm

    this is the latest version of the LDAP API extension patch; it should be
    preceded by the OpenLDAP C API cleanup patch:


    which should be otherwise harmless, but I strongly recommend it to avoid
    issues, e.g., with 64 bit archs and the likely.

    The main patch is


    and it is accompanied by a test script (please feel free to improve):


    which requires some limited manual intervention, and OpenLDAP 2.3, to
    run. Comments and rationale are available inside each patch; they also
    contain a statement about the applicable license, which of course is the
    PHP license.

    I'd appreciate if you can comment about the proposed enhancements, and
    integrate them at your convenience in PHP repository. If you like, I'd
    be happy to be granted limited CVS write access to maintain that portion
    of software myself, as it appears essentially unmaintained since long
    time ago. As soon as it gets integrated, I'll keep posting further
    development with the missing controls.

    Sincerely, p.

    Ing. Pierangelo Masarati
    Responsabile Open Solution

    SysNet s.n.c.
    Via Dossi, 8 - 27100 Pavia - ITALIA
    Office: +39.02.23998309
    Mobile: +39.333.4963172
    Email: pierangelo.masarati@sys-net.it

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-internals @
postedNov 21, '05 at 1:45p
activeDec 10, '05 at 3:35p

1 user in discussion

Pierangelo Masarati: 2 posts



site design / logo © 2022 Grokbase