r20580: pass the DSDB_CONTROL_REPLICATED_OBJECT_OID with the ldb_add request
authorStefan Metzmacher <metze@samba.org>
Sat, 6 Jan 2007 01:13:59 +0000 (01:13 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:37:06 +0000 (14:37 -0500)
when applying replicated objects.

the samldb module ignores such requests now...
and the repl_meta_data module has different functions
for the replicated and originating cases...

metze
(This used to be commit a4d5e0126cfd6135ab829f4984269e265a868a28)

source4/dsdb/samdb/ldb_modules/repl_meta_data.c
source4/dsdb/samdb/ldb_modules/samldb.c
source4/dsdb/samdb/samdb.h
source4/torture/libnet/libnet_BecomeDC.c

index d9ad9d6e51a97dfaddb7fb409ad3b1a1800d9f58..171af52eda843f2ce7a6912021d0044d061b0ae7 100644 (file)
  */
 
 #include "includes.h"
-#include "ldb/include/includes.h"
+#include "lib/ldb/include/ldb.h"
+#include "lib/ldb/include/ldb_errors.h"
+#include "lib/ldb/include/ldb_private.h"
 #include "librpc/gen_ndr/ndr_misc.h"
+#include "dsdb/samdb/samdb.h"
 
 static struct ldb_message_element *replmd_find_attribute(const struct ldb_message *msg, const char *name)
 {
@@ -108,8 +111,24 @@ static int add_uint64_element(struct ldb_message *msg, const char *attr, uint64_
        return 0;
 }
 
-/* add_record: add objectGUID attribute */
-static int replmd_add(struct ldb_module *module, struct ldb_request *req)
+static int replmd_add_replicated(struct ldb_module *module, struct ldb_request *req, struct ldb_control *ctrl)
+{
+       struct ldb_control **saved_ctrls;
+       int ret;
+
+       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "replmd_add_replicated\n");
+
+       if (!save_controls(ctrl, req, &saved_ctrls)) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       ret = ldb_next_request(module, req);
+       req->controls = saved_ctrls;
+
+       return ret;
+}
+
+static int replmd_add_originating(struct ldb_module *module, struct ldb_request *req)
 {
        struct ldb_request *down_req;
        struct ldb_message_element *attribute;
@@ -121,12 +140,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
        int ret;
        time_t t = time(NULL);
 
-       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "replmd_add_record\n");
-
-       /* do not manipulate our control entries */
-       if (ldb_dn_is_special(req->op.add.message->dn)) {
-               return ldb_next_request(module, req);
-       }
+       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "replmd_add_originating\n");
 
        if ((attribute = replmd_find_attribute(req->op.add.message, "objectGUID")) != NULL ) {
                return ldb_next_request(module, req);
@@ -192,8 +206,42 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
        return ret;
 }
 
-/* modify_record: update timestamps */
-static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
+static int replmd_add(struct ldb_module *module, struct ldb_request *req)
+{
+       struct ldb_control *ctrl;
+
+       /* do not manipulate our control entries */
+       if (ldb_dn_is_special(req->op.add.message->dn)) {
+               return ldb_next_request(module, req);
+       }
+
+       ctrl = get_control_from_list(req->controls, DSDB_CONTROL_REPLICATED_OBJECT_OID);
+       if (ctrl) {
+               /* handle replicated objects different */
+               return replmd_add_replicated(module, req, ctrl);
+       }
+
+       return replmd_add_originating(module, req);
+}
+
+static int replmd_modify_replicated(struct ldb_module *module, struct ldb_request *req, struct ldb_control *ctrl)
+{
+       struct ldb_control **saved_ctrls;
+       int ret;
+
+       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "replmd_modify_replicated\n");
+
+       if (!save_controls(ctrl, req, &saved_ctrls)) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       ret = ldb_next_request(module, req);
+       req->controls = saved_ctrls;
+
+       return ret;
+}
+
+static int replmd_modify_originating(struct ldb_module *module, struct ldb_request *req)
 {
        struct ldb_request *down_req;
        struct ldb_message *msg;
@@ -201,12 +249,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
        time_t t = time(NULL);
        uint64_t seq_num;
 
-       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "replmd_modify\n");
-
-       /* do not manipulate our control entries */
-       if (ldb_dn_is_special(req->op.add.message->dn)) {
-               return ldb_next_request(module, req);
-       }
+       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "replmd_modify_originating\n");
 
        down_req = talloc(req, struct ldb_request);
        if (down_req == NULL) {
@@ -250,6 +293,24 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
        return ret;
 }
 
+static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
+{
+       struct ldb_control *ctrl;
+
+       /* do not manipulate our control entries */
+       if (ldb_dn_is_special(req->op.mod.message->dn)) {
+               return ldb_next_request(module, req);
+       }
+
+       ctrl = get_control_from_list(req->controls, DSDB_CONTROL_REPLICATED_OBJECT_OID);
+       if (ctrl) {
+               /* handle replicated objects different */
+               return replmd_modify_replicated(module, req, ctrl);
+       }
+
+       return replmd_modify_originating(module, req);
+}
+
 static const struct ldb_module_ops replmd_ops = {
        .name          = "repl_meta_data",
        .add           = replmd_add,
index 1c1ff0ea6e2ce5cc0327cda69f6855d0243d8968..07d77ee3fcd85e0236ddbbb642042b615e92dd40 100644 (file)
@@ -680,6 +680,11 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
                return ldb_next_request(module, req);
        }
 
