diff options
author | Ralph Boehme <slow@samba.org> | 2018-11-21 17:20:30 +0100 |
---|---|---|
committer | Ralph Boehme <slow@samba.org> | 2018-11-27 07:13:14 +0100 |
commit | aa1fac696956f96e89e54ddd4535a6e2844161b0 (patch) | |
tree | ab2ee6bebc63c8d86f5b7460ebe1d10e12b45176 /source3 | |
parent | 9c462e1b324ebad60c51bd6e8e659b39a31ec02e (diff) | |
download | samba-aa1fac696956f96e89e54ddd4535a6e2844161b0.tar.gz |
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3')
-rw-r--r-- | source3/modules/vfs_shadow_copy2.c | 58 |
1 files changed, 50 insertions, 8 deletions
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, |