[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Wed May 30 19:47:03 UTC 2018


The branch, master has been updated
       via  003f24e selftest: Fix resolv_wrapper config variables
       via  465b7d0 s3:smbd: don't allow renaming basefile if streams are open
       via  dd8cf54 s3:locking: add file_has_open_streams()
       via  37e7ff0 s3:smbd: add private option NTCREATEX_OPTIONS_PRIVATE_STREAM_BASEOPEN
       via  f166207 s4:torture/vfs/fruit: adjust test testing basefile rename to expect failure
       via  00d19bd s4:torture/smb2/streams: try to rename basefile while is has open streams
       via  aa096ab selftest: run smb2.streams tests against a share with vfs_streams_xattr
      from  0196318 dsdb: Add log when ignoring a replicated object outside of partition

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


- Log -----------------------------------------------------------------
commit 003f24ee43c733de6c625f708c2ae665d44d1d1f
Author: Volker Lendecke <vl at samba.org>
Date:   Wed May 30 17:03:55 2018 +0200

    selftest: Fix resolv_wrapper config variables
    
    It can't really matter in this case, but it removes confusion
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed May 30 21:46:53 CEST 2018 on sn-devel-144

commit 465b7d07e5db787c3d6330371e5e42ecbb1b57b9
Author: Ralph Boehme <slow at samba.org>
Date:   Sat May 26 18:32:21 2018 +0200

    s3:smbd: don't allow renaming basefile if streams are open
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13451
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit dd8cf54c79fe8536e34cde15801d60931cd47b8b
Author: Ralph Boehme <slow at samba.org>
Date:   Sun May 27 13:03:25 2018 +0200

    s3:locking: add file_has_open_streams()
    
    This can be used to check if a file opened by fsp also has stream opens.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13451
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 37e7ff05ab9443c0330e68f5c701ffecedf2d738
Author: Ralph Boehme <slow at samba.org>
Date:   Sun May 27 13:01:50 2018 +0200

    s3:smbd: add private option NTCREATEX_OPTIONS_PRIVATE_STREAM_BASEOPEN
    
    This will be used to mark basefile opens of streams opens. This is
    needed to later implement a function that can determine if a file has
    stream opens.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13451
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f166207fc0344b51879d863857055ab7ff36a09b
Author: Ralph Boehme <slow at samba.org>
Date:   Sat May 26 18:33:00 2018 +0200

    s4:torture/vfs/fruit: adjust test testing basefile rename to expect failure
    
    Renaming a basefile that has open streams must fail with
    NT_STATUS_ACCESS_DENIED.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13451
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 00d19bdab15102083b8ba395ede161824c898be1
Author: Ralph Boehme <slow at samba.org>
Date:   Sat May 26 16:07:14 2018 +0200

    s4:torture/smb2/streams: try to rename basefile while is has open streams
    
    This tests the following:
    
    - create a file with a stream
    - open the the stream and keep it open
    - on a second connection, try to rename the basefile, this should fail
      with NT_STATUS_ACCESS_DENIED
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13451
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit aa096ab70a466388a9947f73a525b2dcbb9821e5
Author: Ralph Boehme <slow at samba.org>
Date:   Sat May 26 16:30:47 2018 +0200

    selftest: run smb2.streams tests against a share with vfs_streams_xattr
    
    The tests are currently only run against streams_depot, where stream IO
    is handle based, compared to streams_xattr which is path
    based. vfs_streams_xattr is also used much more in real world setups, so
    we should run our tests against it.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13451
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 selftest/knownfail             |  3 ++
 selftest/target/Samba3.pm      |  4 +--
 source3/include/smb.h          |  3 ++
 source3/locking/locking.c      | 31 ++++++++++++++++
 source3/locking/proto.h        |  1 +
 source3/selftest/tests.py      |  4 +++
 source3/smbd/open.c            |  7 +++-
 source3/smbd/reply.c           |  4 +++
 source4/torture/smb2/streams.c | 82 ++++++++++++++++++++++++++++++++++++++++++
 source4/torture/vfs/fruit.c    | 25 +++----------
 10 files changed, 140 insertions(+), 24 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/knownfail b/selftest/knownfail
index f718f45..97bdd71 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -177,6 +177,9 @@
 ^samba3.smb2.streams.rename
 ^samba3.smb2.streams.rename2
 ^samba3.smb2.streams.attributes
+^samba3.smb2.streams streams_xattr.rename\(nt4_dc\)
+^samba3.smb2.streams streams_xattr.rename2\(nt4_dc\)
+^samba3.smb2.streams streams_xattr.attributes\(nt4_dc\)
 ^samba3.smb2.getinfo.complex
 ^samba3.smb2.getinfo.fsinfo # quotas don't work yet
 ^samba3.smb2.setinfo.setinfo
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index c6ae7ab..a553405 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -2269,9 +2269,9 @@ force_user:x:$gid_force_user:
 	$createuser_env{NSS_WRAPPER_HOSTS} = $nss_wrapper_hosts;
 	$createuser_env{NSS_WRAPPER_HOSTNAME} = "${hostname}.samba.example.com";
 	if ($ENV{SAMBA_DNS_FAKING}) {
-		$createuser_env{RESOLV_WRAPPER_CONF} = $resolv_conf;
-	} else {
 		$createuser_env{RESOLV_WRAPPER_HOSTS} = $dns_host_file;
+	} else {
+		$createuser_env{RESOLV_WRAPPER_CONF} = $resolv_conf;
 	}
 
 	createuser($self, $unix_name, $password, $conffile, \%createuser_env) || die("Unable to create user");
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 3316f09..5e83ee9 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -419,6 +419,9 @@ Offset  Data			length.
 /* Private options for printer support */
 #define NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE 0x0008
 
+/* Private option for streams support */
+#define NTCREATEX_OPTIONS_PRIVATE_STREAM_BASEOPEN 0x0010
+
 /* Flag for NT transact rename call. */
 #define RENAME_REPLACE_IF_EXISTS 1
 
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 791878c..e962fee 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -1316,3 +1316,34 @@ struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
 	}
 	return d->old_write_time;
 }
+
+bool file_has_open_streams(files_struct *fsp)
+{
+	struct share_mode_lock *lock = NULL;
+	struct share_mode_data *d = NULL;
+	uint32_t i;
+
+	lock = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
+	if (lock == NULL) {
+		return false;
+	}
+	d = lock->data;
+
+	for (i = 0; i < d->num_share_modes; i++) {
+		struct share_mode_entry *e = &d->share_modes[i];
+
+		if (share_mode_stale_pid(d, i)) {
+			continue;
+		}
+
+		if (e->private_options &
+		    NTCREATEX_OPTIONS_PRIVATE_STREAM_BASEOPEN)
+		{
+			TALLOC_FREE(lock);
+			return true;
+		}
+	}
+
+	TALLOC_FREE(lock);
+	return false;
+}
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index afd5373..403729c 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -207,6 +207,7 @@ bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash);
 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time);
 bool set_write_time(struct file_id fileid, struct timespec write_time);
 struct timespec get_share_mode_write_time(struct share_mode_lock *lck);
+bool file_has_open_streams(files_struct *fsp);
 int share_mode_forall(int (*fn)(struct file_id fid,
 				const struct share_mode_data *data,
 				void *private_data),
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index bd84d00..983f0ac 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -568,6 +568,10 @@ for t in tests:
         plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%%$PASSWORD '
                                     '--option=torture:smburl=smb://$USERNAME:$PASSWORD@$SERVER/tmp '
                                     '--option=torture:replace_smbconf=%s' % os.path.join(srcdir(), "testdata/samba3/smb_new.conf"))
+    elif t == "smb2.streams":
+        plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
+        plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
+        plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/streams_xattr -U$USERNAME%$PASSWORD', 'streams_xattr')
     else:
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
         plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index c54d380..4b28e7f 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -5144,6 +5144,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
 	    && (!(private_flags & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
 		uint32_t base_create_disposition;
 		struct smb_filename *smb_fname_base = NULL;
+		uint32_t base_privflags;
 
 		if (create_options & FILE_DIRECTORY_FILE) {
 			status = NT_STATUS_NOT_A_DIRECTORY;
@@ -5194,13 +5195,17 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
 			}
 		}
 
+		base_privflags = NTCREATEX_OPTIONS_PRIVATE_STREAM_BASEOPEN;
+
 		/* Open the base file. */
 		status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
 					      FILE_SHARE_READ
 					      | FILE_SHARE_WRITE
 					      | FILE_SHARE_DELETE,
 					      base_create_disposition,
-					      0, 0, 0, NULL, 0, 0, NULL, NULL,
+					      0, 0, 0, NULL, 0,
+					      base_privflags,
+					      NULL, NULL,
 					      &base_fsp, NULL);
 		TALLOC_FREE(smb_fname_base);
 
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index fc56e32..1b99664 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -6643,6 +6643,10 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 		return status;
 	}
 
+	if (file_has_open_streams(fsp)) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	/* Make a copy of the dst smb_fname structs */
 
 	smb_fname_dst = cp_smb_filename(ctx, smb_fname_dst_in);
diff --git a/source4/torture/smb2/streams.c b/source4/torture/smb2/streams.c
index d302bf9..b39d96d 100644
--- a/source4/torture/smb2/streams.c
+++ b/source4/torture/smb2/streams.c
@@ -1830,6 +1830,86 @@ done:
 	return ret;
 }
 
