From aa1fac696956f96e89e54ddd4535a6e2844161b0 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 21 Nov 2018 17:20:30 +0100 Subject: [PATCH] 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 --- 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 e105a813e23..0ddc01737bb 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.34.1