--- a/smbldap.c Thu Feb 19 15:52:00 2004 +++ b/smbldap.c Thu Feb 19 15:52:13 2004 @@ -970,22 +970,166 @@ int rc = LDAP_SERVER_DOWN; int attempts = 0; char *utf8_dn; + /* Yohann */ + BOOL do_rename = False; + BOOL naming_deleted = False; + BOOL naming_more_value = False; + int i,j,k,new_rdn_len,new_dn_len; + char *rdn_attribut; + char **rdn; + char *new_rdn; + char *new_dn; + char *utf8_new_rdn; + char *utf8_new_dn; + char *new_rdn_value; + char *rdn_value; + + rdn = ldap_explode_dn(dn,0); + rdn_attribut = strdup(strtok(rdn[0],"=")); + rdn_value = strdup(strtok(NULL,",")); + DEBUG(5,("smbldap_modify: dn => [%s]\n", dn )); + + for (i = 0; attrs[i] != NULL; i++) { + if ( ( attrs[i]->mod_op == LDAP_MOD_DELETE ) + && strequal(attrs[i]->mod_type,rdn_attribut) ) { + for (j=0;attrs[i]->mod_values[j] != NULL; j++) { + if (strequal(attrs[i]->mod_values[j],rdn_value)) { + SAFE_FREE(attrs[i]->mod_values[j]); + attrs[i]->mod_values[j]=attrs[i]->mod_values[j+1]; + for (k=j+1;attrs[i]->mod_values[k] != NULL; k++) + attrs[i]->mod_values[k]=attrs[i]->mod_values[k+1]; + naming_deleted = True; + } else { + naming_more_value = True; + } + } + + if (!naming_more_value) { + SAFE_FREE(attrs[i]->mod_type); + for (j=0;attrs[i]->mod_values[j] != NULL; j++) + SAFE_FREE(attrs[i]->mod_values[j]); + SAFE_FREE(attrs[i]->mod_values); + SAFE_FREE(attrs[i]); + attrs[i]=attrs[i+1]; + for (j=i+1; attrs[j] != NULL; j++) { + attrs[j]=attrs[j+1]; + } + } + } + + if ( ( attrs[i] != NULL ) + && ( ( attrs[i]->mod_op == LDAP_MOD_ADD && naming_deleted ) || attrs[i]->mod_op == LDAP_MOD_REPLACE ) + && ( attrs[i]->mod_values[0] != NULL) + && ( strequal(attrs[i]->mod_type,rdn_attribut) ) ) { + do_rename = True; + new_rdn_value = strdup(attrs[i]->mod_values[0]); + if (!new_rdn_value) { + SAFE_FREE(rdn_attribut); + return LDAP_NO_MEMORY; + } + + new_rdn_len= strlen(rdn_attribut) + strlen(new_rdn_value) + 2; + new_rdn = malloc( new_rdn_len ); + if (!new_rdn) { + SAFE_FREE(rdn_attribut); + SAFE_FREE(new_rdn_value); + return LDAP_NO_MEMORY; + } + + new_rdn[0] = '\0'; + safe_strcat( new_rdn, rdn_attribut, new_rdn_len); + safe_strcat( new_rdn, "=" , new_rdn_len); + safe_strcat( new_rdn, new_rdn_value, new_rdn_len); + if (push_utf8_allocate(&utf8_new_rdn, new_rdn) == (size_t)-1) { + SAFE_FREE(rdn_attribut); + SAFE_FREE(new_rdn_value); + SAFE_FREE(new_rdn); + return LDAP_NO_MEMORY; + } + + new_dn_len=strlen(new_rdn); + for(j=1; rdn[j] != NULL; j++) { + new_dn_len += strlen(rdn[j]) + 1; + } + new_dn=malloc(new_dn_len + 1); + if (!new_dn) { + SAFE_FREE(rdn_attribut); + SAFE_FREE(new_rdn_value); + SAFE_FREE(new_rdn); + SAFE_FREE(utf8_new_rdn); + return LDAP_NO_MEMORY; + } + new_dn[0]='\0'; + safe_strcat(new_dn,new_rdn,new_dn_len); + for(j=1; rdn[j] != NULL; j++) { + safe_strcat(new_dn,",",new_dn_len); + safe_strcat(new_dn,rdn[j],new_dn_len); + } + + if (push_utf8_allocate(&utf8_new_dn, new_dn) == (size_t)-1) { + SAFE_FREE(rdn_attribut); + SAFE_FREE(new_rdn_value); + SAFE_FREE(new_rdn); + SAFE_FREE(new_dn); + SAFE_FREE(utf8_new_rdn); + return LDAP_NO_MEMORY; + } + + DEBUG(5,("smbldap_modify: newdn => [%s]\n", new_rdn )); + SAFE_FREE(new_rdn_value); + SAFE_FREE(new_rdn); + SAFE_FREE(new_dn); + if (attrs[i]->mod_op != LDAP_MOD_REPLACE) { + if (attrs[i]->mod_values[1] == NULL) { + SAFE_FREE(attrs[i]->mod_type); + for (j=0;attrs[i]->mod_values[j] != NULL; j++) + SAFE_FREE(attrs[i]->mod_values[j]); + SAFE_FREE(attrs[i]->mod_values); + SAFE_FREE(attrs[i]); + attrs[i]=attrs[i+1]; + for (j=i+1; attrs[j] != NULL; j++) { + attrs[j]=attrs[j+1]; + } + } else { + SAFE_FREE(attrs[i]->mod_values[0]); + attrs[i]->mod_values[0]=attrs[i]->mod_values[1]; + for (j=1;attrs[i]->mod_values[j] != NULL; j++) + attrs[i]->mod_values[j]=attrs[i]->mod_values[j+1]; + } + } + continue; + } + } + SAFE_FREE(rdn_attribut); + SAFE_FREE(rdn_value); + ldap_value_free(rdn); + SMB_ASSERT(ldap_state); DEBUG(5,("smbldap_modify: dn => [%s]\n", dn )); if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) { + SAFE_FREE(utf8_new_rdn); + SAFE_FREE(utf8_new_dn); return LDAP_NO_MEMORY; } + while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) { if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) continue; - rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs); + if (do_rename && (rc = ldap_modrdn2_s(ldap_state->ldap_struct, utf8_dn, utf8_new_rdn, 1)) != LDAP_SUCCESS ) + continue; + + if (do_rename) + rc = ldap_modify_s(ldap_state->ldap_struct, utf8_new_dn, attrs); + else + rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs); } + if (rc == LDAP_SERVER_DOWN) { DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO)); @@ -994,6 +1138,11 @@ ldap_state->last_use = time(NULL); + + if (do_rename) { + SAFE_FREE(utf8_new_rdn); + SAFE_FREE(utf8_new_dn); + } SAFE_FREE(utf8_dn); return rc; }