[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Fri Jul 8 11:40:03 UTC 2016


The branch, master has been updated
       via  6e4e914 selftest: Add more tests for samba-tool drs replicate
       via  eeb0c97 samba-tool: Add --local-online mode to samba-tool drs replicate
       via  ae2bd00 samba-tool: Add success message to samba-tool drs replicate --local
       via  f060811 schema: raise debug level
       via  657e314 schema: Remove unnecessary schema reload code
       via  769230a s4:torture/drs: verify the whole metadata array to be the same in the repl_move tests
       via  2a44b69 Revert "selftest/flapping: mark samba4.drs.repl_move.python as temporary flapping"
       via  26d117c s4:dsdb/password_hash: force replication meta data for empty password attributes
       via  b0501a1 s4:dsdb/common: add a replication metadata stamp for an empty logonHours attribute
       via  c7307fb selftest/flapping: mark samba4.drs.repl_move.python as temporary flapping
       via  3f66ccd tests:samba3sam: make use of the dsdb_flags_ignore module
       via  d243996 s4:samba_dsdb: add "dsdb_flags_ignore" module
       via  1ca71aa s4:dsdb/samdb: add DSDB_FLAG_INTERNAL_FORCE_META_DATA
      from  f76a429 CVE-2016-2019: s3:selftest: add regression tests for guest logins and mandatory signing

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 6e4e914c76c209f30892b2a6a2b448c344df385f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jul 8 12:54:40 2016 +1200

    selftest: Add more tests for samba-tool drs replicate
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Fri Jul  8 13:39:01 CEST 2016 on sn-devel-144

commit eeb0c97fdf88c7c4d46c34e4637c523664a5ee07
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jul 8 12:54:22 2016 +1200

    samba-tool: Add --local-online mode to samba-tool drs replicate
    
    This mode avoids an issue with using -P on an RODC, instead using an IRPC message
    to trigger online replication right away
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit ae2bd0012cdd4ad4cfa14773a24e8dcbacd2b300
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jul 8 12:53:09 2016 +1200

    samba-tool: Add success message to samba-tool drs replicate --local
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit f060811a9f85fe9506e6a45d7e7c31b548613c72
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Fri Jul 8 14:53:22 2016 +1200

    schema: raise debug level
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 657e31450c704b4d62423d9386372fc3bb248669
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Jul 6 16:57:26 2016 +1200

    schema: Remove unnecessary schema reload code
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 769230a49aeb504adc9f5ead36acaa12e3418198
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 7 16:04:14 2016 +0200

    s4:torture/drs: verify the whole metadata array to be the same in the repl_move tests
    
    We've removed the difference compared to Windows and store metadata stamps for
    some empty attributes.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 2a44b692c08fa222cd3ca08c3b3d23a8d63e24ba
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 7 17:56:37 2016 +0200

    Revert "selftest/flapping: mark samba4.drs.repl_move.python as temporary flapping"
    
    We pass this tests again...
    
    This reverts commit HEAD~2.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 26d117c2a2705b58222ba46b3f8f82c69ec2d9db
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jun 1 23:25:22 2016 +0200

    s4:dsdb/password_hash: force replication meta data for empty password attributes
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9654
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b0501a1cb0b6503b71a2854a4abba3baae1d4f83
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 7 15:44:47 2016 +0200

    s4:dsdb/common: add a replication metadata stamp for an empty logonHours attribute
    
    When a user object is created it gets a metadata stamp for logonHours,
    while the logonHours attribute has no value.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c7307fb7e4b61cec9a70aa56e5cb199a43d79459
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 7 16:14:05 2016 +0200

    selftest/flapping: mark samba4.drs.repl_move.python as temporary flapping
    
    We'll change the behaviour step by step to match Windows.
    At the end we'll pass the test again and revert this patch.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3f66ccdfd2b52913c8bd919ea25675f5c907771c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jun 2 00:30:01 2016 +0200

    tests:samba3sam: make use of the dsdb_flags_ignore module
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9654
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d243996341b46f535ad87aa437dea5a846e36ac7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jun 2 00:08:54 2016 +0200

    s4:samba_dsdb: add "dsdb_flags_ignore" module
    
    This module removes internal flags from ldb_message_elements.
    Typically the repl_meta_data module handles DSDB_FLAG_INTERNAL_FORCE_META_DATA,
    but there're some cases where we don't use that module.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9654
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 1ca71aa1523e9653964d63b496e3cf50f18ee0a1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jun 1 23:13:21 2016 +0200

    s4:dsdb/samdb: add DSDB_FLAG_INTERNAL_FORCE_META_DATA
    
    With this it's possible to add a replPropertyMetaData entry for an empty
    attribute.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9654
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 python/samba/netcmd/drs.py                      |  17 +++-
 python/samba/tests/blackbox/samba_tool_drs.py   |  45 ++++++++++
 python/samba/tests/samba3sam.py                 |   2 +-
 source4/dsdb/common/util.c                      |  24 +++++-
 source4/dsdb/samdb/ldb_modules/password_hash.c  |  41 ++++++++-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |  52 ++++++++++--
 source4/dsdb/samdb/ldb_modules/samba_dsdb.c     | 106 +++++++++++++++++++++++-
 source4/dsdb/samdb/ldb_modules/schema_load.c    |   9 +-
 source4/dsdb/samdb/samdb.h                      |   8 +-
 source4/ldap_server/ldap_backend.c              |  22 -----
 source4/selftest/tests.py                       |   2 +-
 source4/torture/drs/python/repl_move.py         |  22 -----
 12 files changed, 276 insertions(+), 74 deletions(-)


Changeset truncated at 500 lines:

diff --git a/python/samba/netcmd/drs.py b/python/samba/netcmd/drs.py
index 230dd33..cbd1672 100644
--- a/python/samba/netcmd/drs.py
+++ b/python/samba/netcmd/drs.py
@@ -276,6 +276,8 @@ def drs_local_replicate(self, SOURCE_DC, NC):
         raise CommandError("Error replicating DN %s" % NC, e)
     self.samdb.transaction_commit()
 
+    self.message("Replicate from %s to %s was successful." % (SOURCE_DC, self.local_samdb.url))
+
 
 
 class cmd_drs_replicate(Command):
@@ -297,11 +299,13 @@ class cmd_drs_replicate(Command):
         Option("--sync-all", help="use SYNC_ALL to replicate from all DCs", action="store_true"),
         Option("--full-sync", help="resync all objects", action="store_true"),
         Option("--local", help="pull changes directly into the local database (destination DC is ignored)", action="store_true"),
+        Option("--local-online", help="pull changes into the local database (destination DC is ignored) as a normal online replication", action="store_true"),
         ]
 
     def run(self, DEST_DC, SOURCE_DC, NC,
             add_ref=False, sync_forced=False, sync_all=False, full_sync=False,
-            local=False, sambaopts=None, credopts=None, versionopts=None, server=None):
+            local=False, local_online=False,
+            sambaopts=None, credopts=None, versionopts=None, server=None):
 
         self.server = DEST_DC
         self.lp = sambaopts.get_loadparm()
