[SCM] Samba Shared Repository - branch v4-18-stable updated

Jule Anger janger at samba.org
Wed Feb 1 17:42:33 UTC 2023


The branch, v4-18-stable has been updated
       via  71fa86a3fbb VERSION: Disable GIT_SNAPSHOT for the 4.18.0rc2 release.
       via  0679a07af31 WHATSNEW: Add release notes for Samba 4.18.0rc2.
       via  46e0575931e tmp
       via  65077cd390f WHATSNEW: Add note about Azure AD cloud connect sync support
       via  c9b7fd177d4 s4-drsuapi: Give an error that matches windows on destination_dsa_guid lookup failure
       via  68fcea19bd0 s4-drsuapi: Clarify role of drs_security_access_check_nc_root()
       via  262fef5acbf s4-rpc_server: Pre-check destination_dsa_guid in GetNCChanges for validity
       via  68edd5c1c7f s4-drsuapi: Use samdb_get_ntds_obj_by_guid() to find RODC in REPL_SECRET
       via  dc7497c3a46 s4-dsdb: Require that the NTDS object is an nTDSDSA objectclass
       via  29a89f07aa7 s4-dsdb: Split samdb_get_ntds_obj_by_guid() out of samdb_is_rodc()
       via  613d9b75499 s4-rpc_server/drsuapi: Return correct error code for an invalid DN to EXOP_REPL_OBJ/EXOP_REPL_OBJ
       via  64df0963f8c s4-drs: Make drs_ObjectIdentifier_to_dn() safer and able to cope with DummyDN values
       via  84a952b01ee s4-dsdb: rework drs_ObjectIdentifier_to_dn() into drs_ObjectIdentifier_to_dn_and_nc_root()
       via  1a97e897f86 s4-rpc_server/drsuapi: Use dsdb_normalise_dn_and_find_nc_root()
       via  feffb9ec5df s4-dsdb: Add dsdb_normalise_dn_and_find_nc_root() around dsdb_find_nc_root()
       via  ab282dba376 s4-dsdb: Add better debugging to dsdb_objects_have_same_nc()
       via  855c11c4146 s4-dsdb: Make dsdb_find_nc_root() first try and use DSDB_CONTROL_CURRENT_PARTITION_OID
       via  92f56081291 s4-dsdb: Schedule SD propegation only after successful rename
       via  f70fd3385f3 s4-selftest/drs: Confirm GetNCChanges REPL_SECRET works with a DummyDN and real GUID
       via  87ed6e23061 s4-selftest/drs: Confirm GetNCChanges full replication works with a DummyDN and real GUID
       via  a40d3697e1a s4-selftest/drs: Confirm GetNCChanges REPL_OBJ works with a DummyDN and real GUID
       via  7712ef7288a s4-selftest/drs Allow re-run of DRS tests after failed cleanup
       via  11540d828f7 s4-selftest/drs Allow some DRS tests to operate against an IP
       via  501728cdcfe s4-selftest/drs Add test of expected return code for invaid DNs in GetNCChanges
       via  d0c2305b35a s4-dsdb: Add tests of SamDB.get_nc_root()
       via  af00a0df70a s3/lib: Prevent use after free of messaging_ctdb_fde_ev structs
       via  f21236ac004 s3:auth: call wbcFreeMemory(info) in auth3_generate_session_info_pac()
       via  6e6913bcac2 WHATSNEW: add acl_xattr:security_acl_name option
       via  8b97aca0dee WHATSNEW 4.18: mention samba-tool dsacl delete
       via  1886a72d966 VERSION: Bump version up to 4.18.0rc2...
      from  fbba9a24796 VERSION: Disable GIT_SNAPSHOT for the Samba 4.18.0rc1 release.

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-18-stable


- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 VERSION                                     |   2 +-
 WHATSNEW.txt                                |  49 +++-
 python/samba/tests/dsdb.py                  | 122 ++++++++++
 source3/auth/auth_generic.c                 |   1 +
 source3/lib/messages_ctdb.c                 |  19 ++
 source4/dsdb/common/dsdb_dn.c               | 183 ++++++++++++++-
 source4/dsdb/common/util.c                  | 335 ++++++++++++++++++++++++++--
 source4/dsdb/samdb/ldb_modules/descriptor.c | 134 +++++++----
 source4/rpc_server/drsuapi/drsutil.c        |  28 ++-
 source4/rpc_server/drsuapi/getncchanges.c   | 182 ++++++++++++---
 source4/rpc_server/drsuapi/updaterefs.c     |  39 +++-
 source4/torture/drs/python/drs_base.py      |  15 +-
 source4/torture/drs/python/getnc_exop.py    | 169 +++++++++++++-
 source4/torture/drs/python/getncchanges.py  |  52 ++++-
 source4/torture/drs/python/repl_move.py     |  11 +-
 source4/torture/drs/python/repl_rodc.py     |  46 ++++
 source4/torture/drs/python/repl_schema.py   |   9 +-
 17 files changed, 1242 insertions(+), 154 deletions(-)


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index 97e56c10a35..d8f3b790191 100644
--- a/VERSION
+++ b/VERSION
@@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE=
 # e.g. SAMBA_VERSION_RC_RELEASE=1                      #
 #  ->  "3.0.0rc1"                                      #
 ########################################################
-SAMBA_VERSION_RC_RELEASE=1
+SAMBA_VERSION_RC_RELEASE=2
 
 ########################################################
 # To mark SVN snapshots this should be set to 'yes'    #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index eb71f69fadc..66a7a80e963 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,12 +1,12 @@
 Release Announcements
 =====================
 
-This is the first release candidate of Samba 4.18.  This is *not*
+This is the second release candidate of Samba 4.18.  This is *not*
 intended for production environments and is designed for testing
 purposes only.  Please report any defects via the Samba bug reporting
 system at https://bugzilla.samba.org/.
 
-Samba 4.18 will be the next version of the Samba suite.
+Samba 4.18 will be the next version of the Samba suite...
 
 
 UPGRADING
@@ -65,6 +65,14 @@ already used it, the defaults have changed slightly.
    set it overrides --color for the purpose of the output diagram, but
    not for other output like error messages.
 
+New samba-tool dsacl subcommand for deleting ACES
+-------------------------------------------------
+
+The samba-tool dsacl tool can now delete entries in directory access
+control lists. The interface for 'samba-tool dsacl delete' is similar
+to that of 'samba-tool dsacl set', with the difference being that the
+ACEs described by the --sddl argument are deleted rather than added.
+
 No colour with NO_COLOR environment variable
 --------------------------------------------
 
@@ -82,6 +90,28 @@ which forces the trust account password to be changed at a specified domain
 controller. If the specified domain controller cannot be contacted the
 password change fails rather than trying other DCs.
 
+New option to change the NT ACL default location
+------------------------------------------------
+
+Usually the NT ACLs are stored in the security.NTACL extended
+attribute (xattr) of files and directories. The new
+"acl_xattr:security_acl_name" option allows to redefine the default
+location. The default "security.NTACL" is a protected location, which
+means the content of the security.NTACL attribute is not accessible
+from normal users outside of Samba. When this option is set to use a
+user-defined value, e.g. user.NTACL then any user can potentially
+access and overwrite this information. The module prevents access to
+this xattr over SMB, but the xattr may still be accessed by other
+means (eg local access, SSH, NFS). This option must only be used when
+this consequence is clearly understood and when specific precautions
+are taken to avoid compromising the ACL content.
+
+Azure Active Directory / Office365 synchronisation improvements
+--------------------------------------------------------------
+
+Use of the Azure AD Connect cloud sync tool is now supported for
+password hash synchronisation, allowing Samba AD Domains to synchronise
+passwords with this popular cloud environment.
 
 REMOVED FEATURES
 ================
@@ -92,6 +122,21 @@ smb.conf changes
 
   Parameter Name                          Description     Default
   --------------                          -----------     -------
+  acl_xattr:security_acl_name             New             security.NTACL
+
+
+CHANGES SINCE 4.18.0rc1
+=======================
+
+o  Andrew Bartlett <abartlet at samba.org>
+   * BUG 10635: Office365 azure Password Sync not working.
+
+o  Stefan Metzmacher <metze at samba.org>
+   * BUG 15286: auth3_generate_session_info_pac leaks wbcAuthUserInfo.
+
+o  Noel Power <noel.power at suse.com>
+   * BUG 15293: With clustering enabled samba-bgqd can core dump due to use
+     after free.
 
 
 KNOWN ISSUES
