s3: VFS: shadow_copy2: Fix shadow_copy2_readlinkat() to cope with real directory...
authorJeremy Allison <jra@samba.org>
Thu, 11 Feb 2021 19:36:22 +0000 (11:36 -0800)
committerJeremy Allison <jra@samba.org>
Sat, 13 Feb 2021 00:17:31 +0000 (00:17 +0000)
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Noel Power <noel.power@suse.com>
source3/modules/vfs_shadow_copy2.c

index 227ac148260c701b4757a8e096b8e27bdabae604..76d09587007230325a4ab080bfb5a2479f1c4920 100644 (file)
@@ -1578,26 +1578,43 @@ static int shadow_copy2_readlinkat(vfs_handle_struct *handle,
        char *stripped = NULL;
        int saved_errno = 0;
        int ret;
+       struct smb_filename *full_fname = NULL;
        struct smb_filename *conv = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
-                                        smb_fname,
-                                        &timestamp, &stripped)) {
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               errno = ENOMEM;
                return -1;
        }
+
+       if (!shadow_copy2_strip_snapshot(talloc_tos(),
+                                       handle,
+                                       full_fname,
+                                       &timestamp,
+                                       &stripped)) {
+               TALLOC_FREE(full_fname);
+               return -1;
+       }
+
        if (timestamp == 0) {
+               TALLOC_FREE(full_fname);
+               TALLOC_FREE(stripped);
                return SMB_VFS_NEXT_READLINKAT(handle,
                                dirfsp,
                                smb_fname,
                                buf,
                                bufsiz);
        }
-       conv = cp_smb_filename(talloc_tos(), smb_fname);
+       conv = cp_smb_filename(talloc_tos(), full_fname);
        if (conv == NULL) {
+               TALLOC_FREE(full_fname);
                TALLOC_FREE(stripped);
                errno = ENOMEM;
                return -1;
        }
+       TALLOC_FREE(full_fname);
        conv->base_name = shadow_copy2_convert(
                conv, handle, stripped, timestamp);
        TALLOC_FREE(stripped);
@@ -1605,7 +1622,7 @@ static int shadow_copy2_readlinkat(vfs_handle_struct *handle,
                return -1;
        }
        ret = SMB_VFS_NEXT_READLINKAT(handle,
-                               dirfsp,
+                               handle->conn->cwd_fsp,
                                conv,
                                buf,
                                bufsiz);