The branch, master has been updated
       via  d05ecd26b94 vfs: update status of SMB_VFS_READLINKAT()
       via  0cbb9400809 s3: smbd: Change smb_unix_read_symlink() to use a real 
directory fsp for SMB_VFS_READLINKAT().
       via  92ec8a00970 s3: smbd: Factor out the SMB1 UNIX extensions read 
symlink code into a function.
       via  e884793cf28 s3: VFS: unityed_media: Fix um_readlinkat() to cope 
with real directory fsps.
       via  9077983ff91 s3: VFS: time_audit: Fix smb_time_audit_readlinkat() to 
cope with real directory fsps.
       via  b1ddc4bb653 3: VFS: snapper: Fix snapper_gmt_readlinkat() to cope 
with real directory fsps.
       via  7973e09fd11 s3: VFS: shadow_copy2: Fix shadow_copy2_readlinkat() to 
cope with real directory fsps.
       via  89f116689da s3: VFS: media_harmony: Fix mh_readlinkat() to cope 
with real directory fsps.
       via  2786a564e6a s3: VFS: glusterfs: Fix vfs_gluster_readlinkat() to 
cope with real directory fsps.
       via  b500162b011 s3: VFS: full_audit: Fix smb_full_audit_readlinkat() to 
cope with real directory fsps.
       via  3e256f508c4 s3: VFS: ceph_snapshots: Fix ceph_snap_gmt_readlinkat() 
to cope with real directory fsps.
       via  7933ee403b6 s3: VFS: ceph: Fix cephwrap_readlinkat() to cope with 
real directory fsps.
       via  545ba86581e s3: VFS: cap: Fix cap_readlinkat() to cope with real 
directory fsps.
       via  ca6cad5f00b s3: VFS: expand_msdfs: Since we moved to 
SMB_VFS_READ_DFS_PATHAT() this module has looked at the wrong function.
      from  b6b6925347c nsswitch pam_winbind: Fix clang compilation error

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d05ecd26b943d64405643a99ec7ceb9fb73dcb37
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 11:59:06 2021 -0800

    vfs: update status of SMB_VFS_READLINKAT()
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>
    
    Autobuild-User(master): Jeremy Allison <j...@samba.org>
    Autobuild-Date(master): Sat Feb 13 01:19:49 UTC 2021 on sn-devel-184

commit 0cbb940080940830acdc4611f75075058fa0468b
Author: Jeremy Allison <j...@samba.org>
Date:   Wed Feb 10 14:50:36 2021 -0800

    s3: smbd: Change smb_unix_read_symlink() to use a real directory fsp for 
SMB_VFS_READLINKAT().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit 92ec8a009703884627a67aa7492c221f1723cda4
Author: Jeremy Allison <j...@samba.org>
Date:   Wed Feb 10 13:34:42 2021 -0800

    s3: smbd: Factor out the SMB1 UNIX extensions read symlink code into a 
function.
    
    Will make it much easier to convert to a dirfsp later.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit e884793cf280fe21cfe4c9d003d74342c50f670f
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 11:55:16 2021 -0800

    s3: VFS: unityed_media: Fix um_readlinkat() to cope with real directory 
fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit 9077983ff9114bac227350b60c388bc19cf22bd0
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 11:49:24 2021 -0800

    s3: VFS: time_audit: Fix smb_time_audit_readlinkat() to cope with real 
directory fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit b1ddc4bb65357205fe7a875a66006854df33842d
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 11:43:50 2021 -0800

    3: VFS: snapper: Fix snapper_gmt_readlinkat() to cope with real directory 
fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit 7973e09fd113360a5cb019666a7988fd8a639c37
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 11:36:22 2021 -0800

    s3: VFS: shadow_copy2: Fix shadow_copy2_readlinkat() to cope with real 
directory fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit 89f116689da5a9ff4e62d650c7cbadc1f3c6a13e
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 11:05:28 2021 -0800

    s3: VFS: media_harmony: Fix mh_readlinkat() to cope with real directory 
fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit 2786a564e6afcc678347b616ab2ab0a8cca58d18
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 11:02:28 2021 -0800

    s3: VFS: glusterfs: Fix vfs_gluster_readlinkat() to cope with real 
directory fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit b500162b0118b61c1ef702f489dc83f1ce3e2571
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 10:59:18 2021 -0800

    s3: VFS: full_audit: Fix smb_full_audit_readlinkat() to cope with real 
