TODO ... s4-dsdb: While replicating add isRecycled
authorMatthieu Patou <mat@matws.net>
Tue, 1 Nov 2011 22:12:47 +0000 (23:12 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 29 Nov 2011 13:44:06 +0000 (14:44 +0100)
The attirbute is added:
 * if recycle-bin is not activated
 * if isRecycled is valid in the schema
 * the attribute is not already present

source4/dsdb/samdb/ldb_modules/repl_meta_data.c

index 76259f7535ba3189f4f30f00296f07c59478f1d9..1e039d9be539dbbbb16e52557c14df2a2aee752b 100644 (file)
@@ -3660,36 +3660,42 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
        for (i=0; i<msg->num_elements; i++) {
                struct ldb_message_element *el = &msg->elements[i];
 
        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 (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;
                        }
                                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];
 
                }
 
                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;
                        }
                                is_recycled = true;
                        }
+                       continue;
                }
 
                if (ldb_attr_cmp(el->name, "msDS-LastKnownRDN") == 0) {
                        has_lastknownrdn = true;
                }
 
                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;
                }
        }
                        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;
        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;
 
        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);
        }
 
                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;
        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++;
        }
 
                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;
 
        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;
 
                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;
 
         */
        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) {
                 */
                ret = replmd_add_isrecycled(ar, ldb, msg, &nmd);
                if (ret != LDB_SUCCESS) {