The branch, master has been updated
       via  93b6db3328c s3: smbd: Convert smb_file_rename_information() to use 
filename_convert_dirfsp().
       via  0e7a151c2f7 s3: smbd: Convert smb_file_link_information() to use 
filename_convert_dirfsp().
       via  e960f4b30bf s3: smbd: Convert smb2_file_rename_information() to use 
filename_convert_dirfsp().
       via  3b3cab81884 s3: smbd: Convert smb_set_file_unix_hlink() to use 
filename_convert_dirfsp().
       via  22403ec72ef s3: smbd: Convert reply_ntrename() to use 
filename_convert_dirfsp().
       via  8b667db0f7d s3: smbd: Convert reply_mv() to use 
filename_convert_dirfsp().
       via  b14e4f59255 s3: smbd: Convert reply_mkdir() to use 
filename_convert_dirfsp().
       via  79257334c22 s3: smbd: Convert reply_unlink() to use 
filename_convert_dirfsp().
       via  dc309e60623 s3: smbd: Convert cmd_utime() to use 
filename_convert_dirfsp().
       via  ab9397726ef s3: smbd: Convert 
smbd_smb2_create_durable_lease_check() to use filename_convert_dirfsp().
       via  c3737300ed9 s3: smbd: Convert _srvsvc_NetSetFileSecurity() to use 
filename_convert_dirfsp().
       via  d89ec90c87b s3: smbd: Convert _srvsvc_NetGetFileSecurity() to use 
filename_convert_dirfsp().
       via  1006b1af4b7 s3: smbd: Convert call_trans2setfilepathinfo() to use 
filename_convert_dirfsp().
       via  a9ed7f6064c s3: smbd: Convert call_trans2qfilepathinfo() to use 
filename_convert_dirfsp().
       via  c71368a080b s3: smbd: Convert reply_setatr() to use 
filename_convert_dirfsp().
       via  a457d59e985 s3: smbd: Convert reply_getatr() to use 
filename_convert_dirfsp().
       via  2a9d7beb9e3 s3: smbd: Add dirfsp parameter to create_directory().
       via  a6c34ec3c25 s3: smbd: Add src_dirfsp and dst_dirfsp parameters to 
copy_internals().
       via  b80e51137c3 s3: smbd: Add old_dirfsp and new_dirfsp parameters to 
hardlink_internals().
       via  1d658bbe65a s3: smbd: Add dst_dirfsp parameter to 
rename_internals_fsp().
       via  0b33ec49e38 s3: smbd: Add dirfsp parameter to unlink_internals().
       via  d9f144acb64 s3: smbd: Add src_dirfsp and dst_dirfsp parameters to 
rename_internals().
       via  beb10e8bbe4 s3: smbd: In reply_ntrename(), don't call 
filename_convert() if we know it's a stream rename.
       via  c673ca15c56 s3: smbd: Tweak the logic of 
smb2_file_rename_information().
       via  b9006f33b4f s3: smbd: Inside filename_convert_dirfsp_nosymlink(), 
don't require UCF_PREP_CREATEFILE when parsing a stream name that doesn't 
already exist.
       via  2c4719a0cda s3: smbd: In filename_convert_dirfsp(), don't let an 
SMB1+POSIX client see a symlink to a directory with no permissions.
       via  5249cb3d0fd s3: smbd: In filename_convert_dirfsp_nosymlink(), in 
SMB1-only POSIX mode, allow a pathname referencing a symlink to be returned.
       via  6fd8f7fd18f s3: smbd: In filename_convert_dirfsp(), allow 
SMB1+POSIX to traverse non-terminal symlinks.
      from  766151bf5b7 lib:replace: Only include <sys/mount.h> on non-Linux 
systems

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


- Log -----------------------------------------------------------------
commit 93b6db3328cef0fea864480b3047cc6f17b05a0f
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 12:38:47 2022 -0700

    s3: smbd: Convert smb_file_rename_information() to use 
filename_convert_dirfsp().
    
    There is only one last user of filename_convert(), in 
