--- samba-3.0.0beta3-vanilla/source/lib/smbldap.c Wed Jul 16 15:23:58 2003 +++ samba-3.0.0beta3/source/lib/smbldap.c Tue Aug 26 19:51:05 2003 @@ -428,28 +428,32 @@ ldap_value_free(values); return; } - - /* Regardless of the real operation (add or modify) - we add the new value here. We rely on deleting - the old value, should it exist. */ - - if ((newval != NULL) && (strlen(newval) > 0)) { + + /* 20030826 erik.tews@millenux.com jochen.schmidt@millenux.com + Once we did an add and a del when we had to do a update, + This is known to work on openldap, but will fail on some other + ldap-servers when doing this on a SINGLE-VALUE field. So we now + do a real replace in ldap. Doing a del first and then add is not + an option too, because this will fail on required attributes. */ + + /* If values == NULL we will do a add because there is no old + data on the ldap-server */ + + if ((newval != NULL) && (strlen(newval) > 0) && (values == NULL)) { smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval); } - + + /* If values is NULL, we don't need a replace because there + is no old data on the ldap-server */ + if (values == NULL) { - /* There has been no value before, so don't delete it. - Here's a possible race: We might end up with - duplicate attributes */ return; } + + /* Now we do a real replace on the ldap-server and no add del + combination */ - /* By deleting exactly the value we found in the entry this - should be race-free in the sense that the LDAP-Server will - deny the complete operation if somebody changed the - attribute behind our back. */ - - smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, values[0]); + smbldap_set_mod(mods, LDAP_MOD_REPLACE, attribute, newval); ldap_value_free(values); }