[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed May 31 05:00:01 UTC 2023


The branch, master has been updated
       via  9aa440d52d7 s4-rpc_server: Filter via dsdb_dc_functional_level() before we are returning a lookup directly
       via  0f3abb291fd s3-libads: Also handle the DS_WEB_SERVICE_REQUIRED flag in check_cldap_reply_required_flags()
       via  63e2db8206e s4-libads: Confirm newer functional levels in check_cldap_reply_required_flags()
       via  ff310caabd5 librpc: No longer consider the DS_DIRECTORY_SERVICE_{8,9,10}_REQUIRED bits as invalid
       via  6f30eca3bbb sefltest: Improve getdcname test by confirming the _REQUIRED flag behaviours
       via  3c25ddb1ce9 selftest: Fix remaining incorrect references to 2012 -> 2012R2 FL in GetDCNameEx test
       via  49537a41709 selftest: Change self.assertTrue(x is not None) -> self.assertIsNotNone(x)
      from  2a0e53374dd selftest: Confirm that the flags like DS_DIRECTORY_SERVICE_9_REQUIRED work

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


- Log -----------------------------------------------------------------
commit 9aa440d52d78d5f91607b4cb5816ae99d75d0838
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue May 30 18:03:13 2023 +1200

    s4-rpc_server: Filter via dsdb_dc_functional_level() before we are returning a lookup directly
    
    Otherwise, punt to winbindd to see if another DC has this capability.
    
    This allows a FL2008-emulating DC to forward a request to a
    2012R2-emlating DC, particularly in another domain.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed May 31 04:59:01 UTC 2023 on atb-devel-224

commit 0f3abb291fd58f83c2a3f765aa5e50771e8ba9ab
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue May 30 16:38:22 2023 +1200

    s3-libads: Also handle the DS_WEB_SERVICE_REQUIRED flag in check_cldap_reply_required_flags()
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 63e2db8206e683293d4b347ffc9ac8ce344b1111
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue May 30 14:28:42 2023 +1200

    s4-libads: Confirm newer functional levels in check_cldap_reply_required_flags()
    
    This will allow us to require that the target DC has FL 2008,
    2012, 2012R2 or 2016.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit ff310caabd5547b7d098ea7770869d04a58a11db
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue May 30 14:08:47 2023 +1200

    librpc: No longer consider the DS_DIRECTORY_SERVICE_{8,9,10}_REQUIRED bits as invalid
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 6f30eca3bbbc147825bf32bb1f194d275b383a92
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue May 30 16:06:04 2023 +1200

    sefltest: Improve getdcname test by confirming the _REQUIRED flag behaviours
    
    We do this by checking what the underlying CLDAP netlogon call returns.
    
    This also validates that behaviour.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 3c25ddb1ce9932c0fd71965f690228ce6084560a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue May 30 15:11:31 2023 +1200

    selftest: Fix remaining incorrect references to 2012 -> 2012R2 FL in GetDCNameEx test
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 49537a41709a09ed73c65bfff2241ec3aa3e2ca8
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed May 31 09:08:59 2023 +1200

    selftest: Change self.assertTrue(x is not None) -> self.assertIsNotNone(x)
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

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

Summary of changes:
 librpc/idl/netlogon.idl                       |  10 +-
 python/samba/tests/getdcname.py               | 243 ++++++++++++++++++++++----
 selftest/knownfail.d/getdcname                |   3 -
 source3/libads/cldap.c                        |  16 ++
 source4/rpc_server/netlogon/dcerpc_netlogon.c |  51 ++++--
 5 files changed, 264 insertions(+), 59 deletions(-)
 delete mode 100644 selftest/knownfail.d/getdcname


Changeset truncated at 500 lines:

diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl
index 3a821c0a905..95487638bbb 100644
--- a/librpc/idl/netlogon.idl
+++ b/librpc/idl/netlogon.idl
@@ -1174,13 +1174,9 @@ interface netlogon
 					 DS_TRY_NEXTCLOSEST_SITE |
 					 DS_DIRECTORY_SERVICE_6_REQUIRED |
 					 DS_WEB_SERVICE_REQUIRED |
-					 /*
-					  * For now we skip these until
-					  * we have test for them:
-					  * DS_DIRECTORY_SERVICE_8_REQUIRED |
-					  * DS_DIRECTORY_SERVICE_9_REQUIRED |
-					  * DS_DIRECTORY_SERVICE_10_REQUIRED |
-					  */
+					 DS_DIRECTORY_SERVICE_8_REQUIRED |
+					 DS_DIRECTORY_SERVICE_9_REQUIRED |
+					 DS_DIRECTORY_SERVICE_10_REQUIRED |
 					 DS_RETURN_FLAT_NAME |
 					 DS_RETURN_DNS_NAME);
 
