for (i=0; i<msg->num_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;
}
}
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;
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;
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;
*/
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) {