filename_convert_smb1_search_path().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>
    
    Autobuild-User(master): Jeremy Allison <j...@samba.org>
    Autobuild-Date(master): Tue Aug  2 20:46:38 UTC 2022 on sn-devel-184

commit 0e7a151c2f76c8746ad2a374447f6e3233516dee
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 12:32:07 2022 -0700

    s3: smbd: Convert smb_file_link_information() to use 
filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Later we should optimize this by passing in
    the src_dirfsp from the caller.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit e960f4b30bf735aa50edffca96641f8607c9353d
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 12:29:22 2022 -0700

    s3: smbd: Convert smb2_file_rename_information() to use 
filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 3b3cab818842c8768b3ae3e5c30d01cce925b9e7
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 12:23:36 2022 -0700

    s3: smbd: Convert smb_set_file_unix_hlink() to use 
filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Later we should optimize this by passing in
    the src_dirfsp from the caller.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 22403ec72ef9d448be03121098de12f757c7f61d
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 12:18:47 2022 -0700

    s3: smbd: Convert reply_ntrename() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 8b667db0f7d59875e38feb5b14a339eefc8f1c79
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 12:09:34 2022 -0700

    s3: smbd: Convert reply_mv() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit b14e4f592551b2a8310fd0529ce503b8abaf87bf
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 12:04:47 2022 -0700

    s3: smbd: Convert reply_mkdir() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 79257334c22823de3587caacdd430655112e888b
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 11:52:36 2022 -0700

    s3: smbd: Convert reply_unlink() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit dc309e60623701b992d42898ce07f6537300ae22
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 10:56:28 2022 -0700

    s3: smbd: Convert cmd_utime() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit ab9397726efd075274f1f8c4c75f8dedac2b95e7
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 10:54:03 2022 -0700

    s3: smbd: Convert smbd_smb2_create_durable_lease_check() to use 
filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit c3737300ed9ba62da1dc343d94f76b886ec12317
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 10:48:18 2022 -0700

    s3: smbd: Convert _srvsvc_NetSetFileSecurity() to use 
filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit d89ec90c87b3c52c9d0d9d371da123ffe6630d56
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 10:46:25 2022 -0700

    s3: smbd: Convert _srvsvc_NetGetFileSecurity() to use 
filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 1006b1af4b733df70a667982e07c14c7e1aa4d62
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 10:41:25 2022 -0700

    s3: smbd: Convert call_trans2setfilepathinfo() to use 
filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit a9ed7f6064cae00345a1030fb51a10c43b8cf12a
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 10:39:12 2022 -0700

    s3: smbd: Convert call_trans2qfilepathinfo() to use 
filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit c71368a080b9357c9c320ac5bfb41095205cfb59
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 10:33:31 2022 -0700

    s3: smbd: Convert reply_setatr() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit a457d59e98547177944b8a4c198b8d86e3c23d0f
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 10:30:02 2022 -0700

    s3: smbd: Convert reply_getatr() to use filename_convert_dirfsp().
    
    One less use of filename_convert().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 2a9d7beb9e33316ac185d5cbd0e498502474b4e8
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 12:01:21 2022 -0700

    s3: smbd: Add dirfsp parameter to create_directory().
    
    Not yet used but passed down to SMB_VFS_CREATE().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit a6c34ec3c2598ad364444da829b9fff23996cebc
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 11:49:35 2022 -0700

    s3: smbd: Add src_dirfsp and dst_dirfsp parameters to copy_internals().
    
    Not yet used.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit b80e51137c3b39b36d124eb6a1e028b692d0a863
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 11:43:21 2022 -0700

    s3: smbd: Add old_dirfsp and new_dirfsp parameters to hardlink_internals().
    
    Not yet used.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 1d658bbe65a5a037efa403250c9513a50b5dc8be
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 11:25:48 2022 -0700

    s3: smbd: Add dst_dirfsp parameter to rename_internals_fsp().
    
    Not yet used, but when this is fully plumbed though we can
    look at optimizing and removing the code inside rename_internals_fsp()
    that currently gets it's own dst_dirfsp.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 0b33ec49e385f279fbb495173017b2be45e9d206
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 11:17:47 2022 -0700

    s3: smbd: Add dirfsp parameter to unlink_internals().
    
    Not yet used but passed to SMB_VFS_CREATE().
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit d9f144acb64911b20e81b8948fcdc4ca0636891c
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jul 28 11:08:17 2022 -0700

    s3: smbd: Add src_dirfsp and dst_dirfsp parameters to rename_internals().
    
    Not yet used (but passed to SMB_VFS_CREATE_FILE()).
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit beb10e8bbe4909b6bcc70da89c11560e04e483e9
Author: Jeremy Allison <j...@samba.org>
Date:   Fri Jul 29 14:07:50 2022 -0700

    s3: smbd: In reply_ntrename(), don't call filename_convert() if we know 
