s4:dsdb/repl_meta_data: call dsdb_module_schedule_sd_propagation() for replicated...
authorStefan Metzmacher <metze@samba.org>
Fri, 23 Nov 2012 16:10:38 +0000 (17:10 +0100)
committerStefan Metzmacher <metze@samba.org>
Sun, 25 Nov 2012 22:30:11 +0000 (23:30 +0100)
We only do so if the replicated object is not deleted.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
source4/dsdb/samdb/ldb_modules/repl_meta_data.c

index 7e1993cada496940872fbfae885db441ca5b0275..4dcb8d505bebb72122524de55e93168d05353979 100644 (file)
@@ -3654,6 +3654,7 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
        struct ldb_val md_value;
        unsigned int i;
        int ret;
+       bool remote_isDeleted = false;
 
        /*
         * TODO: check if the parent object exist
@@ -3707,6 +3708,9 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
                }
        }
 
+       remote_isDeleted = ldb_msg_find_attr_as_bool(msg,
+                                                    "isDeleted", false);
+
        /*
         * the meta data array is already sorted by the caller
         */
@@ -3726,6 +3730,14 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
 
        replmd_ldb_message_sort(msg, ar->schema);
 
+       if (!remote_isDeleted) {
+               ret = dsdb_module_schedule_sd_propagation(ar->module,
+                                                         msg->dn, true);
+               if (ret != LDB_SUCCESS) {
+                       return replmd_replicated_request_error(ar, ret);
+               }
+       }
+
        if (DEBUGLVL(4)) {
                char *s = ldb_ldif_message_string(ldb, ar, LDB_CHANGETYPE_ADD, msg);
                DEBUG(4, ("DRS replication add message:\n%s\n", s));
@@ -4012,6 +4024,11 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
        unsigned int removed_attrs = 0;
        int ret;
        int (*callback)(struct ldb_request *req, struct ldb_reply *ares) = replmd_op_callback;
+       bool isDeleted = false;
+       bool local_isDeleted = false;
+       bool remote_isDeleted = false;
+       bool take_remote_isDeleted = false;
+       bool sd_updated = false;
 
        ldb = ldb_module_get_ctx(ar->module);
        msg = ar->objs->objects[ar->index_current].msg;
@@ -4035,6 +4052,11 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
                }
        }
 
+       local_isDeleted = ldb_msg_find_attr_as_bool(ar->search_msg,
+                                                   "isDeleted", false);
+       remote_isDeleted = ldb_msg_find_attr_as_bool(msg,
+                                                    "isDeleted", false);
+
        /* handle renames that come in over DRS */
        ret = replmd_replicated_handle_rename(ar, msg, rmd, &omd, ar->req);
 
@@ -4132,6 +4154,16 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
                                        }
                                }
                                nmd.ctr.ctr1.array[j].local_usn = ar->seq_num;
+                               switch (nmd.ctr.ctr1.array[j].attid) {
+                               case DRSUAPI_ATTID_ntSecurityDescriptor:
+                                       sd_updated = true;
+                                       break;
+                               case DRSUAPI_ATTID_isDeleted:
+                                       take_remote_isDeleted = true;
+                                       break;
+                               default:
+                                       break;
+                               }
                                found = true;
                                break;
                        }
@@ -4161,6 +4193,16 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
                        }
                }
                nmd.ctr.ctr1.array[ni].local_usn = ar->seq_num;
+               switch (nmd.ctr.ctr1.array[ni].attid) {
+               case DRSUAPI_ATTID_ntSecurityDescriptor:
+                       sd_updated = true;
+                       break;
+               case DRSUAPI_ATTID_isDeleted:
+                       take_remote_isDeleted = true;
+                       break;
+               default:
+                       break;
+               }
                ni++;
        }
 
@@ -4195,6 +4237,20 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
        ldb_debug(ldb, LDB_DEBUG_TRACE, "replmd_replicated_apply_merge[%u]: replace %u attributes\n",
                  ar->index_current, msg->num_elements);
 
+       if (take_remote_isDeleted) {
+               isDeleted = remote_isDeleted;
+       } else {
+               isDeleted = local_isDeleted;
+       }
+
+       if (sd_updated && !isDeleted) {
+               ret = dsdb_module_schedule_sd_propagation(ar->module,
+                                                         msg->dn, true);
+               if (ret != LDB_SUCCESS) {
+                       return ldb_operr(ldb);
+               }
+       }
+
        /* create the meta data value */
        ndr_err = ndr_push_struct_blob(&nmd_value, msg, &nmd,
                                       (ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob);