[SCM] Samba Shared Repository - branch master updated

Ralph Böhme slow at samba.org
Mon Mar 30 16:24:01 UTC 2020


The branch, master has been updated
       via  1cc250b46e9 s3: smbd: RIP smb_filename->original_lcomp.
       via  d875f60e970 s3: smbd: Remove UCF_SAVE_LCOMP flag. Note it is no longer used.
       via  e0d3190b4b1 s3: smbd: Remove all references to original_lcomp from name copying code.
       via  79b945d44ea s3: smbd: Now we no longer use it, remove all references to original_lcomp from pathname processing code.
       via  5104ec8dec8 s3: smbd: Use get_original_lcomp() inside smb_file_rename_information().
       via  d7f2143206e s3: smbd: Use get_original_lcomp() inside smb2_file_rename_information().
       via  aa80e9732f8 s3: smbd: Use get_original_lcomp() inside reply_mv().
       via  7d2cb52163b s3: smbd: Use get_original_lcomp() inside reply_ntrename().
       via  d5408193953 s3: smbd: Inside rename_internals() wildcard case, re-purpose dst_original_lcomp.
       via  6c6e5d52ea3 s3: smbd: Add 'const char *dst_original_lcomp' parameter to rename_internals()
       via  6c53372a3ea s3: smbd: Reformatting caller of rename_internals() to make it easer to see changed parameters.
       via  454ecaf3b4b s3: smbd: Add a dst_original_lcomp parameter to rename_internals_fsp().
       via  614b3003017 s3: smbd: Reformatting callers of rename_internals_fsp() to make it easer to see changed parameters.
       via  500037f2181 s3: smbd: Remove use of smb_fname->original_lcomp from call_trans2findfirst().
       via  9d785ae5170 s3: smbd: Remove use of smb_fname->original_lcomp from smb2 query directory.
       via  f88c36b3947 s3: smbd: Add utility function get_original_lcomp().
       via  dd015436b3e s3: smbd: Extract large directory case normalization code into a utility function normalize_filename_case().
      from  047b0d8ab53 nsswitch: fix use-after-free causing segfault in _pam_delete_cred

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


- Log -----------------------------------------------------------------
commit 1cc250b46e932511b878fd66bb9014b15dcaffaa
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 16:30:48 2020 -0700

    s3: smbd: RIP smb_filename->original_lcomp.
    
    Removed from struct smb_filename. You will not be missed :-).
    Note that VFS ABI modified.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Mon Mar 30 16:23:45 UTC 2020 on sn-devel-184

