Hi,

As explained in http://bugs.php.net/bug.php?id=45477 it's not possible to change the userPassword attribute using PHP on NDS/AD because these LDAP servers require to perform the deleteAttribute and addAttribute operations in the same LDAP request.

Currently working at Hachette-Livre (Paris, France), we're experiencing this bug and the developer who wrote the app I'm working on was forced to use a BIG hack to perform an password changing request : he calls a Java app who does the LDAP request by using a system(). Admit it, it's ugly.

So i've made a patch which fixes the bug. It creates a ldap_mod_deleteadd function which delete an attribute and adding it in the same LDAP request.

Some parts of the code is imported from pam_ldap.

The syntax is pretty obvious (but not very clean asap, i wanted to know if you like my function before making it as pretty as ldap_mod_replace) :

ldap_mod_deleteadd(resource link, string dn, string attr, string old, string new[, boolean binary = false])

The boolean binary attribute is here for AD which uses an unicode encoded password (and so needs LDAP_MOD_BVALUES).

Currently waiting for your insults :)

Alexis ROBERT
[EMAIL PROTECTED]
Index: ext/ldap/ldap.c
===================================================================
RCS file: /repository/php-src/ext/ldap/ldap.c,v
retrieving revision 1.161.2.3.2.13
diff -r1.161.2.3.2.13 ldap.c
136a137,140
> /* additional functions for changing passwords (NDS/AD), Alexis Robert */
> 	PHP_FE(ldap_mod_deleteadd,							NULL)
> /* end deleteadd */
> 
1537a1542,1596
> /* {{{ proto bool ldap_mod_deleteadd(resource link, string dn, string attr, string old, string new[, boolean binary = false])
>    Delete and add an attribute in the same LDAP request (used for NDS/AD password changing)
>    Alexis Robert <[EMAIL PROTECTED]> (Hachette-Livre)
> */
> PHP_FUNCTION(ldap_mod_deleteadd)
> {
> 	zval *link;
> 	char *dn, *attr, *old, *new;
> 	int dn_len, attr_len, old_len, new_len;
> 	zend_bool binary = 0;
> 	
> 	ldap_linkdata *ld;
> 	char *strvalsold[2];
> 	char *strvalsnew[2];
> 	LDAPMod mod, mod2;
> 	LDAPMod *mods[3];
> 	int rc;
> 	
> 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zssss|b", &link, &dn, &dn_len, &attr, &attr_len, &old, &old_len, &new, &new_len, &binary) == FAILURE) {
> 		WRONG_PARAM_COUNT;
> 	}
> 	
> 	ZEND_FETCH_RESOURCE(ld, ldap_linkdata*, &link, -1, "ldap link", le_link);
> 
> 	// Ported from pam_ldap
> 	strvalsold[0] = old;
> 	strvalsold[1] = NULL;
> 	strvalsnew[0] = new;
> 	strvalsnew[1] = NULL;
> 	
> 	mod.mod_vals.modv_strvals = strvalsold;
> 	mod.mod_type = attr;
> 	mod.mod_op = LDAP_MOD_DELETE;
> 	if (binary)
> 		mod.mod_op = mod.mod_op | LDAP_MOD_BVALUES;
> 	
> 	mod2.mod_vals.modv_strvals = strvalsnew;
> 	mod2.mod_type = attr;
> 	mod2.mod_op = LDAP_MOD_ADD;
> 	if (binary)
> 		mod.mod_op = mod.mod_op | LDAP_MOD_BVALUES;
> 
> 	mods[0] = &mod;
> 	mods[1] = &mod2;
> 	mods[2] = NULL;
> 
> 	if ((rc = ldap_modify_s(ld->link, dn, mods)) != LDAP_SUCCESS) {
> 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "mod_deleteadd: %s", ldap_err2string(rc));
> 		RETURN_FALSE;	
> 	}
> 
> 	RETURN_TRUE;
> }
> /* }}} */
> 
Index: ext/ldap/php_ldap.h
===================================================================
RCS file: /repository/php-src/ext/ldap/php_ldap.h,v
retrieving revision 1.32.2.1.2.3
diff -r1.32.2.1.2.3 php_ldap.h
65a66
> PHP_FUNCTION(ldap_mod_deleteadd);

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

Reply via email to