diff --git a/python/samba/tests/getdcname.py b/python/samba/tests/getdcname.py
index 55116bf98dc..f6c4ea2e88c 100644
--- a/python/samba/tests/getdcname.py
+++ b/python/samba/tests/getdcname.py
@@ -24,9 +24,9 @@ from samba import WERRORError, werror
 import samba.tests
 import os
 from samba.credentials import Credentials
-from samba.dcerpc import netlogon
+from samba.dcerpc import netlogon, nbt
 from samba.dcerpc.misc import GUID
-
+from samba.net import Net
 
 class GetDCNameEx(samba.tests.TestCase):
 
@@ -71,9 +71,9 @@ class GetDCNameEx(samba.tests.TestCase):
         """
         response = self._call_get_dc_name(ex2=True)
 
-        self.assertTrue(response.dc_unc is not None)
+        self.assertIsNotNone(response.dc_unc)
         self.assertTrue(response.dc_unc.startswith('\\\\'))
-        self.assertTrue(response.dc_address is not None)
+        self.assertIsNotNone(response.dc_address)
         self.assertTrue(response.dc_address.startswith('\\\\'))
 
         self.assertTrue(response.domain_name.lower() ==
@@ -105,9 +105,9 @@ class GetDCNameEx(samba.tests.TestCase):
         response = self._call_get_dc_name(domain=self.realm,
                                           ex2=True)
 
-        self.assertTrue(response_trust.dc_unc is not None)
+        self.assertIsNotNone(response_trust.dc_unc)
         self.assertTrue(response_trust.dc_unc.startswith('\\\\'))
-        self.assertTrue(response_trust.dc_address is not None)
+        self.assertIsNotNone(response_trust.dc_address)
         self.assertTrue(response_trust.dc_address.startswith('\\\\'))
 
         self.assertNotEqual(response_trust.dc_unc,
@@ -142,9 +142,9 @@ class GetDCNameEx(samba.tests.TestCase):
         response_trust = self._call_get_dc_name(domain=self.trust_realm,
                                                 flags=netlogon.DS_RETURN_DNS_NAME)
 
-        self.assertTrue(response_trust.dc_unc is not None)
+        self.assertIsNotNone(response_trust.dc_unc)
         self.assertTrue(response_trust.dc_unc.startswith('\\\\'))
-        self.assertTrue(response_trust.dc_address is not None)
+        self.assertIsNotNone(response_trust.dc_address)
         self.assertTrue(response_trust.dc_address.startswith('\\\\'))
 
         self.assertEqual(response_trust.domain_name.lower(),
@@ -163,9 +163,9 @@ class GetDCNameEx(samba.tests.TestCase):
                                                 site_name=site,
                                                 flags=netlogon.DS_RETURN_DNS_NAME)
 
-        self.assertTrue(response_trust.dc_unc is not None)
+        self.assertIsNotNone(response_trust.dc_unc)
         self.assertTrue(response_trust.dc_unc.startswith('\\\\'))
-        self.assertTrue(response_trust.dc_address is not None)
+        self.assertIsNotNone(response_trust.dc_address)
         self.assertTrue(response_trust.dc_address.startswith('\\\\'))
 
         self.assertEqual(response_trust.domain_name.lower(),
@@ -226,15 +226,15 @@ class GetDCNameEx(samba.tests.TestCase):
         except WERRORError as e:
             self.fail("Unable to get empty string site result: " + str(e))
 
-        self.assertTrue(response_trust.dc_unc is not None)
+        self.assertIsNotNone(response_trust.dc_unc)
         self.assertTrue(response_trust.dc_unc.startswith('\\\\'))
-        self.assertTrue(response_trust.dc_address is not None)
+        self.assertIsNotNone(response_trust.dc_address)
         self.assertTrue(response_trust.dc_address.startswith('\\\\'))
 
         self.assertEqual(response_trust.domain_name.lower(),
                          self.trust_realm.lower())
 
-        self.assertTrue(response_trust.dc_site_name is not None)
+        self.assertIsNotNone(response_trust.dc_site_name)
         self.assertNotEqual('', response_trust.dc_site_name)
 
     def test_get_dc_over_winbind_netbios(self):
@@ -248,7 +248,7 @@ class GetDCNameEx(samba.tests.TestCase):
         except WERRORError as e:
             self.fail("Failed to succeed over winbind: " + str(e))
 
-        self.assertTrue(response_trust is not None)
+        self.assertIsNotNone(response_trust)
         self.assertEqual(response_trust.domain_name.lower(),
                          self.trust_realm.lower())
 
@@ -272,7 +272,7 @@ class GetDCNameEx(samba.tests.TestCase):
             self.fail("get_dc_name (domain=%s,site=%s) over winbind failed: %s"
                       % (self.trust_domain, site, e))
 
-        self.assertTrue(response_trust is not None)
+        self.assertIsNotNone(response_trust)
         self.assertEqual(response_trust.domain_name.lower(),
                          self.trust_realm.lower())
 
@@ -291,9 +291,9 @@ class GetDCNameEx(samba.tests.TestCase):
         except WERRORError as e:
             self.fail("Unable to get NULL domain GUID result: " + str(e))
 
-        self.assertTrue(response_trust.dc_unc is not None)
+        self.assertIsNotNone(response_trust.dc_unc)
         self.assertTrue(response_trust.dc_unc.startswith('\\\\'))
-        self.assertTrue(response_trust.dc_address is not None)
+        self.assertIsNotNone(response_trust.dc_address)
         self.assertTrue(response_trust.dc_address.startswith('\\\\'))
 
         self.assertEqual(response_trust.domain_name.lower(),
@@ -310,9 +310,9 @@ class GetDCNameEx(samba.tests.TestCase):
                                           site_name=site,
                                           flags=netlogon.DS_RETURN_DNS_NAME)
 
-        self.assertTrue(response.dc_unc is not None)
+        self.assertIsNotNone(response.dc_unc)
         self.assertTrue(response.dc_unc.startswith('\\\\'))
-        self.assertTrue(response.dc_address is not None)
+        self.assertIsNotNone(response.dc_address)
         self.assertTrue(response.dc_address.startswith('\\\\'))
 
         self.assertEqual(response.domain_name.lower(),
@@ -371,15 +371,15 @@ class GetDCNameEx(samba.tests.TestCase):
         except WERRORError as e:
             self.fail("Unable to get empty string site result: " + str(e))
 
-        self.assertTrue(response.dc_unc is not None)
+        self.assertIsNotNone(response.dc_unc)
         self.assertTrue(response.dc_unc.startswith('\\\\'))
-        self.assertTrue(response.dc_address is not None)
+        self.assertIsNotNone(response.dc_address)
         self.assertTrue(response.dc_address.startswith('\\\\'))
 
         self.assertEqual(response.domain_name.lower(),
                          self.realm.lower())
 
-        self.assertTrue(response.dc_site_name is not None)
+        self.assertIsNotNone(response.dc_site_name)
         self.assertNotEqual('', response.dc_site_name)
 
     def test_get_dc_netbios(self):
@@ -392,7 +392,7 @@ class GetDCNameEx(samba.tests.TestCase):
         except WERRORError as e:
             self.fail("Failed to succeed over winbind: " + str(e))
 
-        self.assertTrue(response is not None)
+        self.assertIsNotNone(response)
         self.assertEqual(response.domain_name.lower(),
                          self.realm.lower())
 
@@ -408,7 +408,7 @@ class GetDCNameEx(samba.tests.TestCase):
         except WERRORError as e:
             self.fail("Failed to succeed over winbind: " + str(e))
 
-        self.assertTrue(response is not None)
+        self.assertIsNotNone(response)
         self.assertEqual(response.domain_name.lower(),
                          self.realm.lower())
 
@@ -422,9 +422,9 @@ class GetDCNameEx(samba.tests.TestCase):
                                           domain_guid=null_guid,
                                           flags=netlogon.DS_RETURN_DNS_NAME)
 
-        self.assertTrue(response.dc_unc is not None)
+        self.assertIsNotNone(response.dc_unc)
         self.assertTrue(response.dc_unc.startswith('\\\\'))
-        self.assertTrue(response.dc_address is not None)
+        self.assertIsNotNone(response.dc_address)
         self.assertTrue(response.dc_address.startswith('\\\\'))
 
         self.assertEqual(response.domain_name.lower(),
@@ -435,9 +435,9 @@ class GetDCNameEx(samba.tests.TestCase):
         response = self._call_get_dc_name(domain='',
                                           flags=netlogon.DS_RETURN_DNS_NAME)
 
-        self.assertTrue(response.dc_unc is not None)
+        self.assertIsNotNone(response.dc_unc)
         self.assertTrue(response.dc_unc.startswith('\\\\'))
-        self.assertTrue(response.dc_address is not None)
+        self.assertIsNotNone(response.dc_address)
         self.assertTrue(response.dc_address.startswith('\\\\'))
 
         self.assertEqual(response.domain_name.lower(),
@@ -455,14 +455,23 @@ class GetDCNameEx(samba.tests.TestCase):
             enum, estr = e.args
             self.fail(f"netr_DsRGetDCNameEx failed: {estr}")
 
-        self.assertTrue(response_trust.dc_unc is not None)
+        self.assertIsNotNone(response_trust.dc_unc)
         self.assertTrue(response_trust.dc_unc.startswith('\\\\'))
-        self.assertTrue(response_trust.dc_address is not None)
+        self.assertIsNotNone(response_trust.dc_address)
         self.assertTrue(response_trust.dc_address.startswith('\\\\'))
 
         self.assertEqual(response_trust.domain_name.lower(),
                          self.trust_realm.lower())
 
+        # Now check the CLDAP netlogon response matches the above
+        dc_ip = response_trust.dc_address[2:]
+
+        net = Net(creds=self.creds, lp=self.lp)
+        cldap_netlogon_reply = net.finddc(domain=self.trust_realm, address=dc_ip,
+                                          flags=(nbt.NBT_SERVER_LDAP |
+                                                 nbt.NBT_SERVER_DS))
+        self.assertTrue(cldap_netlogon_reply.server_type & nbt.NBT_SERVER_DS_9)
+
     def test_get_dc_direct_need_2012r2_but_not_found(self):
         """Test requring that we have a FL2012R2 DC as answer, aginst the FL2008R2 domain
 