commit d875f60e970298ba27e7c9f3118c0e1040944774
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 16:27:25 2020 -0700

    s3: smbd: Remove UCF_SAVE_LCOMP flag. Note it is no longer used.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit e0d3190b4b199dff4f2089533db6fb32b939a826
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 16:24:08 2020 -0700

    s3: smbd: Remove all references to original_lcomp from name copying code.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 79b945d44eac5891e2a3cd4ef3c4aef9a1923c0a
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 16:22:36 2020 -0700

    s3: smbd: Now we no longer use it, remove all references to original_lcomp from pathname processing code.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 5104ec8dec8c0bcf05bfa8569d54dc55b3b8bc22
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 16:18:53 2020 -0700

    s3: smbd: Use get_original_lcomp() inside smb_file_rename_information().
    
    Pass to rename_internals_fsp() and rename_internals().
    
    Removes the last uses of the struct member original_lcomp
    outside of the filename and struct util copying code.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit d7f2143206ebc5d1ac8e0add273147b5da94b3b7
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 15:59:51 2020 -0700

    s3: smbd: Use get_original_lcomp() inside smb2_file_rename_information().
    
    Pass to rename_internals_fsp(). Note this is a logic change,
    as the original code only set smb_fname->original_lcomp if
    it was doing a stream rename. Inside rename_internals_fsp()
    we only look at original_lcomp in the stream rename case, so
    this code worked. However, it is much safer to always correctly
    create dst_original_lcomp than pass in a NULL here. It won't
    hurt if it's not actually looked at.
    
    Removes one more use of the struct member original_lcomp.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit aa80e9732f84626c36b8d7dce4cdd28c1d0be2e9
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 15:51:18 2020 -0700

    s3: smbd: Use get_original_lcomp() inside reply_mv().
    
    Pass to rename_internals().
    
    Removes one more use of the struct member original_lcomp.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 7d2cb52163baed3cfd5e7f16cb42d513371d4cbf
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 15:48:08 2020 -0700

    s3: smbd: Use get_original_lcomp() inside reply_ntrename().
    
    Pass to rename_internals().
    
    Removes one more use of the struct member original_lcomp.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit d5408193953c1b185e5e74a7e39bb40d0f6ff093
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 15:32:36 2020 -0700

    s3: smbd: Inside rename_internals() wildcard case, re-purpose dst_original_lcomp.
    
    Pass to rename_internals_fsp() instead of using smb_fname_dst->original_lcomp.
    
    Removes one more use of the struct member original_lcomp.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 6c6e5d52ea31f6ddc81823603573c4e3f1a6e93c
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 25 18:41:10 2020 -0700

    s3: smbd: Add 'const char *dst_original_lcomp' parameter to rename_internals()
    
    Pass through the existing smb_fname_dst->original_lcomp
    parameter so no logic change. Preparing to remove the
    use of original_lcomp.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 6c53372a3ea79d0f799c99fe3a63c40d54d5ca01
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 25 17:17:30 2020 -0700

    s3: smbd: Reformatting caller of rename_internals() to make it easer to see changed parameters.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 454ecaf3b4b26619f5a82b265a9f3bb65b8967a2
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 25 16:20:23 2020 -0700

    s3: smbd: Add a dst_original_lcomp parameter to rename_internals_fsp().
    
    Currently passed in as dst_fname->original_lcomp in all callers
    but will eventually be converted to allow original_lcomp to be
    removed from struct smb_filename.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 614b3003017657e8a6268d3cf73513ab557ed4b2
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 25 13:42:34 2020 -0700

    s3: smbd: Reformatting callers of rename_internals_fsp() to make it easer to see changed parameters.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 500037f218157b9473e684abaf5d6a990b3466a8
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 25 10:20:14 2020 -0700

    s3: smbd: Remove use of smb_fname->original_lcomp from call_trans2findfirst().
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 9d785ae5170ef8f4a072afa01a8965c4d0ff19fc
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 25 10:03:16 2020 -0700

    s3: smbd: Remove use of smb_fname->original_lcomp from smb2 query directory.
    
    Use get_original_lcomp() call. Removes one use of smb_fname->original_lcomp.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit f88c36b394716b8ed7ad43b027ce4152e9024cd3
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 25 10:00:57 2020 -0700

    s3: smbd: Add utility function get_original_lcomp().
    
    Gets the last component from a client passed-in
    filename. Copes with @GMT snapshot and MS-DFS names.
    
    Preparing to remove original_lcomp from
    struct smb_filename.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit dd015436b3e671f8cf7b503f23f6bd990e4e857c
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 26 12:35:26 2020 -0700

    s3: smbd: Extract large directory case normalization code into a utility function normalize_filename_case().
    
    It is done before the original_lcomp is extracted
    from the client pathname, so the new function that
    will allow us to remove original_lcomp also needs
    this logic.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

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

Summary of changes:
 source3/include/vfs.h               |   2 +-
 source3/lib/filename_util.c         |  13 +--
 source3/smbd/filename.c             | 156 ++++++++++++++++++++++++++----------
 source3/smbd/nttrans.c              |  29 +++++--
 source3/smbd/proto.h                |   6 ++
 source3/smbd/reply.c                |  59 ++++++++++----
 source3/smbd/smb2_query_directory.c |  18 ++++-
 source3/smbd/smbd.h                 |   2 +-
 source3/smbd/trans2.c               |  91 ++++++++++++++-------
 9 files changed, 266 insertions(+), 110 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index bda6cde3fdc..eae9f97179f 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -293,6 +293,7 @@
 /* Change to Version 43 - will ship with 4.13. */
 /* Version 43 - Remove deferred_close from struct files_struct */
 /* Version 43 - Remove SMB_VFS_OPENDIR() */
+/* Version 43 - Remove original_lcomp from struct smb_filename */
 
 #define SMB_VFS_INTERFACE_VERSION 43
 
