From ed564fb0440b06dfb9f7420568593fb3833a0a52 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Tue, 1 Nov 2011 23:12:47 +0100 Subject: [PATCH] TODO ... s4-dsdb: While replicating add isRecycled The attirbute is added: * if recycle-bin is not activated * if isRecycled is valid in the schema * the attribute is not already present --- .../dsdb/samdb/ldb_modules/repl_meta_data.c | 216 +++++++++++++----- 1 file changed, 165 insertions(+), 51 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 76259f7535ba..1e039d9be539 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -3660,36 +3660,42 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar) for (i=0; inum_elements; i++) { struct ldb_message_element *el = &msg->elements[i]; + if (el->num_values == 0) { + DEBUG(4,(__location__ ": Removing attribute %s with num_values==0\n", + el->name)); + memmove(el, el+1, sizeof(*el)*(msg->num_elements - (i+1))); + msg->num_elements--; + i--; + continue; + } + if (ldb_attr_cmp(el->name, "isDeleted") == 0) { struct ldb_val *v = &el->values[0]; - if (strncasecmp((const char*)v->data, "TRUE", 4) == 0 ) { + + if (strncmp((const char*)v->data, "TRUE", 4) == 0 ) { DEBUG(11, ("Found isDeleted on %s while doing replmd_replicated_apply_add\n", ldb_dn_get_linearized(msg->dn))); is_deleted = true; } + continue; } if (ldb_attr_cmp(el->name, "isRecycled") == 0) { struct ldb_val *v = &el->values[0]; - /* Normaly we do not store boolean equals to false, - * but nothing forbids to do so, especially if you undelete an object. + /* + * Normaly we do not store boolean equals to false, but + * nothing forbids to do so, especially if you undelete + * an object. */ - if (strncasecmp((const char*)v->data, "TRUE", 4) == 0 ) { + if (strncmp((const char*)v->data, "TRUE", 4) == 0 ) { is_recycled = true; } + continue; } if (ldb_attr_cmp(el->name, "msDS-LastKnownRDN") == 0) { has_lastknownrdn = true; - } - - if (el->num_values == 0) { - DEBUG(4,(__location__ ": Removing attribute %s with num_values==0\n", - el->name)); - memmove(el, el+1, sizeof(*el)*(msg->num_elements - (i+1))); - msg->num_elements--; - i--; continue; } } @@ -3824,10 +3830,18 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) uint32_t j,ni=0; unsigned int removed_attrs = 0; int ret; - bool is_deleted = false; - bool is_recycled = false; - bool has_lastknownrdn = false; - bool rcbin_enabled = false; + bool found_old_is_deleted = false; + bool found_old_is_recycled = false; + bool found_old_has_lastknownrdn = false; + bool old_is_deleted = false; + bool old_is_recycled = false; + bool old_has_lastknownrdn = false; + bool found_new_is_deleted = false; + bool found_new_is_recycled = false; + bool found_new_has_lastknownrdn = false; + bool new_is_deleted = false; + bool new_is_recycled = false; + bool new_has_lastknownrdn = false; ldb = ldb_module_get_ctx(ar->module); msg = ar->objs->objects[ar->index_current].msg; @@ -3871,6 +3885,58 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) return replmd_replicated_request_werror(ar, WERR_DS_DRA_DB_ERROR); } + for (i=0; i < ar->search_msg->num_elements; i++) { + struct ldb_message_element *el = &ar->search_msg->elements[i]; + + if (ar->isDeleted && strcmp(el->name, ar->isDeleted->lDAPDisplayName) == 0) { + struct ldb_val *v = NULL; + + if (el->num_values == 0) { + continue; + } + + found_old_is_deleted = true; + + v = &el->values[0]; + + if (strncmp((const char*)v->data, "TRUE", 4) == 0) { + old_is_deleted = true; + } + } + + if (ar->isRecycled && strcmp(el->name, ar->isRecycled->lDAPDisplayName) == 0) { + struct ldb_val *v = NULL; + + if (el->num_values == 0) { + continue; + } + + found_old_is_recycled = true; + + v = &el->values[0]; + + if (strncmp((const char*)v->data, "TRUE", 4) == 0) { + old_is_recycled = true; + } + } + + if (ar->lastKnownRDN && strcmp(el->name, ar->lastKnownRDN->lDAPDisplayName) == 0) { + struct ldb_val *v = NULL; + + if (el->num_values == 0) { + continue; + } + + found_old_has_lastknownrdn = true; + + v = &el->values[0]; + + if (strncmp((const char*)v->data, "TRUE", 4) == 0) { + old_has_lastknownrdn = true; + } + } + } + ZERO_STRUCT(nmd); nmd.version = 1; nmd.ctr.ctr1.count = omd.ctr.ctr1.count + rmd->ctr.ctr1.count; @@ -3885,37 +3951,11 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) ni++; } - ret = dsdb_recyclebin_enabled(ar->module, &rcbin_enabled); - if (ret != LDB_SUCCESS) { - return replmd_replicated_request_werror(ar, WERR_DS_DRA_DB_ERROR); - } - ar->seq_num = 0; /* now merge in the new meta data */ for (i=0; i < rmd->ctr.ctr1.count; i++) { bool found = false; - if (ar->isDeleted && rmd->ctr.ctr1.array[i].attid == ar->isDeleted->attributeID_id) { - struct ldb_val *v = &msg->elements[i-removed_attrs].values[0]; - - if (strncasecmp((const char*)v->data, "TRUE", 4) == 0) { - DEBUG(11, ("Found isDeleted on %s while doing replmd_replicated_apply_merge\n", - ldb_dn_get_linearized(msg->dn))); - is_deleted = true; - } - } - - if (ar->isRecycled && rmd->ctr.ctr1.array[i].attid == ar->isRecycled->attributeID_id) { - struct ldb_val *v = &msg->elements[i-removed_attrs].values[0]; - - if (strncasecmp((const char*)v->data, "TRUE", 4) == 0) { - is_recycled = true; - } - } - - if (ar->lastKnownRDN && rmd->ctr.ctr1.array[i].attid == ar->lastKnownRDN->attributeID_id) { - has_lastknownrdn = true; - } for (j=0; j < ni; j++) { bool cmp; @@ -3982,16 +4022,90 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) */ nmd.ctr.ctr1.count = ni; - if (!rcbin_enabled && is_deleted && ar->isRecycled && !is_recycled && !has_lastknownrdn) { + for (i=0; i < msg->num_elements; i++) { + struct ldb_message_element *el = &msg->elements[i]; + + if (ar->isDeleted && strcmp(el->name, ar->isDeleted->lDAPDisplayName) == 0) { + struct ldb_val *v = NULL; + + if (el->num_values == 0) { + continue; + } + + found_new_is_deleted = true; + + v = &el->values[0]; - /* The recycle-bin is not enabled and - * the replicated attributes for the current object has the isDeleted attribute - * but not the isRecycled and no the lastKnownRDN and isDeleted is true. - * It means that we knew the object before and now we are notified - * that is has been deleted but it's not a recycled one. - * If we support the isRecycled attribute we had this attribute. - * As we check for the recycle bin not to be enabled we are insured - * that we will face only simple cases. + if (strncmp((const char*)v->data, "TRUE", 4) == 0) { + new_is_deleted = true; + } + } + + if (ar->isRecycled && strcmp(el->name, ar->isRecycled->lDAPDisplayName) == 0) { + struct ldb_val *v = NULL; + + if (el->num_values == 0) { + continue; + } + + found_new_is_recycled = true; + + v = &el->values[0]; + + if (strncmp((const char*)v->data, "TRUE", 4) == 0) { + new_is_recycled = true; + } + } + + if (ar->lastKnownRDN && strcmp(el->name, ar->lastKnownRDN->lDAPDisplayName) == 0) { + struct ldb_val *v = NULL; + + if (el->num_values == 0) { + continue; + } + + found_new_has_lastknownrdn = true; + + v = &el->values[0]; + + if (strncmp((const char*)v->data, "TRUE", 4) == 0) { + new_has_lastknownrdn = true; + } + } + } + + is_deleted = false; + if (found_old_is_deleted) { + is_deleted = old_is_deleted; + } + if (found_new_is_deleted) { + is_deleted = new_is_deleted; + } + + is_recycled = false; + if (found_old_is_recycled) { + is_recycled = old_is_recycled; + } + if (found_new_is_recycled) { + is_recycled = new_is_recycled; + } + + has_lastknownrdn = false; + if (found_old_has_lastknownrdn) { + has_lastknownrdn = old_has_lastknownrdn; + } + if (found_new_has_lastknownrdn) { + has_lastknownrdn = new_has_lastknownrdn; + } + + if (is_deleted && ar->isRecycled && !is_recycled && !has_lastknownrdn) { + /* + * The replicated attributes for the current object has the + * isDeleted attribute but not the isRecycled and no the + * lastKnownRDN. It means that we knew the object before and + * now we are notified that is has been deleted but it's not a + * recycled one. If we support the isRecycled attribute we had + * this attribute. */ ret = replmd_add_isrecycled(ar, ldb, msg, &nmd); if (ret != LDB_SUCCESS) { -- 2.34.1