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

Jule Anger janger at samba.org
Wed Feb 1 17:27:01 UTC 2023


The branch, v4-18-test has been updated
       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()
      from  af00a0df70a s3/lib: Prevent use after free of messaging_ctdb_fde_ev structs

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


- Log -----------------------------------------------------------------
commit 65077cd390f8ec5153b8b3295da1f4251c8c1b03
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Feb 1 13:08:05 2023 +1300

    WHATSNEW: Add note about Azure AD cloud connect sync support
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(v4-18-test): Jule Anger <janger at samba.org>
    Autobuild-Date(v4-18-test): Wed Feb  1 17:26:50 UTC 2023 on atb-devel-224

commit c9b7fd177d4ec4589712f8acf6f084f650b95a5e
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 25 15:24:57 2023 +1300

    s4-drsuapi: Give an error that matches windows on destination_dsa_guid lookup failure
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Tue Jan 31 13:43:54 UTC 2023 on atb-devel-224
    
    (cherry picked from commit 0f2978bbc0ed5b65d75c20472650a749643312e7)

commit 68fcea19bd03d96f3ecfbcf1cdcaa39097ee401a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 25 16:01:48 2023 +1300

    s4-drsuapi: Clarify role of drs_security_access_check_nc_root()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 1838f349c94b878de1740af35351a2e8e0c8cffb)

commit 262fef5acbff53e6a4e8cc654ddf1ce7accc9e20
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 25 14:18:11 2023 +1300

    s4-rpc_server: Pre-check destination_dsa_guid in GetNCChanges for validity
    
    This allows our new tests to pass as these need to be checked first.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 115a3a10440f44ba11029be5ae3a05534a7b98c0)

commit 68edd5c1c7f0e6cbd929cd592b79f89cb2c8369f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 25 15:24:01 2023 +1300

    s4-drsuapi: Use samdb_get_ntds_obj_by_guid() to find RODC in REPL_SECRET
    
    We need to find the RODC per the destination_dsa_guid to mark the secrets as
    having been replicated, and by using samdb_get_ntds_obj_by_guid() we are stricter
    in the checks, as the RODC has to be the right objectClass (nTDSDSA) and under
    the CN=Configuration partition.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 09ec6a1db2d3b831548bf7d66475c486be29b1d1)

commit dc7497c3a4681c96fdf71e82db1b93e21214cc19
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 25 15:18:47 2023 +1300

    s4-dsdb: Require that the NTDS object is an nTDSDSA objectclass
    
    This should avoid a user being able to specify the GUID of a different
    type of object.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit adb776149e5ac0eb346992775610627106e1a986)

commit 29a89f07aa7b167adea921fd583b3b93ae0695f9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 25 15:17:44 2023 +1300

    s4-dsdb: Split samdb_get_ntds_obj_by_guid() out of samdb_is_rodc()
    
    This will allow the logic here to be tighened up and shared
    in the next few commits.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit d5a2af3feae98057ba29de444d308d499d633941)

commit 613d9b75499822be4a870fd78900922be779a638
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Dec 16 14:22:20 2022 +1300

    s4-rpc_server/drsuapi: Return correct error code for an invalid DN to EXOP_REPL_OBJ/EXOP_REPL_OBJ
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit cbe18353d8d7b2a35b965e4fc8c895ac497e67e8)

commit 64df0963f8c8f7e6f203780c5d2dbb61b749a439
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Jan 31 13:29:05 2023 +1300

    s4-drs: Make drs_ObjectIdentifier_to_dn() safer and able to cope with DummyDN values
    
    We want to totally ignore the string DN if there is a GUID,
    as clients like "Microsoft Azure AD connect cloud sync" will
    set a literal "DummyDN" string.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 73f3ece8b2b44ac4b3323a08fb969f29bf2b0380)

commit 84a952b01eeff32b70d71de48751d7f910bfea64
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Dec 12 09:47:36 2022 +1300

    s4-dsdb: rework drs_ObjectIdentifier_to_dn() into drs_ObjectIdentifier_to_dn_and_nc_root()
    
    This make this funciton the gatekeeper between the wire format and the
    internal struct ldb_dn, checking if the DN exists and which NC
    it belongs to along the way, and presenting only a DB-returned
    DN for internal processing.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit aee2039e63ceeb5e69a0461fb77e0f18278e4dc4)

commit 1a97e897f860e95e3f512fc0ee92b255c7496079
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Dec 12 16:15:44 2022 +1300

    s4-rpc_server/drsuapi: Use dsdb_normalise_dn_and_find_nc_root()
    
    This reuses the search done for dsdb_find_nc_root() to normalise the DN.
    
    This will allow a GUID-input DN to be compared safely with a RID Manager DN
    or Naming Context.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit e96dfc74b3ece40fe64a33aa8b8d810b576982bd)

