The Samba-Bugzilla – Attachment 427 Details for
Bug 762
ldap Naming violation when deleting user with pdbedit
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
LDAP Modify Naming Violation Fix
sambaLDAPModify.patch3 (text/plain), 8.22 KB, created by
Yohann Fourteau
on 2004-03-05 06:29:21 UTC
(
hide
)
Description:
LDAP Modify Naming Violation Fix
Filename:
MIME Type:
Creator:
Yohann Fourteau
Created:
2004-03-05 06:29:21 UTC
Size:
8.22 KB
patch
obsolete
>--- a/smbldap.c Thu Feb 19 15:52:00 2004 >+++ b/smbldap.c Wed Feb 25 17:28:43 2004 >@@ -971,21 +971,284 @@ > int attempts = 0; > char *utf8_dn; > >- SMB_ASSERT(ldap_state); >+ BOOL do_rename = False; >+ BOOL naming_deleted = False; >+ BOOL naming_more_value = False; >+ int i,j,k; >+ char *rdn_attribut; >+ char *first_rdn; >+ char *new_rdn_value; >+ char *new_rdn; >+ char *rdn_value; >+ TALLOC_CTX *t_ctx; >+ LDAPDN *parts; >+ LDAPDN *part; >+ >+ /* >+ * The naming attribute is the attribute used in the first RDN >+ * of the DN (first from the left). >+ * Ex : uid=foo,ou=people,dc=boo,dc=com => Naming attribut is "uid" >+ * >+ * In fact, it's a little bit more complex with multiple naming >+ * attributes : >+ * Ex : uid=foo+cn=bar,ou=people,dc=boo,dc=com >+ * (Not supported by that patch) >+ * >+ * The attrs array contains the list of the modification. >+ * If the naming attribute is modified or deleted, the DN won't be >+ * correct. >+ * >+ * To apply a modification on the naming attribute, you must modify >+ * the DN with the ldap_modrdn2_s function. That function change the >+ * naming attribute both in the DN and in the entry. >+ * >+ * The problem is that we must extract and remove the modification >+ * of the naming attribute from the attrs array. >+ * >+ * */ >+ >+ t_ctx=talloc_init("smbldap_modify"); > >- DEBUG(5,("smbldap_modify: dn => [%s]\n", dn )); > > if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) { >+ talloc_destroy(t_ctx); >+ return LDAP_NO_MEMORY; >+ } >+ >+ /* >+ * All strings are now in UTF8 >+ * */ >+ >+ /* >+ * Extraction of the naming attribute from the DN >+ * rdn : array of rdn extrated from the DN >+ * rdn_attribut : naming attribute (string) >+ * utf8_rdn_value : value of the naming attribute >+ * in the DN (UTF8 string) >+ * >+ * */ >+ >+ /* >+ * ldap_explode_dn is deprecated in favor of >+ * ldap_dn2str() and ldap_str_2dn. >+ * >+ * The flag LDAP_DN_PRETTY causes UTF-8 to be represented. >+ * >+ * */ >+ >+ /* We build the first RDN in firstrdn */ >+ ldap_str2dn(dn, &parts, LDAP_DN_FORMAT_LDAP); >+ >+ /* We can use >+ * ldap_rdn2str(parts[0][0], &first_rdn,LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY ); >+ * or */ >+ part=talloc(t_ctx,sizeof(char *) * 2); >+ if (!part) { >+ talloc_destroy(t_ctx); >+ SAFE_FREE(utf8_dn); > return LDAP_NO_MEMORY; > } >+ part[0]=talloc(t_ctx,sizeof(char *) * 2); >+ if (!part[0]) { >+ talloc_destroy(t_ctx); >+ SAFE_FREE(utf8_dn); >+ return LDAP_NO_MEMORY; >+ } >+ part[0][0]=parts[0][0]; >+ part[0][1]=NULL; >+ part[1]=NULL; >+ ldap_dn2str(part, &first_rdn,LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY ); >+ /* but ldap_rdn2str is not documented */ >+ >+ /* we take the rdn value */ >+ rdn_value=talloc_strdup(t_ctx, strchr(first_rdn,'=')+1); >+ >+ if (!rdn_value) { >+ talloc_destroy(t_ctx); >+ SAFE_FREE(utf8_dn); >+ return LDAP_NO_MEMORY; >+ } >+ >+ >+ /* we take the rdn attribute */ >+ first_rdn[strlen(first_rdn)-strlen(rdn_value)-1]='\0'; >+ rdn_attribut=talloc_strdup(t_ctx, first_rdn); >+ if (!rdn_attribut) { >+ SAFE_FREE(utf8_dn); >+ talloc_destroy(t_ctx); >+ return LDAP_NO_MEMORY; >+ } >+ >+ /* we release the memory */ >+ SAFE_FREE(first_rdn); >+ ldap_dnfree(parts); >+ >+ DEBUG(5,("smbldap_modify: dn => [%s]\n", dn )); >+ >+ /* >+ * We have to walk into the attrs array to find if the naming >+ * attributes is changed or deleted >+ * >+ * */ >+ for (i = 0; attrs[i] != NULL; i++) { >+ /* >+ * If mod_type is the naming attribute >+ * Three cases : the operation is DELETE or ADD or REPLACE >+ * >+ * Note: Samba doesn't use REPLACE operation >+ * for LDAP manipulation. Instead it uses two >+ * operations : DELETE and ADD >+ * >+ * */ >+ if ( ( attrs[i]->mod_op == LDAP_MOD_DELETE ) >+ && strequal(attrs[i]->mod_type,rdn_attribut) ) { >+ /* >+ * In the DELETE operation. >+ * If we have more than one value in the entry for >+ * the naming attribute, the DELETE operation can >+ * delete other values than the one uses in the DN. >+ * >+ * So we have to walk into the mod_values arrray. >+ * >+ * The values are in UTF8 (see smbldap_set_mod()) >+ * So a simple strcmp is good. >+ * >+ * */ >+ for (j=0;attrs[i]->mod_values[j] != NULL; j++) { >+ if (!strcmp(attrs[i]->mod_values[j], >+ rdn_value)) { >+ /* The modification deletes >+ * the naming attribute. >+ * We have to remove that value >+ * from the mod_values array. >+ * */ >+ 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 { >+ /* The modification deletes more than >+ * the naming attribute value */ >+ naming_more_value = True; >+ } >+ } >+ >+ /* >+ * If we the DELETE operation delete only >+ * the good value of the naming attribute, >+ * we can remove that modification >+ * from the attrs array. >+ * >+ * */ >+ 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 we have removed the DELETE modification, we can be at the last item from attrs >+ * array. >+ * >+ * */ >+ 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) ) ) { >+ /* >+ * In the ADD or REPLACE operation. >+ * If we add a naming attribute after >+ * to have deleted it or if we replace >+ * the naming attribute, we have to build >+ * the new RDN of the entry. >+ * >+ * We use the first value added to build the RDN. >+ * */ >+ do_rename = True; >+ new_rdn_value = talloc_strdup(t_ctx, >+ attrs[i]->mod_values[0]); >+ if (!new_rdn_value) { >+ talloc_destroy(t_ctx); >+ SAFE_FREE(utf8_dn); >+ return LDAP_NO_MEMORY; >+ } >+ >+ /* >+ * We build the new RDN in UTF8 >+ * */ >+ new_rdn = talloc_asprintf(t_ctx, >+ "%s=%s",rdn_attribut,new_rdn_value); >+ if (!new_rdn) { >+ talloc_destroy(t_ctx); >+ SAFE_FREE(utf8_dn); >+ return LDAP_NO_MEMORY; >+ } >+ >+ DEBUG(5,("smbldap_modify: newdn => [%s]\n", new_rdn )); >+ /* >+ * If it's an ADD operation, we have to remove >+ * the first value from the operation >+ * (or the complete operation if there is >+ * only one value added). >+ * */ >+ 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]; >+ } >+ } >+ /* We have our new RDN, >+ * we can go out of the attrs array */ >+ continue; >+ } >+ } >+ >+ >+ SMB_ASSERT(ldap_state); > > while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) { > > if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) > continue; >+ >+ /* >+ * We apply modifications on the entry. >+ * >+ * */ >+ if ((rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs)) != LDAP_SUCCESS) >+ continue; >+ >+ /* >+ * We have detected a modification of the naming attribute >+ * and we have a new RDN. >+ * */ >+ if (do_rename) >+ rc = ldap_modrdn2_s(ldap_state->ldap_struct, utf8_dn, new_rdn, 1); > >- 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)); >@@ -995,6 +1258,7 @@ > ldap_state->last_use = time(NULL); > > SAFE_FREE(utf8_dn); >+ talloc_destroy(t_ctx); > return rc; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 762
:
281
|
410
| 427 |
640
|
641
|
642
|
643