@@ -312,7 +316,14 @@ class cmd_drs_replicate(Command):
             drs_local_replicate(self, SOURCE_DC, NC)
             return
 
-        drsuapi_connect(self)
+        if local_online:
+            server_bind = drsuapi.drsuapi("irpc:dreplsrv", self.lp)
+            server_bind_handle = misc.policy_handle()
+        else:
+            drsuapi_connect(self)
+            server_bind = self.drsuapi
+            server_bind_handle = self.drsuapi_handle
+
         samdb_connect(self)
 
         # we need to find the NTDS GUID of the source DC
@@ -347,7 +358,7 @@ class cmd_drs_replicate(Command):
             req_options |= drsuapi.DRSUAPI_DRS_FULL_SYNC_NOW
 
         try:
-            drs_utils.sendDsReplicaSync(self.drsuapi, self.drsuapi_handle, source_dsa_guid, NC, req_options)
+            drs_utils.sendDsReplicaSync(server_bind, server_bind_handle, source_dsa_guid, NC, req_options)
         except drs_utils.drsException, estr:
             raise CommandError("DsReplicaSync failed", estr)
         self.message("Replicate from %s to %s was successful." % (SOURCE_DC, DEST_DC))
diff --git a/python/samba/tests/blackbox/samba_tool_drs.py b/python/samba/tests/blackbox/samba_tool_drs.py
index 6056645..afaa4af 100644
--- a/python/samba/tests/blackbox/samba_tool_drs.py
+++ b/python/samba/tests/blackbox/samba_tool_drs.py
@@ -103,6 +103,51 @@ class SambaToolDrsTests(samba.tests.BlackboxTestCase):
         self.assertTrue("Replicate from" in out)
         self.assertTrue("was successful" in out)
 