@@ -477,11 +486,77 @@ class GetDCNameEx(samba.tests.TestCase):
             response = self._call_get_dc_name(domain=self.realm,
                                               flags=netlogon.DS_RETURN_DNS_NAME|netlogon.DS_DIRECTORY_SERVICE_9_REQUIRED)
 
-            self.fail("Failed to detect requirement for 2012 that is not met")
+            self.fail("Failed to detect that requirement for 2012R2 was not met")
+        except WERRORError as e:
+            enum, estr = e.args
+            if enum != werror.WERR_NO_SUCH_DOMAIN:
+                self.fail(f"Incorrect error {estr} from GetDcNameEx looking for 2012R2 DC that was not available")
+
+    def test_get_dc_direct_need_web_but_not_found(self):
+        """Test requring that we (do not) have a AD Web Services on the DC
+
+        This test requires that the DC does not advertise AD Web Services
+
+        This is used as a test that is easy for a modern windows
+        version to fail, as (say) Windows 2022 will succeed for all
+        the DS_DIRECTORY_SERVICE_* flags.  Disable AD Web services in
+        services.mmc to run this test successfully.
+
+        """
+        self.assertIsNotNone(self.realm)
+
+
+        try:
+            response = self._call_get_dc_name(domain=self.realm,
+                                              flags=netlogon.DS_RETURN_DNS_NAME|netlogon.DS_WEB_SERVICE_REQUIRED)
+
+            self.fail("Failed to detect that requirement for Web Services was not")
+        except WERRORError as e:
+            enum, estr = e.args
+            if enum != werror.WERR_NO_SUCH_DOMAIN:
+                self.fail(f"Incorrect error {estr} from GetDcNameEx looking for AD Web Services enabled DC that should not be available")
+
+        # Now check the CLDAP netlogon response matches the above - that the bit was not set
+        net = Net(creds=self.creds, lp=self.lp)
+        cldap_netlogon_reply = net.finddc(domain=self.realm,
+                                          flags=(nbt.NBT_SERVER_LDAP |
+                                                 nbt.NBT_SERVER_DS))
+        # We can assert this, even without looking for a particular
+        # DC, as if any DC has WEB_SERVICE we would have got it above.
+        self.assertFalse(cldap_netlogon_reply.server_type & nbt.NBT_SERVER_ADS_WEB_SERVICE)
+
+    def test_get_dc_winbind_need_web_but_not_found(self):
+        """Test requring that we (do not) have a AD Web Services on the trusted DC
+
+        This test requires that the DC does not advertise AD Web Services
+
+        This is used as a test that is easy for a modern windows
+        version to fail, as (say) Windows 2022 will succeed for all
+        the DS_DIRECTORY_SERVICE_* flags.  Disable AD Web services in
+        services.mmc to run this test successfully.
+
+        """
+        self.assertIsNotNone(self.trust_realm)
+
+
+        try:
+            response = self._call_get_dc_name(domain=self.trust_realm,
+                                              flags=netlogon.DS_RETURN_DNS_NAME|netlogon.DS_WEB_SERVICE_REQUIRED)
+
+            self.fail("Failed to detect that requirement for Web Services was not")
         except WERRORError as e:
             enum, estr = e.args
             if enum != werror.WERR_NO_SUCH_DOMAIN:
-                self.fail("Failed to detect requirement for 2012 that is not met")
+                self.fail(f"Incorrect error {estr} from GetDcNameEx looking for AD Web Services enabled DC that should not be available")
+
+        # Now check the CLDAP netlogon response matches the above - that the bit was not set
+        net = Net(creds=self.creds, lp=self.lp)
+        cldap_netlogon_reply = net.finddc(domain=self.trust_realm,
+                                          flags=(nbt.NBT_SERVER_LDAP |
+                                                 nbt.NBT_SERVER_DS))
+        # We can assert this, even without looking for a particular
+        # DC, as if any DC has WEB_SERVICE we would have got it above.
+        self.assertFalse(cldap_netlogon_reply.server_type & nbt.NBT_SERVER_ADS_WEB_SERVICE)
 
     def test_get_dc_direct_need_2012r2(self):
         """Test requring that we have a FL2012R2 DC as answer
@@ -494,14 +569,23 @@ class GetDCNameEx(samba.tests.TestCase):
         response_trust = self._call_get_dc_name(domain=self.trust_realm,
                                                 flags=netlogon.DS_RETURN_DNS_NAME|netlogon.DS_DIRECTORY_SERVICE_9_REQUIRED)
 
-        self.assertTrue(response_trust.dc_unc is not None)
+        self.assertIsNotNone(response_trust.dc_unc)
         self.assertTrue(response_trust.dc_unc.startswith('\\\\'))
-        self.assertTrue(response_trust.dc_address is not None)
+        self.assertIsNotNone(response_trust.dc_address)
         self.assertTrue(response_trust.dc_address.startswith('\\\\'))
 
         self.assertEqual(response_trust.domain_name.lower(),
                          self.trust_realm.lower())
 
+        # Now check the CLDAP netlogon response matches the above
+        dc_ip = response_trust.dc_address[2:]
+
+        net = Net(creds=self.creds, lp=self.lp)
+        cldap_netlogon_reply = net.finddc(domain=self.trust_realm, address=dc_ip,
+                                          flags=(nbt.NBT_SERVER_LDAP |
+                                                 nbt.NBT_SERVER_DS))
+        self.assertTrue(cldap_netlogon_reply.server_type & nbt.NBT_SERVER_DS_9)
+
     def test_get_dc_winbind_need_2012r2_but_not_found(self):
         """Test requring that we have a FL2012R2 DC as answer, aginst the FL2008R2 domain
 
