[SCM] Samba Shared Repository - branch master updated

Garming Sam garming at samba.org
Fri May 4 07:12:02 UTC 2018


The branch, master has been updated
       via  d1730d6 netlogon: Allow zero-GUID to act the same as NULL in GetDCNameEx2
       via  7b56b52 netlogon: Store the client site to clobber any plausibly returned via winbind
       via  6d188fe netlogon: Forward GetDCNameEx2 to winbind via IRPC
       via  7d23177 winbindd_irpc: Add an IRPC call to trigger a DC locate
       via  972659e tests/getdcname: Add a number of tests for GetDCNameEx
       via  00cb8a3 netlogon: Allow return of error code in future asynchronous winbind forwards
       via  3fcb768 dsdb: Allow the disable of the Windows server site fallback
       via  0b6186b netlogon: Add a comment regarding one of the DC location calls
      from  53ff08a s3:cleanupd: sends MSG_SMB_UNLOCK twice to interested peers

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


- Log -----------------------------------------------------------------
commit d1730d6ff19b60ebf9f6b18aaa4afab733b18b25
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Tue Mar 27 12:19:31 2018 +1300

    netlogon: Allow zero-GUID to act the same as NULL in GetDCNameEx2
    
    This matches Windows behaviour and allows rpcclient to work against
    Samba without knowing the GUID ahead of time. Errors related to this
    don't appear to occur within selftest.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13365
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Garming Sam <garming at samba.org>
    Autobuild-Date(master): Fri May  4 09:11:19 CEST 2018 on sn-devel-144

commit 7b56b522d49f3e20dc2ea3819a82f742e614ea9c
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Mon Mar 26 14:32:07 2018 +1300

    netlogon: Store the client site to clobber any plausibly returned via winbind
    
    So far, I have never observed the case where the winbind call ever
    bothered to return a proper site, but in case it ever does so, we
    clobber it here. This has implications for returning a non-local domain
    site name, but for now, we ignore them.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13365
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6d188fe05b7860e3abd7cfcc21ce1390bbfd8a71
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Mar 21 11:25:19 2018 +1300

    netlogon: Forward GetDCNameEx2 to winbind via IRPC
    
    Here we simply forward everything without alteration (the same struct is
    returned). This helps us to fix the case where the DC does not exist in
    the target site, furthermore, this is supposed to work for trusted
    domains.
    
    In calling out to winbind, we now also notice if you provide a site
    which exists in multiple domains and provide the correct domain (instead
    of accidentally returning ourselves).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13365
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7d23177cea2a919ec37177954448d090e84a13fe
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Mar 21 11:25:19 2018 +1300

    winbindd_irpc: Add an IRPC call to trigger a DC locate
    
    Calling the top level winbindd API would probably be more appropriate,
    but we lack certain structures. We introduce this call in order to
    return the result to NETLOGON (in order to give site-aware and domain
    aware DC location).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13365
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 972659eb29b7ae496cb2558dfc75ad7f4b9dc4ff
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Mar 28 17:16:25 2018 +1300

    tests/getdcname: Add a number of tests for GetDCNameEx
    
    This will test the winbind forwarding to deal with sites that the target
    DC does not exist in.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13365
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 00cb8a3e12a5f6358b11d3f9c3080e7d62fc99d1
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Mar 28 13:05:11 2018 +1300

    netlogon: Allow return of error code in future asynchronous winbind forwards
    
    We change the naming conventions to match dcesrv_netr_*_base_call used elsewhere.
    
    This is important when we make the underlying Ex2 call asynchronous.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13365
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3fcb7680571621f229f37dc7ff6ee4df29750b85
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Mon Mar 26 14:25:45 2018 +1300

    dsdb: Allow the disable of the Windows server site fallback
    
    A usage in GetDCNameEx2 could return the wrong result. This may need to
    be fixed in other places.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13365
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0b6186bfce3f0f251ea57c7a01d0bf608fdb1805
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Mar 22 16:54:59 2018 +1300

    netlogon: Add a comment regarding one of the DC location calls
    
    It appears to be basically deprecated, as it was superceded by other
    calls. Presumably it is also unused.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13365
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 dfs_server/dfs_server_ad.c                    |   4 +-
 python/samba/tests/getdcname.py               | 459 ++++++++++++++++++++++++++
 selftest/flapping.d/getdcname                 |   2 +
 source3/winbindd/winbindd_irpc.c              |  68 ++++
 source4/dsdb/common/util.c                    |   8 +-
 source4/dsdb/samdb/ldb_modules/netlogon.c     |   3 +-
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 330 +++++++++++++++---
 source4/selftest/tests.py                     |   5 +
 8 files changed, 830 insertions(+), 49 deletions(-)
 create mode 100644 python/samba/tests/getdcname.py
 create mode 100644 selftest/flapping.d/getdcname


