]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: VFS: vfs_shadow_copy2. Implement readlinkat().
authorJeremy Allison <jra@samba.org>
Thu, 22 Aug 2019 21:26:47 +0000 (14:26 -0700)
committerJeremy Allison <jra@samba.org>
Fri, 23 Aug 2019 18:49:36 +0000 (18:49 +0000)
Currently identical to readlink().

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Böhme <slow@samba.org>
source3/modules/vfs_shadow_copy2.c

index 2891a5c09599471ae30c1f13dca24e675c6f26ac..7425628d70aadf4c72b67e074f0a6184cf200583 100644 (file)
@@ -1710,6 +1710,57 @@ static int shadow_copy2_readlink(vfs_handle_struct *handle,
        return ret;
 }
 
+static int shadow_copy2_readlinkat(vfs_handle_struct *handle,
+                               files_struct *dirfsp,
+                               const struct smb_filename *smb_fname,
+                               char *buf,
+                               size_t bufsiz)
+{
+       time_t timestamp = 0;
+       char *stripped = NULL;
+       int saved_errno = 0;
+       int ret;
+       struct smb_filename *conv = NULL;
+
+       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
+                                        smb_fname->base_name,
+                                        &timestamp, &stripped)) {
+               return -1;
+       }
+       if (timestamp == 0) {
+               return SMB_VFS_NEXT_READLINKAT(handle,
+                               dirfsp,
+                               smb_fname,
+                               buf,
+                               bufsiz);
+       }
+       conv = cp_smb_filename(talloc_tos(), smb_fname);
+       if (conv == NULL) {
+               TALLOC_FREE(stripped);
+               errno = ENOMEM;
+               return -1;
+       }
+       conv->base_name = shadow_copy2_convert(
+               conv, handle, stripped, timestamp);
+       TALLOC_FREE(stripped);
+       if (conv->base_name == NULL) {
+               return -1;
+       }
+       ret = SMB_VFS_NEXT_READLINKAT(handle,
+                               dirfsp,
+                               conv,
+                               buf,
+                               bufsiz);
+       if (ret == -1) {
+               saved_errno = errno;
+       }
+       TALLOC_FREE(conv);
+       if (saved_errno != 0) {
+               errno = saved_errno;
+       }
+       return ret;
+}
+
 static int shadow_copy2_mknodat(vfs_handle_struct *handle,
                        files_struct *dirfsp,
                        const struct smb_filename *smb_fname,
@@ -3155,6 +3206,7 @@ static struct vfs_fn_pointers vfs_shadow_copy2_fns = {
        .chdir_fn = shadow_copy2_chdir,
        .ntimes_fn = shadow_copy2_ntimes,
        .readlink_fn = shadow_copy2_readlink,
+       .readlinkat_fn = shadow_copy2_readlinkat,
        .mknodat_fn = shadow_copy2_mknodat,
        .realpath_fn = shadow_copy2_realpath,
        .get_nt_acl_fn = shadow_copy2_get_nt_acl,