The branch, master has been updated
       via  ab018150e68 s3: VFS: default. Ensure read_dfs_pathat() returns stat 
info.
       via  50cb3ef0aeb s3: VFS: shadow_copy2. Ensure read_dfs_pathat() returns 
stat info.
       via  636c83741a4 s3: VFS: gluster. Ensure read_dfs_pathat() returns stat 
info.
       via  5e9e7e2d0cf s3: VFS: ceph. Ensure read_dfs_pathat() returns stat 
info.
       via  d9f5e36538a s3: VFS: catia. Ensure read_dfs_pathat() returns stat 
info.
       via  c4f5dfeef6c s3: VFS: cap. Ensure read_dfs_pathat() returns stat 
info.
       via  65b8c0cfbe8 s3: VFS: Change the function signature for 
SMB_VFS_READ_DFS_PATHAT() to take a non-const smb_filename.
       via  2a4705129d0 s3: torture: Add test for getting attibutes on an MSDFS 
link.
       via  84134812e34 s3: torture: Add a MSDFS-ATTRIBUTE test.
       via  6463f2612a6 s3: libsmb: Info level SMB_FIND_EA_SIZE encodes 
attibutes as a uint16, not a uint8.
       via  be52f87c376 s3: libsmb: Info level SMB_FIND_INFO_STANDARD encodes 
attibutes as a uint16, not a uint8.
       via  5e3e6c4c0c7 s3: libsmb: Info level 
SMB_FIND_FILE_BOTH_DIRECTORY_INFO encodes attibutes as a uint32, not a uint8.
       via  3063e1601ad s3: libsmb: Info level SMB2_FIND_ID_BOTH_DIRECTORY_INFO 
encodes attibutes as a uint32, not a uint8.
      from  1ded80ae6f0 s3/rpc_server: remove unnecessary srv_fss_agent.h header

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


- Log -----------------------------------------------------------------
commit ab018150e6822b0e5dd7b63e4449fe38b6b0ef01
Author: Jeremy Allison <j...@samba.org>
Date:   Fri May 29 17:56:58 2020 -0700

    s3: VFS: default. Ensure read_dfs_pathat() returns stat info.
    
    Remove the knownfail.d/msdfs-attr file.
    
    Everything now passes.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>
    
    Autobuild-User(master): Ralph Böhme <s...@samba.org>
    Autobuild-Date(master): Wed Jun  3 06:19:21 UTC 2020 on sn-devel-184

commit 50cb3ef0aeb1b422f519fc5649ad55fffc2c7df2
Author: Jeremy Allison <j...@samba.org>
Date:   Fri May 29 17:52:51 2020 -0700

    s3: VFS: shadow_copy2. Ensure read_dfs_pathat() returns stat info.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 636c83741a4c8f14182b4e9216d2d1ca3a40e0e6
Author: Jeremy Allison <j...@samba.org>
Date:   Fri May 29 17:49:17 2020 -0700

    s3: VFS: gluster. Ensure read_dfs_pathat() returns stat info.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 5e9e7e2d0cf96ea70b3db71341f4576da147b354
Author: Jeremy Allison <j...@samba.org>
Date:   Fri May 29 17:35:06 2020 -0700

    s3: VFS: ceph. Ensure read_dfs_pathat() returns stat info.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit d9f5e36538a7a01cf3ed90e747fa63473aac9d81
Author: Jeremy Allison <j...@samba.org>
Date:   Fri May 29 16:38:53 2020 -0700

    s3: VFS: catia. Ensure read_dfs_pathat() returns stat info.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit c4f5dfeef6cc7819b7d4e295b589d46060b58dbf
Author: Jeremy Allison <j...@samba.org>
Date:   Fri May 29 16:36:55 2020 -0700

    s3: VFS: cap. Ensure read_dfs_pathat() returns stat info.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 65b8c0cfbe81cc8ca587ef92c5b951a3c147d542
Author: Jeremy Allison <j...@samba.org>
Date:   Fri May 29 16:32:12 2020 -0700

    s3: VFS: Change the function signature for SMB_VFS_READ_DFS_PATHAT() to 
