[SCM] Samba Shared Repository - branch master updated

Alexander Bokovoy ab at samba.org
Tue Jul 24 07:56:02 UTC 2018


The branch, master has been updated
       via  c390728 samba-tool trust: support discovery via netr_GetDcName
       via  6800077 s3:selftest: run rpc.lsa.lookupsids also with explicit [smb1] and [smb2]
       via  4422f73 s4:librpc: autonegotiate SMB1/2/3
       via  802e43b python/tests: use explicit "client ipc max protocol = NT1" for samba.tests.net_join_no_spnego
       via  70a9cf9 tests/auth_log: Permit SMB2 service description if empty binding is used for kerberos authentication
       via  e4910f3 s4:libcli: add smb_connect_nego_{send,recv}()
       via  5188454 s4:libcli: allow a fallback to NTLMSSP if SPNEGO is not supported locally
       via  ca000d8 s4:libcli: add fallback_to_anonymous to smb2_connect_send()
       via  f20e607 s4:libcli: allow passing an already negotiated connection to smb2_connect_send()
       via  5ad5b81 s4:libcli: split out smb2_connect_session_start()
       via  ce2248c s4:libcli: add smb2_transport_raw_init()
       via  2b68f9b s4:libcli: allow passing an already negotiated connection to smb_composite_connect()
       via  87d7339 s4:libcli: use talloc_zero() for struct smb_composite_connect in fetchfile.c
       via  b7e99c2 s4:libcli: add smbcli_transport_raw_init()
       via  17b12a9 s4:libcli: split out smb_raw_negotiate_fill_transport()
       via  062b518 librpc: add binding handle support for [smb1]
      from  6de9d87 python/samba/tests: make sure samba.tests can be imported without SamDB

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


- Log -----------------------------------------------------------------
commit c390728819e73cefbf02e0d52d22805930f4c45b
Author: Alexander Bokovoy <ab at samba.org>
Date:   Sat Feb 24 14:34:44 2018 +0200

    samba-tool trust: support discovery via netr_GetDcName
    
    In case a remote DC does not support netr_DsRGetDCNameEx2(),
    use netr_GetDcName() instead.
    
    This should help with FreeIPA where embedded smbd runs as a domain
    controller but does not implement full Active Directory compatibility.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13538
    
    Signed-off-by: Alexander Bokovoy <ab at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Alexander Bokovoy <ab at samba.org>
    Autobuild-Date(master): Tue Jul 24 09:55:23 CEST 2018 on sn-devel-144

commit 6800077c5c57c257326573537d1f2bb7a8066149
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 19 07:34:11 2018 +0200

    s3:selftest: run rpc.lsa.lookupsids also with explicit [smb1] and [smb2]
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 4422f7382aad3090cb959ade030a02bf4fef81ac
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 16:55:33 2018 +0200

    s4:librpc: autonegotiate SMB1/2/3
    
    Windows Server 1709 defaults to SMB2 and does not have SMB1 enabled.
    When establishing trust, samba-tool does not specify SMB protocol
    version and fail by default.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 802e43bf742e756896fa73fcd139feca9ae293dd
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 23 00:17:35 2018 +0200

    python/tests: use explicit "client ipc max protocol = NT1" for samba.tests.net_join_no_spnego
    
    The tests rely on SMB1.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 70a9cf9ccfc4075cc08209191db1bce2c9b432fc