+       if (get_control_from_list(req->controls, DSDB_CONTROL_REPLICATED_OBJECT_OID)) {
+               /* if it's a replicated object we have nothing to do */
+               return ldb_next_request(module, req);
+       }
+
        /* is user or computer? */
        if ((samdb_find_attribute(module->ldb, msg, "objectclass", "user") != NULL) ||
            (samdb_find_attribute(module->ldb, msg, "objectclass", "computer") != NULL)) {
index 8ff44f7554b8f55688e0f39b6a55389c67e8522c..7d16b2d380da42bc432472c8ba5ee562f10506d6 100644 (file)
@@ -29,6 +29,11 @@ struct drsuapi_DsReplicaObject;
 struct drsuapi_DsReplicaOIDMapping_Ctr;
 struct drsuapi_DsReplicaAttribute;
 
+#define DSDB_CONTROL_REPLICATED_OBJECT_OID "1.3.6.1.4.1.7165.4.3.1"
+struct dsdb_control_replicated_object {
+       uint8_t __dummy;
+};
+
 #include "librpc/gen_ndr/security.h"
 #include "lib/ldb/include/ldb.h"
 #include "librpc/gen_ndr/samr.h"
index 0d4114c170992caffb49e9e0ce94afcb672c39d0..f4f232d19b9d57b5b67cf009c5a325eb44c95870 100644 (file)
@@ -182,16 +182,16 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
                "                                \"server_sort\",\n"
                "                                \"extended_dn\",\n"
                "                                \"asq\",\n"
-               "                                //\"samldb\",should only handle originating changes...\n"
+               "                                \"samldb\",\n"
                "                                \"password_hash\",\n"
                "                                \"operational\",\n"
                "                                \"objectclass\",\n"
                "                                \"rdn_name\",\n"
                "                                \"partition\");\n"
                "subobj.MODULES_LIST = join(\",\", modules_list);\n"
-               "subobj.DOMAINDN_MOD = \"objectguid\";\n"
-               "subobj.CONFIGDN_MOD = \"objectguid\";\n"
-               "subobj.SCHEMADN_MOD = \"objectguid\";\n"
+               "subobj.DOMAINDN_MOD = \"repl_meta_data\";\n"
+               "subobj.CONFIGDN_MOD = \"repl_meta_data\";\n"
+               "subobj.SCHEMADN_MOD = \"repl_meta_data\";\n"
                "\n"
                "var paths = provision_default_paths(subobj);\n"
                "paths.samdb = \"%s\";\n"
@@ -265,6 +265,9 @@ static WERROR test_object_to_ldb(struct test_become_dc_state *s,
        struct drsuapi_DsReplicaMetaData *name_d;
        struct replPropertyMetaData1 *rdn_m;
        struct drsuapi_DsReplicaObjMetaData *rdn_mc;
+       struct ldb_request *req;
+       struct ldb_control **ctrls;
+       struct dsdb_control_replicated_object *ctrl;
        int ret;
 
        if (!obj->object.identifier) {
@@ -424,7 +427,37 @@ static WERROR test_object_to_ldb(struct test_become_dc_state *s,
                NDR_PRINT_DEBUG(drsuapi_DsReplicaObjMetaDataCtr, &mdc);
        }
 
-       ret = ldb_add(s->ldb, msg);
+       /*
+        * apply the record to the ldb
+        * using an ldb_control so indicate
+        * that it's a replicated change
+        */
+       ret = ldb_msg_sanity_check(s->ldb, msg);
+       if (ret != LDB_SUCCESS) {
+               return WERR_FOOBAR;
+       }
+       ctrls = talloc_array(msg, struct ldb_control *, 2);
+       W_ERROR_HAVE_NO_MEMORY(ctrls);
+       ctrls[0] = talloc(ctrls, struct ldb_control);
+       W_ERROR_HAVE_NO_MEMORY(ctrls[0]);
+       ctrls[1] = NULL;
+
+       ctrl = talloc(ctrls, struct dsdb_control_replicated_object);
+       W_ERROR_HAVE_NO_MEMORY(ctrl);
+       ctrls[0]->oid           = DSDB_CONTROL_REPLICATED_OBJECT_OID;
+       ctrls[0]->critical      = True;
+       ctrls[0]->data          = ctrl;
+
+       ret = ldb_build_add_req(&req, s->ldb, msg, msg, ctrls, NULL, NULL);
+       if (ret != LDB_SUCCESS) {
+               return WERR_FOOBAR;
+       }
+       ldb_set_timeout(s->ldb, req, 0); /* use default timeout */
+       ret = ldb_request(s->ldb, req);
+       if (ret == LDB_SUCCESS) {
+               ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+       }
+       talloc_free(req);
        if (ret != LDB_SUCCESS) {
                if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
                        DEBUG(0,("record exists (ignored): %s: %d\n",