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

Karolin Seeger kseeger at samba.org
Fri Jun 30 12:58:03 UTC 2017


The branch, v4-5-test has been updated
       via  7d8f7fb s3:smb2_create: avoid reusing the 'tevent_req' within smbd_smb2_create_send()
       via  dc4a6a9 s3: libsmb: Correctly save and restore connection tcon in smbclient, smbcacls and smbtorture3.
       via  c939552 s3: libsmb: Correctly do lifecycle management on cli->smb1.tcon and cli->smb2.tcon.
       via  0d0d982 s3: libsmb: Fix cli_state_has_tcon() to cope with SMB2 connections.
       via  cf68b64 s3: libsmb: Widen cli_state_get_tid() / cli_state_set_tid() to 32-bits.
       via  5d9c3b3 s3: smbtorture: Show correct use of cli_state_save_tcon() / cli_state_restore_tcon().
       via  5ec9fca s3: libsmb: Add cli_state_save_tcon() / cli_state_restore_tcon().
       via  43735d6 libcli: smb: Add smb2cli_tcon_set_id().
       via  85896c3 libcli: smb: Add smbXcli_tcon_copy().
       via  48a6971 auth/spnego: fix gensec_update_ev() argument order for the SPNEGO_FALLBACK case
       via  e260f4f s3:smbd: unimplement FSCTL_VALIDATE_NEGOTIATE_INFO with "server max protocol = SMB2_02"
       via  2544198 samba-tool: fix log message of 'samba-tool user syncpasswords'
      from  1329592 auth/ntlmssp: enforce NTLMSSP_NEGOTIATE_NTLM2 for the NTLMv2 client case

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


- Log -----------------------------------------------------------------
commit 7d8f7fbe02cf972a1a356125833fa6c665427cdb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jun 9 12:30:33 2017 +0200

    s3:smb2_create: avoid reusing the 'tevent_req' within smbd_smb2_create_send()
    
    As the caller ("smbd_smb2_request_process_create()") already sets the callback,
    the first time, it's not safe to reuse the tevent_req structure.
    
    The typical 'tevent_req_nterror(); return tevent_req_post()' will
    crash as the tevent_req_nterror() already triggered the former callback,
    which calls smbd_smb2_create_recv(), were tevent_req_received() invalidates
    the tevent_req structure, so that tevent_req_post() will crash.
    
    We just remember the required values from the old state
    and move them to the new state.
    
    We tried to write reproducers for this, but sadly weren't able to trigger
    the backtrace we had from a create a customer (using recent code)
    with commit 6beba782f1bf951236813e0b46115b8102212c03
    included. And this patch fixed the situation for the
    customer.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12832
    
    Pair-Programmed-With: Volker Lendecke <vl at samba.org>
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 02146ea5ee729de0e49ecf617e6983f4e61fbe59)
    
    Autobuild-User(v4-5-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-5-test): Fri Jun 30 14:57:14 CEST 2017 on sn-devel-144

commit dc4a6a980a16f7effb2b422ad6332936f457546c
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jun 13 16:56:48 2017 -0700

    s3: libsmb: Correctly save and restore connection tcon in smbclient, smbcacls and smbtorture3.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12831
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>
    (cherry picked from commit bd31d538a26bb21cbb53986a6105204da4392e2d)

commit c939552b7e52396ab78419ae0706759ff3ca30a3
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jun 13 16:37:39 2017 -0700

    s3: libsmb: Correctly do lifecycle management on cli->smb1.tcon and cli->smb2.tcon.
    
    Treat them identically. Create them on demand after for a tcon call,
    and delete them on a tdis call.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12831
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>
    (cherry picked from commit 50f50256aa8805921c42d0f9f2f8f89d06d9bd93)

commit 0d0d9820531aca17a5300f4e4eb47f07a999aaca
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jun 13 16:36:54 2017 -0700

    s3: libsmb: Fix cli_state_has_tcon() to cope with SMB2 connections.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12831
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>
    (cherry picked from commit c9178ed9cc69b9089292db28ac1a0b7a0519bc2c)

commit cf68b647b3a839c9ffe31a508ac167f897fc0d04
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jun 13 16:26:00 2017 -0700

    s3: libsmb: Widen cli_state_get_tid() / cli_state_set_tid() to 32-bits.
    
    Copes with SMB2 connections.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12831
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>
    (cherry picked from commit 93fa0c8660e47cb2605d70dac1156576ab719d64)