diff --git a/python/samba/tests/dsdb.py b/python/samba/tests/dsdb.py
index f4f7a705626..6c52994ece7 100644
--- a/python/samba/tests/dsdb.py
+++ b/python/samba/tests/dsdb.py
@@ -1029,6 +1029,128 @@ class DsdbTests(TestCase):
                                 str(part_dn) + "," + str(domain_dn)),
                          self.samdb.normalize_dn_in_domain(part_dn))
 
+class DsdbNCRootTests(TestCase):
+
+    def setUp(self):
+        super().setUp()
+        self.lp = samba.tests.env_loadparm()
+        self.creds = Credentials()
+        self.creds.guess(self.lp)
+        self.session = system_session()
+        self.samdb = SamDB(session_info=self.session,
+                           credentials=self.creds,
+                           lp=self.lp)
+        self.remote = False
+
+    # These all use the local mode of operation inside
+    # dsdb_find_nc_root() using the partitions control
+    def test_dsdb_dn_nc_root_sid(self):
+        dom_sid = self.samdb.get_domain_sid()
+        domain_dn = ldb.Dn(self.samdb, self.samdb.domain_dn())
+        dn = ldb.Dn(self.samdb, f"<SID={dom_sid}>")
+        try:
+            nc_root = self.samdb.get_nc_root(dn)
+        except ldb.LdbError as e:
+            (code, msg) = e.args
+            self.fail("Got unexpected exception %d - %s "
+                      % (code, msg))
+        self.assertEqual(domain_dn, nc_root)
+
+    def test_dsdb_dn_nc_root_admin_sid(self):
+        dom_sid = self.samdb.get_domain_sid()
+        domain_dn = ldb.Dn(self.samdb, self.samdb.domain_dn())
+        dn = ldb.Dn(self.samdb, f"<SID={dom_sid}-500>")
+        try:
+            nc_root = self.samdb.get_nc_root(dn)
+        except ldb.LdbError as e:
+            (code, msg) = e.args
+            self.fail("Got unexpected exception %d - %s "
+                      % (code, msg))
+        self.assertEqual(domain_dn, nc_root)
+
+    def test_dsdb_dn_nc_root_users_container(self):
+        dom_sid = self.samdb.get_domain_sid()
+        domain_dn = ldb.Dn(self.samdb, self.samdb.domain_dn())
+        dn = ldb.Dn(self.samdb, f"CN=Users,{domain_dn}")
+        try:
+            nc_root = self.samdb.get_nc_root(dn)
+        except ldb.LdbError as e:
+            (code, msg) = e.args
+            self.fail("Got unexpected exception %d - %s "
+                      % (code, msg))
+        self.assertEqual(domain_dn, nc_root)
+
+    def test_dsdb_dn_nc_root_new_dn(self):
+        dom_sid = self.samdb.get_domain_sid()
+        domain_dn = ldb.Dn(self.samdb, self.samdb.domain_dn())
+        dn = ldb.Dn(self.samdb, f"CN=Xnotexisting,CN=Users,{domain_dn}")
+        try:
+            nc_root = self.samdb.get_nc_root(dn)
+        except ldb.LdbError as e:
+            (code, msg) = e.args
+            self.fail("Got unexpected exception %d - %s "
+                      % (code, msg))
+        self.assertEqual(domain_dn, nc_root)
+
+    def test_dsdb_dn_nc_root_new_dn_with_guid(self):
+        domain_dn = ldb.Dn(self.samdb, self.samdb.domain_dn())
+        dn = ldb.Dn(self.samdb, f"<GUID=828e3baf-fa02-4d82-ba5d-6f647dab5fd8>;CN=Xnotexisting,CN=Users,{domain_dn}")
+        try:
+            nc_root = self.samdb.get_nc_root(dn)
+        except ldb.LdbError as e:
+            (code, msg) = e.args
+            self.fail("Got unexpected exception %d - %s "
+                      % (code, msg))
+        self.assertEqual(domain_dn, nc_root)
+
+    def test_dsdb_dn_nc_root_guid(self):
+        ntds_guid = self.samdb.get_ntds_GUID()
+        configuration_dn = self.samdb.get_config_basedn()
+        dn = ldb.Dn(self.samdb, f"<GUID={ntds_guid}>")
+        try:
+            nc_root = self.samdb.get_nc_root(dn)
+        except ldb.LdbError as e:
+            (code, msg) = e.args
+            self.fail("Got unexpected exception %d - %s "
+                      % (code, msg))
+        self.assertEqual(configuration_dn, nc_root)
+
+    def test_dsdb_dn_nc_root_misleading_to_noexisting_guid(self):
+        ntds_guid = self.samdb.get_ntds_GUID()
+        configuration_dn = self.samdb.get_config_basedn()
+        domain_dn = ldb.Dn(self.samdb, self.samdb.domain_dn())
+        dn = ldb.Dn(self.samdb, f"<GUID={ntds_guid}>;CN=Xnotexisting,CN=Users,{domain_dn}")
+        try:
+            nc_root = self.samdb.get_nc_root(dn)
+        except ldb.LdbError as e:
+            (code, msg) = e.args
+            self.fail("Got unexpected exception %d - %s "
+                      % (code, msg))
+        self.assertEqual(configuration_dn, nc_root)
+
+    def test_dsdb_dn_nc_root_misleading_to_existing_guid(self):
+        ntds_guid = self.samdb.get_ntds_GUID()
+        configuration_dn = self.samdb.get_config_basedn()
+        domain_dn = ldb.Dn(self.samdb, self.samdb.domain_dn())
+        dn = ldb.Dn(self.samdb, f"<GUID={ntds_guid}>;{domain_dn}")
+        try:
+            nc_root = self.samdb.get_nc_root(dn)
+        except ldb.LdbError as e:
+            (code, msg) = e.args
+            self.fail("Got unexpected exception %d - %s "
+                      % (code, msg))
+        self.assertEqual(configuration_dn, nc_root)
+
+class DsdbRemoteNCRootTests(DsdbNCRootTests):
+    def setUp(self):
+        super().setUp()
+        # Reconnect to the remote LDAP port
+        self.samdb = SamDB(url="ldap://%s" % samba.tests.env_get_var_value('SERVER'),
+                           session_info=self.session,
+                           credentials=self.get_credentials(),
+                           lp=self.lp)
+        self.remote = True
+
 
 class DsdbFullScanTests(TestCase):
 
diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
index ff51307e43a..6c61eb4e827 100644
--- a/source3/auth/auth_generic.c
+++ b/source3/auth/auth_generic.c
@@ -143,6 +143,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
 							  info->account_name,
 							  info->domain_name,
 							  info, &server_info);
+		wbcFreeMemory(info);
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
 				   nt_errstr(status)));
diff --git a/source3/lib/messages_ctdb.c b/source3/lib/messages_ctdb.c
index 3e784bf7237..d55b53bf601 100644
--- a/source3/lib/messages_ctdb.c
+++ b/source3/lib/messages_ctdb.c
@@ -76,6 +76,21 @@ static int messaging_ctdb_recv(
 
 struct messaging_ctdb_context *global_ctdb_context;
 
+static int global_ctdb_ctx_destructor(struct messaging_ctdb_context *ctx)
+{
+	if (ctx != NULL) {
+		struct messaging_ctdb_fde_ev *fde_ev = NULL;
+		for (fde_ev = ctx->fde_evs;
+		     fde_ev != NULL;
+		     fde_ev = fde_ev->next) {
+			if (fde_ev->ctx == ctx) {
+				fde_ev->ctx = NULL;
+			}
+		}
+	}
+	return 0;
+}
+
 int messaging_ctdb_init(const char *sockname, int timeout, uint64_t unique_id,
 			void (*recv_cb)(struct tevent_context *ev,
 					const uint8_t *msg, size_t msg_len,
@@ -94,6 +109,10 @@ int messaging_ctdb_init(const char *sockname, int timeout, uint64_t unique_id,
 	if (ctx == NULL) {
 		return ENOMEM;
 	}
+
+	talloc_set_destructor(ctx,
+			      global_ctdb_ctx_destructor);
+
 	ctx->recv_cb = recv_cb;
 	ctx->recv_cb_private_data = private_data;
 
diff --git a/source4/dsdb/common/dsdb_dn.c b/source4/dsdb/common/dsdb_dn.c
index e348ab6aa94..c86848fd697 100644
--- a/source4/dsdb/common/dsdb_dn.c
+++ b/source4/dsdb/common/dsdb_dn.c
@@ -359,10 +359,12 @@ int dsdb_dn_string_comparison(struct ldb_context *ldb, void *mem_ctx,
 }
 
 /*
-  format a drsuapi_DsReplicaObjectIdentifier naming context as a string
+ * format a drsuapi_DsReplicaObjectIdentifier naming context as a string for debugging
+ *
+ * When forming a DN for DB access you must use drs_ObjectIdentifier_to_dn()
  */
-char *drs_ObjectIdentifier_to_string(TALLOC_CTX *mem_ctx,
-				     struct drsuapi_DsReplicaObjectIdentifier *nc)
+char *drs_ObjectIdentifier_to_debug_string(TALLOC_CTX *mem_ctx,
+					   struct drsuapi_DsReplicaObjectIdentifier *nc)
 {
 	char *ret = NULL;
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
@@ -386,13 +388,172 @@ char *drs_ObjectIdentifier_to_string(TALLOC_CTX *mem_ctx,
 	return ret;
 }
 
-struct ldb_dn *drs_ObjectIdentifier_to_dn(TALLOC_CTX *mem_ctx,
-					  struct ldb_context *ldb,
-					  struct drsuapi_DsReplicaObjectIdentifier *nc)
+/*
+ * Safely convert a drsuapi_DsReplicaObjectIdentifier into an LDB DN
+ *
+ * We need to have GUID and SID prority and not allow extended
+ * components in the DN.
+ *
+ * We must also totally honour the prority even if the string DN is not valid or able to parse as a DN.
+ */
+static struct ldb_dn *drs_ObjectIdentifier_to_dn(TALLOC_CTX *mem_ctx,
+						 struct ldb_context *ldb,
+						 struct drsuapi_DsReplicaObjectIdentifier *nc)
+{
+	struct ldb_dn *new_dn = NULL;
+
+	if (!GUID_all_zero(&nc->guid)) {
+		struct GUID_txt_buf buf;
+		char *guid = GUID_buf_string(&nc->guid, &buf);
+
+		new_dn = ldb_dn_new_fmt(mem_ctx,
+					ldb,
+					"<GUID=%s>",
+					guid);
+		if (new_dn == NULL) {
+			DBG_ERR("Failed to prepare drs_ObjectIdentifier "
+				"GUID %s into a DN\n",
+				guid);
+			return NULL;
+		}
+
+		return new_dn;
+	}
+
+	if (nc->__ndr_size_sid != 0 && nc->sid.sid_rev_num != 0) {
+		struct dom_sid_buf buf;
+		char *sid = dom_sid_str_buf(&nc->sid, &buf);
+
+		new_dn = ldb_dn_new_fmt(mem_ctx,
+					ldb,
+					"<SID=%s>",
+					sid);
+		if (new_dn == NULL) {
+			DBG_ERR("Failed to prepare drs_ObjectIdentifier "
+				"SID %s into a DN\n",
+				sid);
+			return NULL;
+		}
+		return new_dn;
+	}
+
+	if (nc->__ndr_size_dn != 0 && nc->dn) {
+		int dn_comp_num = 0;
+		bool new_dn_valid = false;
+
+		new_dn = ldb_dn_new(mem_ctx, ldb, nc->dn);
+		if (new_dn == NULL) {
+			/* Set to WARNING as this is user-controlled, don't print the value into the logs */
+			DBG_WARNING("Failed to parse string DN in "
+				    "drs_ObjectIdentifier into an LDB DN\n");
+			return NULL;
+		}
+
+		new_dn_valid = ldb_dn_validate(new_dn);
+		if (!new_dn_valid) {
+			/*
+			 * Set to WARNING as this is user-controlled,
+			 * but can print the value into the logs as it
+			 * parsed a bit
+			 */
+			DBG_WARNING("Failed to validate string DN [%s] in "
+				    "drs_ObjectIdentifier as an LDB DN\n",
+				    ldb_dn_get_linearized(new_dn));
+			return NULL;
+		}
+
+		dn_comp_num = ldb_dn_get_comp_num(new_dn);
+		if (dn_comp_num <= 0) {
+			/*
+			 * Set to WARNING as this is user-controlled,
+			 * but can print the value into the logs as it
+			 * parsed a bit
+			 */
+			DBG_WARNING("DN [%s] in drs_ObjectIdentifier "
+				    "must have 1 or more components\n",
+				    ldb_dn_get_linearized(new_dn));
+			return NULL;
+		}
+
+		if (ldb_dn_is_special(new_dn)) {
+			/*
+			 * Set to WARNING as this is user-controlled,
+			 * but can print the value into the logs as it
+			 * parsed a bit
+			 */
+			DBG_WARNING("New string DN [%s] in "
+				    "drs_ObjectIdentifier is a "
+				    "special LDB DN\n",
+				    ldb_dn_get_linearized(new_dn));
+			return NULL;
+		}
+
+		/*
+		 * We want this just to be a string DN, extended
+		 * components are manually handled above
+		 */
+		if (ldb_dn_has_extended(new_dn)) {
+			/*
+			 * Set to WARNING as this is user-controlled,
+			 * but can print the value into the logs as it
+			 * parsed a bit
+			 */
+			DBG_WARNING("Refusing to parse New string DN [%s] in "
+				    "drs_ObjectIdentifier as an "
+				    "extended LDB DN "
+				    "(GUIDs and SIDs should be in the "
+				    ".guid and .sid IDL elelements, "
+				    "not in the string\n",
+				    ldb_dn_get_extended_linearized(mem_ctx,
+								   new_dn,
+								   1));
+			return NULL;
+		}
+		return new_dn;
+	}
+
+	DBG_WARNING("Refusing to parse empty string DN "
+		    "(and no GUID or SID) "
+		    "drs_ObjectIdentifier into a empty "
+		    "(eg RootDSE) LDB DN\n");
+	return NULL;
+}
+
+/*
+ * Safely convert a drsuapi_DsReplicaObjectIdentifier into a validated
+ * LDB DN of an existing DB entry, and/or find the NC root
+ *
+ * We need to have GUID and SID prority and not allow extended
+ * components in the DN.
+ *
+ * We must also totally honour the prority even if the string DN is
+ * not valid or able to parse as a DN.
+ *
+ * Finally, we must return the DN as found in the DB, as otherwise a
+ * subsequence ldb_dn_compare(dn, nc_root) will fail (as this is based
+ * on the string components).
+ */
+int drs_ObjectIdentifier_to_dn_and_nc_root(TALLOC_CTX *mem_ctx,
+					   struct ldb_context *ldb,
+					   struct drsuapi_DsReplicaObjectIdentifier *nc,
+					   struct ldb_dn **normalised_dn,
+					   struct ldb_dn **nc_root)
 {
-	char *dn_string = drs_ObjectIdentifier_to_string(mem_ctx, nc);
-	struct ldb_dn *new_dn;
-	new_dn = ldb_dn_new(mem_ctx, ldb, dn_string);
-	talloc_free(dn_string);
-	return new_dn;
+	int ret;
+	struct ldb_dn *new_dn = NULL;
+
+	new_dn = drs_ObjectIdentifier_to_dn(mem_ctx,
+					    ldb,
+					    nc);
+	if (new_dn == NULL) {
+		return LDB_ERR_INVALID_DN_SYNTAX;
+	}
+
+	ret = dsdb_normalise_dn_and_find_nc_root(ldb,
+						 mem_ctx,
+						 new_dn,
+						 normalised_dn,
+						 nc_root);
+	TALLOC_FREE(new_dn);
+	return ret;
 }
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index f5de9d82cdf..55940227106 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -3550,9 +3550,49 @@ int drsuapi_DsReplicaCursor_compare(const struct drsuapi_DsReplicaCursor *c1,
 	return GUID_compare(&c1->source_dsa_invocation_id, &c2->source_dsa_invocation_id);
 }
 
+/*
+ * Return the NTDS object for a GUID, confirming it is in the
+ * configuration partition and a nTDSDSA object
+ */
+int samdb_get_ntds_obj_by_guid(TALLOC_CTX *mem_ctx,
+			       struct ldb_context *sam_ctx,
+			       const struct GUID *objectGUID,
+			       const char **attrs,
+			       struct ldb_message **msg)
+{
+	int ret;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list