directory fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit 3e256f508c4529a6ba61945029de525cbc0db6b2
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 09:54:52 2021 -0800

    s3: VFS: ceph_snapshots: Fix ceph_snap_gmt_readlinkat() to cope with real 
directory fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit 7933ee403b6c51eb6a2b055ae1064c07ae3d70fd
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 09:26:15 2021 -0800

    s3: VFS: ceph: Fix cephwrap_readlinkat() to cope with real directory fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit 545ba86581e1b981f9353f92de168b332b5ef35d
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 09:21:41 2021 -0800

    s3: VFS: cap: Fix cap_readlinkat() to cope with real directory fsps.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

commit ca6cad5f00b151702756498d2f79fd059ab75655
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Feb 11 10:52:47 2021 -0800

    s3: VFS: expand_msdfs: Since we moved to SMB_VFS_READ_DFS_PATHAT() this 
module has looked at the wrong function.
    
    Fix it to work as a redirection of SMB_VFS_READ_DFS_PATHAT()
    instead of SMB_VFS_READLINKAT().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Noel Power <noel.po...@suse.com>

-----------------------------------------------------------------------

Summary of changes:
 source3/modules/The_New_VFS.org      |   2 +-
 source3/modules/The_New_VFS.txt      |   2 +-
 source3/modules/vfs_cap.c            |  18 +++++-
 source3/modules/vfs_ceph.c           |  16 ++++--
 source3/modules/vfs_ceph_snapshots.c |  40 ++++++++-----
 source3/modules/vfs_expand_msdfs.c   | 105 ++++++++++++++++++++++-------------
 source3/modules/vfs_full_audit.c     |  12 +++-
 source3/modules/vfs_glusterfs.c      |  16 +++++-
 source3/modules/vfs_media_harmony.c  |  16 +++++-
 source3/modules/vfs_shadow_copy2.c   |  27 +++++++--
 source3/modules/vfs_snapper.c        |  36 +++++++-----
 source3/modules/vfs_time_audit.c     |  12 +++-
 source3/modules/vfs_unityed_media.c  |  16 +++++-
 source3/smbd/trans2.c                | 103 +++++++++++++++++++++++-----------
 14 files changed, 299 insertions(+), 122 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/modules/The_New_VFS.org b/source3/modules/The_New_VFS.org
index e6e9b155f95..1b7a36c63d5 100644
--- a/source3/modules/The_New_VFS.org
+++ b/source3/modules/The_New_VFS.org
@@ -273,7 +273,7 @@ whenever VFS access is done in a piecemeal fashion.
 | SMB_VFS_READ_DFS_PATHAT()         | [[Symlink][Symlink]]  | Todo   |
 | SMB_VFS_READDIR()                 | [[fsp][fsp]]      | -      |
 | SMB_VFS_READDIR_ATTR()            | [[Path][Path]]     | Todo   |
-| SMB_VFS_READLINKAT()              | [[Symlink][Symlink]]  | Todo   |
+| SMB_VFS_READLINKAT()              | [[Symlink][Symlink]]  | -      |
 | SMB_VFS_REALPATH()                | [[P2px][P2px]]     | -      |
 | SMB_VFS_RECVFILE()                | [[fsp][fsp]]      | -      |
 | SMB_VFS_REMOVEXATTR()             | [[Path][Path]]     | Todo   |
diff --git a/source3/modules/The_New_VFS.txt b/source3/modules/The_New_VFS.txt
index f0a84731810..59df7a97a8e 100644
--- a/source3/modules/The_New_VFS.txt
+++ b/source3/modules/The_New_VFS.txt
@@ -341,7 +341,7 @@ Table of Contents
    SMB_VFS_READ_DFS_PATHAT()          [Symlink]   Todo
    SMB_VFS_READDIR()                  [fsp]       -
    SMB_VFS_READDIR_ATTR()             [Path]      Todo