+static bool test_basefile_rename_with_open_stream(struct torture_context *tctx,
+						  struct smb2_tree *tree)
+{
+	bool ret = true;
+	NTSTATUS status;
+	struct smb2_tree *tree2 = NULL;
+	struct smb2_create create, create2;
+	struct smb2_handle h1 = {{0}}, h2 = {{0}};
+	const char *fname = "test_rename_openfile";
+	const char *sname = "test_rename_openfile:foo";
+	const char *fname_renamed = "test_rename_openfile_renamed";
+	union smb_setfileinfo sinfo;
+	const char *data = "test data";
+
+	ret = torture_smb2_connection(tctx, &tree2);
+	torture_assert_goto(tctx, ret == true, ret, done,
+			    "torture_smb2_connection failed\n");
+
+	torture_comment(tctx, "Creating file with stream\n");
+
+	ZERO_STRUCT(create);
+	create.in.desired_access = SEC_FILE_ALL;
+	create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+	create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+	create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+	create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
+	create.in.fname = sname;
+
+	status = smb2_create(tree, tctx, &create);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_create failed\n");
+
+	h1 = create.out.file.handle;
+
+	torture_comment(tctx, "Writing to stream\n");
+
+	status = smb2_util_write(tree, h1, data, 0, strlen(data));
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_util_write failed\n");
+
+	torture_comment(tctx, "Renaming base file\n");
+
+	ZERO_STRUCT(create2);
+	create2.in.desired_access = SEC_FILE_ALL;
+	create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+	create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+	create2.in.create_disposition = NTCREATEX_DISP_OPEN;
+	create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
+	create2.in.fname = fname;
+
+	status = smb2_create(tree2, tctx, &create2);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_create failed\n");
+
+	h2 = create2.out.file.handle;
+
+	ZERO_STRUCT(sinfo);
+	sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
+	sinfo.rename_information.in.file.handle = h2;
+	sinfo.rename_information.in.new_name = fname_renamed;
+
+	status = smb2_setinfo_file(tree2, &sinfo);
+	torture_assert_ntstatus_equal_goto(
+		tctx, status, NT_STATUS_ACCESS_DENIED, ret, done,
+		"smb2_setinfo_file didn't return NT_STATUS_ACCESS_DENIED\n");
+
+	smb2_util_close(tree2, h2);
+
+done:
+	if (!smb2_util_handle_empty(h1)) {
+		smb2_util_close(tree, h1);
+	}
+	if (!smb2_util_handle_empty(h2)) {
+		smb2_util_close(tree2, h2);
+	}
+	smb2_util_unlink(tree, fname);
+	smb2_util_unlink(tree, fname_renamed);
+
+	return ret;
+}
 
 /*
    basic testing of streams calls SMB2
@@ -1850,6 +1930,8 @@ struct torture_suite *torture_smb2_streams_init(TALLOC_CTX *ctx)
 	torture_suite_add_1smb2_test(suite, "attributes", test_stream_attributes);
 	torture_suite_add_1smb2_test(suite, "delete", test_stream_delete);
 	torture_suite_add_1smb2_test(suite, "zero-byte", test_zero_byte_stream);
+	torture_suite_add_1smb2_test(suite, "basefile-rename-with-open-stream",
+					test_basefile_rename_with_open_stream);
 
 	suite->description = talloc_strdup(suite, "SMB2-STREAM tests");
 
diff --git a/source4/torture/vfs/fruit.c b/source4/torture/vfs/fruit.c
index 14191fd0..4c49a6b 100644
--- a/source4/torture/vfs/fruit.c
+++ b/source4/torture/vfs/fruit.c
@@ -3902,7 +3902,6 @@ static bool test_rename_and_read_rsrc(struct torture_context *tctx,
 	const char *fname_renamed = "test_rename_openfile_renamed";
 	const char *data = "1234567890";
 	union smb_setfileinfo sinfo;
-	struct smb2_read r;
 
 	ret = enable_aapl(tctx, tree);
 	torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
@@ -3954,28 +3953,12 @@ static bool test_rename_and_read_rsrc(struct torture_context *tctx,
 	sinfo.rename_information.in.new_name = fname_renamed;
 
 	status = smb2_setinfo_file(tree, &sinfo);
-	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file failed");
-
-	smb2_util_close(tree, h2);
-
-	ZERO_STRUCT(r);
-	r.in.file.handle = h1;
-	r.in.length      = 10;
-	r.in.offset      = 0;
-
-	torture_comment(tctx, "Read resource fork of renamed file\n");
-
-	status = smb2_read(tree, tree, &r);
-	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read failed");
+	torture_assert_ntstatus_equal_goto(
+		tctx, status, NT_STATUS_ACCESS_DENIED, ret, done,
+		"smb2_setinfo_file failed");
 
 	smb2_util_close(tree, h1);
-
-	torture_assert_goto(tctx, r.out.data.length == 10, ret, done,
-			    talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected 10\n",
-					    (intmax_t)r.out.data.length));
-
-	torture_assert_goto(tctx, memcmp(r.out.data.data, data, 10) == 0, ret, done,
-			    talloc_asprintf(tctx, "Bad data in stream\n"));
+	smb2_util_close(tree, h2);
 
 done:
 	smb2_util_unlink(tree, fname);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list