take a non-const smb_filename.
    
    Otherwise there's no good way to return proper stat(2) information
    for a DFS link without making assumptions it's a symlink store.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 2a4705129d06b91023bc3fc435fccf91d3939553
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Jun 1 13:45:28 2020 -0700

    s3: torture: Add test for getting attibutes on an MSDFS link.
    
    Mark as knownfail for now.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 84134812e3447317125ae08b2a98848a2e4bbd65
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Jun 1 12:08:17 2020 -0700

    s3: torture: Add a MSDFS-ATTRIBUTE test.
    
    Framework to drive comes next.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 6463f2612a662f217af18455206afde122323375
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Jun 1 11:33:13 2020 -0700

    s3: libsmb: Info level SMB_FIND_EA_SIZE encodes attibutes as a uint16, not 
a uint8.
    
    We will need this to detect FILE_ATTRIBUTE_REPARSE_POINT in a later commit.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit be52f87c376a8f71b2de4aa52f25818cad2b160e
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Jun 1 12:01:13 2020 -0700

    s3: libsmb: Info level SMB_FIND_INFO_STANDARD encodes attibutes as a 
uint16, not a uint8.
    
    We will need this to detect FILE_ATTRIBUTE_REPARSE_POINT in a later commit.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 5e3e6c4c0c70e171607f4b5351bd8ec146730f08
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Jun 1 11:36:03 2020 -0700

    s3: libsmb: Info level SMB_FIND_FILE_BOTH_DIRECTORY_INFO encodes attibutes 
as a uint32, not a uint8.
    
    Cast to a uint16_t for now after pulling the information
    as finfo->mode is currently only 16 bits.
    
    We will need this to detect FILE_ATTRIBUTE_REPARSE_POINT in a later commit.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14391
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 3063e1601ad9e2536651a75a47ebf4921ffddbdc
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Jun 1 13:55:10 2020 -0700

    s3: libsmb: Info level SMB2_FIND_ID_BOTH_DIRECTORY_INFO encodes attibutes 
as a uint32, not a uint8.
    
    Fix the SMB2 parsing code.
    
    Cast to a uint16_t for now after pulling the information
    as finfo->mode is currently only 16 bits.
    
    We will need this to detect FILE_ATTRIBUTE_REPARSE_POINT in a later commit.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

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

Summary of changes:
 examples/VFS/skel_opaque.c            |  2 +-
 examples/VFS/skel_transparent.c       |  2 +-
 source3/include/vfs.h                 |  9 ++--
 source3/libsmb/cli_smb2_fnum.c        |  3 +-
 source3/libsmb/clilist.c              |  7 ++--
 source3/modules/vfs_cap.c             |  8 +++-
 source3/modules/vfs_catia.c           |  7 +++-
 source3/modules/vfs_ceph.c            | 21 +++++++++-
 source3/modules/vfs_default.c         | 16 ++++++-
 source3/modules/vfs_full_audit.c      |  2 +-
 source3/modules/vfs_glusterfs.c       | 17 +++++++-
 source3/modules/vfs_not_implemented.c |  2 +-
 source3/modules/vfs_shadow_copy2.c    |  7 +++-
 source3/modules/vfs_time_audit.c      |  2 +-
 source3/selftest/tests.py             | 27 ++++++++++++
 source3/smbd/vfs.c                    |  2 +-
 source3/torture/torture.c             | 79 +++++++++++++++++++++++++++++++++++
 17 files changed, 194 insertions(+), 19 deletions(-)