it's a stream rename.
    
    There is no point in calling filename_convert() on a raw stream name.
    It can never find the file anyway (and never returns a valid 
smb_fname->fsp).
    Use the same logic as SMB2_FILE_RENAME_INFORMATION_INTERNAL now does
    and generate smb_fname_new directly.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit c673ca15c56feef41501643244ebfe15a48c8d2c
Author: Jeremy Allison <j...@samba.org>
Date:   Fri Jul 29 14:38:17 2022 -0700

    s3: smbd: Tweak the logic of smb2_file_rename_information().
    
    There's no point in calling filename_convert() and then
    just ignoring the returned smb_fname if it's a raw stream name.
    Only call filename_convert() if we know it isn't a raw stream
    name.
    
    Ignore stream/non-stream mismatches in src and dst in
    smb2_file_rename_information, let rename_internals_fsp()
    take care of that as the error returns inside rename_internals_fsp()
    are tested by raw.streams.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit b9006f33b4fbe97ef09ae4e6c4d25eadf9b2b46d
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Aug 1 11:40:14 2022 -0700

    s3: smbd: Inside filename_convert_dirfsp_nosymlink(), don't require 
UCF_PREP_CREATEFILE when parsing a stream name that doesn't already exist.
    
    We don't require it for a new file. Without this change, we have
    to add UCF_PREP_CREATEFILE to the destination flags when we are
    doing renames to a destination stream name, but not when doing
    renames to a destination file name, which makes for inconsistent API use.
    
    filename_convert_dirfsp() is now a drop in replacement
    for filename_convert(), even for the ugly SMB1 POSIX
    cases.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 2c4719a0cda0061bf331227e25cb4534a4c0eb9c
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Aug 1 17:55:23 2022 -0700

    s3: smbd: In filename_convert_dirfsp(), don't let an SMB1+POSIX client see 
a symlink to a directory with no permissions.
    
    This isn't 100% correct, but it gets us close enough
    to the old behavior for SMB1+POSIX libsmbclient. If we went through a
    symlink, and we got NT_STATUS_ACCESS_DENIED on the directory
    containing the target, just don't allow the client to see the
    intermediate path.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 5249cb3d0fdfe96c4bc65a6338d798feada590ec
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Aug 1 14:24:31 2022 -0700

    s3: smbd: In filename_convert_dirfsp_nosymlink(), in SMB1-only POSIX mode, 
allow a pathname referencing a symlink to be returned.
    
    Doesn't contain a valid smb_fname->fsp pointer of course,
    and is only used by the SMB1 code to take a reference to
    a smylink name for manipulation (unlinkat, readlinkat etc.).
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

commit 6fd8f7fd18f6491c906f9281d316c87aab854f67
Author: Jeremy Allison <j...@samba.org>
Date:   Mon Aug 1 14:40:54 2022 -0700

    s3: smbd: In filename_convert_dirfsp(), allow SMB1+POSIX to traverse 
