From 50c94c584f11dca90ac76abd813042031ae29007 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 23 Nov 2018 14:36:56 +0100 Subject: [PATCH 1/6] s3:selftest: add a VSS test reading a stream Bug: https://bugzilla.samba.org/show_bug.cgi?id=13455 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit cfffa2e2428b42db65a4ece00602e0cef8ceb5a3) --- selftest/knownfail.d/samba3.blackbox | 1 + selftest/target/Samba3.pm | 2 +- .../script/tests/test_shadow_copy_torture.sh | 38 ++++++++ source4/torture/smb2/create.c | 87 +++++++++++++++++++ 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 selftest/knownfail.d/samba3.blackbox diff --git a/selftest/knownfail.d/samba3.blackbox b/selftest/knownfail.d/samba3.blackbox new file mode 100644 index 00000000000..a15359e6420 --- /dev/null +++ b/selftest/knownfail.d/samba3.blackbox @@ -0,0 +1 @@ +^samba3.blackbox.shadow_copy_torture.reading stream of a shadow copy of a file\(fileserver\) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 9e85d229670..314aae55bc5 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -2138,7 +2138,7 @@ sub provision($$$$$$$$$) [shadow_write] path = $shadow_tstdir comment = previous versions snapshots under mount point - vfs objects = shadow_copy2 error_inject + vfs objects = shadow_copy2 streams_xattr error_inject aio write size = 0 error_inject:pwrite = EBADF shadow:mountpoint = $shadow_tstdir diff --git a/source3/script/tests/test_shadow_copy_torture.sh b/source3/script/tests/test_shadow_copy_torture.sh index d47cd512a20..3b05fc50f72 100755 --- a/source3/script/tests/test_shadow_copy_torture.sh +++ b/source3/script/tests/test_shadow_copy_torture.sh @@ -48,6 +48,13 @@ build_snapshots() build_files $snapdir/$SNAPSHOT } +build_stream_on_snapshot() +{ + file=$WORKDIR/.snapshots/$SNAPSHOT/foo + + setfattr -n 'user.DosStream.bar:$DATA' -v baz $file || return 1 +} + test_shadow_copy_write() { local msg @@ -68,9 +75,40 @@ test_shadow_copy_write() failed=`expr $failed + 1` } +test_shadow_copy_stream() +{ + local msg + + msg=$1 + + #delete snapshots from previous tests + find $WORKDIR -name ".snapshots" -exec rm -rf {} \; 1>/dev/null 2>&1 + build_snapshots + build_stream_on_snapshot || { + subunit_start_test msg + subunit_skip_test msg <description = talloc_strdup(suite, "SMB2-TWRP tests"); -- 2.17.2 From c0b795d6e9ca8b0d99f431049a340915fb34e382 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sat, 24 Nov 2018 08:56:49 +0100 Subject: [PATCH 2/6] s3:smbd: prepare filename_convert_internal() for twrp Bug: https://bugzilla.samba.org/show_bug.cgi?id=13455 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit bffc540bc8459cbb1bd1a98528fb1d3b2b54d1d2) --- source3/smbd/filename.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 41c1710351e..e861212658a 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1571,6 +1571,7 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, bool *ppath_contains_wcard, struct smb_filename **pp_smb_fname) { + const char *name = NULL; NTSTATUS status; *pp_smb_fname = NULL; @@ -1621,7 +1622,9 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, ucf_flags |= UCF_ALWAYS_ALLOW_WCARD_LCOMP; } - status = unix_convert(ctx, conn, name_in, pp_smb_fname, ucf_flags); + name = name_in; + + status = unix_convert(ctx, conn, name, pp_smb_fname, ucf_flags); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("filename_convert_internal: unix_convert failed " "for name %s with %s\n", -- 2.17.2 From 7f98a83dcf68c9519ea401a8f61051c6f206dcd3 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sat, 24 Nov 2018 09:05:37 +0100 Subject: [PATCH 3/6] s3:smbd: add twrp processing to filename_convert_internal() Not used for now, existing callers pass NULL. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13455 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit c69bd336a17ca04dbfb4f5d04a963d25b9925118) --- source3/smbd/filename.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index e861212658a..bd17f7ac470 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1555,6 +1555,7 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, * UCF_ALWAYS_ALLOW_WCARD_LCOMP will be OR'd in if * p_cont_wcard != NULL and is true and * UCF_COND_ALLOW_WCARD_LCOMP. + * @param twrp Optional VSS time * @param p_cont_wcard If not NULL, will be set to true if the dfs path * resolution detects a wildcard. * @param pp_smb_fname The final converted name will be allocated if the @@ -1568,10 +1569,12 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, struct smb_request *smbreq, const char *name_in, uint32_t ucf_flags, + time_t *twrp, bool *ppath_contains_wcard, struct smb_filename **pp_smb_fname) { const char *name = NULL; + char *twrp_name = NULL; NTSTATUS status; *pp_smb_fname = NULL; @@ -1623,6 +1626,25 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, } name = name_in; + if (twrp != NULL) { + struct tm *tm = NULL; + + tm = gmtime(twrp); + twrp_name = talloc_asprintf( + ctx, + "@GMT-%04u.%02u.%02u-%02u.%02u.%02u/%s", + tm->tm_year + 1900, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + name); + if (twrp_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + name = twrp_name; + } status = unix_convert(ctx, conn, name, pp_smb_fname, ucf_flags); if (!NT_STATUS_IS_OK(status)) { @@ -1630,8 +1652,10 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, "for name %s with %s\n", name_in, nt_errstr(status) )); + TALLOC_FREE(twrp_name); return status; } + TALLOC_FREE(twrp_name); if ((ucf_flags & UCF_UNIX_NAME_LOOKUP) && VALID_STAT((*pp_smb_fname)->st) && @@ -1674,6 +1698,7 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, NULL, name_in, ucf_flags, + NULL, ppath_contains_wcard, pp_smb_fname); } @@ -1696,6 +1721,7 @@ NTSTATUS filename_convert_with_privilege(TALLOC_CTX *ctx, smbreq, name_in, ucf_flags, + NULL, ppath_contains_wcard, pp_smb_fname); } -- 2.17.2 From fd841b29062b5c5ae1815814de93fb06d736ad39 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sat, 24 Nov 2018 10:45:49 +0100 Subject: [PATCH 4/6] s3:smbd: add twrp args to filename_convert() All existing callers pass NULL, no change in behaviour. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13455 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 14b6e6842b76d7c3e53249ba026a3ff51615ebd7) --- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 2 ++ source3/smbd/filename.c | 3 ++- source3/smbd/nttrans.c | 4 ++++ source3/smbd/open.c | 1 + source3/smbd/proto.h | 1 + source3/smbd/reply.c | 15 +++++++++++++++ source3/smbd/smb2_create.c | 3 ++- source3/smbd/smb2_query_directory.c | 1 + source3/smbd/trans2.c | 8 ++++++++ 9 files changed, 36 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index e1963a40a0c..f90d915badf 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -2363,6 +2363,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, r->in.file, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); @@ -2496,6 +2497,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p, r->in.file, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index bd17f7ac470..ffc33f30c70 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1690,6 +1690,7 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, connection_struct *conn, const char *name_in, uint32_t ucf_flags, + time_t *twrp, bool *ppath_contains_wcard, struct smb_filename **pp_smb_fname) { @@ -1698,7 +1699,7 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, NULL, name_in, ucf_flags, - NULL, + twrp, ppath_contains_wcard, pp_smb_fname); } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 68470766f77..e692f520e6c 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -543,6 +543,7 @@ void reply_ntcreate_and_X(struct smb_request *req) fname, ucf_flags, NULL, + NULL, &smb_fname); TALLOC_FREE(case_state); @@ -1115,6 +1116,7 @@ static void call_nt_transact_create(connection_struct *conn, fname, ucf_flags, NULL, + NULL, &smb_fname); TALLOC_FREE(case_state); @@ -1636,6 +1638,7 @@ void reply_ntrename(struct smb_request *req) oldname, ucf_flags_src, NULL, + NULL, &smb_fname_old); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, @@ -1652,6 +1655,7 @@ void reply_ntrename(struct smb_request *req) status = filename_convert(ctx, conn, newname, ucf_flags_dst, + NULL, &dest_has_wcard, &smb_fname_new); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 3ae8adb5f4f..461fb7eb237 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -5572,6 +5572,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, new_base_name, ucf_flags, NULL, + NULL, smb_fname_out); if (!NT_STATUS_IS_OK(status)) { goto out; diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 68fbd8cccb6..4277f204782 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -353,6 +353,7 @@ NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *name_in, uint32_t ucf_flags, + time_t *twrp, bool *ppath_contains_wcard, struct smb_filename **pp_smb_fname); NTSTATUS filename_convert_with_privilege(TALLOC_CTX *mem_ctx, diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 5afe57d11cb..8cdfde4ef01 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1306,6 +1306,7 @@ void reply_checkpath(struct smb_request *req) name, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -1404,6 +1405,7 @@ void reply_getatr(struct smb_request *req) fname, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1507,6 +1509,7 @@ void reply_setatr(struct smb_request *req) fname, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1804,6 +1807,7 @@ void reply_search(struct smb_request *req) nt_status = filename_convert(ctx, conn, path, ucf_flags, + NULL, &mask_contains_wcard, &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { @@ -2147,6 +2151,7 @@ void reply_open(struct smb_request *req) fname, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2319,6 +2324,7 @@ void reply_open_and_X(struct smb_request *req) fname, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2563,6 +2569,7 @@ void reply_mknew(struct smb_request *req) fname, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2699,6 +2706,7 @@ void reply_ctemp(struct smb_request *req) fname, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -3237,6 +3245,7 @@ void reply_unlink(struct smb_request *req) status = filename_convert(ctx, conn, name, ucf_flags, + NULL, &path_contains_wcard, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -6169,6 +6178,7 @@ void reply_mkdir(struct smb_request *req) directory, ucf_flags, NULL, + NULL, &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -6239,6 +6249,7 @@ void reply_rmdir(struct smb_request *req) directory, ucf_flags, NULL, + NULL, &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -7361,6 +7372,7 @@ void reply_mv(struct smb_request *req) conn, name, src_ucf_flags, + NULL, &src_has_wcard, &smb_fname_src); @@ -7378,6 +7390,7 @@ void reply_mv(struct smb_request *req) conn, newname, dst_ucf_flags, + NULL, &dest_has_wcard, &smb_fname_dst); @@ -7671,6 +7684,7 @@ void reply_copy(struct smb_request *req) status = filename_convert(ctx, conn, fname_src, ucf_flags_src, + NULL, &source_has_wild, &smb_fname_src); if (!NT_STATUS_IS_OK(status)) { @@ -7686,6 +7700,7 @@ void reply_copy(struct smb_request *req) status = filename_convert(ctx, conn, fname_dst, ucf_flags_dst, + NULL, &dest_has_wild, &smb_fname_dst); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 7f80f6f8138..ac9235c6611 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -423,7 +423,7 @@ static NTSTATUS smbd_smb2_create_durable_lease_check(struct smb_request *smb1req ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN); status = filename_convert(talloc_tos(), fsp->conn, filename, ucf_flags, - NULL, &smb_fname); + NULL, NULL, &smb_fname); TALLOC_FREE(filename); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("filename_convert returned %s\n", @@ -891,6 +891,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, smb1req->conn, state->fname, ucf_flags, + NULL, NULL, /* ppath_contains_wcards */ &smb_fname); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c index 50a5bca5d7b..fcd4e7a2f27 100644 --- a/source3/smbd/smb2_query_directory.c +++ b/source3/smbd/smb2_query_directory.c @@ -400,6 +400,7 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx, conn, fullpath, ucf_flags, + NULL, &wcard_has_wild, &smb_fname); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 61757c65930..e7a6e051e5b 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1296,6 +1296,7 @@ static void call_trans2open(connection_struct *conn, fname, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2737,6 +2738,7 @@ close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_da ntstatus = filename_convert(talloc_tos(), conn, directory, ucf_flags, + NULL, &mask_contains_wcard, &smb_dname); } @@ -5851,6 +5853,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, fname, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -6687,6 +6690,7 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn, oldname, ucf_flags, NULL, + NULL, &smb_fname_old); if (!NT_STATUS_IS_OK(status)) { return status; @@ -6762,6 +6766,7 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn, newname, ucf_flags, NULL, + NULL, &smb_fname_dst); if (!NT_STATUS_IS_OK(status)) { return status; @@ -6872,6 +6877,7 @@ static NTSTATUS smb_file_link_information(connection_struct *conn, newname, ucf_flags, NULL, + NULL, &smb_fname_dst); if (!NT_STATUS_IS_OK(status)) { return status; @@ -8832,6 +8838,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, fname, ucf_flags, NULL, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -8981,6 +8988,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, directory, ucf_flags, NULL, + NULL, &smb_dname); if (!NT_STATUS_IS_OK(status)) { -- 2.17.2 From d190dca33efe677b82e176212ce0eab8b277075c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sat, 24 Nov 2018 10:54:06 +0100 Subject: [PATCH 5/6] s3:smbd: pass down twrp from SMB2_CREATE to filename_convert() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13455 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 9c462e1b324ebad60c51bd6e8e659b39a31ec02e) --- source3/smbd/smb2_create.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index ac9235c6611..fdd04ac0331 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -476,6 +476,8 @@ struct smbd_smb2_create_state { ssize_t lease_len; bool need_replay_cache; struct smbXsrv_open *op; + time_t twrp_time; + time_t *twrp_timep; struct smb2_create_blob *dhnc; struct smb2_create_blob *dh2c; @@ -891,7 +893,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, smb1req->conn, state->fname, ucf_flags, - NULL, + state->twrp_timep, NULL, /* ppath_contains_wcards */ &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -1179,9 +1181,6 @@ static void smbd_smb2_create_before_exec(struct tevent_req *req) if (state->twrp != NULL) { NTTIME nttime; - time_t t; - struct tm *tm; - char *tmpname = state->fname; if (state->twrp->data.length != 8) { tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -1189,27 +1188,9 @@ static void smbd_smb2_create_before_exec(struct tevent_req *req) } nttime = BVAL(state->twrp->data.data, 0); - t = nt_time_to_unix(nttime); - tm = gmtime(&t); + state->twrp_time = nt_time_to_unix(nttime); + state->twrp_timep = &state->twrp_time; - state->fname = talloc_asprintf( - state, - "%s\\@GMT-%04u.%02u.%02u-%02u.%02u.%02u", - state->fname, - tm->tm_year + 1900, - tm->tm_mon + 1, - tm->tm_mday, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - if (tevent_req_nomem(state->fname, req)) { - return; - } - TALLOC_FREE(tmpname); - /* - * Tell filename_create_ucf_flags() this - * is an @GMT path. - */ smb1req->flags2 |= FLAGS2_REPARSE_PATH; } -- 2.17.2 From 7b7f6e449e1ae97b8a90d86b9d3248909e98165c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 21 Nov 2018 17:20:30 +0100 Subject: [PATCH 6/6] vfs_shadow_copy2: in fstat also convert fsp->fsp_name and fsp->base_fsp->fsp_name Stacked VFS modules might use the file name, not the file handle. Looking at you, vfs_fruit... Bug: https://bugzilla.samba.org/show_bug.cgi?id=13455 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit aa1fac696956f96e89e54ddd4535a6e2844161b0) --- selftest/knownfail.d/samba3.blackbox | 1 - source3/modules/vfs_shadow_copy2.c | 58 ++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 9 deletions(-) delete mode 100644 selftest/knownfail.d/samba3.blackbox diff --git a/selftest/knownfail.d/samba3.blackbox b/selftest/knownfail.d/samba3.blackbox deleted file mode 100644 index a15359e6420..00000000000 --- a/selftest/knownfail.d/samba3.blackbox +++ /dev/null @@ -1 +0,0 @@ -^samba3.blackbox.shadow_copy_torture.reading stream of a shadow copy of a file\(fileserver\) diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 746fbd470a9..06ef3ebc9b8 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -1354,21 +1354,63 @@ static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf) { time_t timestamp = 0; + struct smb_filename *orig_smb_fname = NULL; + struct smb_filename vss_smb_fname; + struct smb_filename *orig_base_smb_fname = NULL; + struct smb_filename vss_base_smb_fname; + char *stripped = NULL; + int saved_errno = 0; + bool ok; int ret; + ok = shadow_copy2_strip_snapshot(talloc_tos(), handle, + fsp->fsp_name->base_name, + ×tamp, &stripped); + if (!ok) { + return -1; + } + + if (timestamp == 0) { + TALLOC_FREE(stripped); + return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); + } + + vss_smb_fname = *fsp->fsp_name; + vss_smb_fname.base_name = shadow_copy2_convert(talloc_tos(), + handle, + stripped, + timestamp); + TALLOC_FREE(stripped); + if (vss_smb_fname.base_name == NULL) { + return -1; + } + + orig_smb_fname = fsp->fsp_name; + fsp->fsp_name = &vss_smb_fname; + + if (fsp->base_fsp != NULL) { + vss_base_smb_fname = *fsp->base_fsp->fsp_name; + vss_base_smb_fname.base_name = vss_smb_fname.base_name; + orig_base_smb_fname = fsp->base_fsp->fsp_name; + fsp->base_fsp->fsp_name = &vss_base_smb_fname; + } + ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); - if (ret == -1) { - return ret; + fsp->fsp_name = orig_smb_fname; + if (fsp->base_fsp != NULL) { + fsp->base_fsp->fsp_name = orig_base_smb_fname; } - if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, - fsp->fsp_name->base_name, - ×tamp, NULL)) { - return 0; + if (ret == -1) { + saved_errno = errno; } - if (timestamp != 0) { + + if (ret == 0) { convert_sbuf(handle, fsp->fsp_name->base_name, sbuf); } - return 0; + if (saved_errno != 0) { + errno = saved_errno; + } + return ret; } static int shadow_copy2_open(vfs_handle_struct *handle, -- 2.17.2