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)
committerKarolin Seeger <kseeger@samba.org>
Thu, 13 Dec 2018 15:47:40 +0000 (16:47 +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>
(cherry picked from commit aa1fac696956f96e89e54ddd4535a6e2844161b0)

Autobuild-User(v4-9-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-9-test): Thu Dec 13 16:47:40 CET 2018 on sn-devel-144

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 746fbd470a990702483079b7e3db12293af5b3ed..06ef3ebc9b80bfa0a7ecd53f92472c0da0575c30 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,