-   SMB_VFS_READLINKAT()               [Symlink]   Todo
+   SMB_VFS_READLINKAT()               [Symlink]   -
    SMB_VFS_REALPATH()                 [P2px]      -
    SMB_VFS_RECVFILE()                 [fsp]       -
    SMB_VFS_REMOVEXATTR()              [Path]      Todo
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 0975742598c..95b6087d41c 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -553,12 +553,22 @@ static int cap_readlinkat(vfs_handle_struct *handle,
                        char *buf,
                        size_t bufsiz)
 {
-       char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+       struct smb_filename *full_fname = NULL;
        struct smb_filename *cap_smb_fname = NULL;
+       char *cappath = NULL;
        int saved_errno = 0;
        int ret;
 
-       if (!cappath) {
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               smb_fname);
+       if (full_fname == NULL) {
+               return -1;
+       }
+
+       cappath = capencode(talloc_tos(), full_fname->base_name);
+       if (cappath == NULL) {
+               TALLOC_FREE(full_fname);
                errno = ENOMEM;
                return -1;
        }
@@ -569,18 +579,20 @@ static int cap_readlinkat(vfs_handle_struct *handle,
                                        smb_fname->twrp,
                                        smb_fname->flags);
        if (cap_smb_fname == NULL) {
+               TALLOC_FREE(full_fname);
                TALLOC_FREE(cappath);
                errno = ENOMEM;
                return -1;
        }
        ret = SMB_VFS_NEXT_READLINKAT(handle,
-                       dirfsp,
+                       handle->conn->cwd_fsp,
                        cap_smb_fname,
                        buf,
                        bufsiz);
        if (ret == -1) {
                saved_errno = errno;
        }
+       TALLOC_FREE(full_fname);
        TALLOC_FREE(cappath);
        TALLOC_FREE(cap_smb_fname);
        if (saved_errno != 0) {
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 9da074a31ce..47b5046cfcb 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1090,13 +1090,21 @@ static int cephwrap_readlinkat(struct vfs_handle_struct 
*handle,
                char *buf,
                size_t bufsiz)
 {
+       struct smb_filename *full_fname = NULL;
        int result = -1;
-       DBG_DEBUG("[CEPH] readlink(%p, %s, %p, %llu)\n", handle,
-                       smb_fname->base_name, buf, llu(bufsiz));
 
-       SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               smb_fname);
+       if (full_fname == NULL) {
+               return -1;
+       }
 
-       result = ceph_readlink(handle->data, smb_fname->base_name, buf, bufsiz);
+       DBG_DEBUG("[CEPH] readlink(%p, %s, %p, %llu)\n", handle,
+                       full_fname->base_name, buf, llu(bufsiz));
+
+       result = ceph_readlink(handle->data, full_fname->base_name, buf, 
bufsiz);
+       TALLOC_FREE(full_fname);
        DBG_DEBUG("[CEPH] readlink(...) = %d\n", result);
        WRAP_RETURN(result);
 }
diff --git a/source3/modules/vfs_ceph_snapshots.c 
b/source3/modules/vfs_ceph_snapshots.c
index 80dfb48c201..1c395e2a020 100644
--- a/source3/modules/vfs_ceph_snapshots.c
+++ b/source3/modules/vfs_ceph_snapshots.c
@@ -1029,15 +1029,19 @@ static int ceph_snap_gmt_readlinkat(vfs_handle_struct 
*handle,
                                size_t bufsiz)
 {
        time_t timestamp = 0;
-       char stripped[PATH_MAX + 1];
        char conv[PATH_MAX + 1];
        int ret;
-       struct smb_filename *new_fname;
+       struct smb_filename *full_fname = NULL;
        int saved_errno;
 
+       /*
+        * Now this function only looks at csmb_fname->twrp
+        * we don't need to copy out the path. Just use
+        * csmb_fname->base_name directly.
+        */
        ret = ceph_snap_gmt_strip_snapshot(handle,
                                        csmb_fname,
-                                       &timestamp, stripped, sizeof(stripped));
+                                       &timestamp, NULL, 0);
        if (ret < 0) {
                errno = -ret;
                return -1;
@@ -1049,26 +1053,34 @@ static int ceph_snap_gmt_readlinkat(vfs_handle_struct 
*handle,
                                buf,
                                bufsiz);
        }
-       ret = ceph_snap_gmt_convert(handle, stripped,
-                                       timestamp, conv, sizeof(conv));
-       if (ret < 0) {
-               errno = -ret;
+
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               csmb_fname);
+       if (full_fname == NULL) {
                return -1;
        }
-       new_fname = cp_smb_filename(talloc_tos(), csmb_fname);
-       if (new_fname == NULL) {
-               errno = ENOMEM;
+
+       /* Find the snapshot path from the full pathname. */
+       ret = ceph_snap_gmt_convert(handle,
+                               full_fname->base_name,
+                               timestamp,
+                               conv,
+                               sizeof(conv));
+       if (ret < 0) {
+               TALLOC_FREE(full_fname);
+               errno = -ret;
                return -1;
        }
-       new_fname->base_name = conv;
+       full_fname->base_name = conv;
 
        ret = SMB_VFS_NEXT_READLINKAT(handle,
-                               dirfsp,
-                               new_fname,
+                               handle->conn->cwd_fsp,
+                               full_fname,
                                buf,
                                bufsiz);
        saved_errno = errno;
-       TALLOC_FREE(new_fname);
+       TALLOC_FREE(full_fname);
        errno = saved_errno;
        return ret;
 }
diff --git a/source3/modules/vfs_expand_msdfs.c 
b/source3/modules/vfs_expand_msdfs.c
index 7deeb2b7374..34e7051dca5 100644
--- a/source3/modules/vfs_expand_msdfs.c
+++ b/source3/modules/vfs_expand_msdfs.c
@@ -24,6 +24,7 @@
 #include "smbd/globals.h"
 #include "auth.h"
 #include "../lib/tsocket/tsocket.h"
+#include "msdfs.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -141,6 +142,12 @@ static char *expand_msdfs_target(TALLOC_CTX *ctx,
        }
        mapfilename[filename_len] = '\0';
 
