--- smbldap.c.orig 2003-09-11 20:05:44.000000000 +0200 +++ smbldap.c 2003-09-19 13:47:45.000000000 +0200 @@ -431,27 +431,34 @@ 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) && (!existed)) { 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 (!existed) { - /* 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, oldval); + + smbldap_set_mod(mods, LDAP_MOD_REPLACE, attribute, newval); } /**********************************************************************