non-terminal symlinks.
    
    This is the behavior of filename_convert() and
    we need to allow it for the legacy SMB1+POSIX libsmbclient
    libraries already deployed out there.
    
    When we add SMB2 POSIX we must disallow symlink
    traversal over any symlinks, the client must
    resolve symlinks locally.
    
    Add a note to show this is where we need to add
    an error for SMB2+POSIX names with UCF_POSIX_PATHNAMES
    set.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>

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

Summary of changes:
 source3/modules/vfs_crossrename.c         |   2 +
 source3/printing/nt_printing.c            |   4 +-
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c |  34 +++++----
 source3/smbd/filename.c                   |  58 +++++++++++++---
 source3/smbd/open.c                       |   6 +-
 source3/smbd/proto.h                      |  12 +++-
 source3/smbd/smb1_nttrans.c               |  84 ++++++++++++++--------
 source3/smbd/smb1_reply.c                 | 112 ++++++++++++++++++++----------
 source3/smbd/smb1_trans2.c                |  39 +++++++----
 source3/smbd/smb2_create.c                |  12 +++-
 source3/smbd/smb2_nttrans.c               |   6 +-
 source3/smbd/smb2_reply.c                 |   9 ++-
 source3/smbd/smb2_trans2.c                | 106 ++++++++++++++++++----------
 source3/torture/cmd_vfs.c                 |  14 ++--
 14 files changed, 345 insertions(+), 153 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/modules/vfs_crossrename.c 