Changeset truncated at 500 lines:

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 1a9b472634d..0a6ca4d9200 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -115,7 +115,7 @@ static NTSTATUS skel_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 static NTSTATUS skel_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count)
 {
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index fdb6d0d5f54..677af2217bf 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -116,7 +116,7 @@ static NTSTATUS skel_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 static NTSTATUS skel_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count)
 {
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index ab4098636dc..d527f850628 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -324,6 +324,9 @@
  * Version 43 - Add dirfsp args to SMB_VFS_CREATE_FILE()
  * Version 43 - Add SMB_VFS_OPENAT()
  * Version 43 - Remove SMB_VFS_OPEN()
+ * Version 43 - SMB_VFS_READ_DFS_PATHAT() should take a non-const name.
+               There's no easy way to return stat info for a DFS link
+               otherwise.
  */
 
 #define SMB_VFS_INTERFACE_VERSION 43
@@ -741,7 +744,7 @@ struct vfs_fn_pointers {
        NTSTATUS (*read_dfs_pathat_fn)(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count);
 
@@ -1255,7 +1258,7 @@ NTSTATUS smb_vfs_call_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 NTSTATUS smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count);
 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
@@ -1705,7 +1708,7 @@ NTSTATUS vfs_not_implemented_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 NTSTATUS vfs_not_implemented_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count);
 NTSTATUS vfs_not_implemented_snap_check_path(struct vfs_handle_struct *handle,
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index c1c755a97ea..46a4ae95977 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -1199,7 +1199,8 @@ static NTSTATUS parse_finfo_id_both_directory_info(const 
uint8_t *dir_data,
        finfo->ctime_ts = interpret_long_date((const char *)dir_data + 32);
        finfo->size = IVAL2_TO_SMB_BIG_UINT(dir_data + 40, 0);
        finfo->allocated_size = IVAL2_TO_SMB_BIG_UINT(dir_data + 48, 0);
-       finfo->mode = CVAL(dir_data + 56, 0);
+       /* NB. We need to enlarge finfo->mode to be 32-bits. */
+       finfo->mode = (uint16_t)IVAL(dir_data + 56, 0);
        finfo->ino = IVAL2_TO_SMB_BIG_UINT(dir_data + 96, 0);
        namelen = IVAL(dir_data + 60,0);
        if (namelen > (dir_data_length - 104)) {
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 3ed9e8292c2..0c4e3db09f1 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -152,7 +152,7 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx,
                        finfo->mtime_ts = convert_time_t_to_timespec(
                                make_unix_date2(p+12, 
smb1cli_conn_server_time_zone(cli->conn)));
                        finfo->size = IVAL(p,16);
-                       finfo->mode = CVAL(p,24);
+                       finfo->mode = SVAL(p,24);
                        len = CVAL(p, 26);
                        p += 27;
                        if (recv_flags2 & FLAGS2_UNICODE_STRINGS) {
@@ -211,7 +211,7 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx,
                        finfo->mtime_ts = convert_time_t_to_timespec(
                                make_unix_date2(p+12, 
smb1cli_conn_server_time_zone(cli->conn)));
                        finfo->size = IVAL(p,16);
-                       finfo->mode = CVAL(p,24);
+                       finfo->mode = SVAL(p,24);
                        len = CVAL(p, 30);
                        p += 31;
                        /* check for unisys! */
@@ -257,7 +257,8 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx,
                        finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0);
                        p += 8;
                        p += 8; /* alloc size */
-                       finfo->mode = CVAL(p,0);
+                       /* NB. We need to enlarge finfo->mode to be 32-bits. */
+                       finfo->mode = (uint16_t)IVAL(p,0);
                        p += 4;
                        namelen = IVAL(p,0);
                        p += 4;
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 17ebb786822..93f0454c608 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -1042,7 +1042,7 @@ static NTSTATUS cap_create_dfs_pathat(vfs_handle_struct 
*handle,
 static NTSTATUS cap_read_dfs_pathat(struct vfs_handle_struct *handle,
                        TALLOC_CTX *mem_ctx,
                        struct files_struct *dirfsp,
-                       const struct smb_filename *smb_fname,
+                       struct smb_filename *smb_fname,
                        struct referral **ppreflist,
                        size_t *preferral_count)
 {
@@ -1070,6 +1070,12 @@ static NTSTATUS cap_read_dfs_pathat(struct 
vfs_handle_struct *handle,
                        cap_smb_fname,
                        ppreflist,
                        preferral_count);
+
+       if (NT_STATUS_IS_OK(status)) {
+               /* Return any stat(2) info. */
+               smb_fname->st = cap_smb_fname->st;
+       }
+
        TALLOC_FREE(cappath);
        TALLOC_FREE(cap_smb_fname);
        return status;
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 6fc14de076b..85ef5cfb0d4 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -2417,7 +2417,7 @@ static NTSTATUS catia_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 static NTSTATUS catia_read_dfs_pathat(struct vfs_handle_struct *handle,
                        TALLOC_CTX *mem_ctx,
                        struct files_struct *dirfsp,
-                       const struct smb_filename *smb_fname,
+                       struct smb_filename *smb_fname,
                        struct referral **ppreflist,
                        size_t *preferral_count)
 {
@@ -2451,6 +2451,11 @@ static NTSTATUS catia_read_dfs_pathat(struct 
vfs_handle_struct *handle,
                                        mapped_smb_fname,
                                        ppreflist,
                                        preferral_count);
+       if (NT_STATUS_IS_OK(status)) {
+               /* Return any stat(2) info. */
+               smb_fname->st = mapped_smb_fname->st;
+       }
+
        TALLOC_FREE(mapped_name);
        TALLOC_FREE(mapped_smb_fname);
        return status;
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 767a2ad8609..0378d633782 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1340,7 +1340,7 @@ static NTSTATUS cephwrap_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 static NTSTATUS cephwrap_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count)
 {
@@ -1354,9 +1354,16 @@ static NTSTATUS cephwrap_read_dfs_pathat(struct 
vfs_handle_struct *handle,
 #else
        char link_target_buf[7];
 #endif
+       struct ceph_statx stx;
+       int ret;
 
        SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
 
+       if (is_named_stream(smb_fname)) {
+               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               goto err;
+       }
+
        if (ppreflist == NULL && preferral_count == NULL) {
                /*
                 * We're only checking if this is a DFS
@@ -1372,6 +1379,16 @@ static NTSTATUS cephwrap_read_dfs_pathat(struct 
vfs_handle_struct *handle,
                }
        }
 
+       ret = ceph_statx(handle->data,
+                        smb_fname->base_name,
+                        &stx,
+                        SAMBA_STATX_ATTR_MASK,
+                        AT_SYMLINK_NOFOLLOW);
+       if (ret < 0) {
+               status = map_nt_error_from_unix(-ret);
+               goto err;
+       }
+
         referral_len = ceph_readlink(handle->data,
                                 smb_fname->base_name,
                                 link_target,
@@ -1404,6 +1421,7 @@ static NTSTATUS cephwrap_read_dfs_pathat(struct 
vfs_handle_struct *handle,
 
         if (ppreflist == NULL && preferral_count == NULL) {
                 /* Early return for checking if this is a DFS link. */
+               init_stat_ex_from_ceph_statx(&smb_fname->st, &stx);
                 return NT_STATUS_OK;
         }
 
@@ -1414,6 +1432,7 @@ static NTSTATUS cephwrap_read_dfs_pathat(struct 
vfs_handle_struct *handle,
                         preferral_count);
 
         if (ok) {
+               init_stat_ex_from_ceph_statx(&smb_fname->st, &stx);
                 status = NT_STATUS_OK;
         } else {
                 status = NT_STATUS_NO_MEMORY;
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 5047582ce46..a4910b4882d 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -420,7 +420,7 @@ static NTSTATUS vfswrap_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 static NTSTATUS vfswrap_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count)
 {
@@ -434,9 +434,15 @@ static NTSTATUS vfswrap_read_dfs_pathat(struct 
vfs_handle_struct *handle,
 #else
        char link_target_buf[7];
 #endif
+       int ret;
 
        SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
 
+       if (is_named_stream(smb_fname)) {
+               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               goto err;
+       }
+
        if (ppreflist == NULL && preferral_count == NULL) {
                /*
                 * We're only checking if this is a DFS
@@ -485,6 +491,14 @@ static NTSTATUS vfswrap_read_dfs_pathat(struct 
vfs_handle_struct *handle,
                goto err;
        }
 
+       ret = sys_lstat(smb_fname->base_name,
+                       &smb_fname->st,
+                       lp_fake_directory_create_times(SNUM(handle->conn)));
+       if (ret < 0) {
+               status = map_nt_error_from_unix(errno);
+               goto err;
+       }
+
        if (ppreflist == NULL && preferral_count == NULL) {
                /* Early return for checking if this is a DFS link. */
                return NT_STATUS_OK;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 3e10a8c4127..9d89bfd396a 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -921,7 +921,7 @@ static NTSTATUS smb_full_audit_create_dfs_pathat(struct 
vfs_handle_struct *handl
 static NTSTATUS smb_full_audit_read_dfs_pathat(struct vfs_handle_struct 
*handle,
                        TALLOC_CTX *mem_ctx,
                        struct files_struct *dirfsp,
-                       const struct smb_filename *smb_fname,
+                       struct smb_filename *smb_fname,
                        struct referral **ppreflist,
                        size_t *preferral_count)
 {
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index 843cf5be78f..ff5382af9fb 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -1941,7 +1941,7 @@ static NTSTATUS vfs_gluster_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 static NTSTATUS vfs_gluster_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count)
 {
@@ -1955,9 +1955,16 @@ static NTSTATUS vfs_gluster_read_dfs_pathat(struct 
vfs_handle_struct *handle,
 #else
        char link_target_buf[7];
 #endif
+       struct stat st;
+       int ret;
 
        SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
 
+       if (is_named_stream(smb_fname)) {
+               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               goto err;
+       }
+
        if (ppreflist == NULL && preferral_count == NULL) {
                /*
                 * We're only checking if this is a DFS
@@ -1973,6 +1980,12 @@ static NTSTATUS vfs_gluster_read_dfs_pathat(struct 
vfs_handle_struct *handle,
                }
        }
 
+       ret = glfs_lstat(handle->data, smb_fname->base_name, &st);
+       if (ret < 0) {
+               status = map_nt_error_from_unix(errno);
+               goto err;
+       }
+
        referral_len = glfs_readlink(handle->data,
                                smb_fname->base_name,
                                link_target,
@@ -2003,6 +2016,7 @@ static NTSTATUS vfs_gluster_read_dfs_pathat(struct 
vfs_handle_struct *handle,
 
        if (ppreflist == NULL && preferral_count == NULL) {
                /* Early return for checking if this is a DFS link. */
+               smb_stat_ex_from_stat(&smb_fname->st, &st);
                return NT_STATUS_OK;
        }
 
@@ -2013,6 +2027,7 @@ static NTSTATUS vfs_gluster_read_dfs_pathat(struct 
vfs_handle_struct *handle,
                        preferral_count);
 
        if (ok) {
+               smb_stat_ex_from_stat(&smb_fname->st, &st);
                status = NT_STATUS_OK;
        } else {
                status = NT_STATUS_NO_MEMORY;
diff --git a/source3/modules/vfs_not_implemented.c 
b/source3/modules/vfs_not_implemented.c
index ca12406ac07..529ad579f49 100644
--- a/source3/modules/vfs_not_implemented.c
+++ b/source3/modules/vfs_not_implemented.c
@@ -109,7 +109,7 @@ NTSTATUS vfs_not_implemented_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 NTSTATUS vfs_not_implemented_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count)
 {
diff --git a/source3/modules/vfs_shadow_copy2.c 
b/source3/modules/vfs_shadow_copy2.c
index 4eb8257f1fc..6a1e560988e 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -2394,7 +2394,7 @@ static NTSTATUS shadow_copy2_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 static NTSTATUS shadow_copy2_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count)
 {
@@ -2441,6 +2441,11 @@ static NTSTATUS shadow_copy2_read_dfs_pathat(struct 
vfs_handle_struct *handle,
                                ppreflist,
                                preferral_count);
 
+       if (NT_STATUS_IS_OK(status)) {
+               /* Return any stat(2) info. */
+               smb_fname->st = conv->st;
+       }
+
        TALLOC_FREE(conv);
        return status;
 }
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index ff4952c45e7..f70ff73fec1 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -352,7 +352,7 @@ static NTSTATUS smb_time_audit_create_dfs_pathat(struct 
vfs_handle_struct *handl
 static NTSTATUS smb_time_audit_read_dfs_pathat(struct vfs_handle_struct 
*handle,
                        TALLOC_CTX *mem_ctx,
                        struct files_struct *dirfsp,
-                       const struct smb_filename *smb_fname,
+                       struct smb_filename *smb_fname,
                        struct referral **ppreflist,
                        size_t *preferral_count)
 {
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index fb07610c3f0..cfca26359c3 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -172,6 +172,33 @@ 
plantestsuite("samba3.smbtorture_s3.hidenewfiles(fileserver_smb1)",
                "",
                "-l $LOCAL_PATH"])
 
+#
+# MSDFS attribute tests.
+#
+plantestsuite("samba3.smbtorture_s3.smb2.MSDFS-ATTRIBUTE",
+                "fileserver",
+                [os.path.join(samba3srcdir,
+                              "script/tests/test_smbtorture_s3.sh"),
+                'MSDFS-ATTRIBUTE',
+                '//$SERVER_IP/msdfs-share',
+                '$USERNAME',
+                '$PASSWORD',
+                smbtorture3,
+                "-mSMB2",
+                "-f msdfs-src1"])
+
+plantestsuite("samba3.smbtorture_s3.smb1.MSDFS-ATTRIBUTE",
+                "fileserver_smb1",
+                [os.path.join(samba3srcdir,
+                              "script/tests/test_smbtorture_s3.sh"),
+                'MSDFS-ATTRIBUTE',
+                '//$SERVER_IP/msdfs-share',
+                '$USERNAME',
+                '$PASSWORD',
+                smbtorture3,
+                "-mNT1",
+                "-f msdfs-src1"])
+
 shares = [
     "vfs_aio_pthread_async_dosmode_default1",
     "vfs_aio_pthread_async_dosmode_default2",
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 849ee6f6523..85b23d35ba6 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -1677,7 +1677,7 @@ NTSTATUS smb_vfs_call_create_dfs_pathat(struct 
vfs_handle_struct *handle,
 NTSTATUS smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct *handle,
                                TALLOC_CTX *mem_ctx,
                                struct files_struct *dirfsp,
-                               const struct smb_filename *smb_fname,
+                               struct smb_filename *smb_fname,
                                struct referral **ppreflist,
                                size_t *preferral_count)
 {
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 997e074c481..31e45405591 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -11448,6 +11448,81 @@ static bool run_large_readx(int dummy)
        return correct;
 }
 
+static NTSTATUS msdfs_attribute_list_fn(const char *mnt,
+                                 struct file_info *finfo,
+                                 const char *mask,
+                                 void *private_data)
+{
+       uint16_t *p_mode = (uint16_t *)private_data;
+
+       if (strequal(finfo->name, test_filename)) {
+               *p_mode = finfo->mode;
+       }
+
+       return NT_STATUS_OK;
+}
+
+static bool run_msdfs_attribute(int dummy)
+{
+       static struct cli_state *cli;
+       bool correct = false;
+       uint16_t mode = 0;
+       NTSTATUS status;
+
+       printf("Starting MSDFS-ATTRIBUTE test\n");
+
+       if (test_filename == NULL || test_filename[0] == '\0') {
+               printf("MSDFS-ATTRIBUTE test "
+                       "needs -f filename-of-msdfs-link\n");
+               return false;
+       }
+
+       /*
+        * NB. We use torture_open_connection_flags() not
+        * torture_open_connection() as the latter forces
+        * SMB1.
+        */
+       if (!torture_open_connection_flags(&cli, 0, 0)) {
+               return false;
+       }
+
+       smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+       status = cli_list(cli,
+                       "*",
+                       FILE_ATTRIBUTE_DIRECTORY,
+                       msdfs_attribute_list_fn,
+                       &mode);
+
+       if (!NT_STATUS_IS_OK(status)) {


-- 
Samba Shared Repository

Reply via email to