From c75b7b196e5e9c7522e01479b5d9b8729478fa9c Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Richard Sharpe (cherry picked from commit 655e10685840fd5ebfde24396853b74020a1dc85) --- 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 593edf9ce78..424a1c06078 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -6118,6 +6118,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 702eedf5dba..57d4209c727 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -496,6 +496,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.11.0 From ccb81c95425d86131cd7661898ce38dab2da795a Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Richard Sharpe (cherry picked from commit e726b60226105d0f52a66dac47bfc5797cfc18e7) --- 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 424a1c06078..b21d7963605 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -6228,6 +6228,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 57d4209c727..e48fc35faa5 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -512,6 +512,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.11.0 From e9115d69276e6640e8229489344f308e6406fd7c Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Richard Sharpe (cherry picked from commit 39026f1c5dbb83120b70b3d9131138a9c2344ba6) --- 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 764f3fc1b12..3ae324eec99 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -198,6 +198,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.11.0 From 81e8765f706af76f14db0094ea3fb8d041ab4639 Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Richard Sharpe (cherry picked from commit 5c0efc9a5ef8ddf96dc394110063bebd5f057415) --- 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.11.0 From 674dd99b501e9cfeb6706bb0d604750d6e67c48b Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Richard Sharpe (cherry picked from commit 93fa0c8660e47cb2605d70dac1156576ab719d64) --- 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 226eb277573..f808c9cf2c9 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -4703,7 +4703,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 3ae324eec99..a583a8ee159 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -196,8 +196,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 754e3b6933a..3f1786aaa06 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; @@ -8869,7 +8869,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.11.0 From 897e4eca7721b5b2a5f047059be91827ac7f1b4d Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Richard Sharpe (cherry picked from commit c9178ed9cc69b9089292db28ac1a0b7a0519bc2c) --- 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.11.0 From 9ada708481f0c1b6174889298cbc5f2f33a342a8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Richard Sharpe (cherry picked from commit 50f50256aa8805921c42d0f9f2f8f89d06d9bd93) --- 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 ef03da17eec..6803d0274a8 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1945,6 +1945,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; @@ -2254,6 +2261,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); @@ -2426,7 +2434,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); } @@ -2442,10 +2450,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)) { @@ -3619,6 +3631,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.11.0 From e9489a7f1f19f664018a812e296c360e1488f7d4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Richard Sharpe (cherry picked from commit bd31d538a26bb21cbb53986a6105204da4392e2d) --- 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 3f1786aaa06..23d019d52c0 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)) { @@ -8871,6 +8879,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"); @@ -8911,6 +8920,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); @@ -8923,9 +8937,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 126839e0e9f..17b3e4dec30 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 18fb8b02893..b56fba7ec8a 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.11.0