commit feffb9ec5dfed472b92ba8879e74b19dd0381c55
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Dec 12 16:15:03 2022 +1300

    s4-dsdb: Add dsdb_normalise_dn_and_find_nc_root() around dsdb_find_nc_root()
    
    Reuse the search done for dsdb_find_nc_root() to normalise the DN.
    
    This will allow a GUID-input DN to be compared safely with a RID Manager DN
    or Naming Context.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 8e1122420efd11a91aa1c5d60c0cc8fd9ffaf157)

commit ab282dba3761d6dc8be3345daf61455571b4b1bf
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Dec 15 18:52:20 2022 +1300

    s4-dsdb: Add better debugging to dsdb_objects_have_same_nc()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 0f501b2316af6568003e520848c1ec80c286fd36)

commit 855c11c41460cadc28cfa7562020c2ab19af4958
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Dec 5 22:21:29 2022 +1300

    s4-dsdb: Make dsdb_find_nc_root() first try and use DSDB_CONTROL_CURRENT_PARTITION_OID
    
    This allows lookup of a DN with a GUID only or GUID and string,
    possibly not yet in the database, yet still getting the correct result.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit d0444be4b74bdad6a731bc5fcf86da6142b03539)

commit 92f56081291183bb9af084fc9576e6a13ca7eaed
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Jan 26 09:44:01 2023 +1300

    s4-dsdb: Schedule SD propegation only after successful rename
    
    This avoids needing to anticipate errors that the rename might give
    while allowing the dsdb_find_nc_root() routine to become stricter.
    
    The problem is that dsdb_find_nc_root() will soon do a real search and
    so fail more often, but these failures will give "wrong" error codes.
    
    We do not need to do this work if the operation fails, so put this in
    the callback.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 7032b86cd5c1456318558ed95f8890e353117ced)

commit f70fd3385f331c7430e1e16869cdeba9619a10f0
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Dec 15 16:02:55 2022 +1300

    s4-selftest/drs: Confirm GetNCChanges REPL_SECRET works with a DummyDN and real GUID
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 7c43388576f768db564aaf15a47d3f9ce5796fb3)

commit 87ed6e23061293c470022152ac0b20a73f5ce022
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Dec 15 16:02:27 2022 +1300

    s4-selftest/drs: Confirm GetNCChanges full replication works with a DummyDN and real GUID
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 539221dda33f03a1abf5ee5f3153db0fe1a9bfe6)

commit a40d3697e1a72d6985ca15a4236fbcc1a1322387
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Dec 2 15:30:05 2022 +1300

    s4-selftest/drs: Confirm GetNCChanges REPL_OBJ works with a DummyDN and real GUID
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 70faccae6d595056174af8d63b3437c9fe3805aa)

commit 7712ef7288aae848dee1d4cc4346585cb2405499
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Dec 2 11:56:38 2022 +1300

    s4-selftest/drs Allow re-run of DRS tests after failed cleanup
    
    Using a random base is a useful start, even if the better solution also includes a self.AddCleanup()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 3204d1350b21704474e577cb5f3f2439b673c421)

commit 11540d828f79db72423550fb610e914579ce3ceb
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Dec 2 11:42:55 2022 +1300

    s4-selftest/drs Allow some DRS tests to operate against an IP
    
    This is not comprehensive, but makes some manual test runs easier by
    avoiding the need for DNS names to resolve.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit a150a2dcb1fc7fc7f606838de17ad4d3e6072bda)

commit 501728cdcfed2289a5f04c66114b06278299966a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Dec 2 10:07:53 2022 +1300

    s4-selftest/drs Add test of expected return code for invaid DNs in GetNCChanges
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit bee45e6b29b97e0cab19a9c3cf692d9a7585a717)

commit d0c2305b35af0c39cfababbd2e3c5302047bb6aa
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Dec 15 12:05:55 2022 +1300

    s4-dsdb: Add tests of SamDB.get_nc_root()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10635
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 2c7bb58703c1fa26782ac6959ea7d81fccf3905c)

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