commit 5d9c3b3d4832b59ca94d031ba965227a25611059
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jun 13 16:25:25 2017 -0700

    s3: smbtorture: Show correct use of cli_state_save_tcon() / cli_state_restore_tcon().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12831
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>
    (cherry picked from commit 5c0efc9a5ef8ddf96dc394110063bebd5f057415)

commit 5ec9fca817d71ec13ea0115e7f41ad54feb66dc7
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jun 13 16:15:00 2017 -0700

    s3: libsmb: Add cli_state_save_tcon() / cli_state_restore_tcon().
    
    Save and restore tcon pointers in smb1 or smb2 structs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12831
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>
    (cherry picked from commit 39026f1c5dbb83120b70b3d9131138a9c2344ba6)

commit 43735d628a5cd87e6ede50f19c247795573a9ad8
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jun 13 16:08:22 2017 -0700

    libcli: smb: Add smb2cli_tcon_set_id().
    
    Will be used in test and client code.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12831
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>
    (cherry picked from commit e726b60226105d0f52a66dac47bfc5797cfc18e7)

commit 85896c3b0051d4af27cbdc17ffdbc5135b25cf32
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jun 13 16:06:22 2017 -0700

    libcli: smb: Add smbXcli_tcon_copy().
    
    Makes a deep copy of a struct smbXcli_tcon *, will
    be used later.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12831
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>
    (cherry picked from commit 655e10685840fd5ebfde24396853b74020a1dc85)

commit 48a697132f0c80d3ee2b9926bf6e551f0a4e6a15
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri May 12 09:10:19 2017 +0200

    auth/spnego: fix gensec_update_ev() argument order for the SPNEGO_FALLBACK case
    
    This went unnoticed so long as we don't use -Wc++-compat
    and gensec_update_ev() used the sync update() hook for all
    NTLMSSP and Kerberos.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 31691963b3d9ac460df0c56d36f81ec815db0225)

commit e260f4ff8d6805ee00734dd1e39a68726ade6807
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri May 5 18:49:37 2017 +0200

    s3:smbd: unimplement FSCTL_VALIDATE_NEGOTIATE_INFO with "server max protocol = SMB2_02"
    
    A client that supports SMB3 will do a signed FSCTL_VALIDATE_NEGOTIATE_INFO
    after a tree connect. This FSCTL_VALIDATE_NEGOTIATE_INFO call contains
    the client capabilities, client guid, security mode and the array of supported
    dialects. But if SMB 2.02 is negotiated the doesn't send these values to the
    server in the first connection attempt (when the client starts with a SMB1 Negotiate).
    
    Windows servers that only support SMB2 just return NT_STATUS_FILE_CLOSED
    as answer to FSCTL_VALIDATE_NEGOTIATE_INFO.
    
    We should do the same if we just pretend to support SMB 2.02,
    as SMB 2.10 always include an SMB2 Negotiate request we can leave it as is.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12772
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit 295c9f7b322e6377d0df1b49cb26597d66e80eda)

commit 25441982869aab0069ee1be1717ceca704ba0b98
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 25 13:25:10 2017 +0200

    samba-tool: fix log message of 'samba-tool user syncpasswords'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12768
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Fri May  5 01:37:45 CEST 2017 on sn-devel-144
    
    (cherry picked from commit 4c17850ae7b6c85e99e5d4d5bc5d8e89a9ba6d47)

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

Summary of changes:
 auth/gensec/spnego.c                 |  6 ++--
 libcli/smb/smbXcli_base.c            | 37 ++++++++++++++++++++
 libcli/smb/smbXcli_base.h            |  3 ++
 python/samba/netcmd/user.py          |  2 +-
 source3/client/client.c              |  5 ++-
 source3/lib/util_sd.c                | 24 ++++++++++---
 source3/libsmb/cliconnect.c          | 23 +++++++++++--
 source3/libsmb/clidfs.c              | 18 +++++++---
 source3/libsmb/clientgen.c           | 67 ++++++++++++++++++++++++++++--------
 source3/libsmb/proto.h               |  7 ++--
 source3/smbd/smb2_create.c           | 43 ++++++++++++-----------
 source3/smbd/smb2_ioctl_network_fs.c | 17 +++++++++
 source3/torture/test_smb2.c          |  8 +++--
 source3/torture/torture.c            | 24 ++++++++++---
 source3/utils/net_rpc.c              | 12 +++++--
 source3/utils/smbcacls.c             | 12 +++++--
 16 files changed, 244 insertions(+), 64 deletions(-)


