[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