[PATCH] Fix bug #Bug 12831 - smbcacls got error NT_STATUS_NETWORK_NAME_DELETED

Jeremy Allison jra at samba.org
Fri Jun 16 16:20:53 UTC 2017


On Wed, Jun 14, 2017 at 08:50:57AM -0700, Jeremy Allison wrote:
> It turns out that smbclient, smbcacls and smbtorture3 depend
> on the ability to temporarily replace the client tcon connection
> struct internally to the client with a new connection to IPC$,
> do some calls on that new connection (usually lookupnames/lookupsids),
> then replace the old values of the tcon and continue.
> 
> This has some problems. (a). It only works for SMB1 (for SMB2 we
> overwrote the tcon pointer) and (b). It didn't really work for SMB1
> either - we ended up with a bastardized cli->smb1.tcon pointer that
> contains type and string from the IPC$ connection whilst being
> connected to the share connection. We only got away with this
> due to the fact we don't use the type and string for anything
> on the wire.
> 
> This patch unifies the cli->smb[1|2].tcon pointer handling and
> allows temporary replacement of the pointer, and also SMB2 access
> to the get/set the 32-bit tid value.
> 
> Most of this patch is fixing up the smbclient/smbcacls/smbtorture3
> code so everything keeps working with make test, so I know this
> is being tested (it took me a day or so to keep all our tests
> passing :-).
> 
> Please review and push if you're happy !

Ping ! Can I get a review on this please ?

It removes one more barrier for us to make SMB2 the default
in our client tools.

Cheers,

Jeremy.