@@ -639,7 +640,6 @@ struct smb_file_time {
 struct smb_filename {
 	char *base_name;
 	char *stream_name;
-	char *original_lcomp;
 	uint32_t flags;
 	SMB_STRUCT_STAT st;
 };
diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c
index 66c07001eba..1f2e4d31072 100644
--- a/source3/lib/filename_util.c
+++ b/source3/lib/filename_util.c
@@ -183,7 +183,6 @@ struct smb_filename *cp_smb_filename(TALLOC_CTX *mem_ctx,
 	struct smb_filename *out;
 	size_t base_len = 0;
 	size_t stream_len = 0;
-	size_t lcomp_len = 0;
 	int num = 0;
 
 	/* stream_name must always be NULL if there is no stream. */
@@ -199,13 +198,9 @@ struct smb_filename *cp_smb_filename(TALLOC_CTX *mem_ctx,
 		stream_len = strlen(in->stream_name) + 1;
 		num += 1;
 	}
-	if (in->original_lcomp != NULL) {
-		lcomp_len = strlen(in->original_lcomp) + 1;
-		num += 1;
-	}
 
 	out = talloc_pooled_object(mem_ctx, struct smb_filename,
-				num, stream_len + base_len + lcomp_len);
+				num, stream_len + base_len);
 	if (out == NULL) {
 		return NULL;
 	}
@@ -228,12 +223,6 @@ struct smb_filename *cp_smb_filename(TALLOC_CTX *mem_ctx,
 		talloc_set_name_const(out->stream_name,
 				      out->stream_name);
 	}
-	if (in->original_lcomp != NULL) {
-		out->original_lcomp = talloc_memdup(
-				out, in->original_lcomp, lcomp_len);
-		talloc_set_name_const(out->original_lcomp,
-				      out->original_lcomp);
-	}
 	out->flags = in->flags;
 	out->st = in->st;
 	return out;
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index d1dc1aef4f2..9faff9da45a 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -399,6 +399,32 @@ static NTSTATUS canonicalize_snapshot_path(struct smb_filename *smb_fname)
 				endp);
 }
 
+/*
+ * Utility function to normalize case on an incoming client filename
+ * if required on this connection struct.
+ * Performs an in-place case conversion guaranteed to stay the same size.
+ */
+
+static NTSTATUS normalize_filename_case(connection_struct *conn, char *filename)
+{
+	bool ok;
+
+	if (!conn->case_sensitive) {
+		return NT_STATUS_OK;
+	}
+	if (conn->case_preserve) {
+		return NT_STATUS_OK;
+	}
+	if (conn->short_case_preserve) {
+		return NT_STATUS_OK;
+	}
+	ok = strnorm(filename, lp_default_case(SNUM(conn)));
+	if (!ok) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+	return NT_STATUS_OK;
+}
+
 /****************************************************************************
 This routine is called to convert names from the dos namespace to unix
 namespace. It needs to handle any case conversions, mangling, format changes,
@@ -419,9 +445,6 @@ Note NT_STATUS_OK doesn't mean the name exists or is valid, just that we
 didn't get any fatal errors that should immediately terminate the calling SMB
 processing whilst resolving.
 
-If the UCF_SAVE_LCOMP flag is passed in, then the unmodified last component
-of the pathname is set in smb_filename->original_lcomp.
-
 If UCF_ALWAYS_ALLOW_WCARD_LCOMP is passed in, then a MS wildcard was detected
 and should be allowed in the last component of the path only.
 
@@ -451,7 +474,6 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 	bool posix_pathnames = (ucf_flags & UCF_POSIX_PATHNAMES);
 	bool allow_wcard_last_component =
 	    (ucf_flags & UCF_ALWAYS_ALLOW_WCARD_LCOMP);
-	bool save_last_component = ucf_flags & UCF_SAVE_LCOMP;
 	bool snapshot_path = (ucf_flags & UCF_GMT_PATHNAME);
 	NTSTATUS status;
 	int ret = -1;
@@ -542,32 +564,11 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 	 * the man page. Thanks to jht at samba.org for finding this. JRA.
 	 */
 
