From 44ee653042b5c77d62c3bc9e7ce4745e600ed39b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Jun 2017 13:12:32 +1200 Subject: [PATCH] dsdb: Ensure replication of renames works in schema partition Signed-off-by: Andrew Bartlett --- source4/dsdb/common/util.c | 13 ++++++++++ source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 9 ++++++- source4/dsdb/samdb/ldb_modules/util.h | 1 + source4/torture/drs/python/repl_schema.py | 32 +++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 8f74b45a84e..0776c7085da 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -48,6 +48,12 @@ #include "../lib/util/util_runcmd.h" #include "lib/util/access.h" +/* + * This included to allow us to handle DSDB_FLAG_REPLICATED_UPDATE in + * dsdb_request_add_controls() + */ +#include "dsdb/samdb/ldb_modules/util.h" + /* search the sam for the specified attributes in a specific domain, filter on objectSid being in domain_sid. @@ -4309,6 +4315,13 @@ int dsdb_request_add_controls(struct ldb_request *req, uint32_t dsdb_flags) } } + if (dsdb_flags & DSDB_FLAG_REPLICATED_UPDATE) { + ret = ldb_request_add_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID, false, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + } + return LDB_SUCCESS; } diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 4f077c01a26..7c3382dd47d 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -4519,7 +4519,14 @@ static int replmd_name_modify(struct replmd_replicated_request *ar, goto failed; } - ret = dsdb_module_modify(ar->module, msg, DSDB_FLAG_OWN_MODULE, req); + /* + * We have to mark this as a replicated update otherwise + * schema_data may reject a rename in the schema partition + */ + + ret = dsdb_module_modify(ar->module, msg, + DSDB_FLAG_OWN_MODULE|DSDB_FLAG_REPLICATED_UPDATE, + req); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to modify rDN/name of conflict DN '%s' - %s", ldb_dn_get_linearized(dn), diff --git a/source4/dsdb/samdb/ldb_modules/util.h b/source4/dsdb/samdb/ldb_modules/util.h index e40730557a3..5ecf0eee0d2 100644 --- a/source4/dsdb/samdb/ldb_modules/util.h +++ b/source4/dsdb/samdb/ldb_modules/util.h @@ -38,3 +38,4 @@ struct netlogon_samlogon_response; #define DSDB_FLAG_OWN_MODULE 0x00400000 #define DSDB_FLAG_TOP_MODULE 0x00800000 #define DSDB_FLAG_TRUSTED 0x01000000 +#define DSDB_FLAG_REPLICATED_UPDATE 0x02000000 diff --git a/source4/torture/drs/python/repl_schema.py b/source4/torture/drs/python/repl_schema.py index 0ce70e75282..092566fd82d 100644 --- a/source4/torture/drs/python/repl_schema.py +++ b/source4/torture/drs/python/repl_schema.py @@ -417,3 +417,35 @@ class DrsReplSchemaTestCase(drs_base.DrsBaseTestCase): nc_dn=self.schema_dn, forced=True) self._net_drs_replicate(DC=self.dnsname_dc2, fromDC=self.dnsname_dc1, nc_dn=self.domain_dn, forced=True) + + def test_rename(self): + """Basic plan is to create a classSchema + and attributeSchema objects, replicate Schema NC + and then check all objects are replicated correctly""" + + # add new classSchema object + (c_ldn, c_dn) = self._schema_new_class(self.ldb_dc1, "cls-B", 20) + + self._net_drs_replicate(DC=self.dnsname_dc2, fromDC=self.dnsname_dc1, + nc_dn=self.schema_dn, forced=True) + + # check objects are replicated + self._check_object(c_dn) + + # rename the Class CN + c_dn_new = ldb.Dn(self.ldb_dc1, str(c_dn)) + c_dn_new.set_component(0, + "CN", + c_dn.get_component_value(0) + "-NEW") + try: + self.ldb_dc1.rename(c_dn, c_dn_new) + except LdbError, (num, _): + self.fail("failed to change CN for %s: %s" % (c_dn, _)) + + # force replication from DC1 to DC2 + self._net_drs_replicate(DC=self.dnsname_dc2, fromDC=self.dnsname_dc1, + nc_dn=self.schema_dn, forced=True) + + # check objects are replicated + self._check_object(c_dn_new) + -- 2.11.0