Changeset truncated at 500 lines:

diff --git a/dfs_server/dfs_server_ad.c b/dfs_server/dfs_server_ad.c
index 04aa7e0..84a19bd 100644
--- a/dfs_server/dfs_server_ad.c
+++ b/dfs_server/dfs_server_ad.c
@@ -602,7 +602,7 @@ static NTSTATUS dodc_referral(struct loadparm_context *lp_ctx,
 		}
 	}
 
-	site_name = samdb_client_site_name(sam_ctx, r, client_str, NULL);
+	site_name = samdb_client_site_name(sam_ctx, r, client_str, NULL, true);
 
 	status = get_dcs(r, sam_ctx, site_name, need_fqdn, &set, 0);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -713,7 +713,7 @@ static NTSTATUS dosysvol_referral(struct loadparm_context *lp_ctx,
 		}
 	}
 
-	site_name = samdb_client_site_name(sam_ctx, r, client_str, NULL);
+	site_name = samdb_client_site_name(sam_ctx, r, client_str, NULL, true);
 
 	status = get_dcs(r, sam_ctx, site_name, need_fqdn, &set, 0);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/python/samba/tests/getdcname.py b/python/samba/tests/getdcname.py
new file mode 100644
index 0000000..9f8f993
--- /dev/null
+++ b/python/samba/tests/getdcname.py
@@ -0,0 +1,459 @@
+# Unix SMB/CIFS implementation.
+# Copyright (C) Andrew Bartlett <abartlet at samba.org> 2018
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""
+    Tests GetDCNameEx calls in NETLOGON
+"""
+
+from samba import auth
+from samba import WERRORError, werror
+import samba.tests
+import time
+import json
+import os
+from samba.credentials import Credentials
+from samba.dcerpc import netlogon
+from samba.tests import delete_force
+from samba.dcerpc.misc import GUID
+
+
+class GetDCNameEx(samba.tests.TestCase):
+
+    def setUp(self):
+        self.lp = samba.tests.env_loadparm()
+        self.creds = Credentials()
+
+        self.netlogon_conn = None
+        self.server = os.environ.get('SERVER')
+        self.realm = os.environ.get('REALM')
+        self.domain = os.environ.get('DOMAIN')
+        self.trust_realm = os.environ.get('TRUST_REALM')
+        self.trust_domain = os.environ.get('TRUST_DOMAIN')
+
+    def _call_get_dc_name(self, domain=None, domain_guid=None,
+                          site_name=None, ex2=False, flags=0):
+        if self.netlogon_conn is None:
+            self.netlogon_conn = netlogon.netlogon("ncalrpc:[schannel]",
+                                                   self.get_loadparm())
+
+        if ex2:
+            return self.netlogon_conn.netr_DsRGetDCNameEx2(self.server,
+                                                           None, 0,
+                                                           domain,
+                                                           domain_guid,
+                                                           site_name,
+                                                           flags)
+        else:
+            return self.netlogon_conn.netr_DsRGetDCNameEx(self.server,
+                                                          domain,
+                                                          domain_guid,
+                                                          site_name,
+                                                          flags)
+
+    def test_get_dc_ex2(self):
+        """Check the most trivial requirements of Ex2 (no domain or site)
+
+        a) The paths are prefixed with two backslashes
+        b) The returned domains conform to the format requested
+        c) The domain matches our own domain
+        """
+        response = self._call_get_dc_name(ex2=True)
+
+        self.assertTrue(response.dc_unc is not None)
+        self.assertTrue(response.dc_unc.startswith('\\\\'))
+        self.assertTrue(response.dc_address is not None)
+        self.assertTrue(response.dc_address.startswith('\\\\'))
+
+        self.assertTrue(response.domain_name.lower() ==
+                        self.realm.lower() or
+                        response.domain_name.lower() ==
+                        self.domain.lower())
+
+        response = self._call_get_dc_name(ex2=True,
+                                          flags=netlogon.DS_RETURN_DNS_NAME)
+        self.assertEqual(response.domain_name.lower(),
+                         self.realm.lower())
+
+        response = self._call_get_dc_name(ex2=True,
+                                          flags=netlogon.DS_RETURN_FLAT_NAME)
+        self.assertEqual(response.domain_name.lower(),
+                         self.domain.lower())
+
+    def test_get_dc_over_winbind_ex2(self):
+        """Check what happens to Ex2 requests after being forwarded to winbind
+
+        a) The paths must still have the same backslash prefixes
+        b) The returned domain does not match our own domain
+        c) The domain matches the format requested
+        """
+        if self.trust_realm is None:
+            return
+
+        response_trust = self._call_get_dc_name(domain=self.trust_realm,
+                                                ex2=True)
+        response = self._call_get_dc_name(domain=self.realm,
+                                          ex2=True)
+
+        self.assertTrue(response_trust.dc_unc is not None)
+        self.assertTrue(response_trust.dc_unc.startswith('\\\\'))
+        self.assertTrue(response_trust.dc_address is not None)
+        self.assertTrue(response_trust.dc_address.startswith('\\\\'))
+
+        self.assertNotEqual(response_trust.dc_unc,
+                            response.dc_unc)
+        self.assertNotEqual(response_trust.dc_address,
+                            response.dc_address)
+
+        self.assertTrue(response_trust.domain_name.lower() ==
+                        self.trust_realm.lower() or
+                        response_trust.domain_name.lower() ==
+                        self.trust_domain.lower())
+
+        response_trust = self._call_get_dc_name(domain=self.trust_realm,
+                                                flags=netlogon.DS_RETURN_DNS_NAME,
+                                                ex2=True)
+        self.assertEqual(response_trust.domain_name.lower(),
+                         self.trust_realm.lower())
+
+        response_trust = self._call_get_dc_name(domain=self.trust_realm,
+                                                flags=netlogon.DS_RETURN_FLAT_NAME,
+                                                ex2=True)
+        self.assertEqual(response_trust.domain_name.lower(),
+                         self.trust_domain.lower())
+
+    def test_get_dc_over_winbind(self):
+        """Test the standard Ex version (not Ex2)
+
+        Ex calls Ex2 anyways, from now on, just test Ex.
+        """
+        if self.trust_realm is None:
+            return
+
+        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.assertTrue(response_trust.dc_unc.startswith('\\\\'))
+        self.assertTrue(response_trust.dc_address is not None)
+        self.assertTrue(response_trust.dc_address.startswith('\\\\'))
+
+        self.assertEqual(response_trust.domain_name.lower(),
+                         self.trust_realm.lower())
+
+    def test_get_dc_over_winbind_with_site(self):
+        """Test the standard Ex version (not Ex2)
+
+        We assume that there is a Default-First-Site-Name site.
+        """
+        if self.trust_realm is None:
+            return
+
+        site = 'Default-First-Site-Name'
+        response_trust = self._call_get_dc_name(domain=self.trust_realm,
+                                                site_name=site,
+                                                flags=netlogon.DS_RETURN_DNS_NAME)
+
+        self.assertTrue(response_trust.dc_unc is not None)
+        self.assertTrue(response_trust.dc_unc.startswith('\\\\'))
+        self.assertTrue(response_trust.dc_address is not None)
+        self.assertTrue(response_trust.dc_address.startswith('\\\\'))
+
+        self.assertEqual(response_trust.domain_name.lower(),
+                         self.trust_realm.lower())
+
+        self.assertEqual(site.lower(), response_trust.dc_site_name.lower())
+
+    def test_get_dc_over_winbind_invalid_site(self):
+        """Test the standard Ex version (not Ex2)
+
+        We assume that there is no Invalid-First-Site-Name site.
+        """
+        if self.trust_realm is None:
+            return
+
+        site = 'Invalid-First-Site-Name'
+        try:
+            response_trust = self._call_get_dc_name(domain=self.trust_realm,
+                                                    site_name=site,
+                                                    flags=netlogon.DS_RETURN_DNS_NAME,
+                                                    ex2=False)
+            self.fail("Failed to give the correct error for incorrect site")
+        except WERRORError as e:
+            enum, estr = e.args
+            if enum != werror.WERR_NO_SUCH_DOMAIN:
+                self.fail("Failed to detect an invalid site name")
+
+    def test_get_dc_over_winbind_invalid_site_ex2(self):
+        """Test the Ex2 version.
+
+        We assume that there is no Invalid-First-Site-Name site.
+        """
+        if self.trust_realm is None:
+            return
+
+        site = 'Invalid-First-Site-Name'
+        try:
+            response_trust = self._call_get_dc_name(domain=self.trust_realm,
+                                                    site_name=site,
+                                                    flags=netlogon.DS_RETURN_DNS_NAME,
+                                                    ex2=True)
+            self.fail("Failed to give the correct error for incorrect site")
+        except WERRORError as e:
+            enum, estr = e.args
+            if enum != werror.WERR_NO_SUCH_DOMAIN:
+                self.fail("Failed to detect an invalid site name")
+
+    def test_get_dc_over_winbind_empty_string_site(self):
+        """Test the standard Ex version (not Ex2)
+
+        We assume that there is a Default-First-Site-Name site.
+        """
+        if self.trust_realm is None:
+            return
+
+        site = ''
+        try:
+            response_trust = self._call_get_dc_name(domain=self.trust_realm,
+                                                    site_name=site,
+                                                    flags=netlogon.DS_RETURN_DNS_NAME)
+        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.assertTrue(response_trust.dc_unc.startswith('\\\\'))
+        self.assertTrue(response_trust.dc_address is not None)
+        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.assertNotEqual('', response_trust.dc_site_name)
+
+    def test_get_dc_over_winbind_netbios(self):
+        """Supply a NETBIOS trust domain name."""
+        if self.trust_realm is None:
+            return
+
+        try:
+            response_trust = self._call_get_dc_name(domain=self.trust_domain,
+                                                    flags=netlogon.DS_RETURN_DNS_NAME,
+                                                    ex2=False)
+        except WERRORError as e:
+            self.fail("Failed to succeed over winbind: " + str(e))
+
+        self.assertTrue(response_trust is not None)
+        self.assertEqual(response_trust.domain_name.lower(),
+                         self.trust_realm.lower())
+
+    def test_get_dc_over_winbind_with_site_netbios(self):
+        """Supply a NETBIOS trust domain name.
+
+        Sporadically fails because NETBIOS queries do not return site name in
+        winbind. The site check in NETLOGON will trigger and fail the request.
+
+        Currently marked in flapping...
+        """
+        if self.trust_realm is None:
+            return
+
+        site = 'Default-First-Site-Name'
+        try:
+            response_trust = self._call_get_dc_name(domain=self.trust_domain,
+                                                    site_name=site,
+                                                    flags=netlogon.DS_RETURN_DNS_NAME,
+                                                    ex2=False)
+        except WERRORError as e:
+            self.fail("Failed to succeed over winbind: " + str(e))
+
+        self.assertTrue(response_trust is not None)
+        self.assertEqual(response_trust.domain_name.lower(),
+                         self.trust_realm.lower())
+
+        self.assertEqual(site.lower(), response_trust.dc_site_name.lower())
+
+    def test_get_dc_over_winbind_domain_guid(self):
+        """Ensure that we do not reject requests supplied with a NULL GUID"""
+
+        if self.trust_realm is None:
+            return
+
+        null_guid = GUID()
+        try:
+            response_trust = self._call_get_dc_name(domain=self.trust_realm,
+                                                    domain_guid=null_guid,
+                                                    flags=netlogon.DS_RETURN_DNS_NAME)
+        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.assertTrue(response_trust.dc_unc.startswith('\\\\'))
+        self.assertTrue(response_trust.dc_address is not None)
+        self.assertTrue(response_trust.dc_address.startswith('\\\\'))
+
+        self.assertEqual(response_trust.domain_name.lower(),
+                         self.trust_realm.lower())
+
+    def test_get_dc_with_site(self):
+        """Test the standard Ex version (not Ex2)
+
+        We assume that there is a Default-First-Site-Name site.
+        """
+
+        site = 'Default-First-Site-Name'
+        response = self._call_get_dc_name(domain=self.realm,
+                                          site_name=site,
+                                          flags=netlogon.DS_RETURN_DNS_NAME)
+
+        self.assertTrue(response.dc_unc is not None)
+        self.assertTrue(response.dc_unc.startswith('\\\\'))
+        self.assertTrue(response.dc_address is not None)
+        self.assertTrue(response.dc_address.startswith('\\\\'))
+
+        self.assertEqual(response.domain_name.lower(),
+                         self.realm.lower())
+
+        self.assertEqual(site.lower(), response.dc_site_name.lower())
+
+    def test_get_dc_invalid_site(self):
+        """Test the standard Ex version (not Ex2)
+
+        We assume that there is no Invalid-First-Site-Name site.
+        """
+        if self.realm is None:
+            return
+
+        site = 'Invalid-First-Site-Name'
+        try:
+            response = self._call_get_dc_name(domain=self.realm,
+                                              site_name=site,
+                                              flags=netlogon.DS_RETURN_DNS_NAME,
+                                              ex2=False)
+            self.fail("Failed to give the correct error for incorrect site")
+        except WERRORError as e:
+            enum, estr = e.args
+            if enum != werror.WERR_NO_SUCH_DOMAIN:
+                self.fail("Failed to detect an invalid site name")
+
+    def test_get_dc_invalid_site_ex2(self):
+        """Test the Ex2 version
+
+        We assume that there is no Invalid-First-Site-Name site.
+        """
+
+        site = 'Invalid-First-Site-Name'
+        try:
+            response = self._call_get_dc_name(domain=self.realm,
+                                              site_name=site,
+                                              flags=netlogon.DS_RETURN_DNS_NAME,
+                                              ex2=True)
+            self.fail("Failed to give the correct error for incorrect site")
+        except WERRORError as e:
+            enum, estr = e.args
+            if enum != werror.WERR_NO_SUCH_DOMAIN:
+                self.fail("Failed to detect an invalid site name")
+
+    def test_get_dc_empty_string_site(self):
+        """Test the standard Ex version (not Ex2)
+
+        We assume that there is a Default-First-Site-Name site.
+        """
+
+        site = ''
+        try:
+            response = self._call_get_dc_name(domain=self.realm,
+                                              site_name=site,
+                                              flags=netlogon.DS_RETURN_DNS_NAME)
+        except WERRORError as e:
+            self.fail("Unable to get empty string site result: " + str(e))
+
+        self.assertTrue(response.dc_unc is not None)
+        self.assertTrue(response.dc_unc.startswith('\\\\'))
+        self.assertTrue(response.dc_address is not None)
+        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.assertNotEqual('', response.dc_site_name)
+
+    def test_get_dc_netbios(self):
+        """Supply a NETBIOS domain name."""
+
+        try:
+            response = self._call_get_dc_name(domain=self.domain,
+                                              flags=netlogon.DS_RETURN_DNS_NAME,
+                                              ex2=False)
+        except WERRORError as e:
+            self.fail("Failed to succeed over winbind: " + str(e))
+
+        self.assertTrue(response is not None)
+        self.assertEqual(response.domain_name.lower(),
+                         self.realm.lower())
+
+    def test_get_dc_with_site_netbios(self):
+        """Supply a NETBIOS domain name."""
+
+        site = 'Default-First-Site-Name'
+        try:
+            response = self._call_get_dc_name(domain=self.domain,
+                                              site_name=site,
+                                              flags=netlogon.DS_RETURN_DNS_NAME,
+                                              ex2=False)
+        except WERRORError as e:
+            self.fail("Failed to succeed over winbind: " + str(e))
+
+        self.assertTrue(response is not None)
+        self.assertEqual(response.domain_name.lower(),
+                         self.realm.lower())
+
+        self.assertEqual(site.lower(), response.dc_site_name.lower())
+
+    def test_get_dc_with_domain_guid(self):
+        """Ensure that we do not reject requests supplied with a NULL GUID"""
+
+        null_guid = GUID()
+        response = self._call_get_dc_name(domain=self.realm,
+                                          domain_guid=null_guid,
+                                          flags=netlogon.DS_RETURN_DNS_NAME)
+
+        self.assertTrue(response.dc_unc is not None)
+        self.assertTrue(response.dc_unc.startswith('\\\\'))
+        self.assertTrue(response.dc_address is not None)
+        self.assertTrue(response.dc_address.startswith('\\\\'))
+
+        self.assertEqual(response.domain_name.lower(),
+                         self.realm.lower())
+
+    def test_get_dc_with_empty_string_domain(self):
+        """Ensure that empty domain resolve to the DC domain"""
+        response = self._call_get_dc_name(domain='',
+                                          flags=netlogon.DS_RETURN_DNS_NAME)
+
+        self.assertTrue(response.dc_unc is not None)
+        self.assertTrue(response.dc_unc.startswith('\\\\'))
+        self.assertTrue(response.dc_address is not None)
+        self.assertTrue(response.dc_address.startswith('\\\\'))
+
+        self.assertEqual(response.domain_name.lower(),
+                         self.realm.lower())
+
+    # TODO Thorough tests of domain GUID
+    #
+    # The domain GUID does not seem to be authoritative, and seems to be a
+    # fallback case for renamed domains.
diff --git a/selftest/flapping.d/getdcname b/selftest/flapping.d/getdcname
new file mode 100644
index 0000000..4c12e75
--- /dev/null
+++ b/selftest/flapping.d/getdcname
@@ -0,0 +1,2 @@
+# winbind appears to return inconsistent answers (depending on whether or not it uses NETBIOS queries or not)
+^samba.tests.getdcname.samba.tests.getdcname.GetDCNameEx.test_get_dc_over_winbind_with_site_netbios.fl2008r2dc:local.*
diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c
index e03312e..731b057 100644
--- a/source3/winbindd/winbindd_irpc.c
+++ b/source3/winbindd/winbindd_irpc.c
@@ -29,6 +29,8 @@


-- 
Samba Shared Repository



More information about the samba-cvs mailing list