-	if (conn->case_sensitive && !conn->case_preserve &&
-			!conn->short_case_preserve) {
-		if (!strnorm(smb_fname->base_name, lp_default_case(SNUM(conn)))) {
-			DBG_ERR("strnorm [%s] failed\n", smb_fname->base_name);
-			status = NT_STATUS_INVALID_PARAMETER;
-			goto err;
-		}
-	}
-
-	/*
-	 * Ensure saved_last_component is valid even if file exists.
-	 */
-
-	if(save_last_component) {
-		end = strrchr_m(smb_fname->base_name, '/');
-		if (end) {
-			smb_fname->original_lcomp = talloc_strdup(smb_fname,
-								  end + 1);
-		} else {
-			smb_fname->original_lcomp =
-			    talloc_strdup(smb_fname, smb_fname->base_name);
-		}
-		if (smb_fname->original_lcomp == NULL) {
-			status = NT_STATUS_NO_MEMORY;
-			goto err;
-		}
+	status = normalize_filename_case(conn, smb_fname->base_name);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_ERR("normalize_filename_case %s failed\n",
+				smb_fname->base_name);
+		goto err;
 	}
 
 	/*
@@ -832,17 +833,6 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 			*end = 0;
 		}
 
-		if (save_last_component) {
-			TALLOC_FREE(smb_fname->original_lcomp);
-			smb_fname->original_lcomp = talloc_strdup(smb_fname,
-							end ? end + 1 : start);
-			if (!smb_fname->original_lcomp) {
-				DBG_ERR("talloc failed\n");
-				status = NT_STATUS_NO_MEMORY;
-				goto err;
-			}
-		}
-
 		/* The name cannot have a component of "." */
 
 		if (ISDOT(start)) {
@@ -1668,6 +1658,90 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
 	return status;
 }
 
+/*
+ * Lightweight function to just get last component
+ * for rename / enumerate directory calls.
+ */
+
+char *get_original_lcomp(TALLOC_CTX *ctx,
+			connection_struct *conn,
+			const char *filename_in,
+			uint32_t ucf_flags)
+{
+	struct smb_filename *smb_fname = NULL;
+	char *last_slash = NULL;
+	char *orig_lcomp;
+	char *fname = NULL;
+	NTSTATUS status;
+
+	if (ucf_flags & UCF_DFS_PATHNAME) {
+		status = resolve_dfspath_wcard(ctx,
+				conn,
+				filename_in,
+				ucf_flags,
+				!conn->sconn->using_smb2,
+				&fname,
+				NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			DBG_DEBUG("resolve_dfspath "
+				"failed for name %s with %s\n",
+				filename_in,
+				nt_errstr(status));
+			return NULL;
+		}
+		filename_in = fname;
+		ucf_flags &= ~UCF_DFS_PATHNAME;
+	}
+
+	/*
+	 * NB. We don't need to care about
+	 * is_fake_file_path(filename_in) here as these
+	 * code paths don't ever return original_lcomp
+	 * or use it anyway.
+	 */
+
+	if (ucf_flags & UCF_GMT_PATHNAME) {
+		/*
+		 * Ensure we don't return a @GMT
+		 * value as the last component.
+		 */
+		smb_fname = synthetic_smb_fname(ctx,
+					filename_in,
+					NULL,
+					NULL,
+					0);
+		if (smb_fname == NULL) {
+			TALLOC_FREE(fname);
+			return NULL;
+		}
+		status = canonicalize_snapshot_path(smb_fname);
+		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(fname);
+			TALLOC_FREE(smb_fname);
+			return NULL;
+		}
+		filename_in = smb_fname->base_name;
+	}
+	last_slash = strrchr(filename_in, '/');
+	if (last_slash != NULL) {
+		orig_lcomp = talloc_strdup(ctx, last_slash+1);
+	} else {
+		orig_lcomp = talloc_strdup(ctx, filename_in);
+	}
+	/* We're done with any temp names here. */
+	TALLOC_FREE(smb_fname);
+	TALLOC_FREE(fname);
+	if (orig_lcomp == NULL) {
+		return NULL;
+	}
+	status = normalize_filename_case(conn, orig_lcomp);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(orig_lcomp);
+		return NULL;
+	}
+	return orig_lcomp;
+}
+
 /**
  * Go through all the steps to validate a filename.
  *
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index d169a59a620..001dbe2a79d 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1585,6 +1585,7 @@ void reply_ntrename(struct smb_request *req)
 	struct smb_filename *smb_fname_new = NULL;
 	char *oldname = NULL;
 	char *newname = NULL;
+	const char *dst_original_lcomp = NULL;
 	const char *p;
 	NTSTATUS status;
 	bool src_has_wcard = False;
@@ -1645,7 +1646,7 @@ void reply_ntrename(struct smb_request *req)
 	 */
 	if (rename_type == RENAME_FLAG_RENAME) {
 		ucf_flags_src |= UCF_COND_ALLOW_WCARD_LCOMP;
-		ucf_flags_dst |= UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP;
+		ucf_flags_dst |= UCF_COND_ALLOW_WCARD_LCOMP;
 	}
 
 	/* rename_internals() calls unix_convert(), so don't call it here. */
