Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:14369 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 24177 invoked by uid 1010); 12 Jan 2005 22:55:31 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 24065 invoked from network); 12 Jan 2005 22:55:30 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 12 Jan 2005 22:55:30 -0000 X-Host-Fingerprint: 213.46.243.21 amsfep14-int.chello.nl Solaris 8 (1) Received: from ([213.46.243.21:21385] helo=amsfep14-int.chello.nl) by pb1.pair.com (ecelerity HEAD (r4059)) with SMTP id 52/DC-40505-0EAA5E14 for ; Wed, 12 Jan 2005 17:55:28 -0500 Received: from h119199.upc-h.chello.nl ([62.194.119.199]) by amsfep14-int.chello.nl (InterMail vM.6.01.03.04 201-2131-111-106-20040729) with ESMTP id <20050112225524.TIVX1537.amsfep14-int.chello.nl@h119199.upc-h.chello.nl> for ; Wed, 12 Jan 2005 23:55:24 +0100 Received: from [127.0.0.1] (localhost [127.0.0.1]) by h119199.upc-h.chello.nl (8.12.10+Sun/8.12.10) with ESMTP id j0CMtCdo018869 for ; Wed, 12 Jan 2005 23:55:13 +0100 (CET) Message-ID: <41E5AAD0.6020705@chello.nl> Date: Wed, 12 Jan 2005 23:55:12 +0100 User-Agent: Mozilla Thunderbird 0.9 (X11/20041105) X-Accept-Language: en-us, en MIME-Version: 1.0 To: internals@lists.php.net Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: (-4.9) BAYES_00 X-Scanned-By: MIMEDefang 2.44 Subject: Extending the ldap_modify functionality (resend) From: p.boven@chello.nl (Paul Boven) Hi everyone, (I sent this question in august last year, but had no replies. Trying once again as I'm running into the same problem). 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. But I feel having a 'complete' ldap_modify in PHP is something worth having, not just in the one case illustrated above. 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.