[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue Aug 2 20:47:01 UTC 2022


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 <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Aug  2 20:46:38 UTC 2022 on sn-devel-184

commit 0e7a151c2f76c8746ad2a374447f6e3233516dee
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit e960f4b30bf735aa50edffca96641f8607c9353d
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 3b3cab818842c8768b3ae3e5c30d01cce925b9e7
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 22403ec72ef9d448be03121098de12f757c7f61d
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 8b667db0f7d59875e38feb5b14a339eefc8f1c79
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit b14e4f592551b2a8310fd0529ce503b8abaf87bf
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 79257334c22823de3587caacdd430655112e888b
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit dc309e60623701b992d42898ce07f6537300ae22
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit ab9397726efd075274f1f8c4c75f8dedac2b95e7
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit c3737300ed9ba62da1dc343d94f76b886ec12317
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit d89ec90c87b3c52c9d0d9d371da123ffe6630d56
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 1006b1af4b733df70a667982e07c14c7e1aa4d62
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit a9ed7f6064cae00345a1030fb51a10c43b8cf12a
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit c71368a080b9357c9c320ac5bfb41095205cfb59
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit a457d59e98547177944b8a4c198b8d86e3c23d0f
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 2a9d7beb9e33316ac185d5cbd0e498502474b4e8
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit a6c34ec3c2598ad364444da829b9fff23996cebc
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit b80e51137c3b39b36d124eb6a1e028b692d0a863
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 1d658bbe65a5a037efa403250c9513a50b5dc8be
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 0b33ec49e385f279fbb495173017b2be45e9d206
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit d9f144acb64911b20e81b8948fcdc4ca0636891c
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit beb10e8bbe4909b6bcc70da89c11560e04e483e9
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit c673ca15c56feef41501643244ebfe15a48c8d2c
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit b9006f33b4fbe97ef09ae4e6c4d25eadf9b2b46d
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 2c4719a0cda0061bf331227e25cb4534a4c0eb9c
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 5249cb3d0fdfe96c4bc65a6338d798feada590ec
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 6fd8f7fd18f6491c906f9281d316c87aab854f67
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at 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



More information about the samba-cvs mailing list