Hi everyone,

While playing with Ldap, Squirrelmail and an Active Directory server I ran into a limitation of the PHP ldap_modify function.

In general, an (non-PHP) ldap_modify will allow you to add, replace and delete several attributes for a DN in one single transaction. The PHP Ldap extension is based on OpenLDAP, and this functionality is indeed available in OpenLDAP [1]. It takes a null-terminated array of modify-structs as it's main argument, and one of the entries of these structs is the type of operation that is requested: add, replace or delete.

The PHP ldap_modify works a bit different: it takes a single array of attributes and values. A normal value and attribute combination will replace the current value for the attribute. An empty value for an attribute will cause the attribute to be deleted ('replaced by nothing'). In fact, in PHP the ldap_modify is just an alias for the function ldap_modify_replace.

In almost all cases this is hardly an issue and one can use several seperate ldap_modify statements in sequence. But sometimes, there is a real need for the complete ldap_modify functionality. Imagine for instance the LDIF statement below:

dn: cn=test,cn=users,dc=test,dc=local
changetype: modify
delete: unicodePwd
unicodePwd:: IgBvAGwAZABwAGEAcwBzAHcAbwByAGQAIgA=
-
add: unicodePwd
unicodePwd:: IgBuAGUAdwBwAGEAcwBzAHcAbwByAGQAIgA=
-

With this statement I delete one specific value from a (write-only) attribute, and at the same time add a new one. This happens to be the way to allow a 'mere' user to change their Active Directory password via Ldap [2]. By supplying the old password (as BER encoded wchars), the user shows that they actually know the old password and are permitted to remove it, and set a new one. This, of course, has to be done in a single transaction. And a simple Ldap replace operation won't suffice here, either.

So I'm happily plodding along extending the change_ldappass plugin for Squirrelmail, and one by one I get rid of all the obstacles [3]. Except for this last one: it simply can't be done in PHP. Works from the command-line or perl, but not here.

My suggestion (or request): extending the PHP ldap_modify statement to work similar to most other ldap_modify's out there. Unfortunately, because currently ldap_modify and ldap_modify_replace are simply the same function, doing this properly requires a bit of thought in order not to break existing applications.

Possible solutions:

1. Extend the current ldap_modify to take more arguments, like so:

bool ldap_modify (resource link_identifier, string dn, array add-entry [, array replace-entry, array delete-entry]);

ldap_modify should behave like presently, except when the two extra arrays are present.

2. Go for a clean break and make ldap_modify a seperate function from ldap_modify_replace once again. The data to be modified could be either passed as three single arrays, or an array with an extra 'dimension' to specify the kind of operation to be performed, e.g.
$entry["add"]["attribute"][0] = value
$enrty["add"]["attribute"][1] = value
$entry["delete"]["attribute"][0] = value
$entry["replace"]["attribute"][0] = value
etc.


3. Create a new function, e.g. ldap_modify_complete that is separate from the current ldap_modify and uses one of the syntaxes described above.

What would the 'proper' way be to accomplish this change? Assuming the developpers share my view of it being neccesary?
I've looked at the ldap.c source and actually implementing this doesn't seem too much of a challenge.


Regards, Paul Boven.

[1] http://www.openldap.org/software/man.cgi?query=ldap_modify
[2] http://support.microsoft.com/?kbid=269190
[3] In brief: building PHP with OpenLDAP and SSL support, importing the AD's certificate into OpenSSL, building OpenLDAP with SSL support (and GSSAPI is helpfull too), figuring out the 'encoding' for the passwords.


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Reply via email to