+    def test_samba_tool_replicate_local_online(self):
+        """Tests 'samba-tool drs replicate --local-online' command."""
+
+        # Output should be like 'Replicate from <DC-SRC> to <DC-DEST> was successful.'
+        nc_name = self._get_rootDSE(self.dc1)["defaultNamingContext"]
+        out = self.check_output("samba-tool drs replicate --local-online %s %s %s" % (self.dc1,
+                                                                                      self.dc2,
+                                                                                      nc_name))
+        self.assertTrue("Replicate from" in out)
+        self.assertTrue("was successful" in out)
+
+    def test_samba_tool_replicate_local_machine_creds(self):
+        """Tests 'samba-tool drs replicate --local -P' command (uses machine creds)."""
+
+        # Output should be like 'Replicate from <DC-SRC> to <DC-DEST> was successful.'
+        nc_name = self._get_rootDSE(self.dc1)["defaultNamingContext"]
+        out = self.check_output("samba-tool drs replicate -P --local %s %s %s" % (self.dc1,
+                                                                                  self.dc2,
+                                                                                  nc_name))
+        self.assertTrue("Replicate from" in out)
+        self.assertTrue("was successful" in out)
+
+    def test_samba_tool_replicate_local(self):
+        """Tests 'samba-tool drs replicate --local' command (uses machine creds)."""
+
+        # Output should be like 'Replicate from <DC-SRC> to <DC-DEST> was successful.'
+        nc_name = self._get_rootDSE(self.dc1)["defaultNamingContext"]
+        out = self.check_output("samba-tool drs replicate --local %s %s %s %s" % (self.dc1,
+                                                                                  self.dc2,
+                                                                                  nc_name,
+                                                                                  self.cmdline_creds))
+        self.assertTrue("Replicate from" in out)
+        self.assertTrue("was successful" in out)
+
+    def test_samba_tool_replicate_machine_creds(self):
+        """Tests 'samba-tool drs replicate -P' command with machine creds."""
+
+        # Output should be like 'Replicate from <DC-SRC> to <DC-DEST> was successful.'
+        nc_name = self._get_rootDSE(self.dc1)["defaultNamingContext"]
+        out = self.check_output("samba-tool drs replicate -P %s %s %s" % (self.dc1,
+                                                                          self.dc2,
+                                                                          nc_name))
+        self.assertTrue("Replicate from" in out)
+        self.assertTrue("was successful" in out)
+
     def test_samba_tool_drs_clone_dc(self):
         """Tests 'samba-tool drs clone-dc-database' command."""
         server_rootdse = self._get_rootDSE(self.dc1)
