From 1635b338d5c5652fb58f6c637b7bb82afe592b4e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Oct 2019 04:54:18 -0700 Subject: [PATCH 1/3] s3: libsmb: DFS: Add cli_dfs_rename_check(). Checks rename target path against source path. If a DFS aware path, ensure rename is against the same server/share and return the local (truncated) pathname for destination if so. Not yet used: BUG: https://bugzilla.samba.org/show_bug.cgi?id=14169 Signed-off-by: Jeremy Allison --- source3/libsmb/clidfs.c | 37 +++++++++++++++++++++++++++++++++++++ source3/libsmb/proto.h | 6 ++++++ 2 files changed, 43 insertions(+) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index ba851f3f471..72e14397fe5 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -1304,3 +1304,40 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, return true; } + +NTSTATUS cli_dfs_rename_check(TALLOC_CTX *mem_ctx, + struct cli_state *cli, + const char *fname_src, + const char *fname_dst, + const char **fname_dst_out) +{ + char *src_dfs_prefix = NULL; + size_t prefix_len = 0; + struct smbXcli_tcon *tcon = NULL; + + *fname_dst_out = fname_dst; + + if (!smbXcli_conn_dfs_supported(cli->conn)) { + return NT_STATUS_OK; + } + if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { + tcon = cli->smb2.tcon; + } else { + tcon = cli->smb1.tcon; + } + if (!smbXcli_tcon_is_dfs_share(tcon)) { + return NT_STATUS_OK; + } + src_dfs_prefix = cli_dfs_make_full_path(mem_ctx, cli, ""); + if (src_dfs_prefix == NULL) { + return NT_STATUS_NO_MEMORY; + } + prefix_len = strlen(src_dfs_prefix); + if (strncmp(fname_dst, src_dfs_prefix, prefix_len) != 0) { + TALLOC_FREE(src_dfs_prefix); + return NT_STATUS_OBJECT_NAME_INVALID; + } + *fname_dst_out = &fname_dst[prefix_len]; + TALLOC_FREE(src_dfs_prefix); + return NT_STATUS_OK; +} diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index 6a647da58c8..e5dea2f62db 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -184,6 +184,12 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, bool force_encrypt, struct cli_credentials *creds); +NTSTATUS cli_dfs_rename_check(TALLOC_CTX *mem_ctx, + struct cli_state *cli, + const char *fname_src, + const char *fname_dst, + const char **fname_dst_out); + /* The following definitions come from libsmb/clientgen.c */ int cli_set_message(char *buf,int num_words,int num_bytes,bool zero); -- 2.17.1 From d9d2c889e429d21b48793d8e53f23f90171d2ad7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Oct 2019 04:54:02 -0700 Subject: [PATCH 2/3] s3: libsmb: DFS: Fix SMB2 rename with DFS-paths. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14169 Signed-off-by: Jeremy Allison --- source3/libsmb/cli_smb2_fnum.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index 15f1420dd8f..0877cebeed3 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -3253,6 +3253,15 @@ NTSTATUS cli_smb2_rename(struct cli_state *cli, goto fail; } + status = cli_dfs_rename_check(frame, + cli, + fname_src, + fname_dst, + &fname_dst); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + status = get_fnum_from_path(cli, fname_src, DELETE_ACCESS, -- 2.17.1 From b53b35ffbfc4a1f18f49b4586e3e00f178774e86 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Oct 2019 04:52:34 -0700 Subject: [PATCH 3/3] s3: libsmb: DFS: Fix SMB1 rename(s) with DFS-paths. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14169 Signed-off-by: Jeremy Allison --- source3/libsmb/clifile.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index dd08b0e30f3..44936eb55fe 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1187,6 +1187,15 @@ static struct tevent_req *cli_smb1_rename_send(TALLOC_CTX *mem_ctx, return NULL; } + status = cli_dfs_rename_check(req, + cli, + fname_src, + fname_dst, + &fname_dst); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + if (!push_ucs2_talloc(talloc_tos(), &converted_str, fname_dst, &converted_size_bytes)) { status = NT_STATUS_INVALID_PARAMETER; @@ -1259,6 +1268,7 @@ static struct tevent_req *cli_cifs_rename_send(TALLOC_CTX *mem_ctx, uint8_t additional_flags = 0; uint16_t additional_flags2 = 0; uint8_t *bytes = NULL; + NTSTATUS status; req = tevent_req_create(mem_ctx, &state, struct cli_cifs_rename_state); if (req == NULL) { @@ -1273,6 +1283,16 @@ static struct tevent_req *cli_cifs_rename_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + status = cli_dfs_rename_check(req, + cli, + fname_src, + fname_dst, + &fname_dst); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + SSVAL(state->vwv+0, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY); bytes = talloc_array(state, uint8_t, 1); @@ -1401,6 +1421,7 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx, uint8_t additional_flags = 0; uint16_t additional_flags2 = 0; uint8_t *bytes = NULL; + NTSTATUS status; req = tevent_req_create(mem_ctx, &state, struct cli_ntrename_internal_state); @@ -1408,6 +1429,16 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx, return NULL; } + status = cli_dfs_rename_check(req, + cli, + fname_src, + fname_dst, + &fname_dst); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + SSVAL(state->vwv+0, 0 ,FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY); SSVAL(state->vwv+1, 0, rename_flag); -- 2.17.1