vfs_shadow_copy2: in fstat also convert fsp->fsp_name and fsp->base_fsp->fsp_name
authorRalph Boehme <slow@samba.org>
Wed, 21 Nov 2018 16:20:30 +0000 (17:20 +0100)
committerRalph Boehme <slow@samba.org>
Tue, 27 Nov 2018 06:13:14 +0000 (07:13 +0100)
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>
selftest/knownfail.d/samba3.blackbox [deleted file]
source3/modules/vfs_shadow_copy2.c

diff --git a/selftest/knownfail.d/samba3.blackbox b/selftest/knownfail.d/samba3.blackbox
deleted file mode 100644 (file)
index a15359e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.blackbox.shadow_copy_torture.reading stream of a shadow copy of a file\(fileserver\)
index e105a813e234c6960a4db998ed4f0b5195462a95..0ddc01737bb33b8beabfb5a0ead9a61995c01f0e 100644 (file)
@@ -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,