@@ -1685,6 +1686,16 @@ void reply_ntrename(struct smb_request *req)
 		goto out;
 	}
 
+	/* Get the last component of the destination for rename_internals(). */
+	dst_original_lcomp = get_original_lcomp(ctx,
+					conn,
+					newname,
+					ucf_flags_dst);
+	if (dst_original_lcomp == NULL) {
+		reply_nterror(req, NT_STATUS_NO_MEMORY);
+		goto out;
+	}
+
 	if (stream_rename) {
 		/* smb_fname_new must be the same as smb_fname_old. */
 		TALLOC_FREE(smb_fname_new->base_name);
@@ -1702,11 +1713,17 @@ void reply_ntrename(struct smb_request *req)
 
 	switch(rename_type) {
 		case RENAME_FLAG_RENAME:
-			status = rename_internals(ctx, conn, req,
-						  smb_fname_old, smb_fname_new,
-						  attrs, False, src_has_wcard,
-						  dest_has_wcard,
-						  DELETE_ACCESS);
+			status = rename_internals(ctx,
+						conn,
+						req,
+						smb_fname_old,
+						smb_fname_new,
+						dst_original_lcomp,
+						attrs,
+						false,
+						src_has_wcard,
+						dest_has_wcard,
+						DELETE_ACCESS);
 			break;
 		case RENAME_FLAG_HARD_LINK:
 			if (src_has_wcard || dest_has_wcard) {
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index c79e82fb69d..cb32ebaca5e 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -357,6 +357,10 @@ NTSTATUS check_name(connection_struct *conn,
 int get_real_filename(connection_struct *conn, const char *path,
 		      const char *name, TALLOC_CTX *mem_ctx,
 		      char **found_name);
+char *get_original_lcomp(TALLOC_CTX *ctx,
+			connection_struct *conn,
+			const char *filename_in,
+			uint32_t ucf_flags);
 NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
 			connection_struct *conn,
 			const char *name_in,
@@ -1014,6 +1018,7 @@ void reply_rmdir(struct smb_request *req);
 NTSTATUS rename_internals_fsp(connection_struct *conn,
 			files_struct *fsp,
 			const struct smb_filename *smb_fname_dst_in,
+			const char *dst_original_lcomp,
 			uint32_t attrs,
 			bool replace_if_exists);
 NTSTATUS rename_internals(TALLOC_CTX *ctx,
@@ -1021,6 +1026,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
 			struct smb_request *req,
 			struct smb_filename *smb_fname_src,
 			struct smb_filename *smb_fname_dst,
+			const char *dst_original_lcomp,
 			uint32_t attrs,
 			bool replace_if_exists,
 			bool src_has_wild,
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 58bc7d05eab..b23a2d373b2 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -7575,6 +7575,7 @@ static NTSTATUS parent_dirname_compatible_open(connection_struct *conn,
 NTSTATUS rename_internals_fsp(connection_struct *conn,
 			files_struct *fsp,
 			const struct smb_filename *smb_fname_dst_in,
+			const char *dst_original_lcomp,
 			uint32_t attrs,
 			bool replace_if_exists)
 {
@@ -7627,7 +7628,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 		/*
 		 * Split off the last component of the processed
 		 * destination name. We will compare this to
-		 * the split components of smb_fname_dst->original_lcomp.
+		 * the split components of dst_original_lcomp.
 		 */
 		if (!parent_dirname(ctx,
 				smb_fname_dst->base_name,
@@ -7638,7 +7639,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 		}
 
 		/*
-		 * The original_lcomp component contains
+		 * The dst_original_lcomp component contains
 		 * the last_component of the path + stream
 		 * name (if a stream exists).
 		 *
@@ -7649,13 +7650,13 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 		if (fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) {
 			/* POSIX - no stream component. */
 			orig_lcomp_path = talloc_strdup(ctx,
-						smb_fname_dst->original_lcomp);
+						dst_original_lcomp);
 			if (orig_lcomp_path == NULL) {
 				ok = false;
 			}
 		} else {
 			ok = split_stream_filename(ctx,
-					smb_fname_dst->original_lcomp,
+					dst_original_lcomp,
 					&orig_lcomp_path,
 					&orig_lcomp_stream);
 		}
@@ -7899,6 +7900,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
 			struct smb_request *req,
 			struct smb_filename *smb_fname_src,
 			struct smb_filename *smb_fname_dst,
+			const char *dst_original_lcomp,
 			uint32_t attrs,
 			bool replace_if_exists,
 			bool src_has_wild,
@@ -7997,7 +7999,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
 			  conn->short_case_preserve,
 			  smb_fname_str_dbg(smb_fname_src),
 			  smb_fname_str_dbg(smb_fname_dst),
-			  smb_fname_dst->original_lcomp));
+			  dst_original_lcomp));
 
 		/* The dest name still may have wildcards. */
 		if (dest_has_wild) {
@@ -8061,8 +8063,12 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
 			goto out;
 		}
 
-		status = rename_internals_fsp(conn, fsp, smb_fname_dst,
-					      attrs, replace_if_exists);
+		status = rename_internals_fsp(conn,
+					fsp,
+					smb_fname_dst,
+					dst_original_lcomp,
+					attrs,
+					replace_if_exists);
 
 		close_file(req, fsp, NORMAL_CLOSE);
 
@@ -8222,15 +8228,18 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
 			break;
 		}
 
-		smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
-							      dname);
-		if (!smb_fname_dst->original_lcomp) {
+		dst_original_lcomp = talloc_strdup(smb_fname_dst, dname);
+		if (dst_original_lcomp == NULL) {
 			status = NT_STATUS_NO_MEMORY;
 			goto out;
 		}
 
-		status = rename_internals_fsp(conn, fsp, smb_fname_dst,
-					      attrs, replace_if_exists);
+		status = rename_internals_fsp(conn,
+					fsp,
+					smb_fname_dst,
+					dst_original_lcomp,
+					attrs,
+					replace_if_exists);
 
 		close_file(req, fsp, NORMAL_CLOSE);
 
@@ -8281,12 +8290,12 @@ void reply_mv(struct smb_request *req)
 	TALLOC_CTX *ctx = talloc_tos();
 	struct smb_filename *smb_fname_src = NULL;
 	struct smb_filename *smb_fname_dst = NULL;
+	const char *dst_original_lcomp = NULL;
 	uint32_t src_ucf_flags = ucf_flags_from_smb_request(req) |
 		(req->posix_pathnames ?
 			UCF_UNIX_NAME_LOOKUP :
 			UCF_COND_ALLOW_WCARD_LCOMP);
 	uint32_t dst_ucf_flags = ucf_flags_from_smb_request(req) |
-		UCF_SAVE_LCOMP |
 		(req->posix_pathnames ?
 			0 :
 			UCF_COND_ALLOW_WCARD_LCOMP);
@@ -8364,6 +8373,16 @@ void reply_mv(struct smb_request *req)
 		goto out;
 	}
 
+	/* Get the last component of the destination for rename_internals(). */
+	dst_original_lcomp = get_original_lcomp(ctx,
+					conn,
+					newname,
+					dst_ucf_flags);
+	if (dst_original_lcomp == NULL) {
+		reply_nterror(req, NT_STATUS_NO_MEMORY);
+		goto out;
+	}
+
 	if (stream_rename) {
 		/* smb_fname_dst->base_name must be the same as
 		   smb_fname_src->base_name. */
@@ -8379,9 +8398,17 @@ void reply_mv(struct smb_request *req)
 	DEBUG(3,("reply_mv : %s -> %s\n", smb_fname_str_dbg(smb_fname_src),
 		 smb_fname_str_dbg(smb_fname_dst)));
 
-	status = rename_internals(ctx, conn, req, smb_fname_src, smb_fname_dst,
-				  attrs, False, src_has_wcard, dest_has_wcard,
-				  DELETE_ACCESS);
+	status = rename_internals(ctx,
+				conn,
+				req,
+				smb_fname_src,
+				smb_fname_dst,
+				dst_original_lcomp,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list