Changeset truncated at 500 lines:

diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c
index 5f5047a..962e1fc 100644
--- a/auth/gensec/spnego.c
+++ b/auth/gensec/spnego.c
@@ -366,7 +366,7 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec
 			return nt_status;
 		}
 		nt_status = gensec_update_ev(spnego_state->sub_sec_security,
-					  ev, out_mem_ctx, in, out);
+					     out_mem_ctx, ev, in, out);
 		return nt_status;
 	}
 	DEBUG(1, ("Failed to parse SPNEGO request\n"));
@@ -756,8 +756,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
 
 	switch (spnego_state->state_position) {
 	case SPNEGO_FALLBACK:
-		return gensec_update_ev(spnego_state->sub_sec_security, ev,
-				     out_mem_ctx, in, out);
+		return gensec_update_ev(spnego_state->sub_sec_security,
+					out_mem_ctx, ev, in, out);
 	case SPNEGO_SERVER_START:
 	{
 		NTSTATUS nt_status;
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index aca5363..43294be 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -5989,6 +5989,38 @@ struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
 	return tcon;
 }
 
+/*
+ * Return a deep structure copy of a struct smbXcli_tcon *
+ */
+
+struct smbXcli_tcon *smbXcli_tcon_copy(TALLOC_CTX *mem_ctx,
+				const struct smbXcli_tcon *tcon_in)
+{
+	struct smbXcli_tcon *tcon;
+
+	tcon = talloc_memdup(mem_ctx, tcon_in, sizeof(struct smbXcli_tcon));
+	if (tcon == NULL) {
+		return NULL;
+	}
+
+	/* Deal with the SMB1 strings. */
+	if (tcon_in->smb1.service != NULL) {
+		tcon->smb1.service = talloc_strdup(tcon, tcon_in->smb1.service);
+		if (tcon->smb1.service == NULL) {
+			TALLOC_FREE(tcon);
+			return NULL;
+		}
+	}
+	if (tcon->smb1.fs_type != NULL) {
+		tcon->smb1.fs_type = talloc_strdup(tcon, tcon_in->smb1.fs_type);
+		if (tcon->smb1.fs_type == NULL) {
+			TALLOC_FREE(tcon);
+			return NULL;
+		}
+	}
+	return tcon;
+}
+
 void smbXcli_tcon_set_fs_attributes(struct smbXcli_tcon *tcon,
 				    uint32_t fs_attributes)
 {
@@ -6067,6 +6099,11 @@ uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon)
 	return tcon->smb2.tcon_id;
 }
 
+void smb2cli_tcon_set_id(struct smbXcli_tcon *tcon, uint32_t tcon_id)
+{
+	tcon->smb2.tcon_id = tcon_id;
+}
+
 uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
 {
 	return tcon->smb2.capabilities;
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 16c8848..55d3f78 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -431,6 +431,8 @@ NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
 NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session);
 
 struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx);
+struct smbXcli_tcon *smbXcli_tcon_copy(TALLOC_CTX *mem_ctx,
+				const struct smbXcli_tcon *tcon_in);
 void smbXcli_tcon_set_fs_attributes(struct smbXcli_tcon *tcon,
 				    uint32_t fs_attributes);
 uint32_t smbXcli_tcon_get_fs_attributes(struct smbXcli_tcon *tcon);
@@ -445,6 +447,7 @@ bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon,
 			     const char *service,
 			     const char *fs_type);
 uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon);
+void smb2cli_tcon_set_id(struct smbXcli_tcon *tcon, uint32_t tcon_id);
 uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon);
 uint32_t smb2cli_tcon_flags(struct smbXcli_tcon *tcon);
 void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon,
diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py
index 4f1bce8..844f7f0 100644
--- a/python/samba/netcmd/user.py
+++ b/python/samba/netcmd/user.py
@@ -1604,7 +1604,7 @@ samba-tool user syncpasswords --terminate \\
             return
 
         def run_sync_command(dn, ldif):
-            log_msg("Call Popen[%s] for %s\n" % (dn, self.sync_command))
+            log_msg("Call Popen[%s] for %s\n" % (self.sync_command, dn))
             sync_command_p = Popen(self.sync_command,
                                    stdin=PIPE,
                                    stdout=PIPE,
diff --git a/source3/client/client.c b/source3/client/client.c
index e7531d3..c173cf4 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -4673,7 +4673,10 @@ static int cmd_tid(void)
 			d_printf("no tcon currently\n");
 		}
 	} else {
-		uint16_t tid = atoi(tid_str);
+		uint32_t tid = atoi(tid_str);
+		if (!cli_state_has_tcon(cli)) {
+			d_printf("no tcon currently\n");
+		}
 		cli_state_set_tid(cli, tid);
 	}
 