Author: Alexander Bokovoy <ab at samba.org>
Date:   Thu Jul 19 14:07:39 2018 +0300

    tests/auth_log: Permit SMB2 service description if empty binding is used for kerberos authentication
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Alexander Bokovoy <ab at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit e4910f35eab008a41cfcac3d97b3647c721ac679
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 14:52:43 2018 +0200

    s4:libcli: add smb_connect_nego_{send,recv}()
    
    This can be used to create a connection up to a negotiated
    smbXcli_conn.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 5188454bdce80f6e2bfc45deca18bd1b7289a7a6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 19 23:04:33 2018 +0200

    s4:libcli: allow a fallback to NTLMSSP if SPNEGO is not supported locally
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit ca000d8901e6acb8a7c59d26d4f75c9d92bafece
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 23:52:30 2018 +0200

    s4:libcli: add fallback_to_anonymous to smb2_connect_send()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit f20e607c15b4c8ae56ade5d7e68d832542a2cd5e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 16:44:16 2018 +0200

    s4:libcli: allow passing an already negotiated connection to smb2_connect_send()
    
    It will just do the session setup and tree connect steps.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 5ad5b81b6ef601596583b4ad7d6a14241fa99a71
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 16:43:32 2018 +0200

    s4:libcli: split out smb2_connect_session_start()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit ce2248c4b5aad2d00155a2e77b3e6340ce824979
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 16:43:04 2018 +0200

    s4:libcli: add smb2_transport_raw_init()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 2b68f9b8b0dd944fa89b9e0037886ddd4fb4e5f9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 15:34:55 2018 +0200

    s4:libcli: allow passing an already negotiated connection to smb_composite_connect()
    
    It will just do the session setup and tree connect steps.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 87d73397f9a9dee8fa0055a2ff08244b2c85e120
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 15:01:50 2018 +0200

    s4:libcli: use talloc_zero() for struct smb_composite_connect in fetchfile.c
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit b7e99c2571e31971a6d7f1898e7458c16dc1031e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 15:36:52 2018 +0200

    s4:libcli: add smbcli_transport_raw_init()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 17b12a9b9a9dfd859679de77aa0c7ffbc782f1bc
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 18 15:36:31 2018 +0200

    s4:libcli: split out smb_raw_negotiate_fill_transport()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 062b518cabd9fb5f72f96cdf400c978c0b844619
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 19 07:32:08 2018 +0200

    librpc: add binding handle support for [smb1]
    
    This will be used to force smb1.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

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

Summary of changes:
 librpc/rpc/binding.c                         |   1 +
 librpc/rpc/rpc_common.h                      |   2 +
 python/samba/netcmd/domain.py                |  26 ++-
 python/samba/tests/auth_log.py               |  26 ++-
 python/samba/tests/net_join_no_spnego.py     |   2 +
 source3/selftest/tests.py                    |   2 +-
 source4/libcli/raw/clitransport.c            |  44 +++++
 source4/libcli/raw/clitree.c                 |   1 +
 source4/libcli/raw/rawnegotiate.c            |  74 ++++----
 source4/libcli/smb2/connect.c                |  69 ++++++-
 source4/libcli/smb2/session.c                |  35 +++-
 source4/libcli/smb2/transport.c              |  35 ++++
 source4/libcli/smb_composite/connect.c       |  48 +++--
 source4/libcli/smb_composite/connect_nego.c  | 209 ++++++++++++++++++++++
 source4/libcli/smb_composite/fetchfile.c     |   2 +-
 source4/libcli/smb_composite/smb_composite.h |  23 +++
 source4/libcli/wscript_build                 |  20 ++-
 source4/librpc/rpc/dcerpc_connect.c          | 257 +++++++++++++--------------
 source4/ntvfs/cifs/vfs_cifs.c                |   1 +
 19 files changed, 668 insertions(+), 209 deletions(-)
 create mode 100644 source4/libcli/smb_composite/connect_nego.c


Changeset truncated at 500 lines:

diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c
index 63ba682..aa8cc6b 100644
--- a/librpc/rpc/binding.c
+++ b/librpc/rpc/binding.c
@@ -103,6 +103,7 @@ static const struct ncacn_option {
 	{"print", DCERPC_DEBUG_PRINT_BOTH},
 	{"padcheck", DCERPC_DEBUG_PAD_CHECK},
 	{"bigendian", DCERPC_PUSH_BIGENDIAN},
+	{"smb1", DCERPC_SMB1},
 	{"smb2", DCERPC_SMB2},
 	{"ndr64", DCERPC_NDR64},
 	{"packet", DCERPC_PACKET},
diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
index d6b2d5d..cdc9fe8 100644
--- a/librpc/rpc/rpc_common.h
+++ b/librpc/rpc/rpc_common.h
@@ -108,6 +108,8 @@ struct dcerpc_binding;
 
 #define DCERPC_PACKET			(1<<26)
 
+#define DCERPC_SMB1                    (1<<27)
+
 /* The following definitions come from ../librpc/rpc/dcerpc_error.c  */
 
 const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code);
diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py
index 555462c..becbc49 100644
--- a/python/samba/netcmd/domain.py
+++ b/python/samba/netcmd/domain.py
@@ -1876,6 +1876,15 @@ class DomainTrustCommand(Command):
 
         return (policy, info)
 
+    def get_netlogon_dc_unc(self, conn, server, domain):
+        try:
+            info = conn.netr_DsRGetDCNameEx2(server,
+                                             None, 0, None, None, None,
+                                             netlogon.DS_RETURN_DNS_NAME)
+            return info.dc_unc
+        except RuntimeError:
+            return conn.netr_GetDcName(server, domain)
+
     def get_netlogon_dc_info(self, conn, server):
         info = conn.netr_DsRGetDCNameEx2(server,
                                          None, 0, None, None, None,
@@ -2509,7 +2518,8 @@ class cmd_domain_trust_create(DomainTrustCommand):
                 raise self.RemoteRuntimeError(self, error, "failed to connect netlogon server")
 
             try:
-                remote_netlogon_info = self.get_netlogon_dc_info(remote_netlogon, remote_server)
+                remote_netlogon_dc_unc = self.get_netlogon_dc_unc(remote_netlogon,
+                                                                  remote_server, domain)
             except RuntimeError as error:
                 raise self.RemoteRuntimeError(self, error, "failed to get netlogon dc info")
 
@@ -2659,9 +2669,9 @@ class cmd_domain_trust_create(DomainTrustCommand):
                         # this triggers netr_GetForestTrustInformation to our domain.
                         # and lsaRSetForestTrustInformation() remotely, but new top level
                         # names are disabled by default.
-                        remote_forest_info = remote_netlogon.netr_DsRGetForestTrustInformation(remote_netlogon_info.dc_unc,
-                                                                      local_lsa_info.dns_domain.string,
-                                                                      netlogon.DS_GFTI_UPDATE_TDO)
+                        remote_forest_info = remote_netlogon.netr_DsRGetForestTrustInformation(remote_netlogon_dc_unc,
+                                                                                               local_lsa_info.dns_domain.string,
+                                                                                               netlogon.DS_GFTI_UPDATE_TDO)
                     except RuntimeError as error:
                         raise self.RemoteRuntimeError(self, error, "netr_DsRGetForestTrustInformation() failed")
 
@@ -2712,10 +2722,10 @@ class cmd_domain_trust_create(DomainTrustCommand):
                 if remote_trust_info.trust_direction & lsa.LSA_TRUST_DIRECTION_OUTBOUND:
                     self.outf.write("Validating incoming trust...\n")
                     try:
-                        remote_trust_verify = remote_netlogon.netr_LogonControl2Ex(remote_netlogon_info.dc_unc,
-                                                                      netlogon.NETLOGON_CONTROL_TC_VERIFY,
-                                                                      2,
-                                                                      local_lsa_info.dns_domain.string)
+                        remote_trust_verify = remote_netlogon.netr_LogonControl2Ex(remote_netlogon_dc_unc,
+                                                                                   netlogon.NETLOGON_CONTROL_TC_VERIFY,
+                                                                                   2,
+                                                                                   local_lsa_info.dns_domain.string)
                     except RuntimeError as error:
                         raise self.RemoteRuntimeError(self, error, "NETLOGON_CONTROL_TC_VERIFY failed")
 
diff --git a/python/samba/tests/auth_log.py b/python/samba/tests/auth_log.py
index cb524d0..4704b92 100644
--- a/python/samba/tests/auth_log.py
+++ b/python/samba/tests/auth_log.py
@@ -28,6 +28,7 @@ from samba.credentials import DONT_USE_KERBEROS, MUST_USE_KERBEROS
 from samba import NTSTATUSError
 from subprocess import call
 from ldb import LdbError
+import re
 
 
 class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
@@ -65,6 +66,20 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         messages = self.waitForMessages(isLastExpectedMessage, x)
         checkFunction(messages, authTypes, service, binding, protection)
 
+    def _assert_ncacn_np_serviceDescription(self, binding, serviceDescription):
+        # Turn "[foo,bar]" into a list ("foo", "bar") to test
+        # lambda x: x removes anything that evaluates to False,
+        # including empty strings, so we handle "" as well
+        binding_list = filter(lambda x: x, re.compile('[\[,\]]').split(binding))
+
+        # Handle explicit smb2, smb1 or auto negotiation
+        if "smb2" in binding_list:
+            self.assertEquals(serviceDescription, "SMB2")
+        elif "smb1" in binding_list:
+            self.assertEquals(serviceDescription, "SMB")
+        else:
+            self.assertIn(serviceDescription, ["SMB", "SMB2"])
+
     def rpc_ncacn_np_ntlm_check(self, messages, authTypes, service,
                                 binding, protection):
 
@@ -77,7 +92,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         msg = messages[0]
         self.assertEquals("Authentication", msg["type"])
         self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"])
-        self.assertEquals("SMB",
+        self._assert_ncacn_np_serviceDescription(binding,
                           msg["Authentication"]["serviceDescription"])
         self.assertEquals(authTypes[1],
                           msg["Authentication"]["authDescription"])
@@ -85,7 +100,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         # Check the second message it should be an Authorization
         msg = messages[1]
         self.assertEquals("Authorization", msg["type"])
-        self.assertEquals("SMB",
+        self._assert_ncacn_np_serviceDescription(binding,
                           msg["Authorization"]["serviceDescription"])
         self.assertEquals(authTypes[2], msg["Authorization"]["authType"])
         self.assertEquals("SMB", msg["Authorization"]["transportProtection"])
@@ -145,12 +160,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         # Check the third message it should be an Authorization
         msg = messages[2]
         self.assertEquals("Authorization", msg["type"])
-        serviceDescription = "SMB"
-        print("binding %s" % binding)
-        if binding == "[smb2]":
-            serviceDescription = "SMB2"
-
-        self.assertEquals(serviceDescription,
+        self._assert_ncacn_np_serviceDescription(binding,
                           msg["Authorization"]["serviceDescription"])
         self.assertEquals(authTypes[3], msg["Authorization"]["authType"])
         self.assertEquals("SMB", msg["Authorization"]["transportProtection"])
diff --git a/python/samba/tests/net_join_no_spnego.py b/python/samba/tests/net_join_no_spnego.py
index 85c6f88..e4dd078 100644
--- a/python/samba/tests/net_join_no_spnego.py
+++ b/python/samba/tests/net_join_no_spnego.py
@@ -42,6 +42,7 @@ class NetJoinNoSpnegoTests(samba.tests.TestCaseInTempDir):
         super(NetJoinNoSpnegoTests, self).tearDown()
 
     def test_net_join_no_spnego(self):
+        self.lp.set("client ipc max protocol", "NT1")
         self.lp.set("client use spnego", "no")
         netbios_name = "NetJoinNoSpnego"
         machinepass  = "abcdefghij"
@@ -65,6 +66,7 @@ class NetJoinNoSpnegoTests(samba.tests.TestCaseInTempDir):
         self.fail("Shoud have rejected NTLMv2 without SPNEGO")
 
     def test_net_join_no_spnego_ntlmv1(self):
+        self.lp.set("client ipc max protocol", "NT1")
         self.lp.set("client use spnego", "no")
         self.lp.set("client ntlmv2 auth", "no")
         netbios_name = "NetJoinNoSpnego"
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index a061483..bf0ba2a 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -581,7 +581,7 @@ for t in tests:
 
 
 test = 'rpc.lsa.lookupsids'
-auth_options = ["", "ntlm", "spnego", "spnego,ntlm" ]
+auth_options = ["", "ntlm", "spnego", "spnego,ntlm", "spnego,smb1", "spnego,smb2"]
 signseal_options = ["", ",connect", ",packet", ",sign", ",seal"]
 endianness_options = ["", ",bigendian"]
 for s in signseal_options:
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index d0dd1f9..47b8dbf 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -114,6 +114,50 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock,
 }
 
 /*
+  create a transport structure based on an established socket
+*/
+NTSTATUS smbcli_transport_raw_init(TALLOC_CTX *mem_ctx,
+				   struct tevent_context *ev,
+				   struct smbXcli_conn **_conn,
+				   const struct smbcli_options *options,
+				   struct smbcli_transport **_transport)
+{
+	struct smbcli_transport *transport = NULL;
+	NTSTATUS status;
+
+	if (*_conn == NULL) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	transport = talloc_zero(mem_ctx, struct smbcli_transport);
+	if (transport == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	transport->ev = ev;
+	transport->options = *options;
+
+	/*
+	 * First only set the pointer without move.
+	 */
+	transport->conn = *_conn;
+	status = smb_raw_negotiate_fill_transport(transport);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(transport);
+		return status;
+	}
+
+	talloc_set_destructor(transport, transport_destructor);
+
+	/*
+	 * Now move it away from the caller...
+	 */
+	transport->conn = talloc_move(transport, _conn);
+	*_transport = transport;
+	return NT_STATUS_OK;
+}
+
+/*
   mark the transport as dead
 */
 void smbcli_transport_dead(struct smbcli_transport *transport, NTSTATUS status)
diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c
index 11be548..b1b6159 100644
--- a/source4/libcli/raw/clitree.c
+++ b/source4/libcli/raw/clitree.c
@@ -207,6 +207,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx,
 	io.in.called_name = strupper_talloc(tmp_ctx, dest_host);
 	io.in.service = service;
 	io.in.service_type = service_type;
+	io.in.existing_conn = NULL;
 	io.in.credentials = credentials;
 	io.in.gensec_settings = gensec_settings;
 	io.in.fallback_to_anonymous = false;
diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c
index 73c9123..cec081c 100644
--- a/source4/libcli/raw/rawnegotiate.c
+++ b/source4/libcli/raw/rawnegotiate.c
@@ -28,6 +28,47 @@
 #include "../libcli/smb/smbXcli_base.h"
 #include "../lib/util/tevent_ntstatus.h"
 
+NTSTATUS smb_raw_negotiate_fill_transport(struct smbcli_transport *transport)
+{
+	struct smbcli_negotiate *n = &transport->negotiate;
+	struct smbXcli_conn *c = transport->conn;
+	NTTIME ntt;
+
+	n->protocol = smbXcli_conn_protocol(c);
+	if (n->protocol > PROTOCOL_NT1) {
+		return NT_STATUS_REVISION_MISMATCH;
+	}
+
+	n->sec_mode = smb1cli_conn_server_security_mode(c);
+	n->max_mux  = smbXcli_conn_max_requests(c);
+	n->max_xmit = smb1cli_conn_max_xmit(c);
+	n->sesskey  = smb1cli_conn_server_session_key(c);
+	n->capabilities = smb1cli_conn_capabilities(c);;
+
+	/* this time arrives in real GMT */
+	ntt = smbXcli_conn_server_system_time(c);
+	n->server_time = nt_time_to_unix(ntt);
+	n->server_zone = smb1cli_conn_server_time_zone(c);
+
+	if (n->capabilities & CAP_EXTENDED_SECURITY) {
+		const DATA_BLOB *b = smbXcli_conn_server_gss_blob(c);
+		if (b) {
+			n->secblob = *b;
+		}
+	} else {
+		const uint8_t *p = smb1cli_conn_server_challenge(c);
+		if (p) {
+			n->secblob = data_blob_const(p, 8);
+		}
+	}
+
+	n->readbraw_supported = smb1cli_conn_server_readbraw(c);
+	n->readbraw_supported = smb1cli_conn_server_writebraw(c);
+	n->lockread_supported = smb1cli_conn_server_lockread(c);
+
+	return NT_STATUS_OK;
+}
+
 struct smb_raw_negotiate_state {
 	struct smbcli_transport *transport;
 };
@@ -82,10 +123,7 @@ static void smb_raw_negotiate_done(struct tevent_req *subreq)
 	struct smb_raw_negotiate_state *state =
 		tevent_req_data(req,
 		struct smb_raw_negotiate_state);
-	struct smbcli_negotiate *n = &state->transport->negotiate;
-	struct smbXcli_conn *c = state->transport->conn;
 	NTSTATUS status;
-	NTTIME ntt;
 
 	status = smbXcli_negprot_recv(subreq);
 	TALLOC_FREE(subreq);
@@ -93,35 +131,11 @@ static void smb_raw_negotiate_done(struct tevent_req *subreq)
 		return;
 	}
 
-	n->protocol = smbXcli_conn_protocol(c);
-
-	n->sec_mode = smb1cli_conn_server_security_mode(c);
-	n->max_mux  = smbXcli_conn_max_requests(c);
-	n->max_xmit = smb1cli_conn_max_xmit(c);
-	n->sesskey  = smb1cli_conn_server_session_key(c);
-	n->capabilities = smb1cli_conn_capabilities(c);;
-
-	/* this time arrives in real GMT */
-	ntt = smbXcli_conn_server_system_time(c);
-	n->server_time = nt_time_to_unix(ntt);
-	n->server_zone = smb1cli_conn_server_time_zone(c);
-
-	if (n->capabilities & CAP_EXTENDED_SECURITY) {
-		const DATA_BLOB *b = smbXcli_conn_server_gss_blob(c);
-		if (b) {
-			n->secblob = *b;
-		}
-	} else {
-		const uint8_t *p = smb1cli_conn_server_challenge(c);
-		if (p) {
-			n->secblob = data_blob_const(p, 8);
-		}
+	status = smb_raw_negotiate_fill_transport(state->transport);
+	if (tevent_req_nterror(req, status)) {
+		return;
 	}
 
-	n->readbraw_supported = smb1cli_conn_server_readbraw(c);
-	n->readbraw_supported = smb1cli_conn_server_writebraw(c);
-	n->lockread_supported = smb1cli_conn_server_lockread(c);
-
 	tevent_req_done(req);
 }
 
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 8ff56c9..e4cbf8c 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -35,6 +35,7 @@
 struct smb2_connect_state {
 	struct tevent_context *ev;
 	struct cli_credentials *credentials;
+	bool fallback_to_anonymous;
 	uint64_t previous_session_id;
 	struct resolve_context *resolve_ctx;
 	const char *host;
@@ -50,6 +51,7 @@ struct smb2_connect_state {
 	struct smb2_tree *tree;
 };
 
+static void smb2_connect_session_start(struct tevent_req *req);
 static void smb2_connect_socket_done(struct composite_context *creq);
 
 /*
@@ -63,6 +65,8 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
 				     const char *share,
 				     struct resolve_context *resolve_ctx,
 				     struct cli_credentials *credentials,
+				     bool fallback_to_anonymous,
+				     struct smbXcli_conn **existing_conn,
 				     uint64_t previous_session_id,
 				     const struct smbcli_options *options,
 				     const char *socket_options,
@@ -81,6 +85,7 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
 
 	state->ev = ev;
 	state->credentials = credentials;
+	state->fallback_to_anonymous = fallback_to_anonymous;
 	state->previous_session_id = previous_session_id;
 	state->options = *options;
 	state->host = host;
@@ -106,6 +111,25 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
+	if (existing_conn != NULL) {
+		NTSTATUS status;
+
+		status = smb2_transport_raw_init(state, ev,
+						 existing_conn,
+						 options,
+						 &state->transport);
+		if (tevent_req_nterror(req, status)) {
+			return tevent_req_post(req, ev);
+		}
+
+		smb2_connect_session_start(req);
+		if (!tevent_req_is_in_progress(req)) {
+			return tevent_req_post(req, ev);
+		}
+
+		return req;
+	}
+
 	creq = smbcli_sock_connect_send(state, NULL, state->ports,
 					state->host, state->resolve_ctx,
 					state->ev, state->socket_options,
@@ -170,10 +194,6 @@ static void smb2_connect_negprot_done(struct tevent_req *subreq)
 	struct tevent_req *req =
 		tevent_req_callback_data(subreq,
 		struct tevent_req);
-	struct smb2_connect_state *state =
-		tevent_req_data(req,
-		struct smb2_connect_state);
-	struct smb2_transport *transport = state->transport;
 	NTSTATUS status;
 
 	status = smbXcli_negprot_recv(subreq);
@@ -182,6 +202,17 @@ static void smb2_connect_negprot_done(struct tevent_req *subreq)
 		return;
 	}
 
+	smb2_connect_session_start(req);
+}
+
+static void smb2_connect_session_start(struct tevent_req *req)
+{
+	struct smb2_connect_state *state =
+		tevent_req_data(req,
+		struct smb2_connect_state);
+	struct smb2_transport *transport = state->transport;
+	struct tevent_req *subreq = NULL;
+
 	state->session = smb2_session_init(transport, state->gensec_settings, state);
 	if (tevent_req_nomem(state->session, req)) {
 		return;
@@ -212,6 +243,34 @@ static void smb2_connect_session_done(struct tevent_req *subreq)
 
 	status = smb2_session_setup_spnego_recv(subreq);
 	TALLOC_FREE(subreq);
+	if (!NT_STATUS_IS_OK(status) &&
+	    !cli_credentials_is_anonymous(state->credentials) &&
+	    state->fallback_to_anonymous) {
+		struct cli_credentials *anon_creds = NULL;
+
+		/*
+		 * The transport was moved to session,
+		 * we need to revert that before removing
+		 * the old broken session.
+		 */
+		state->transport = talloc_move(state, &state->session->transport);
+		TALLOC_FREE(state->session);
+
+		anon_creds = cli_credentials_init_anon(state);
+		if (tevent_req_nomem(anon_creds, req)) {
+			return;
+		}
+		cli_credentials_set_workstation(anon_creds,
+		   cli_credentials_get_workstation(state->credentials),
+		   CRED_SPECIFIED);
+
+		/*
+		 * retry with anonymous credentials
+		 */
+		state->credentials = anon_creds;
+		smb2_connect_session_start(req);
+		return;
+	}
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
@@ -303,6 +362,8 @@ NTSTATUS smb2_connect_ext(TALLOC_CTX *mem_ctx,
 				   share,
 				   resolve_ctx,
 				   credentials,
+				   false, /* fallback_to_anonymous */
+				   NULL, /* existing_conn */
 				   previous_session_id,
 				   options,
 				   socket_options,
diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c
index b2cb838..e94512d 100644
--- a/source4/libcli/smb2/session.c
+++ b/source4/libcli/smb2/session.c
@@ -195,13 +195,38 @@ struct tevent_req *smb2_session_setup_spnego_send(
 
 	if (state->out_secblob.length > 0) {
 		chosen_oid = GENSEC_OID_SPNEGO;
+		status = gensec_start_mech_by_oid(session->gensec, chosen_oid);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n",
+				  gensec_get_name_by_oid(session->gensec,
+							 chosen_oid),
+				  nt_errstr(status)));


-- 
Samba Shared Repository



More information about the samba-cvs mailing list