From 049e7900e5233d6a989572d7cdda1a663f03f204 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 aca5363a66f..d8c604520ab 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) { diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 16c8848dd12..e9607e577bd 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); -- 2.13.2.725.g09c95d1e9-goog From c10039ef5709dea240a61bad390dafa321cb6346 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 d8c604520ab..43294bed7e9 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -6099,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 e9607e577bd..55d3f78b099 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -447,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, -- 2.13.2.725.g09c95d1e9-goog From 7551caee1475f5127aa4d10e1611c1dbcf923228 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 c0e1b749fa5..225da072768 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -177,6 +177,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.2.725.g09c95d1e9-goog From a47c4c615f60ffa867aff9b5823df90518259e47 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 4db8c772b53..da10461f918 100644 --- a/source3/torture/test_smb2.c +++ b/source3/torture/test_smb2.c @@ -172,7 +172,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 */ @@ -189,8 +192,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.2.725.g09c95d1e9-goog From aa25f8cbad09b22488c03a91590824312dc7a2a5 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 e7531d347aa..c173cf4f007 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 9a7b34fa5d7..ca699a948a8 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 d2a4c194f44..5d29314d4ab 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; + 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 225da072768..340cd225ea0 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -175,8 +175,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 f8567c67089..d895f6ac73f 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -1309,7 +1309,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; @@ -2769,8 +2769,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; @@ -8873,7 +8873,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.2.725.g09c95d1e9-goog From 2a71d409e67695e99bac0002ac690c52cadbc224 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.13.2.725.g09c95d1e9-goog From 3fb73e2bc9b3961fca2e201f7f0a6b6ba11b7aa7 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 9c8851f7656..9ab29b678b3 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/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.2.725.g09c95d1e9-goog From f10b043e512ca6a19fea125419b7ee7877f4e80a 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 ca699a948a8..4c46d4cf8a8 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$", "?????", "", 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) { - 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$", "?????", "", 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/clidfs.c b/source3/libsmb/clidfs.c index 5d29314d4ab..16b21bdf6de 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; - uint32_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/torture/torture.c b/source3/torture/torture.c index d895f6ac73f..1a1a23a7570 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -1310,6 +1310,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; @@ -1341,6 +1342,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(cli, share, "?????", password, strlen(password)+1); if (!NT_STATUS_IS_OK(status)) { @@ -1409,6 +1415,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)) { @@ -8875,6 +8883,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"); @@ -8915,6 +8924,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); @@ -8927,9 +8941,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 1e3e2866ae4..3ed376b8b55 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:", "", 0))) { + 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 5cb707d2d7d..f4a0972e1df 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$", "?????", "", 0); 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.2.725.g09c95d1e9-goog