diff --git a/source3/lib/util_sd.c b/source3/lib/util_sd.c
index 9a7b34f..4c46d4c 100644
--- a/source3/lib/util_sd.c
+++ b/source3/lib/util_sd.c
@@ -84,7 +84,7 @@ static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
 				   enum lsa_SidType *type,
 				   char **domain, char **name)
 {
-	uint16_t orig_cnum = cli_state_get_tid(cli);
+	struct smbXcli_tcon *orig_tcon = NULL;
 	struct rpc_pipe_client *p = NULL;
 	struct policy_handle handle;
 	NTSTATUS status;
@@ -93,6 +93,14 @@ static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
 	char **domains;
 	char **names;
 
+	if (cli_state_has_tcon(cli)) {
+		orig_tcon = cli_state_save_tcon(cli);
+		if (orig_tcon == NULL) {
+			status = NT_STATUS_NO_MEMORY;
+			goto tcon_fail;
+		}
+	}
+
 	status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto tcon_fail;
@@ -125,7 +133,7 @@ static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
 	TALLOC_FREE(p);
 	cli_tdis(cli);
  tcon_fail:
-	cli_state_set_tid(cli, orig_cnum);
+	cli_state_restore_tcon(cli, orig_tcon);
 	TALLOC_FREE(frame);
 	return status;
 }
@@ -165,7 +173,7 @@ static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
 				    enum lsa_SidType *type,
 				    struct dom_sid *sid)
 {
-	uint16_t orig_cnum = cli_state_get_tid(cli);
+	struct smbXcli_tcon *orig_tcon = NULL;
 	struct rpc_pipe_client *p;
 	struct policy_handle handle;
 	NTSTATUS status;
@@ -173,6 +181,14 @@ static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
 	struct dom_sid *sids;
 	enum lsa_SidType *types;
 
+	if (cli_state_has_tcon(cli)) {
+		orig_tcon = cli_state_save_tcon(cli);
+		if (orig_tcon == NULL) {
+			status = NT_STATUS_NO_MEMORY;
+			goto tcon_fail;
+		}
+	}
+
 	status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto tcon_fail;
@@ -204,7 +220,7 @@ static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
 	TALLOC_FREE(p);
 	cli_tdis(cli);
  tcon_fail:
-	cli_state_set_tid(cli, orig_cnum);
+	cli_state_restore_tcon(cli, orig_tcon);
 	TALLOC_FREE(frame);
 	return status;
 }
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 9c8851f..9ab29b6 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -2437,6 +2437,13 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
 	state->cli = cli;
 	vwv = state->vwv;
 
+	TALLOC_FREE(cli->smb1.tcon);
+	cli->smb1.tcon = smbXcli_tcon_create(cli);
+	if (tevent_req_nomem(cli->smb1.tcon, req)) {
+		return tevent_req_post(req, ev);
+	}
+	smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
+
 	cli->share = talloc_strdup(cli, share);
 	if (!cli->share) {
 		return NULL;
@@ -2740,6 +2747,7 @@ static struct tevent_req *cli_tree_connect_send(
 	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
 		char *unc;
 
+		TALLOC_FREE(cli->smb2.tcon);
 		cli->smb2.tcon = smbXcli_tcon_create(cli);
 		if (tevent_req_nomem(cli->smb2.tcon, req)) {
 			return tevent_req_post(req, ev);
@@ -2899,7 +2907,7 @@ static void cli_tdis_done(struct tevent_req *subreq)
 		tevent_req_nterror(req, status);
 		return;
 	}
-	cli_state_set_tid(state->cli, UINT16_MAX);
+	TALLOC_FREE(state->cli->smb1.tcon);
 	tevent_req_done(req);
 }
 
@@ -2915,10 +2923,14 @@ NTSTATUS cli_tdis(struct cli_state *cli)
 	NTSTATUS status = NT_STATUS_NO_MEMORY;
 
 	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
-		return smb2cli_tdis(cli->conn,
+		status = smb2cli_tdis(cli->conn,
 				    cli->timeout,
 				    cli->smb2.session,
 				    cli->smb2.tcon);
+		if (NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(cli->smb2.tcon);
+		}
+		return status;
 	}
 
 	if (smbXcli_conn_has_async_calls(cli->conn)) {
@@ -3579,6 +3591,13 @@ static struct tevent_req *cli_raw_tcon_send(
 		return tevent_req_post(req, ev);
 	}
 
+	TALLOC_FREE(cli->smb1.tcon);
+	cli->smb1.tcon = smbXcli_tcon_create(cli);
+	if (tevent_req_nomem(cli->smb1.tcon, req)) {
+		return tevent_req_post(req, ev);
+	}
+	smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
+
 	bytes = talloc_array(state, uint8_t, 0);
 	bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index d2a4c19..16b21bd 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -1179,7 +1179,7 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 	size_t consumed = 0;
 	char *fullpath = NULL;
 	bool res;
-	uint16_t cnum;
+	struct smbXcli_tcon *orig_tcon = NULL;
 	char *newextrapath = NULL;
 	NTSTATUS status;
 	const char *remote_name;
@@ -1189,7 +1189,6 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 	}
 
 	remote_name = smbXcli_conn_remote_name(cli->conn);
-	cnum = cli_state_get_tid(cli);
 
 	/* special case.  never check for a referral on the IPC$ share */
 
@@ -1204,9 +1203,18 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 		return false;
 	}
 