Summary of changes:
 WHATSNEW.txt                                |   6 +
 python/samba/tests/dsdb.py                  | 122 ++++++++++
 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 +-
 14 files changed, 1180 insertions(+), 151 deletions(-)


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 46c9c5fadc1..12b91486c2e 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -106,6 +106,12 @@ 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
 ================
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/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;
+	struct ldb_result *res;
+	struct GUID_txt_buf guid_buf;
+	char *guid_str = GUID_buf_string(objectGUID, &guid_buf);
+	struct ldb_dn *config_dn = NULL;
+
+	config_dn = ldb_get_config_basedn(sam_ctx);
+	if (config_dn == NULL) {
+		return ldb_operr(sam_ctx);
+	}
+
+	ret = dsdb_search(sam_ctx,
+			  mem_ctx,
+			  &res,
+			  config_dn,
+			  LDB_SCOPE_SUBTREE,
+			  attrs,
+			  DSDB_SEARCH_ONE_ONLY,
+			  "(&(objectGUID=%s)(objectClass=nTDSDSA))",
+			  guid_str);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+	if (msg) {
+		*msg = talloc_steal(mem_ctx, res->msgs[0]);
+	}
+	TALLOC_FREE(res);
+	return ret;
+}
+
 
 /*
-  see if a computer identified by its invocationId is a RODC
+  see if a computer identified by its objectGUID is a RODC
 */
 int samdb_is_rodc(struct ldb_context *sam_ctx, const struct GUID *objectGUID, bool *is_rodc)
 {
@@ -3561,20 +3601,15 @@ int samdb_is_rodc(struct ldb_context *sam_ctx, const struct GUID *objectGUID, bo
 	   3) if not present then not a RODC
 	   4) if present and TRUE then is a RODC
 	*/
-	struct ldb_dn *config_dn;
 	const char *attrs[] = { "msDS-isRODC", NULL };
 	int ret;
-	struct ldb_result *res;
+	struct ldb_message *msg;
 	TALLOC_CTX *tmp_ctx = talloc_new(sam_ctx);
 
-	config_dn = ldb_get_config_basedn(sam_ctx);
-	if (!config_dn) {
-		talloc_free(tmp_ctx);
-		return ldb_operr(sam_ctx);
-	}
-
-	ret = dsdb_search(sam_ctx, tmp_ctx, &res, config_dn, LDB_SCOPE_SUBTREE, attrs,
-			  DSDB_SEARCH_ONE_ONLY, "objectGUID=%s", GUID_string(tmp_ctx, objectGUID));
+	ret = samdb_get_ntds_obj_by_guid(tmp_ctx,
+					 sam_ctx,
+					 objectGUID,
+					 attrs, &msg);
 
 	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
 		*is_rodc = false;
@@ -3590,7 +3625,7 @@ int samdb_is_rodc(struct ldb_context *sam_ctx, const struct GUID *objectGUID, bo
 		return ret;
 	}
 
-	ret = ldb_msg_find_attr_as_bool(res->msgs[0], "msDS-isRODC", 0);
+	ret = ldb_msg_find_attr_as_bool(msg, "msDS-isRODC", 0);
 	*is_rodc = (ret == 1);
 
 	talloc_free(tmp_ctx);
@@ -4124,10 +4159,12 @@ static int dsdb_dn_compare_ptrs(struct ldb_dn **dn1, struct ldb_dn **dn2)
 }
 
 /*
-  find a NC root given a DN within the NC
+  find a NC root given a DN within the NC by reading the rootDSE namingContexts
  */
-int dsdb_find_nc_root(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn,
-		      struct ldb_dn **nc_root)
+static int dsdb_find_nc_root_string_based(struct ldb_context *samdb,
+					  TALLOC_CTX *mem_ctx,
+					  struct ldb_dn *dn,
+					  struct ldb_dn **nc_root)
 {
 	const char *root_attrs[] = { "namingContexts", NULL };
 	TALLOC_CTX *tmp_ctx;
@@ -4212,6 +4249,266 @@ int dsdb_find_nc_root(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, struct ldb
        return ldb_error(samdb, LDB_ERR_NO_SUCH_OBJECT, __func__);
 }
 
+struct dsdb_get_partition_and_dn {
+	TALLOC_CTX *mem_ctx;
+	unsigned int count;
+	struct ldb_dn *dn;
+	struct ldb_dn *partition_dn;
+	bool want_partition_dn;
+};
+
+static int dsdb_get_partition_and_dn(struct ldb_request *req,
+				     struct ldb_reply *ares)
+{
+	int ret;
+	struct dsdb_get_partition_and_dn *context = req->context;
+	struct ldb_control *partition_ctrl = NULL;
+	struct dsdb_control_current_partition *partition = NULL;
+
+	if (!ares) {
+		return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+	}
+	if (ares->error != LDB_SUCCESS
+	    && ares->error != LDB_ERR_NO_SUCH_OBJECT) {
+		return ldb_request_done(req, ares->error);
+	}
+
+	switch (ares->type) {
+	case LDB_REPLY_ENTRY:
+		if (context->count != 0) {
+			return ldb_request_done(req,
+						LDB_ERR_CONSTRAINT_VIOLATION);
+		}
+		context->count++;
+
+		context->dn = talloc_steal(context->mem_ctx,
+					   ares->message->dn);
+		break;
+
+	case LDB_REPLY_REFERRAL:
+		talloc_free(ares);
+		return ldb_request_done(req, LDB_SUCCESS);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list