diff --git a/python/samba/tests/samba3sam.py b/python/samba/tests/samba3sam.py
index d4347cd..3a189e0 100644
--- a/python/samba/tests/samba3sam.py
+++ b/python/samba/tests/samba3sam.py
@@ -53,7 +53,7 @@ class MapBaseTestCase(TestCaseInTempDir):
                  "@TO": "sambaDomainName=TESTS," + s3.basedn})
 
         ldb.add({"dn": "@MODULES",
-                 "@LIST": "rootdse,paged_results,server_sort,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,samba3sid,show_deleted,partition"})
+                 "@LIST": "rootdse,paged_results,server_sort,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,samba3sid,show_deleted,dsdb_flags_ignore,partition"})
 
         ldb.add({"dn": "@PARTITION",
             "partition": ["%s" % (s4.basedn_casefold),
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index ed2dde3..2aed804 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -739,6 +739,7 @@ static int samdb_find_or_add_attribute_ex(struct ldb_context *ldb,
 					  struct ldb_message *msg,
 					  const char *name,
 					  const char *set_value,
+					  unsigned attr_flags,
 					  bool *added)
 {
 	int ret;
@@ -753,11 +754,22 @@ static int samdb_find_or_add_attribute_ex(struct ldb_context *ldb,
 		return LDB_SUCCESS;
 	}
 
-	ret = ldb_msg_add_string(msg, name, set_value);
+	SMB_ASSERT(set_value != NULL || attr_flags != 0);
+
+	ret = ldb_msg_add_empty(msg, name,
+				LDB_FLAG_MOD_ADD | attr_flags,
+				&el);
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
-	msg->elements[msg->num_elements - 1].flags = LDB_FLAG_MOD_ADD;
+
+	if (set_value != NULL) {
+		ret = ldb_msg_add_string(msg, name, set_value);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
 	if (added != NULL) {
 		*added = true;
 	}
@@ -766,7 +778,7 @@ static int samdb_find_or_add_attribute_ex(struct ldb_context *ldb,
 
 int samdb_find_or_add_attribute(struct ldb_context *ldb, struct ldb_message *msg, const char *name, const char *set_value)
 {
-	return samdb_find_or_add_attribute_ex(ldb, msg, name, set_value, NULL);
+	return samdb_find_or_add_attribute_ex(ldb, msg, name, set_value, 0, NULL);
 }
 
 /*
@@ -5294,6 +5306,7 @@ int dsdb_user_obj_set_defaults(struct ldb_context *ldb,
 		const char *name;
 		const char *value;
 		const char *add_control;
+		unsigned attr_flags;
 	} map[] = {
 		{
 			.name = "accountExpires",
@@ -5328,6 +5341,10 @@ int dsdb_user_obj_set_defaults(struct ldb_context *ldb,
 			.value = "0"
 		},
 		{
+			.name = "logonHours",
+			.attr_flags = DSDB_FLAG_INTERNAL_FORCE_META_DATA,
+		},
+		{
 			.name = "pwdLastSet",
 			.value = "0",
 			.add_control = DSDB_CONTROL_PASSWORD_DEFAULT_LAST_SET_OID,
@@ -5340,6 +5357,7 @@ int dsdb_user_obj_set_defaults(struct ldb_context *ldb,
 		ret = samdb_find_or_add_attribute_ex(ldb, usr_obj,
 						     map[i].name,
 						     map[i].value,
+						     map[i].attr_flags,
 						     &added);
 		if (ret != LDB_SUCCESS) {
 			return ret;
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index c50a778..7213015 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -2289,13 +2289,44 @@ static int update_final_msg(struct setup_password_fields_io *io)
 	struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
 	int ret;
 	int el_flags = 0;
+	bool update_password = io->ac->update_password;
+	bool update_scb = io->ac->update_password;
 
-	if (io->ac->req->operation == LDB_MODIFY) {
+	/*
+	 * If we add a user without initial password,
+	 * we need to add replication meta data for
+	 * following attributes:
+	 * - unicodePwd
+	 * - dBCSPwd
+	 * - ntPwdHistory
+	 * - lmPwdHistory
+	 *
+	 * If we add a user with initial password or a
+	 * password is changed of an existing user,
+	 * we need to replace the following attributes
+	 * with a forced meta data update, e.g. also
+	 * when updating an empty attribute with an empty value:
+	 * - unicodePwd
+	 * - dBCSPwd
+	 * - ntPwdHistory
+	 * - lmPwdHistory
+	 * - supplementalCredentials
+	 */
+
+	switch (io->ac->req->operation) {
+	case LDB_ADD:
+		update_password = true;
+		el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
+		break;
+	case LDB_MODIFY:
 		el_flags |= LDB_FLAG_MOD_REPLACE;
+		el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
+		break;
+	default:
+		return ldb_module_operr(io->ac->module);
 	}
 
-	/* make sure we replace all the old attributes */
-	if (io->ac->update_password && el_flags != 0) {
+	if (update_password) {
 		ret = ldb_msg_add_empty(io->ac->update_msg,
 					"unicodePwd",
 					el_flags, NULL);
@@ -2320,6 +2351,8 @@ static int update_final_msg(struct setup_password_fields_io *io)
 		if (ret != LDB_SUCCESS) {
 			return ret;
 		}
+	}
+	if (update_scb) {
 		ret = ldb_msg_add_empty(io->ac->update_msg,
 					"supplementalCredentials",
 					el_flags, NULL);
@@ -2327,7 +2360,7 @@ static int update_final_msg(struct setup_password_fields_io *io)
 			return ret;
 		}
 	}
-	if (io->ac->update_lastset && el_flags != 0) {
+	if (io->ac->update_lastset) {
 		ret = ldb_msg_add_empty(io->ac->update_msg,
 					"pwdLastSet",
 					el_flags, NULL);
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 1db2392..8080834 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -986,12 +986,15 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 
 	is_schema_nc = ldb_dn_compare_base(replmd_private->schema_dn, msg->dn) == 0;
 
-	for (i=0; i < msg->num_elements; i++) {
+	for (i=0; i < msg->num_elements;) {
 		struct ldb_message_element *e = &msg->elements[i];
 		struct replPropertyMetaData1 *m = &nmd.ctr.ctr1.array[ni];
 		const struct dsdb_attribute *sa;
 
-		if (e->name[0] == '@') continue;
+		if (e->name[0] == '@') {
+			i++;
+			continue;
+		}
 
 		sa = dsdb_attribute_by_lDAPDisplayName(ac->schema, e->name);
 		if (!sa) {
@@ -1006,6 +1009,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 			/* if the attribute is not replicated (0x00000001)
 			 * or constructed (0x00000004) it has no metadata
 			 */
+			i++;
 			continue;
 		}
 
@@ -1019,6 +1023,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 			}
 			/* linked attributes are not stored in
 			   replPropertyMetaData in FL above w2k */
+			i++;
 			continue;
 		}
 
@@ -1051,6 +1056,20 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 		m->originating_usn		= ac->seq_num;
 		m->local_usn			= ac->seq_num;
 		ni++;
+
+		if (!(e->flags & DSDB_FLAG_INTERNAL_FORCE_META_DATA)) {
+			i++;
+			continue;
+		}
+
+		e->flags &= ~DSDB_FLAG_INTERNAL_FORCE_META_DATA;
+
+		if (e->num_values != 0) {
+			i++;
+			continue;
+		}
+
+		ldb_msg_remove_element(msg, e);
 	}
 
 	/* fix meta data count */
@@ -1237,6 +1256,11 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
 		}
 	}
 
+	if (el->flags & DSDB_FLAG_INTERNAL_FORCE_META_DATA) {
+		may_skip = false;
+		el->flags &= ~DSDB_FLAG_INTERNAL_FORCE_META_DATA;
+	}
+
 	if (may_skip) {
 		if (strcmp(el->name, "interSiteTopologyGenerator") != 0 &&
 		    !ldb_request_get_control(req, LDB_CONTROL_PROVISION_OID)) {
@@ -1565,10 +1589,13 @@ static int replmd_update_rpmd(struct ldb_module *module,
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
 
-		for (i=0; i<msg->num_elements; i++) {
+		for (i=0; i<msg->num_elements;) {
+			struct ldb_message_element *el = &msg->elements[i];
 			struct ldb_message_element *old_el;
-			old_el = ldb_msg_find_element(res->msgs[0], msg->elements[i].name);
-			ret = replmd_update_rpmd_element(ldb, msg, &msg->elements[i], old_el, &omd, schema, seq_num,
+
+			old_el = ldb_msg_find_element(res->msgs[0], el->name);
+			ret = replmd_update_rpmd_element(ldb, msg, el, old_el,
+							 &omd, schema, seq_num,
 							 our_invocation_id,
 							 now, is_schema_nc,
 							 req);
@@ -1577,9 +1604,22 @@ static int replmd_update_rpmd(struct ldb_module *module,
 			}
 
 			if (!*is_urgent && (situation == REPL_URGENT_ON_UPDATE)) {
-				*is_urgent = replmd_check_urgent_attribute(&msg->elements[i]);
+				*is_urgent = replmd_check_urgent_attribute(el);
+			}
+
+			if (!(el->flags & DSDB_FLAG_INTERNAL_FORCE_META_DATA)) {
+				i++;
+				continue;
+			}
+
+			el->flags &= ~DSDB_FLAG_INTERNAL_FORCE_META_DATA;
+
+			if (el->num_values != 0) {
+				i++;
+				continue;
 			}
 
+			ldb_msg_remove_element(msg, el);
 		}
 	}
 
diff --git a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
index 3297eb1..3f8cc51 100644
--- a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
+++ b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
@@ -312,9 +312,9 @@ static int samba_dsdb_init(struct ldb_module *module)
 
 	const char **backend_modules;
 	static const char *fedora_ds_backend_modules[] = {
-		"nsuniqueid", "paged_searches", "simple_dn", NULL };
+		"dsdb_flags_ignore", "nsuniqueid", "paged_searches", "simple_dn", NULL };
 	static const char *openldap_backend_modules[] = {
-		"entryuuid", "simple_dn", NULL };
+		"dsdb_flags_ignore", "entryuuid", "simple_dn", NULL };
 
 	static const char *samba_dsdb_attrs[] = { "backendType", NULL };
 	static const char *partition_attrs[] = { "ldapBackend", NULL };
@@ -492,8 +492,108 @@ static const struct ldb_module_ops ldb_samba_dsdb_module_ops = {
 	.init_context	   = samba_dsdb_init,
 };
 
+static struct ldb_message *dsdb_flags_ignore_fixup(TALLOC_CTX *mem_ctx,
+						const struct ldb_message *_msg)
+{
+	struct ldb_message *msg = NULL;
+	unsigned int i;
+
+	/* we have to copy the message as the caller might have it as a const */
+	msg = ldb_msg_copy_shallow(mem_ctx, _msg);
+	if (msg == NULL) {
+		return NULL;
+	}
+
+	for (i=0; i < msg->num_elements;) {
+		struct ldb_message_element *e = &msg->elements[i];
+
+		if (!(e->flags & DSDB_FLAG_INTERNAL_FORCE_META_DATA)) {
+			i++;
+			continue;
+		}
+
+		e->flags &= ~DSDB_FLAG_INTERNAL_FORCE_META_DATA;
+
+		if (e->num_values != 0) {
+			i++;
+			continue;
+		}
+
+		ldb_msg_remove_element(msg, e);
+	}
+
+	return msg;
+}
+
+static int dsdb_flags_ignore_add(struct ldb_module *module, struct ldb_request *req)
+{
+	struct ldb_context *ldb = ldb_module_get_ctx(module);
+	struct ldb_request *down_req = NULL;
+	struct ldb_message *msg = NULL;
+	int ret;
+
+	msg = dsdb_flags_ignore_fixup(req, req->op.add.message);
+	if (msg == NULL) {
+		return ldb_module_oom(module);
+	}
+
+	ret = ldb_build_add_req(&down_req, ldb, req,
+				msg,
+				req->controls,
+				req, dsdb_next_callback,
+				req);
+	LDB_REQ_SET_LOCATION(down_req);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/* go on with the call chain */
+	return ldb_next_request(module, down_req);
+}
+
+static int dsdb_flags_ignore_modify(struct ldb_module *module, struct ldb_request *req)
+{
+	struct ldb_context *ldb = ldb_module_get_ctx(module);
+	struct ldb_request *down_req = NULL;
+	struct ldb_message *msg = NULL;
+	int ret;
+
+	msg = dsdb_flags_ignore_fixup(req, req->op.mod.message);
+	if (msg == NULL) {
+		return ldb_module_oom(module);
+	}
+
+	ret = ldb_build_mod_req(&down_req, ldb, req,
+				msg,
+				req->controls,
+				req, dsdb_next_callback,
+				req);
+	LDB_REQ_SET_LOCATION(down_req);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/* go on with the call chain */
+	return ldb_next_request(module, down_req);
+}
+
+static const struct ldb_module_ops ldb_dsdb_flags_ignore_module_ops = {
+	.name   = "dsdb_flags_ignore",
+	.add    = dsdb_flags_ignore_add,
+	.modify = dsdb_flags_ignore_modify,
+};
+
 int ldb_samba_dsdb_module_init(const char *version)
 {
+	int ret;
 	LDB_MODULE_CHECK_VERSION(version);
-	return ldb_register_module(&ldb_samba_dsdb_module_ops);
+	ret = ldb_register_module(&ldb_samba_dsdb_module_ops);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+	ret = ldb_register_module(&ldb_dsdb_flags_ignore_module_ops);
+	if (ret != LDB_SUCCESS) {
+		return ret;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list