b/source3/modules/vfs_crossrename.c
index 930eec02739..042144bfc4d 100644
--- a/source3/modules/vfs_crossrename.c
+++ b/source3/modules/vfs_crossrename.c
@@ -115,7 +115,9 @@ static NTSTATUS copy_reg(vfs_handle_struct *handle,
        status = copy_internals(talloc_tos(),
                                handle->conn,
                                NULL,
+                               srcfsp, /* src_dirfsp */
                                full_fname_src,
+                               dstfsp, /* dst_dirfsp */
                                full_fname_dst,
                                FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
        if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 0929e532436..dc54a194f65 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1577,7 +1577,7 @@ WERROR move_driver_to_download_area(const struct 
auth_session_info *session_info
 
        DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
 
-       nt_status = create_directory(conn, NULL, smb_dname);
+       nt_status = create_directory(conn, NULL, NULL, smb_dname);
        if (!NT_STATUS_IS_OK(nt_status)
         && !NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_COLLISION)) {
                DEBUG(0, ("failed to create driver destination directory: %s\n",
@@ -2042,7 +2042,7 @@ static NTSTATUS driver_unlink_internals(connection_struct 
*conn,
                goto err_out;
        }
 
-       status = unlink_internals(conn, NULL, 0, smb_fname);
+       status = unlink_internals(conn, NULL, 0, NULL, smb_fname);
 err_out:
        talloc_free(tmp_ctx);
        return status;
diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c 
b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
index b6f2b34b8e8..c5b39ed9cb6 100644
--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
@@ -2498,9 +2498,11 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
        struct conn_struct_tos *c = NULL;
        connection_struct *conn = NULL;
        struct sec_desc_buf *sd_buf = NULL;
+       struct files_struct *dirfsp = NULL;
        files_struct *fsp = NULL;
        int snum;
        uint32_t ucf_flags = 0;
+       NTTIME twrp = 0;
 
        ZERO_STRUCT(st);
 
@@ -2532,12 +2534,13 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct 
*p,
        }
        conn = c->conn;
 
-       nt_status = filename_convert(frame,
-                                       conn,
-                                       r->in.file,
-                                       ucf_flags,
-                                       0,
-                                       &smb_fname);
+       nt_status = filename_convert_dirfsp(frame,
+                                           conn,
+                                           r->in.file,
+                                           ucf_flags,
+                                           twrp,
+                                           &dirfsp,
+                                           &smb_fname);
        if (!NT_STATUS_IS_OK(nt_status)) {
                werr = ntstatus_to_werror(nt_status);
                goto error_exit;
@@ -2546,7 +2549,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
        nt_status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
                NULL,                                   /* req */
-               NULL,                                   /* dirfsp */
+               dirfsp,                                 /* dirfsp */
                smb_fname,                              /* fname */
                FILE_READ_ATTRIBUTES,                   /* access_mask */
                FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
@@ -2627,6 +2630,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
                loadparm_s3_global_substitution();
        struct smb_filename *smb_fname = NULL;
        char *servicename = NULL;
+       struct files_struct *dirfsp = NULL;
        files_struct *fsp = NULL;
        SMB_STRUCT_STAT st;
        NTSTATUS nt_status;
@@ -2637,6 +2641,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
        struct security_descriptor *psd = NULL;
        uint32_t security_info_sent = 0;
        uint32_t ucf_flags = 0;
+       NTTIME twrp = 0;
 
        ZERO_STRUCT(st);
 
@@ -2670,12 +2675,13 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct 
*p,
        }
        conn = c->conn;
 
-       nt_status = filename_convert(frame,
-                                       conn,
-                                       r->in.file,
-                                       ucf_flags,
-                                       0,
-                                       &smb_fname);
+       nt_status = filename_convert_dirfsp(frame,
+                                           conn,
+                                           r->in.file,
+                                           ucf_flags,
+                                           twrp,
+                                           &dirfsp,
+                                           &smb_fname);
        if (!NT_STATUS_IS_OK(nt_status)) {
                werr = ntstatus_to_werror(nt_status);
                goto error_exit;
@@ -2684,7 +2690,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
        nt_status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
                NULL,                                   /* req */
-               NULL,                                   /* dirfsp */
+               dirfsp,                                 /* dirfsp */
                smb_fname,                              /* fname */
                FILE_WRITE_ATTRIBUTES,                  /* access_mask */
                FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 3f0c395fd8f..3e90b8dd71b 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -2907,6 +2907,28 @@ static NTSTATUS filename_convert_dirfsp_nosymlink(
                char *normalized = NULL;
 
                if (VALID_STAT(smb_fname_rel->st)) {
+#if defined(WITH_SMB1SERVER)
+                       /*
+                        * In SMB1 posix mode, if this is a symlink,
+                        * allow access to the name with a NULL smb_fname->fsp.
+                        */
+                       if (!conn->sconn->using_smb2 &&
+                                       posix &&
+                                       S_ISLNK(smb_fname_rel->st.st_ex_mode)) {
+                               SMB_ASSERT(smb_fname_rel->fsp == NULL);
+                               SMB_ASSERT(streamname == NULL);
+
+                               smb_fname = full_path_from_dirfsp_atname(
+                                               mem_ctx,
+                                               smb_dirname->fsp,
+                                               smb_fname_rel);
+                               if (smb_fname == NULL) {
+                                       status = NT_STATUS_NO_MEMORY;
+                                       goto fail;
+                               }
+                               goto done;
+                       }
+#endif
                        /*
                         * NT_STATUS_OBJECT_NAME_NOT_FOUND is
                         * misleading: The object exists but might be
@@ -3003,8 +3025,7 @@ static NTSTATUS filename_convert_dirfsp_nosymlink(
                goto done;
        }
 
-       if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
-           (ucf_flags & UCF_PREP_CREATEFILE)) {
+       if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                /*
                 * Creating a new stream
                 *
@@ -3073,6 +3094,22 @@ next:
                &substitute,
                &unparsed);
 
+#if defined(WITH_SMB1SERVER)
+       /*
+        * This isn't 100% correct, but it gets us close enough
+        * to the old behavior for SMB1+POSIX libsmbclient. If we went through a
+        * symlink, and we got NT_STATUS_ACCESS_DENIED on the directory
+        * containing the target, just don't allow the client to see the
+        * intermediate path.
+        */
+       if (!conn->sconn->using_smb2 &&
+                       (ucf_flags & UCF_POSIX_PATHNAMES) &&
+                       symlink_redirects > 0 &&
+                       NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+       }
+#endif
+
        if (!NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
                return status;
        }
@@ -3081,12 +3118,17 @@ next:
                return NT_STATUS_OBJECT_PATH_NOT_FOUND;
        }
 
-       if (ucf_flags & UCF_POSIX_PATHNAMES) {
-               /*
-                * SMB1 posix never traverses symlinks
-                */
-               return NT_STATUS_OBJECT_PATH_NOT_FOUND;
-       }
+       /*
+        * Right now, SMB2 and SMB1 always traverse symlinks
+        * within the share. SMB1+POSIX traverses non-terminal
+        * symlinks within the share.
+        *
+        * When we add SMB2+POSIX we need to return
+        * a NT_STATUS_STOPPED_ON_SYMLINK error here, using the
+        * symlink target data read below if SMB2+POSIX has
+        * UCF_POSIX_PATHNAMES set to cause the client to
+        * resolve all symlinks locally.
+        */
 
        target = symlink_target_path(mem_ctx, name_in, substitute, unparsed);
        if (target == NULL) {
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index ee61137ab9d..30628cc4fd0 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -4765,7 +4765,9 @@ static NTSTATUS open_directory(connection_struct *conn,
        return NT_STATUS_OK;
 }
 
-NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
+NTSTATUS create_directory(connection_struct *conn,
+                         struct smb_request *req,
+                         struct files_struct *dirfsp,
                          struct smb_filename *smb_dname)
 {
        NTSTATUS status;
@@ -4774,7 +4776,7 @@ NTSTATUS create_directory(connection_struct *conn, struct 
smb_request *req,
        status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
                req,                                    /* req */
-               NULL,                                   /* dirfsp */
+               dirfsp,                                 /* dirfsp */
                smb_dname,                              /* fname */
                FILE_READ_ATTRIBUTES,                   /* access_mask */
                FILE_SHARE_NONE,                        /* share_access */
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 341c98cde71..0d541d15466 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -698,7 +698,9 @@ NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, 
uint32_t sd_len,
 NTSTATUS copy_internals(TALLOC_CTX *ctx,
                        connection_struct *conn,
                        struct smb_request *req,
+                       struct files_struct *src_dirfsp,
                        struct smb_filename *smb_fname_src,
+                       struct files_struct *dst_dirfsp,
                        struct smb_filename *smb_fname_dst,
                        uint32_t attrs);
 NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
@@ -745,7 +747,9 @@ NTSTATUS send_break_message(struct messaging_context 
*msg_ctx,
 struct deferred_open_record;
 bool is_deferred_open_async(const struct deferred_open_record *rec);
 bool defer_smb1_sharing_violation(struct smb_request *req);
-NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
+NTSTATUS create_directory(connection_struct *conn,
+                         struct smb_request *req,
+                         struct files_struct *dirfsp,
                          struct smb_filename *smb_dname);
 void msg_file_was_renamed(struct messaging_context *msg,
                          void *private_data,
@@ -973,6 +977,7 @@ void reply_special(struct smbXsrv_connection *xconn, char 
*inbuf, size_t inbuf_s
 NTSTATUS unlink_internals(connection_struct *conn,
                        struct smb_request *req,
                        uint32_t dirtype,
+                       struct files_struct *dirfsp,
                        struct smb_filename *smb_fname);
 ssize_t fake_sendfile(struct smbXsrv_connection *xconn, files_struct *fsp,
                      off_t startpos, size_t nread);
@@ -983,6 +988,7 @@ ssize_t sendfile_short_send(struct smbXsrv_connection 
*xconn,
                            size_t smb_maxcnt);
 NTSTATUS rename_internals_fsp(connection_struct *conn,
                        files_struct *fsp,
+                       struct files_struct *dst_dirfsp,
                        struct smb_filename *smb_fname_dst_in,
                        const char *dst_original_lcomp,
                        uint32_t attrs,
@@ -990,7 +996,9 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 NTSTATUS rename_internals(TALLOC_CTX *ctx,
                        connection_struct *conn,
                        struct smb_request *req,
+                       struct files_struct *src_dirfsp,
                        struct smb_filename *smb_fname_src,
+                       struct files_struct *dst_dirfsp,
                        struct smb_filename *smb_fname_dst,
                        const char *dst_original_lcomp,
                        uint32_t attrs,
@@ -1139,7 +1147,9 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                connection_struct *conn,
                struct smb_request *req,
                bool overwrite_if_exists,
+               struct files_struct *old_dirfsp,
                const struct smb_filename *smb_fname_old,
+               struct files_struct *new_dirfsp,
                struct smb_filename *smb_fname_new);
 NTSTATUS smb_set_file_time(connection_struct *conn,
                           files_struct *fsp,
diff --git a/source3/smbd/smb1_nttrans.c b/source3/smbd/smb1_nttrans.c
index acb09fb7650..cd68ecd2590 100644
--- a/source3/smbd/smb1_nttrans.c
+++ b/source3/smbd/smb1_nttrans.c
@@ -1401,7 +1401,9 @@ void reply_ntcancel(struct smb_request *req)
 void reply_ntrename(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
+       struct files_struct *src_dirfsp = NULL;
        struct smb_filename *smb_fname_old = NULL;
+       struct files_struct *dst_dirfsp = NULL;
        struct smb_filename *smb_fname_new = NULL;
        char *oldname = NULL;
        char *newname = NULL;
@@ -1410,7 +1412,9 @@ void reply_ntrename(struct smb_request *req)
        NTSTATUS status;
        uint32_t attrs;
        uint32_t ucf_flags_src = ucf_flags_from_smb_request(req);
+       NTTIME src_twrp = 0;
        uint32_t ucf_flags_dst = ucf_flags_from_smb_request(req);
+       NTTIME dst_twrp = 0;
        uint16_t rename_type;
        TALLOC_CTX *ctx = talloc_tos();
        bool stream_rename = false;
@@ -1463,12 +1467,16 @@ void reply_ntrename(struct smb_request *req)
                }
        }
 
-       /* rename_internals() calls unix_convert(), so don't call it here. */
-       status = filename_convert(ctx, conn,
-                                 oldname,
-                                 ucf_flags_src,
-                                 0,
-                                 &smb_fname_old);
+       if (ucf_flags_src & UCF_GMT_PATHNAME) {
+               extract_snapshot_token(oldname, &src_twrp);
+       }
+       status = filename_convert_dirfsp(ctx,
+                                        conn,
+                                        oldname,
+                                        ucf_flags_src,
+                                        src_twrp,
+                                        &src_dirfsp,
+                                        &smb_fname_old);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,
                                    NT_STATUS_PATH_NOT_COVERED)) {
@@ -1491,32 +1499,46 @@ void reply_ntrename(struct smb_request *req)
                goto out;
        }
 
-       status = filename_convert(ctx, conn,
-                                 newname,
-                                 ucf_flags_dst,
-                                 0,
-                                 &smb_fname_new);
-       if (!NT_STATUS_IS_OK(status)) {
-               if (NT_STATUS_EQUAL(status,
-                                   NT_STATUS_PATH_NOT_COVERED)) {
-                       reply_botherror(req,
-                                       NT_STATUS_PATH_NOT_COVERED,
-                                       ERRSRV, ERRbadpath);
-                       goto out;
-               }
-               reply_nterror(req, status);
-               goto out;
-       }
-
        if (stream_rename) {
-               /* smb_fname_new must be the same as smb_fname_old. */
-               TALLOC_FREE(smb_fname_new->base_name);
-               smb_fname_new->base_name = talloc_strdup(smb_fname_new,
-                                               smb_fname_old->base_name);
-               if (!smb_fname_new->base_name) {
+               /*
+                * No point in calling filename_convert()
+                * on a raw stream name. It can never find
+                * the file anyway. Use the same logic as
+                * SMB2_FILE_RENAME_INFORMATION_INTERNAL
+                * and generate smb_fname_new directly.
+                */
+               smb_fname_new = synthetic_smb_fname(talloc_tos(),
+                                       smb_fname_old->base_name,
+                                       newname,
+                                       NULL,
+                                       smb_fname_old->twrp,
+                                       smb_fname_old->flags);
+               if (smb_fname_new == NULL) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
                        goto out;
                }
+       } else {
+               if (ucf_flags_dst & UCF_GMT_PATHNAME) {
+                       extract_snapshot_token(newname, &dst_twrp);
+               }
+               status = filename_convert_dirfsp(ctx,
+                                                conn,
+                                                newname,
+                                                ucf_flags_dst,
+                                                dst_twrp,
+                                                &dst_dirfsp,
+                                                &smb_fname_new);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (NT_STATUS_EQUAL(status,
+                                           NT_STATUS_PATH_NOT_COVERED)) {
+                               reply_botherror(req,
+                                               NT_STATUS_PATH_NOT_COVERED,
+                                               ERRSRV, ERRbadpath);
+                               goto out;
+                       }
+                       reply_nterror(req, status);
+                       goto out;
+               }
        }
 
        DEBUG(3,("reply_ntrename: %s -> %s\n",
@@ -1528,7 +1550,9 @@ void reply_ntrename(struct smb_request *req)
                        status = rename_internals(ctx,
                                                conn,
                                                req,
+                                               src_dirfsp,
                                                smb_fname_old,
+                                               dst_dirfsp,
                                                smb_fname_new,
                                                dst_original_lcomp,
                                                attrs,
@@ -1540,14 +1564,18 @@ void reply_ntrename(struct smb_request *req)
                                                    conn,
                                                    req,
                                                    false,
+                                                   src_dirfsp,
                                                    smb_fname_old,
+                                                   dst_dirfsp,
                                                    smb_fname_new);
                        break;
                case RENAME_FLAG_COPY:
                        status = copy_internals(ctx,
                                                conn,
                                                req,
+                                               src_dirfsp,
                                                smb_fname_old,
+                                               dst_dirfsp,
                                                smb_fname_new,
                                                attrs);
                        break;
diff --git a/source3/smbd/smb1_reply.c b/source3/smbd/smb1_reply.c
index de38817ea76..fcfd670163d 100644
--- a/source3/smbd/smb1_reply.c
+++ b/source3/smbd/smb1_reply.c
@@ -682,13 +682,19 @@ void reply_getatr(struct smb_request *req)
                size = 0;
                mtime = 0;
        } else {
+               struct files_struct *dirfsp = NULL;
                uint32_t ucf_flags = ucf_flags_from_smb_request(req);
-               status = filename_convert(ctx,
-                               conn,
-                               fname,
-                               ucf_flags,
-                               0,
-                               &smb_fname);
+               NTTIME twrp = 0;
+               if (ucf_flags & UCF_GMT_PATHNAME) {
+                       extract_snapshot_token(fname, &twrp);
+               }
+               status = filename_convert_dirfsp(ctx,
+                                                conn,
+                                                fname,
+                                                ucf_flags,
+                                                twrp,
+                                                &dirfsp,
+                                                &smb_fname);
                if (!NT_STATUS_IS_OK(status)) {
                        if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) 
{
                                reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -762,12 +768,14 @@ void reply_setatr(struct smb_request *req)
        struct smb_file_time ft;
        connection_struct *conn = req->conn;
        struct smb_filename *smb_fname = NULL;
+       struct files_struct *dirfsp = NULL;
        char *fname = NULL;
        int mode;
        time_t mtime;
        const char *p;
        NTSTATUS status;
        uint32_t ucf_flags = ucf_flags_from_smb_request(req);
+       NTTIME twrp = 0;
        TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBsetatr);
@@ -785,12 +793,16 @@ void reply_setatr(struct smb_request *req)
                goto out;
        }
 
-       status = filename_convert(ctx,
-                               conn,
-                               fname,
-                               ucf_flags,
-                               0,


-- 
Samba Shared Repository

Reply via email to