+	/* Store tcon state. */
+	if (cli_state_has_tcon(cli)) {
+		orig_tcon = cli_state_save_tcon(cli);
+		if (orig_tcon == NULL) {
+			return false;
+		}
+	}
+
 	/* check for the referral */
 
 	if (!NT_STATUS_IS_OK(cli_tree_connect(cli, "IPC$", "IPC", NULL, 0))) {
+		cli_state_restore_tcon(cli, orig_tcon);
 		return false;
 	}
 
@@ -1217,6 +1225,7 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 					domain,
 					"IPC$");
 		if (!NT_STATUS_IS_OK(status)) {
+			cli_state_restore_tcon(cli, orig_tcon);
 			return false;
 		}
 	}
@@ -1226,12 +1235,13 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 	res = NT_STATUS_IS_OK(status);
 
 	status = cli_tdis(cli);
+
+	cli_state_restore_tcon(cli, orig_tcon);
+
 	if (!NT_STATUS_IS_OK(status)) {
 		return false;
 	}
 
-	cli_state_set_tid(cli, cnum);
-
 	if (!res || !num_refs) {
 		return false;
 	}
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index bc5c1b1..2b53a93 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -227,11 +227,6 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx,
 
 	cli->smb1.pid = (uint32_t)getpid();
 	cli->smb1.vc_num = cli->smb1.pid;
-	cli->smb1.tcon = smbXcli_tcon_create(cli);
-	if (cli->smb1.tcon == NULL) {
-		goto error;
-	}
-	smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
 	cli->smb1.session = smbXcli_session_create(cli, cli->conn);
 	if (cli->smb1.session == NULL) {
 		goto error;
@@ -341,27 +336,69 @@ uint32_t cli_getpid(struct cli_state *cli)
 
 bool cli_state_has_tcon(struct cli_state *cli)
 {
-	uint16_t tid = cli_state_get_tid(cli);
-
-	if (tid == UINT16_MAX) {
-		return false;
+	uint32_t tid;
+	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+		if (cli->smb2.tcon == NULL) {
+			return false;
+		}
+		tid = cli_state_get_tid(cli);
+		if (tid == UINT32_MAX) {
+			return false;
+		}
+	} else {
+		if (cli->smb1.tcon == NULL) {
+			return false;
+		}
+		tid = cli_state_get_tid(cli);
+		if (tid == UINT16_MAX) {
+			return false;
+		}
 	}
-
 	return true;
 }
 
-uint16_t cli_state_get_tid(struct cli_state *cli)
+uint32_t cli_state_get_tid(struct cli_state *cli)
 {
-	return smb1cli_tcon_current_id(cli->smb1.tcon);
+	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+		return smb2cli_tcon_current_id(cli->smb2.tcon);
+	} else {
+		return (uint32_t)smb1cli_tcon_current_id(cli->smb1.tcon);
+	}
 }
 