> From 53ca9dc795733551a8b4cc9b7842cd2dd44087ac Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 13 Jun 2017 16:06:22 -0700
> Subject: [PATCH 1/8] 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>
> ---
>  libcli/smb/smbXcli_base.c | 32 ++++++++++++++++++++++++++++++++
>  libcli/smb/smbXcli_base.h |  2 ++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
> index 1ec11a9dec4..ee25e369b80 100644
> --- a/libcli/smb/smbXcli_base.c
> +++ b/libcli/smb/smbXcli_base.c
> @@ -6099,6 +6099,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)
>  {
> diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
> index 1abeb2b180b..7b83b1a7bc8 100644
> --- a/libcli/smb/smbXcli_base.h
> +++ b/libcli/smb/smbXcli_base.h
> @@ -501,6 +501,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);
> -- 
> 2.13.1.508.gb3defc5cc-goog
> 
> 
> From b72281410da0092db647dd7f6299e5da549e7f30 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 13 Jun 2017 16:08:22 -0700
> Subject: [PATCH 2/8] 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>
> ---
>  libcli/smb/smbXcli_base.c | 5 +++++
>  libcli/smb/smbXcli_base.h | 1 +
>  2 files changed, 6 insertions(+)
> 
> diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
> index ee25e369b80..31319a34981 100644
> --- a/libcli/smb/smbXcli_base.c
> +++ b/libcli/smb/smbXcli_base.c
> @@ -6209,6 +6209,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 7b83b1a7bc8..52fec9a5044 100644
> --- a/libcli/smb/smbXcli_base.h
> +++ b/libcli/smb/smbXcli_base.h
> @@ -517,6 +517,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,
> -- 
> 2.13.1.508.gb3defc5cc-goog
> 
> 
> From 9afc8edc08898c7b30aefaf74c229ad4a3246d7d Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 13 Jun 2017 16:15:00 -0700
> Subject: [PATCH 3/8] 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>
> ---
>  source3/libsmb/clientgen.c | 20 ++++++++++++++++++++
>  source3/libsmb/proto.h     |  3 +++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
> index bc5c1b1ce3c..1aea4cf247e 100644
> --- a/source3/libsmb/clientgen.c
> +++ b/source3/libsmb/clientgen.c
> @@ -362,6 +362,26 @@ uint16_t cli_state_set_tid(struct cli_state *cli, uint16_t 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 137c3554771..3d545024d98 100644
> --- a/source3/libsmb/proto.h
> +++ b/source3/libsmb/proto.h
> @@ -196,6 +196,9 @@ 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);
> +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);
> -- 
> 2.13.1.508.gb3defc5cc-goog
> 
> 
> From 72245a240e1d1658c2cfee12f860f23879513054 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 13 Jun 2017 16:25:25 -0700
> Subject: [PATCH 4/8] 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>
> ---
>  source3/torture/test_smb2.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/source3/torture/test_smb2.c b/source3/torture/test_smb2.c
> index c0d11e61087..9368ab3264d 100644
> --- a/source3/torture/test_smb2.c
> +++ b/source3/torture/test_smb2.c
> @@ -170,7 +170,10 @@ bool run_smb2_basic(int dummy)
>  	}
>  
>  	saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
> -	saved_tcon = cli->smb2.tcon;
> +	saved_tcon = cli_state_save_tcon(cli);
> +	if (saved_tcon == NULL) {
> +		return false;
> +	}
>  	cli->smb2.tcon = smbXcli_tcon_create(cli);
>  	smb2cli_tcon_set_values(cli->smb2.tcon,
>  				NULL, /* session */
> @@ -187,8 +190,7 @@ bool run_smb2_basic(int dummy)
>  		printf("smb2cli_tdis returned %s\n", nt_errstr(status));
>  		return false;
>  	}
> -	talloc_free(cli->smb2.tcon);
> -	cli->smb2.tcon = saved_tcon;
> +	cli_state_restore_tcon(cli, saved_tcon);
>  
>  	status = smb2cli_tdis(cli->conn,
>  			      cli->timeout,
> -- 
> 2.13.1.508.gb3defc5cc-goog
> 
> 
> From 774f1d5cc1e39007bf4266d97637b78ea79e387e Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 13 Jun 2017 16:26:00 -0700
> Subject: [PATCH 5/8] 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>
> ---
>  source3/client/client.c    |  5 ++++-
>  source3/lib/util_sd.c      |  4 ++--
>  source3/libsmb/clidfs.c    |  2 +-
>  source3/libsmb/clientgen.c | 22 ++++++++++++++++------
>  source3/libsmb/proto.h     |  4 ++--
>  source3/torture/torture.c  |  8 ++++----
>  6 files changed, 29 insertions(+), 16 deletions(-)
> 
> diff --git a/source3/client/client.c b/source3/client/client.c
> index 64647365dc4..3285240d404 100644
> --- a/source3/client/client.c
> +++ b/source3/client/client.c
> @@ -4712,7 +4712,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 d79fe79b94b..a95cafd5f7a 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);
> +	uint32_t orig_cnum = cli_state_get_tid(cli);
>  	struct rpc_pipe_client *p = NULL;
>  	struct policy_handle handle;
>  	NTSTATUS status;
> @@ -165,7 +165,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);
> +	uint32_t orig_cnum = cli_state_get_tid(cli);
>  	struct rpc_pipe_client *p;
>  	struct policy_handle handle;
>  	NTSTATUS status;
> diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
> index c477d7c6a46..1010e1b5c28 100644
> --- a/source3/libsmb/clidfs.c
> +++ b/source3/libsmb/clidfs.c
> @@ -1205,7 +1205,7 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
>  	size_t consumed = 0;
>  	char *fullpath = NULL;
>  	bool res;
> -	uint16_t cnum;
> +	uint32_t cnum;
>  	char *newextrapath = NULL;
>  	NTSTATUS status;
>  	const char *remote_name;
> diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
> index 1aea4cf247e..25f72991956 100644
> --- a/source3/libsmb/clientgen.c
> +++ b/source3/libsmb/clientgen.c
> @@ -341,7 +341,7 @@ 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);
> +	uint32_t tid = cli_state_get_tid(cli);
>  
>  	if (tid == UINT16_MAX) {
>  		return false;
> @@ -350,15 +350,25 @@ bool cli_state_has_tcon(struct cli_state *cli)
>  	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;
>  }
>  
> diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
> index 3d545024d98..6728c97664c 100644
> --- a/source3/libsmb/proto.h
> +++ b/source3/libsmb/proto.h
> @@ -194,8 +194,8 @@ 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);
> diff --git a/source3/torture/torture.c b/source3/torture/torture.c
> index bdcf1e13f17..58f0ce0a31f 100644
> --- a/source3/torture/torture.c
> +++ b/source3/torture/torture.c
> @@ -1301,7 +1301,7 @@ static bool run_tcon_test(int dummy)
>  	static struct cli_state *cli;
>  	const char *fname = "\\tcontest.tmp";
>  	uint16_t fnum1;
> -	uint16_t cnum1, cnum2, cnum3;
> +	uint32_t cnum1, cnum2, cnum3;
>  	uint16_t vuid1, vuid2;
>  	char buf[4];
>  	bool ret = True;
> @@ -2764,8 +2764,8 @@ static bool run_fdsesstest(int dummy)
>  	struct cli_state *cli;
>  	uint16_t new_vuid;
>  	uint16_t saved_vuid;
> -	uint16_t new_cnum;
> -	uint16_t saved_cnum;
> +	uint32_t new_cnum;
> +	uint32_t saved_cnum;
>  	const char *fname = "\\fdsess.tst";
>  	const char *fname1 = "\\fdsess1.tst";
>  	uint16_t fnum1;
> @@ -9015,7 +9015,7 @@ static bool run_uid_regression_test(int dummy)
>  {
>  	static struct cli_state *cli;
>  	int16_t old_vuid;
> -	int16_t old_cnum;
> +	int32_t old_cnum;
>  	bool correct = True;
>  	NTSTATUS status;
>  
> -- 
> 2.13.1.508.gb3defc5cc-goog
> 
> 
> From 344d065a9c0604dbba902b6657aaedbd6b8cc5b0 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 13 Jun 2017 16:36:54 -0700
> Subject: [PATCH 6/8] 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>
> ---
>  source3/libsmb/clientgen.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
> index 25f72991956..4541763ea3f 100644
> --- a/source3/libsmb/clientgen.c
> +++ b/source3/libsmb/clientgen.c
> @@ -341,12 +341,24 @@ uint32_t cli_getpid(struct cli_state *cli)
>  
>  bool cli_state_has_tcon(struct cli_state *cli)
>  {
> -	uint32_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;
>  }
>  
> -- 
> 2.13.1.508.gb3defc5cc-goog
> 
> 
> From 675678e98fade2ecd852f1263889fcb306f231fc Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 13 Jun 2017 16:37:39 -0700
> Subject: [PATCH 7/8] 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>
> ---
>  source3/libsmb/cliconnect.c | 23 +++++++++++++++++++++--
>  source3/libsmb/clientgen.c  |  5 -----
>  2 files changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
> index 200657aff09..3fa80a2ec36 100644
> --- a/source3/libsmb/cliconnect.c
> +++ b/source3/libsmb/cliconnect.c
> @@ -1948,6 +1948,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;
> @@ -2257,6 +2264,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);
> @@ -2429,7 +2437,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);
>  }
>  
> @@ -2445,10 +2453,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)) {
> @@ -3623,6 +3635,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/clientgen.c b/source3/libsmb/clientgen.c
> index 4541763ea3f..2b53a930809 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;
> -- 
> 2.13.1.508.gb3defc5cc-goog
> 
> 
> From 811cc4b491e66b43d02476d83397c12fb3978807 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 13 Jun 2017 16:56:48 -0700
> Subject: [PATCH 8/8] 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>
> ---
>  source3/lib/util_sd.c     | 24 ++++++++++++++++++++----
>  source3/libsmb/clidfs.c   | 18 ++++++++++++++----
>  source3/torture/torture.c | 16 ++++++++++++++++
>  source3/utils/net_rpc.c   | 12 +++++++++---
>  source3/utils/smbcacls.c  | 12 ++++++++++--
>  5 files changed, 69 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/lib/util_sd.c b/source3/lib/util_sd.c
> index a95cafd5f7a..aa6d4809fc8 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)
>  {
> -	uint32_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$", "?????", NULL);
>  	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)
>  {
> -	uint32_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$", "?????", NULL);
>  	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/clidfs.c b/source3/libsmb/clidfs.c
> index 1010e1b5c28..75012b28e87 100644
> --- a/source3/libsmb/clidfs.c
> +++ b/source3/libsmb/clidfs.c
> @@ -1205,7 +1205,7 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
>  	size_t consumed = 0;
>  	char *fullpath = NULL;
>  	bool res;
> -	uint32_t cnum;
> +	struct smbXcli_tcon *orig_tcon = NULL;
>  	char *newextrapath = NULL;
>  	NTSTATUS status;
>  	const char *remote_name;
> @@ -1215,7 +1215,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 */
>  
> @@ -1230,15 +1229,25 @@ 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))) {
> +		cli_state_restore_tcon(cli, orig_tcon);
>  		return false;
>  	}
>  
>  	if (force_encrypt) {
>  		status = cli_cm_force_encryption_creds(cli, creds, "IPC$");
>  		if (!NT_STATUS_IS_OK(status)) {
> +			cli_state_restore_tcon(cli, orig_tcon);
>  			return false;
>  		}
>  	}
> @@ -1248,12 +1257,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/torture/torture.c b/source3/torture/torture.c
> index 58f0ce0a31f..378cb8ba35f 100644
> --- a/source3/torture/torture.c
> +++ b/source3/torture/torture.c
> @@ -1302,6 +1302,7 @@ static bool run_tcon_test(int dummy)
>  	const char *fname = "\\tcontest.tmp";
>  	uint16_t fnum1;
>  	uint32_t cnum1, cnum2, cnum3;
> +	struct smbXcli_tcon *orig_tcon = NULL;
>  	uint16_t vuid1, vuid2;
>  	char buf[4];
>  	bool ret = True;
> @@ -1333,6 +1334,11 @@ static bool run_tcon_test(int dummy)
>  		return False;
>  	}
>  
> +	orig_tcon = cli_state_save_tcon(cli);
> +	if (orig_tcon == NULL) {
> +		return false;
> +	}
> +
>  	status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		printf("%s refused 2nd tree connect (%s)\n", host,
> @@ -1400,6 +1406,8 @@ static bool run_tcon_test(int dummy)
>  		return False;
>  	}
>  
> +	cli_state_restore_tcon(cli, orig_tcon);
> +
>  	cli_state_set_tid(cli, cnum1);
>  
>  	if (!torture_close_connection(cli)) {
> @@ -9017,6 +9025,7 @@ static bool run_uid_regression_test(int dummy)
>  	int16_t old_vuid;
>  	int32_t old_cnum;
>  	bool correct = True;
> +	struct smbXcli_tcon *orig_tcon = NULL;
>  	NTSTATUS status;
>  
>  	printf("starting uid regression test\n");
> @@ -9057,6 +9066,11 @@ static bool run_uid_regression_test(int dummy)
>  	}
>  
>  	old_cnum = cli_state_get_tid(cli);
> +	orig_tcon = cli_state_save_tcon(cli);
> +	if (orig_tcon == NULL) {
> +		correct = false;
> +		goto out;
> +	}
>  
>  	/* Now try a SMBtdis with the invald vuid set to zero. */
>  	cli_state_set_uid(cli, 0);
> @@ -9069,9 +9083,11 @@ static bool run_uid_regression_test(int dummy)
>  	} else {
>  		d_printf("First tdis failed (%s)\n", nt_errstr(status));
>  		correct = false;
> +		cli_state_restore_tcon(cli, orig_tcon);
>  		goto out;
>  	}
>  
> +	cli_state_restore_tcon(cli, orig_tcon);
>  	cli_state_set_uid(cli, old_vuid);
>  	cli_state_set_tid(cli, old_cnum);
>  
> diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
> index e98f65a3158..7059ebde3ca 100644
> --- a/source3/utils/net_rpc.c
> +++ b/source3/utils/net_rpc.c
> @@ -5101,7 +5101,7 @@ static void show_userlist(struct rpc_pipe_client *pipe_hnd,
>  	union srvsvc_NetShareInfo info;
>  	WERROR result;
>  	NTSTATUS status;
> -	uint16_t cnum;
> +	struct smbXcli_tcon *orig_tcon = NULL;
>  	struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
>  
>  	status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
> @@ -5123,9 +5123,15 @@ static void show_userlist(struct rpc_pipe_client *pipe_hnd,
>  			  netname));
>  	}
>  
> -	cnum = cli_state_get_tid(cli);
> +	if (cli_state_has_tcon(cli)) {
> +		orig_tcon = cli_state_save_tcon(cli);
> +		if (orig_tcon == NULL) {
> +			return;
> +		}
> +	}
>  
>  	if (!NT_STATUS_IS_OK(cli_tree_connect(cli, netname, "A:", NULL))) {
> +		cli_state_restore_tcon(cli, orig_tcon);
>  		return;
>  	}
>  
> @@ -5168,7 +5174,7 @@ static void show_userlist(struct rpc_pipe_client *pipe_hnd,
>  	if (fnum != (uint16_t)-1)
>  		cli_close(cli, fnum);
>  	cli_tdis(cli);
> -	cli_state_set_tid(cli, cnum);
> +	cli_state_restore_tcon(cli, orig_tcon);
>  
>  	return;
>  }
> diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
> index 11289e69e43..86b4591d365 100644
> --- a/source3/utils/smbcacls.c
> +++ b/source3/utils/smbcacls.c
> @@ -51,12 +51,20 @@ static NTSTATUS cli_lsa_lookup_domain_sid(struct cli_state *cli,
>  					  struct dom_sid *sid)
>  {
>  	union lsa_PolicyInformation *info = NULL;
> -	uint16_t orig_cnum = cli_state_get_tid(cli);
> +	struct smbXcli_tcon *orig_tcon = NULL;
>  	struct rpc_pipe_client *rpc_pipe = NULL;
>  	struct policy_handle handle;
>  	NTSTATUS status, result;
>  	TALLOC_CTX *frame = talloc_stackframe();
>  
> +	if (cli_state_has_tcon(cli)) {
> +		orig_tcon = cli_state_save_tcon(cli);
> +		if (orig_tcon == NULL) {
> +			status = NT_STATUS_NO_MEMORY;
> +			goto done;
> +		}
> +	}
> +
>  	status = cli_tree_connect(cli, "IPC$", "?????", NULL);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		goto done;
> @@ -88,7 +96,7 @@ tdis:
>  	TALLOC_FREE(rpc_pipe);
>  	cli_tdis(cli);
>  done:
> -	cli_state_set_tid(cli, orig_cnum);
> +	cli_state_restore_tcon(cli, orig_tcon);
>  	TALLOC_FREE(frame);
>  	return status;
>  }
> -- 
> 2.13.1.508.gb3defc5cc-goog
> 




More information about the samba-technical mailing list