summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2018-11-21 17:20:30 +0100
committerRalph Boehme <slow@samba.org>2018-11-27 07:13:14 +0100
commitaa1fac696956f96e89e54ddd4535a6e2844161b0 (patch)
treeab2ee6bebc63c8d86f5b7460ebe1d10e12b45176 /source3
parent9c462e1b324ebad60c51bd6e8e659b39a31ec02e (diff)
downloadsamba-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.c58
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,
+ &timestamp, &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,
- &timestamp, 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,