-uint16_t cli_state_set_tid(struct cli_state *cli, uint16_t tid)
+uint32_t cli_state_set_tid(struct cli_state *cli, uint32_t tid)
 {
-	uint16_t ret = smb1cli_tcon_current_id(cli->smb1.tcon);
-	smb1cli_tcon_set_id(cli->smb1.tcon, tid);
+	uint32_t ret;
+	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+		ret = smb2cli_tcon_current_id(cli->smb2.tcon);
+		smb2cli_tcon_set_id(cli->smb1.tcon, tid);
+	} else {
+		ret = smb1cli_tcon_current_id(cli->smb1.tcon);
+		smb1cli_tcon_set_id(cli->smb1.tcon, tid);
+	}
 	return ret;
 }
 
+struct smbXcli_tcon *cli_state_save_tcon(struct cli_state *cli)
+{
+	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+		return smbXcli_tcon_copy(cli, cli->smb2.tcon);
+	} else {
+		return smbXcli_tcon_copy(cli, cli->smb1.tcon);
+	}
+}
+
+void cli_state_restore_tcon(struct cli_state *cli, struct smbXcli_tcon *tcon)
+{
+	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+		TALLOC_FREE(cli->smb2.tcon);
+		cli->smb2.tcon = tcon;
+	} else {
+		TALLOC_FREE(cli->smb1.tcon);
+		cli->smb1.tcon = tcon;
+	}
+}
+
 uint16_t cli_state_get_uid(struct cli_state *cli)
 {
 	return smb1cli_session_current_id(cli->smb1.session);
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index c0e1b74..340cd22 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -175,8 +175,11 @@ uint16_t cli_state_get_vc_num(struct cli_state *cli);
 uint32_t cli_setpid(struct cli_state *cli, uint32_t pid);
 uint32_t cli_getpid(struct cli_state *cli);
 bool cli_state_has_tcon(struct cli_state *cli);
-uint16_t cli_state_get_tid(struct cli_state *cli);
-uint16_t cli_state_set_tid(struct cli_state *cli, uint16_t tid);
+uint32_t cli_state_get_tid(struct cli_state *cli);
+uint32_t cli_state_set_tid(struct cli_state *cli, uint32_t tid);
+struct smbXcli_tcon;
+struct smbXcli_tcon *cli_state_save_tcon(struct cli_state *cli);
+void cli_state_restore_tcon(struct cli_state *cli, struct smbXcli_tcon *tcon);
 uint16_t cli_state_get_uid(struct cli_state *cli);
 uint16_t cli_state_set_uid(struct cli_state *cli, uint16_t uid);
 bool cli_set_case_sensitive(struct cli_state *cli, bool case_sensitive);
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 8211991..0158924 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -483,35 +483,38 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 		requested_oplock_level = in_oplock_level;
 	}
 
-
-	if (smb2req->subreq == NULL) {
-		/* New create call. */
-		req = tevent_req_create(mem_ctx, &state,
+	req = tevent_req_create(mem_ctx, &state,
 				struct smbd_smb2_create_state);
-		if (req == NULL) {
-			return NULL;
-		}
-		state->smb2req = smb2req;
+	if (req == NULL) {
+		return NULL;
+	}
+	state->smb2req = smb2req;
 
-		smb1req = smbd_smb2_fake_smb_request(smb2req);
-		if (tevent_req_nomem(smb1req, req)) {
-			return tevent_req_post(req, ev);
-		}
-		state->smb1req = smb1req;
-		smb2req->subreq = req;
+	smb1req = smbd_smb2_fake_smb_request(smb2req);
+	if (tevent_req_nomem(smb1req, req)) {
+		return tevent_req_post(req, ev);
+	}
+	state->smb1req = smb1req;
+
+	if (smb2req->subreq == NULL) {
 		DEBUG(10,("smbd_smb2_create: name[%s]\n",
 			in_name));
 	} else {
-		/* Re-entrant create call. */
-		req = smb2req->subreq;
-		state = tevent_req_data(req,
-				struct smbd_smb2_create_state);
-		smb1req = state->smb1req;
-		TALLOC_FREE(state->out_context_blobs);
+		struct smbd_smb2_create_state *old_state = tevent_req_data(
+			smb2req->subreq, struct smbd_smb2_create_state);
+
 		DEBUG(10,("smbd_smb2_create_send: reentrant for file %s\n",
 			in_name ));
+
+		state->id = old_state->id;
+		state->request_time = old_state->request_time;
+		state->open_rec = talloc_move(state, &old_state->open_rec);
+		state->open_was_deferred = old_state->open_was_deferred;
 	}
 
+	TALLOC_FREE(smb2req->subreq);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list