[SCM] Samba Shared Repository - branch master updated

Noel Power npower at samba.org
Mon May 24 17:48:01 UTC 2021


The branch, master has been updated
       via  1d781bbff84 s3: smbd: Allow SMB1+UNIX extensions rename of dangling symlink.
       via  0c2ceb0435c s3: torture: Add regression test for renaming SMB1+POSIX symlinks, dangling and real.
       via  6917e324660 s3: smbd: Remove use of synthetic_pathref() in rename_internals_fsp().
      from  f96cc297111 smbd: correctly initialize close timestamp fields

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


- Log -----------------------------------------------------------------
commit 1d781bbff84667b3ada4afc06c1d15829754dcb4
Author: Jeremy Allison <jra at samba.org>
Date:   Fri May 21 10:53:49 2021 -0700

    s3: smbd: Allow SMB1+UNIX extensions rename of dangling symlink.
    
    Remove knownfail. Only in master, so no bug number needed.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Noel Power <noel.power at suse.com>
    
    Autobuild-User(master): Noel Power <npower at samba.org>
    Autobuild-Date(master): Mon May 24 17:47:40 UTC 2021 on sn-devel-184

commit 0c2ceb0435c7d03d72c7f9c29b0240f944f6cc42
Author: Jeremy Allison <jra at samba.org>
Date:   Fri May 21 11:14:19 2021 -0700

    s3: torture: Add regression test for renaming SMB1+POSIX symlinks, dangling and real.
    
    Mark as knownfail.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Noel Power <noel.power at suse.com>

commit 6917e3246603b9d84133b10f0415e1cc11d184f7
Author: Jeremy Allison <jra at samba.org>
Date:   Fri May 21 10:27:09 2021 -0700

    s3: smbd: Remove use of synthetic_pathref() in rename_internals_fsp().
    
    As we're renaming an open file we don't need to do another
    open, we already have an fsp here.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Noel Power <noel.power at suse.com>

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

Summary of changes:
 source3/selftest/tests.py    |   1 +
 source3/smbd/reply.c         |  54 +++++++++--------
 source3/torture/proto.h      |   1 +
 source3/torture/test_posix.c | 134 +++++++++++++++++++++++++++++++++++++++++++
 source3/torture/torture.c    |   4 ++
 5 files changed, 169 insertions(+), 25 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 13f0466802e..d4f9ea27ba6 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -265,6 +265,7 @@ posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL", "POSIX-SYMLINK-EA",
                "POSIX-SYMLINK-PARENT",
                "POSIX-SYMLINK-CHMOD",
                "POSIX-DIR-DEFAULT-ACL",
+               "POSIX-SYMLINK-RENAME",
               ]
 
 for t in posix_tests:
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 4ba3b0ee624..1b670020143 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -7829,33 +7829,25 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 		    (lp_map_archive(SNUM(conn)) ||
 		    lp_store_dos_attributes(SNUM(conn))))
 		{
-			struct smb_filename *pathref = NULL;
-			status = synthetic_pathref(ctx,
-						conn->cwd_fsp,
-						smb_fname_dst->base_name,
-						smb_fname_dst->stream_name,
-						NULL,
-						smb_fname_dst->twrp,
-						smb_fname_dst->flags,
-						&pathref);
-			if (NT_STATUS_IS_OK(status)) {
+			/*
+			 * We must set the archive bit on the newly renamed
+			 * file.
+			 */
+			ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
+			if (ret == 0) {
+				uint32_t old_dosmode;
+				old_dosmode = fdos_mode(fsp);
 				/*
-				 * We must set the archive bit on the newly renamed
-				 * file.
+				 * We can use fsp->fsp_name here as it has
+				 * already been changed to the new name.
 				 */
-				ret = SMB_VFS_FSTAT(fsp, &pathref->st);
-				if (ret == 0) {
-					uint32_t old_dosmode;
-					fsp->fsp_name->st = pathref->st;
-					old_dosmode = fdos_mode(fsp);
-					file_set_dosmode(conn,
-							pathref,
-							old_dosmode | FILE_ATTRIBUTE_ARCHIVE,
-							NULL,
-							true);
-				}
+				SMB_ASSERT(fsp->fsp_name->fsp == fsp);
+				file_set_dosmode(conn,
+						fsp->fsp_name,
+						old_dosmode | FILE_ATTRIBUTE_ARCHIVE,
+						NULL,
+						true);
 			}
-			TALLOC_FREE(pathref);
 		}
 
 		/*
@@ -8052,7 +8044,19 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
 
 		status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src);
 		if (!NT_STATUS_IS_OK(status)) {
-			goto out;
+			if (!NT_STATUS_EQUAL(status,
+					NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+				goto out;
+			}
+			/*
+			 * Possible symlink src.
+			 */
+			if (!(smb_fname_src->flags & SMB_FILENAME_POSIX_PATH)) {
+				goto out;
+			}
+			if (!S_ISLNK(smb_fname_src->st.st_ex_mode)) {
+				goto out;
+			}
 		}
 
 		if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
diff --git a/source3/torture/proto.h b/source3/torture/proto.h
index bc2d8c7b3f2..4e813c473b1 100644
--- a/source3/torture/proto.h
+++ b/source3/torture/proto.h
@@ -93,6 +93,7 @@ bool run_posix_symlink_parent_test(int dummy);
 bool run_posix_symlink_chmod_test(int dummy);
 bool run_posix_dir_default_acl_test(int dummy);
 bool run_case_insensitive_create(int dummy);
+bool run_posix_symlink_rename_test(int dummy);
 
 bool run_nbench2(int dummy);
 bool run_async_echo(int dummy);
diff --git a/source3/torture/test_posix.c b/source3/torture/test_posix.c
index 8c1306c5066..dc25db4c985 100644
--- a/source3/torture/test_posix.c
+++ b/source3/torture/test_posix.c
@@ -1309,3 +1309,137 @@ out:
 	TALLOC_FREE(frame);
 	return correct;
 }
+
+/*
+  Ensure we can rename a symlink whether it is
+  pointing to a real object or dangling.
+ */
+bool run_posix_symlink_rename_test(int dummy)
+{
+	TALLOC_CTX *frame = NULL;
+	struct cli_state *cli_unix = NULL;
+	NTSTATUS status;
+	uint16_t fnum = (uint16_t)-1;
+	const char *fname_real = "file_real";
+	const char *fname_real_symlink = "file_real_symlink";
+	const char *fname_real_symlink_newname = "rename_file_real_symlink";
+	const char *nonexist = "nonexist";
+	const char *nonexist_symlink = "dangling_symlink";
+	const char *nonexist_symlink_newname = "dangling_symlink_rename";
+	bool correct = false;
+
+	frame = talloc_stackframe();
+
+	printf("Starting POSIX-SYMLINK-RENAME test\n");
+
+	if (!torture_open_connection(&cli_unix, 0)) {
+		TALLOC_FREE(frame);
+		return false;
+	}
+
+	torture_conn_set_sockopt(cli_unix);
+
+	status = torture_setup_unix_extensions(cli_unix);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(frame);
+		return false;
+	}
+
+	/* Start with a clean slate. */
+	cli_posix_unlink(cli_unix, fname_real);
+	cli_posix_unlink(cli_unix, fname_real_symlink);
+	cli_posix_unlink(cli_unix, fname_real_symlink_newname);
+	cli_posix_unlink(cli_unix, nonexist);
+	cli_posix_unlink(cli_unix, nonexist_symlink);
+	cli_posix_unlink(cli_unix, nonexist_symlink_newname);
+
+	/* Create a real file. */
+	status = cli_posix_open(cli_unix,
+				fname_real,
+				O_RDWR|O_CREAT,
+				0644,
+				&fnum);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("cli_posix_open of %s failed error %s\n",
+		       fname_real,
+		       nt_errstr(status));
+		goto out;
+	}
+	status = cli_close(cli_unix, fnum);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("cli_close failed %s\n", nt_errstr(status));
+		goto out;
+	}
+	fnum = (uint16_t)-1;
+
+	/* Create symlink to real target. */
+	status = cli_posix_symlink(cli_unix,
+				   fname_real,
+				   fname_real_symlink);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("cli_posix_symlink of %s -> %s failed error %s\n",
+		       fname_real_symlink,
+		       fname_real,
+		       nt_errstr(status));
+		goto out;
+	}
+
+	/* Ensure we can rename the symlink to the real file. */
+	status = cli_rename(cli_unix,
+				fname_real_symlink,
+				fname_real_symlink_newname,
+				false);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("cli_rename of %s -> %s failed %s\n",
+			fname_real_symlink,
+			fname_real_symlink_newname,
+			nt_errstr(status));
+		goto out;
+	}
+
+	/* Now create symlink to non-existing target. */
+	status = cli_posix_symlink(cli_unix,
+				   nonexist,
+				   nonexist_symlink);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("cli_posix_symlink of %s -> %s failed error %s\n",
+		       nonexist_symlink,
+		       nonexist,
+		       nt_errstr(status));
+		goto out;
+	}
+
+	/* Ensure we can rename the dangling symlink. */
+	status = cli_rename(cli_unix,
+				nonexist_symlink,
+				nonexist_symlink_newname,
+				false);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("cli_rename of %s -> %s failed %s\n",
+			nonexist_symlink,
+			nonexist_symlink_newname,
+			nt_errstr(status));
+		goto out;
+	}
+
+	printf("POSIX-SYMLINK-RENAME test passed\n");
+	correct = true;
+
+out:
+	if (fnum != (uint16_t)-1) {
+		cli_close(cli_unix, fnum);
+	}
+	cli_posix_unlink(cli_unix, fname_real);
+	cli_posix_unlink(cli_unix, fname_real_symlink);
+	cli_posix_unlink(cli_unix, fname_real_symlink_newname);
+	cli_posix_unlink(cli_unix, nonexist);
+	cli_posix_unlink(cli_unix, nonexist_symlink);
+	cli_posix_unlink(cli_unix, nonexist_symlink_newname);
+
+	if (!torture_close_connection(cli_unix)) {
+		correct = false;
+	}
+
+	TALLOC_FREE(frame);
+	return correct;
+}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 06bb44943e6..914c7705faf 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -14955,6 +14955,10 @@ static struct {
 		.name  = "POSIX-SYMLINK-CHMOD",
 		.fn    = run_posix_symlink_chmod_test,
 	},
+	{
+		.name  = "POSIX-SYMLINK-RENAME",
+		.fn    = run_posix_symlink_rename_test,
+	},
 	{
 		.name  = "POSIX-DIR-DEFAULT-ACL",
 		.fn    = run_posix_dir_default_acl_test,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list