@@ -519,11 +603,98 @@ class GetDCNameEx(samba.tests.TestCase):
             response = self._call_get_dc_name(domain=self.realm,
                                               flags=netlogon.DS_RETURN_DNS_NAME|netlogon.DS_DIRECTORY_SERVICE_9_REQUIRED)
 
-            self.fail("Failed to detect requirement for 2012 that is not met")
+            self.fail("Failed to detect requirement for 2012R2 that is not met")
+        except WERRORError as e:
+            enum, estr = e.args
+            if enum != werror.WERR_NO_SUCH_DOMAIN:
+                self.fail("Failed to detect requirement for 2012R2 that is not met")
+
+        # Now check the CLDAP netlogon response matches the above - that the DS_9 bit was not set
+        net = Net(creds=self.creds, lp=self.lp)
+        cldap_netlogon_reply = net.finddc(domain=self.realm,
+                                          flags=(nbt.NBT_SERVER_LDAP |
+                                                 nbt.NBT_SERVER_DS))
+        self.assertFalse(cldap_netlogon_reply.server_type & nbt.NBT_SERVER_DS_9)
+
+    def test_get_dc_winbind_need_2012r2_but_not_found_fallback(self):
+        """Test requring that we have a FL2012R2 DC as answer, aginst the
+        FL2008R2 domain, then trying for just FL2008R2 (to show caching bugs)
+
+        This test requires that the DC in the FL2008R2 does not claim
+        to be 2012R2 capable (off by default in Samba)
+
+        """
+        self.assertIsNotNone(self.realm)
+
+        self.netlogon_conn = netlogon.netlogon(f"ncacn_ip_tcp:{self.trust_server}",
+                                               self.get_loadparm())
+
+
+        try:
+            response = self._call_get_dc_name(domain=self.realm,
+                                              flags=netlogon.DS_RETURN_DNS_NAME|netlogon.DS_DIRECTORY_SERVICE_9_REQUIRED)
+
+            self.fail("Failed to detect requirement for 2012R2 that is not met")
+        except WERRORError as e:
+            enum, estr = e.args
+            if enum != werror.WERR_NO_SUCH_DOMAIN:
+                self.fail("Failed to detect requirement for 2012R2 that is not met")
+
+        try:
+            response = self._call_get_dc_name(domain=self.realm,
+                                              flags=netlogon.DS_RETURN_DNS_NAME|netlogon.DS_DIRECTORY_SERVICE_6_REQUIRED)
+
+        except WERRORError as e:
+            enum, estr = e.args
+            self.fail("Unexpectedly failed to find 2008 DC")
+
+        dc_ip = response.dc_address[2:]
+
+        net = Net(creds=self.creds, lp=self.lp)
+        cldap_netlogon_reply = net.finddc(domain=self.realm, address=dc_ip,
+                                          flags=(nbt.NBT_SERVER_LDAP |
+                                                 nbt.NBT_SERVER_DS))
+        self.assertTrue(cldap_netlogon_reply.server_type & nbt.NBT_SERVER_FULL_SECRET_DOMAIN_6)
+
+    def test_get_dc_direct_need_2012r2_but_not_found_fallback(self):
+        """Test requring that we have a FL2012R2 DC as answer, aginst the
+        FL2008R2 domain, then trying for just FL2008R2 (to show caching bugs)
+
+        This test requires that the DC in the FL2008R2 does not claim
+        to be 2012R2 capable (off by default in Samba)
+
+        """
+        self.assertIsNotNone(self.realm)
+
+        self.netlogon_conn = netlogon.netlogon(f"ncacn_ip_tcp:{self.server}",
+                                               self.get_loadparm())
+
+
+        try:
+            response = self._call_get_dc_name(domain=self.realm,
+                                              flags=netlogon.DS_RETURN_DNS_NAME|netlogon.DS_DIRECTORY_SERVICE_9_REQUIRED)
+
+            self.fail("Failed to detect requirement for 2012R2 that is not met")
         except WERRORError as e:
             enum, estr = e.args
             if enum != werror.WERR_NO_SUCH_DOMAIN:
-                self.fail("Failed to detect requirement for 2012 that is not met")
+                self.fail("Failed to detect requirement for 2012R2 that is not met")
+
+        try:
+            response = self._call_get_dc_name(domain=self.realm,
+                                              flags=netlogon.DS_RETURN_DNS_NAME|netlogon.DS_DIRECTORY_SERVICE_6_REQUIRED)
+
+        except WERRORError as e:
+            enum, estr = e.args
+            self.fail("Unexpectedly failed to find 2008 DC")
+
+        dc_ip = response.dc_address[2:]
+
+        net = Net(creds=self.creds, lp=self.lp)
+        cldap_netlogon_reply = net.finddc(domain=self.realm, address=dc_ip,
+                                          flags=(nbt.NBT_SERVER_LDAP |
+                                                 nbt.NBT_SERVER_DS))
+        self.assertTrue(cldap_netlogon_reply.server_type & nbt.NBT_SERVER_FULL_SECRET_DOMAIN_6)
 
     # TODO Thorough tests of domain GUID
     #
diff --git a/selftest/knownfail.d/getdcname b/selftest/knownfail.d/getdcname
deleted file mode 100644
index a0091c0e7dc..00000000000
--- a/selftest/knownfail.d/getdcname
+++ /dev/null
@@ -1,3 +0,0 @@
-^samba.tests.getdcname.samba.tests.getdcname.GetDCNameEx.test_get_dc_direct_need_2012r2_but_not_found
-^samba.tests.getdcname.samba.tests.getdcname.GetDCNameEx.test_get_dc_winbind_need_2012r2
-^samba.tests.getdcname.samba.tests.getdcname.GetDCNameEx.test_get_dc_winbind_need_2012r2_but_not_found
diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c
index c44201ab8b5..56c2537ffa9 100644
--- a/source3/libads/cldap.c
+++ b/source3/libads/cldap.c
@@ -79,9 +79,25 @@ bool check_cldap_reply_required_flags(uint32_t ret_flags,
 	if (req_flags & DS_TIMESERV_REQUIRED)
 		RETURN_ON_FALSE(ret_flags & NBT_SERVER_TIMESERV);
 
+	if (req_flags & DS_WEB_SERVICE_REQUIRED)
+		RETURN_ON_FALSE(ret_flags & NBT_SERVER_ADS_WEB_SERVICE);
+
 	if (req_flags & DS_WRITABLE_REQUIRED)
 		RETURN_ON_FALSE(ret_flags & NBT_SERVER_WRITABLE);
 
+	if (req_flags & DS_DIRECTORY_SERVICE_6_REQUIRED)
+		RETURN_ON_FALSE(ret_flags & (NBT_SERVER_SELECT_SECRET_DOMAIN_6
+					     |NBT_SERVER_FULL_SECRET_DOMAIN_6));
+
+	if (req_flags & DS_DIRECTORY_SERVICE_8_REQUIRED)
+		RETURN_ON_FALSE(ret_flags & NBT_SERVER_DS_8);
+
+	if (req_flags & DS_DIRECTORY_SERVICE_9_REQUIRED)
+		RETURN_ON_FALSE(ret_flags & NBT_SERVER_DS_9);
+
+	if (req_flags & DS_DIRECTORY_SERVICE_10_REQUIRED)
+		RETURN_ON_FALSE(ret_flags & NBT_SERVER_DS_10);
+
 	return true;
 }
 
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index b06b542791d..9d9b6c792ab 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -3192,7 +3192,9 @@ static WERROR dcesrv_netr_DsRGetDCName_base_call(struct dcesrv_netr_DsRGetDCName
 	const char *domain_name = NULL;
 	const char *pdc_ip;
 	bool different_domain = true;
+	bool force_remote_lookup = false;
 	uint32_t valid_flags;
+	uint32_t this_dc_valid_flags;
 	int dc_level;
 
 	ZERO_STRUCTP(r->out.info);
@@ -3257,17 +3259,8 @@ static WERROR dcesrv_netr_DsRGetDCName_base_call(struct dcesrv_netr_DsRGetDCName
 	 * ...
 	 */
 
-	dc_level = dsdb_dc_functional_level(sam_ctx);
 	valid_flags = DSGETDC_VALID_FLAGS;
-	if (dc_level >= DS_DOMAIN_FUNCTION_2012) {


-- 
Samba Shared Repository



More information about the samba-cvs mailing list