+       /*
+        * dfs links returned have had '/' characters replaced with '\'.
+        * Return them to '/' so we can have absoute path mapfilenames.
+        */
+       string_replace(mapfilename, '\\', '/');
+
        DEBUG(10, ("Expanding from table [%s]\n", mapfilename));
 
        raddr = tsocket_address_inet_addr_string(conn->sconn->remote_address,
@@ -182,56 +189,76 @@ static char *expand_msdfs_target(TALLOC_CTX *ctx,
        return new_target;
 }
 
-static int expand_msdfs_readlinkat(struct vfs_handle_struct *handle,
-                               const struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
-                               char *buf,
-                               size_t bufsiz)
+static NTSTATUS expand_read_dfs_pathat(struct vfs_handle_struct *handle,
+                               TALLOC_CTX *mem_ctx,
+                               struct files_struct *dirfsp,
+                               struct smb_filename *smb_fname,
+                               struct referral **ppreflist,
+                               size_t *preferral_count)
 {
-       TALLOC_CTX *ctx = talloc_tos();
-       int result;
-       char *target = talloc_array(ctx, char, PATH_MAX+1);
-       size_t len;
-
-       if (!target) {
-               errno = ENOMEM;
-               return -1;
-       }
-       if (bufsiz == 0) {
-               errno = EINVAL;
-               return -1;
-       }
-
-       result = SMB_VFS_NEXT_READLINKAT(handle,
+       NTSTATUS status;
+       size_t i;
+       struct referral *reflist = NULL;
+       size_t count = 0;
+       TALLOC_CTX *frame = talloc_stackframe();
+
+       /*
+        * Always call the NEXT function first, then
+        * modify the return if needed.
+        */
+       status = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
+                               mem_ctx,
                                dirfsp,
                                smb_fname,
-                               target,
-                               PATH_MAX);
+                               ppreflist,
+                               preferral_count);
 
-       if (result <= 0)
-               return result;
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
 
-       target[result] = '\0';
+       /*
+        * This function can be called to check if a pathname
+        * is an MSDFS link, but not return the values of it.
+        * In this case ppreflist and preferral_count are NULL,
+        * so don't bother trying to look at any returns.
+        */
+       if (ppreflist == NULL || preferral_count == NULL) {
+               TALLOC_FREE(frame);
+               return status;
+       }
 
-       if ((strncmp(target, "msdfs:", 6) == 0) &&
-           (strchr_m(target, '@') != NULL)) {
-               target = expand_msdfs_target(ctx, handle->conn, target);
-               if (!target) {
-                       errno = ENOENT;
-                       return -1;
+       /*
+        * We are always returning the values returned
+        * returned by the NEXT call, but we might mess
+        * with the reflist[i].alternate_path values,
+        * so use local pointers to minimise indirections.
+        */
+       count = *preferral_count;
+       reflist = *ppreflist;
+
+       for (i = 0; i < count; i++) {
+               if (strchr_m(reflist[i].alternate_path, '@') != NULL) {
+                       char *new_altpath = expand_msdfs_target(frame,
+                                               handle->conn,
+                                               reflist[i].alternate_path);
+                       if (new_altpath == NULL) {
+                               TALLOC_FREE(*ppreflist);
+                               *preferral_count = 0;
+                               TALLOC_FREE(frame);
+                               return NT_STATUS_NO_MEMORY;
+                       }
+                       reflist[i].alternate_path = talloc_move(reflist,
+                                                       &new_altpath);
                }
        }
-
-       len = MIN(bufsiz, strlen(target));
-
-       memcpy(buf, target, len);
-
-       TALLOC_FREE(target);
-       return len;
+       TALLOC_FREE(frame);
+       return status;
 }
 
 static struct vfs_fn_pointers vfs_expand_msdfs_fns = {
-       .readlinkat_fn = expand_msdfs_readlinkat
+       .read_dfs_pathat_fn = expand_read_dfs_pathat,
 };
 
 static_decl_vfs;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 7d47871680d..cfb9ba4fcef 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -1846,8 +1846,16 @@ static int smb_full_audit_readlinkat(vfs_handle_struct 
*handle,
                        char *buf,
                        size_t bufsiz)
 {
+       struct smb_filename *full_fname = NULL;
        int result;
 
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               smb_fname);
+       if (full_fname == NULL) {
+               return -1;
+       }
+
        result = SMB_VFS_NEXT_READLINKAT(handle,
                        dirfsp,
                        smb_fname,
@@ -1858,7 +1866,9 @@ static int smb_full_audit_readlinkat(vfs_handle_struct 
*handle,
               (result >= 0),
               handle,
               "%s",
-              smb_fname_str_do_log(handle->conn, smb_fname));
+              smb_fname_str_do_log(handle->conn, full_fname));
+
+       TALLOC_FREE(full_fname);
 
        return result;
 }
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index b1fd2a7f098..af0ce70e1e8 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -1876,11 +1876,23 @@ static int vfs_gluster_readlinkat(struct 
vfs_handle_struct *handle,
                                char *buf,
                                size_t bufsiz)
 {
+       struct smb_filename *full_fname = NULL;
        int ret;
 
        START_PROFILE(syscall_readlinkat);
-       SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
-       ret = glfs_readlink(handle->data, smb_fname->base_name, buf, bufsiz);
+
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               smb_fname);
+       if (full_fname == NULL) {
+               END_PROFILE(syscall_readlinkat);
+               return -1;
+       }
+
+       ret = glfs_readlink(handle->data, full_fname->base_name, buf, bufsiz);
+
+       TALLOC_FREE(full_fname);
+
        END_PROFILE(syscall_readlinkat);
 
        return ret;
diff --git a/source3/modules/vfs_media_harmony.c 
b/source3/modules/vfs_media_harmony.c
index fb5a082c98e..1df23169472 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -1679,10 +1679,19 @@ static int mh_readlinkat(vfs_handle_struct *handle,
                size_t bufsiz)
 {
        int status;
+       struct smb_filename *full_fname = NULL;
        struct smb_filename *clientFname = NULL;
 
        DEBUG(MH_INFO_DEBUG, ("Entering mh_readlinkat\n"));
-       if (!is_in_media_files(smb_fname->base_name)) {
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               smb_fname);
+       if (full_fname == NULL) {
+               status = -1;
+               goto err;
+       }
+
+       if (!is_in_media_files(full_fname->base_name)) {
                status = SMB_VFS_NEXT_READLINKAT(handle,
                                dirfsp,
                                smb_fname,
@@ -1692,13 +1701,13 @@ static int mh_readlinkat(vfs_handle_struct *handle,
        }
 
        if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
-                               smb_fname,
+                               full_fname,
                                &clientFname))) {
                goto err;
        }
 
        status = SMB_VFS_NEXT_READLINKAT(handle,
-                               dirfsp,
+                               handle->conn->cwd_fsp,
                                clientFname,
                                buf,
                                bufsiz);
@@ -1706,6 +1715,7 @@ static int mh_readlinkat(vfs_handle_struct *handle,
 err:
        TALLOC_FREE(clientFname);
 out:
+       TALLOC_FREE(full_fname);
        return status;
 }
 
diff --git a/source3/modules/vfs_shadow_copy2.c 
b/source3/modules/vfs_shadow_copy2.c
index 227ac148260..76d09587007 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -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);
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index 3663bf2d4a3..d97e38f6216 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -2243,14 +2243,18 @@ static int snapper_gmt_readlinkat(vfs_handle_struct 
*handle,
                                size_t bufsiz)
 {


-- 
Samba Shared Repository

Reply via email to