[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Sun Oct 30 13:18:03 MDT 2011


The branch, master has been updated
       via  a354758 s4:torture:smb2: add durable_open_basic2 test: test durable open against all lease types
       via  976f980 s4:torture:smb2: add a new durable_open_basic1 test: test open against all oplock types
       via  f8aeca1 s4:torture:smb2: check wheter open was durable in existing tests
       via  530cd2a s4:libcli: in smb2_create_recv, map SMB2_CREATE_DURABLE_HANDLE_RESPONSE buffer smb2_create.out.durable_open
       via  d01b248 source4/libcli: add bool durable_open to smb2_create.out.
       via  de967f2 s4:torture: test also break semantics between batch-oplocks and leases
       via  69ca2bd s4:torture:smb2: adapt comment in durable-open.lease test according to current information.
       via  5975e8a s4:torture:smb2: fix the durable_open test to succeed against w7 and w2k8r2
      from  f30f71c Fix bug #8548 - winbind_samlogon_retry_loop ignores logon_parameters flags.

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


- Log -----------------------------------------------------------------
commit a354758da50d09341bbea237548de52e3821a198
Author: Michael Adam <obnox at samba.org>
Date:   Sat Oct 29 17:28:38 2011 +0200

    s4:torture:smb2: add durable_open_basic2 test: test durable open against all lease types
    
    Autobuild-User: Michael Adam <obnox at samba.org>
    Autobuild-Date: Sun Oct 30 20:17:16 CET 2011 on sn-devel-104

commit 976f9806c9255202bd3c3d2f927d2d854f7034f8
Author: Michael Adam <obnox at samba.org>
Date:   Sat Oct 29 17:26:53 2011 +0200

    s4:torture:smb2: add a new durable_open_basic1 test: test open against all oplock types

commit f8aeca1018cf036b3294f2d6807fd35b2de2c44b
Author: Michael Adam <obnox at samba.org>
Date:   Sat Oct 29 17:25:00 2011 +0200

    s4:torture:smb2: check wheter open was durable in existing tests

commit 530cd2aac6178570c182b6f33364c7d3c6316c00
Author: Michael Adam <obnox at samba.org>
Date:   Sat Oct 29 13:18:05 2011 +0200

    s4:libcli: in smb2_create_recv, map SMB2_CREATE_DURABLE_HANDLE_RESPONSE buffer smb2_create.out.durable_open

commit d01b248d4f6260c9d67a82e6497f8f4c99666a4c
Author: Michael Adam <obnox at samba.org>
Date:   Sat Oct 29 13:16:07 2011 +0200

    source4/libcli: add bool durable_open to smb2_create.out.
    
    The server gives indication whether the open was durable
    we should record this.

commit de967f22fc9e5a6f9f95be90e882935761295917
Author: Michael Adam <obnox at samba.org>
Date:   Sat Oct 29 14:48:58 2011 +0200

    s4:torture: test also break semantics between batch-oplocks and leases
    
    This must have been a typo (listing EXCLUSIVE twice).
    But BATCH and EXCLUSIVE oplocks apparently share the
    same break semantics with respect to leases.

commit 69ca2bd048fa8ec98ab668baf651d3e84f7e919c
Author: Michael Adam <obnox at samba.org>
Date:   Sun Oct 30 18:40:00 2011 +0100

    s4:torture:smb2: adapt comment in durable-open.lease test according to current information.

commit 5975e8a3f46f3d6f99d997d36f874141f80b9c33
Author: Michael Adam <obnox at samba.org>
Date:   Sat Oct 29 11:56:48 2011 +0200

    s4:torture:smb2: fix the durable_open test to succeed against w7 and w2k8r2
    
    When a first client that has a durable open with share read/write/delete
    and a read-write-handle lease on the file disconnects, a second
    client will succeed in opening the file and the new client will be
    given a RWH-lease if requested, not only a RH-lease, as was previously
    checked in the test.
    
    This might have been a bug in win7 build 7000, which is what the
    comments in the test give as reference.

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

Summary of changes:
 source4/libcli/raw/interfaces.h     |    1 +
 source4/libcli/smb2/create.c        |    7 +
 source4/torture/smb2/durable_open.c |  270 ++++++++++++++++++++++++++++++++++-
 source4/torture/smb2/lease.c        |    2 +-
 4 files changed, 278 insertions(+), 2 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 7bb5255..7aba48b 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -1741,6 +1741,7 @@ union smb_open {
 			uint32_t maximal_access;
 			uint8_t on_disk_id[32];
 			struct smb2_lease lease_response;
+			bool durable_open;
 
 			/* tagged blobs in the reply */
 			struct smb2_create_blobs blobs;
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index 4e15064..438651f 100644
--- a/source4/libcli/smb2/create.c
+++ b/source4/libcli/smb2/create.c
@@ -274,6 +274,13 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
 			io->out.lease_response.lease_flags = IVAL(data, 20);
 			io->out.lease_response.lease_duration = BVAL(data, 24);
 		}
+		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_DHNQ) == 0) {
+			if (io->out.blobs.blobs[i].data.length != 8) {
+				smb2_request_destroy(req);
+				return NT_STATUS_INVALID_NETWORK_RESPONSE;
+			}
+			io->out.durable_open = true;
+		}
 	}
 
 	data_blob_free(&blob);
diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c
index 544f404..33ce1e9 100644
--- a/source4/torture/smb2/durable_open.c
+++ b/source4/torture/smb2/durable_open.c
@@ -49,6 +49,261 @@
 		CHECK_VAL((__io)->out.reserved2, 0);			\
 	} while(0)
 
+
+static inline uint32_t map_lease(const char *ls)
+{
+	uint32_t val = 0;
+	int i;
+
+	for (i = 0; i < strlen(ls); i++) {
+		switch (ls[i]) {
+		case 'R':
+			val |= SMB2_LEASE_READ;
+			break;
+		case 'H':
+			val |= SMB2_LEASE_HANDLE;
+			break;
+		case 'W':
+			val |= SMB2_LEASE_WRITE;
+			break;
+		}
+	}
+
+	return val;
+}
+
+/**
+ * basic durable_open test.
+ * durable state should only be granted when requested
+ * along with a batch oplock or a handle lease.
+ *
+ * This test tests durable open with all possible oplock types.
+ */
+
+struct durable_open_vs_oplock {
+	uint8_t level;
+	bool expected;
+};
+
+#define NUM_OPLOCK_OPEN_TESTS 4
+struct durable_open_vs_oplock durable_open_vs_oplock_table[NUM_OPLOCK_OPEN_TESTS] =
+{
+	{ SMB2_OPLOCK_LEVEL_NONE, false },
+	{ SMB2_OPLOCK_LEVEL_II, false },
+	{ SMB2_OPLOCK_LEVEL_EXCLUSIVE, false },
+	{ SMB2_OPLOCK_LEVEL_BATCH, true },
+};
+
+static bool test_one_durable_open_basic1(struct torture_context *tctx,
+					 struct smb2_tree *tree,
+					 const char *fname,
+					 struct smb2_create io,
+					 struct durable_open_vs_oplock test)
+{
+	NTSTATUS status;
+	TALLOC_CTX *mem_ctx = talloc_new(tctx);
+	struct smb2_handle _h;
+	struct smb2_handle *h = NULL;
+	bool ret = true;
+
+	smb2_util_unlink(tree, fname);
+
+	io.in.fname = fname;
+	io.in.oplock_level = test.level;
+	status = smb2_create(tree, mem_ctx, &io);
+	CHECK_STATUS(status, NT_STATUS_OK);
+	_h = io.out.file.handle;
+	h = &_h;
+	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+	CHECK_VAL(io.out.durable_open, test.expected);
+	CHECK_VAL(io.out.oplock_level, test.level);
+
+done:
+	if (h != NULL) {
+		smb2_util_close(tree, *h);
+	}
+	smb2_util_unlink(tree, fname);
+	talloc_free(mem_ctx);
+
+	return ret;
+}
+
+bool test_durable_open_basic1(struct torture_context *tctx,
+			      struct smb2_tree *tree)
+{
+	TALLOC_CTX *mem_ctx = talloc_new(tctx);
+	struct smb2_create io;
+	char fname[256];
+	bool ret = true;
+	int i;
+
+	/* Choose a random name in case the state is left a little funky. */
+	snprintf(fname, 256, "durable_open_basic1_%s.dat", generate_random_str(tctx, 8));
+
+	smb2_util_unlink(tree, fname);
+
+	ZERO_STRUCT(io);
+	io.in.security_flags		= 0x00;
+	io.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
+	io.in.create_flags		= 0x00000000;
+	io.in.reserved			= 0x00000000;
+	io.in.desired_access		= SEC_RIGHTS_FILE_ALL;
+	io.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
+	io.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
+					  NTCREATEX_SHARE_ACCESS_WRITE |
+					  NTCREATEX_SHARE_ACCESS_DELETE;
+	io.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
+	io.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
+					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
+					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
+					  0x00200000;
+	io.in.durable_open		= true;
+	io.in.fname			= fname;
+
+	/* test various oplock levels with durable open */
+
+	for (i = 0; i < NUM_OPLOCK_OPEN_TESTS; i++) {
+		ret = test_one_durable_open_basic1(tctx,
+						   tree,
+						   fname,
+						   io,
+						   durable_open_vs_oplock_table[i]);
+		if (ret == false) {
+			goto done;
+		}
+	}
+
+done:
+	smb2_util_unlink(tree, fname);
+	talloc_free(tree);
+	talloc_free(mem_ctx);
+
+	return ret;
+}
+
+/**
+ * basic durable_open test.
+ * durable state should only be granted when requested
+ * along with a batch oplock or a handle lease.
+ *
+ * This test tests durable open with all valid lease types.
+ */
+
+struct durable_open_vs_lease {
+	const char *type;
+	bool expected;
+};
+
+#define NUM_LEASE_OPEN_TESTS 5
+struct durable_open_vs_lease durable_open_vs_lease_table[NUM_LEASE_OPEN_TESTS] =
+{
+	{ "", false },
+	{ "R", false },
+	{ "RW", false },
+	{ "RH", true },
+	{ "RHW", true },
+};
+
+static bool test_one_durable_open_basic2(struct torture_context *tctx,
+					 struct smb2_tree *tree,
+					 const char *fname,
+					 struct smb2_create io,
+					 struct durable_open_vs_lease test)
+{
+	NTSTATUS status;
+	TALLOC_CTX *mem_ctx = talloc_new(tctx);
+	struct smb2_handle _h;
+	struct smb2_handle *h = NULL;
+	bool ret = true;
+	struct smb2_lease ls;
+	uint64_t lease;
+
+	smb2_util_unlink(tree, fname);
+
+	io.in.fname = fname;
+	io.in.oplock_level = SMB2_OPLOCK_LEVEL_LEASE;
+
+	lease = random();
+
+	ZERO_STRUCT(ls);
+	ls.lease_key.data[0] = lease;
+	ls.lease_key.data[1] = ~lease;
+	ls.lease_state = map_lease(test.type);
+	io.in.lease_request = &ls;
+
+	status = smb2_create(tree, mem_ctx, &io);
+	CHECK_STATUS(status, NT_STATUS_OK);
+	_h = io.out.file.handle;
+	h = &_h;
+	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+	CHECK_VAL(io.out.durable_open, test.expected);
+	CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
+	CHECK_VAL(io.out.lease_response.lease_key.data[0], lease);
+	CHECK_VAL(io.out.lease_response.lease_key.data[1], ~lease);
+	CHECK_VAL(io.out.lease_response.lease_state, map_lease(test.type));
+done:
+	if (h != NULL) {
+		smb2_util_close(tree, *h);
+	}
+	smb2_util_unlink(tree, fname);
+	talloc_free(mem_ctx);
+
+	return ret;
+}
+
+bool test_durable_open_basic2(struct torture_context *tctx,
+			      struct smb2_tree *tree)
+{
+	TALLOC_CTX *mem_ctx = talloc_new(tctx);
+	struct smb2_create io;
+	char fname[256];
+	bool ret = true;
+	int i;
+
+	/* Choose a random name in case the state is left a little funky. */
+	snprintf(fname, 256, "durable_open_basic2_%s.dat", generate_random_str(tctx, 8));
+
+	smb2_util_unlink(tree, fname);
+
+	ZERO_STRUCT(io);
+	io.in.security_flags		= 0x00;
+	io.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
+	io.in.create_flags		= 0x00000000;
+	io.in.reserved			= 0x00000000;
+	io.in.desired_access		= SEC_RIGHTS_FILE_ALL;
+	io.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
+	io.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
+					  NTCREATEX_SHARE_ACCESS_WRITE |
+					  NTCREATEX_SHARE_ACCESS_DELETE;
+	io.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
+	io.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
+					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
+					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
+					  0x00200000;
+	io.in.durable_open		= true;
+	io.in.fname			= fname;
+
+	/* test various oplock levels with durable open */
+
+	for (i = 0; i < NUM_LEASE_OPEN_TESTS; i++) {
+		ret = test_one_durable_open_basic2(tctx,
+						   tree,
+						   fname,
+						   io,
+						   durable_open_vs_lease_table[i]);
+		if (ret == false) {
+			goto done;
+		}
+	}
+
+done:
+	smb2_util_unlink(tree, fname);
+	talloc_free(tree);
+	talloc_free(mem_ctx);
+
+	return ret;
+}
+
 /*
    basic testing of SMB2 durable opens
    regarding the position information on the handle
@@ -92,6 +347,7 @@ bool test_durable_open_file_position(struct torture_context *tctx,
 	CHECK_STATUS(status, NT_STATUS_OK);
 	h1 = io1.out.file.handle;
 	CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+	CHECK_VAL(io1.out.durable_open, true);
 	CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
 
 	/* TODO: check extra blob content */
@@ -138,6 +394,7 @@ bool test_durable_open_file_position(struct torture_context *tctx,
 
 	status = smb2_create(tree2, mem_ctx, &io2);
 	CHECK_STATUS(status, NT_STATUS_OK);
+	CHECK_VAL(io2.out.durable_open, true);
 	CHECK_VAL(io2.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
 	CHECK_VAL(io2.out.reserved, 0x00);
 	CHECK_VAL(io2.out.create_action, NTCREATEX_ACTION_EXISTED);
@@ -217,6 +474,7 @@ bool test_durable_open_oplock(struct torture_context *tctx,
 	CHECK_STATUS(status, NT_STATUS_OK);
 	h1 = io1.out.file.handle;
 	CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+	CHECK_VAL(io1.out.durable_open, true);
 	CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
 
 	/* Disconnect after getting the batch */
@@ -232,6 +490,7 @@ bool test_durable_open_oplock(struct torture_context *tctx,
 	CHECK_STATUS(status, NT_STATUS_OK);
 	h2 = io2.out.file.handle;
 	CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
+	CHECK_VAL(io2.out.durable_open, true);
 	CHECK_VAL(io2.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
 
 	/* What if tree1 tries to come back and reclaim? */
@@ -321,6 +580,7 @@ bool test_durable_open_lease(struct torture_context *tctx,
 	status = smb2_create(tree1, mem_ctx, &io1);
 	CHECK_STATUS(status, NT_STATUS_OK);
 	h1 = io1.out.file.handle;
+	CHECK_VAL(io1.out.durable_open, true);
 	CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
 
 	CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
@@ -337,17 +597,21 @@ bool test_durable_open_lease(struct torture_context *tctx,
 	 * Windows7 (build 7000) will grant an RH lease immediate (not an RHW?)
 	 * even if the original client is gone. (ZML: This seems like a bug. It
 	 * should give some time for the client to reconnect! And why RH?)
+	 * 
+	 * obnox: Current windows 7 and w2k8r2 grant RHW instead of RH.
+	 * Test is adapted accordingly.
 	 */
 	status = smb2_create(tree2, mem_ctx, &io2);
 	CHECK_STATUS(status, NT_STATUS_OK);
 	h2 = io2.out.file.handle;
+	CHECK_VAL(io2.out.durable_open, true);
 	CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
 
 	CHECK_VAL(io2.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
 	CHECK_VAL(io2.out.lease_response.lease_key.data[0], lease2);
 	CHECK_VAL(io2.out.lease_response.lease_key.data[1], ~lease2);
 	CHECK_VAL(io2.out.lease_response.lease_state,
-	    SMB2_LEASE_READ|SMB2_LEASE_HANDLE);
+	    SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
 
 	/* What if tree1 tries to come back and reclaim? */
 	if (!torture_smb2_connection(tctx, &tree1)) {
@@ -432,6 +696,7 @@ bool test_durable_open_lock(struct torture_context *tctx,
 	h = io.out.file.handle;
 	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
 
+	CHECK_VAL(io.out.durable_open, true);
 	CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
 	CHECK_VAL(io.out.lease_response.lease_key.data[0], lease);
 	CHECK_VAL(io.out.lease_response.lease_key.data[1], ~lease);
@@ -545,6 +810,7 @@ bool test_durable_open_open(struct torture_context *tctx,
 	status = smb2_create(tree1, mem_ctx, &io1);
 	CHECK_STATUS(status, NT_STATUS_OK);
 	h1 = io1.out.file.handle;
+	CHECK_VAL(io1.out.durable_open, true);
 	CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
 
 	CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
@@ -601,6 +867,8 @@ struct torture_suite *torture_smb2_durable_open_init(void)
 	struct torture_suite *suite =
 	    torture_suite_create(talloc_autofree_context(), "durable-open");
 
+	torture_suite_add_1smb2_test(suite, "basic1", test_durable_open_basic1);
+	torture_suite_add_1smb2_test(suite, "basic2", test_durable_open_basic2);
 	torture_suite_add_2smb2_test(suite, "file-position",
 	    test_durable_open_file_position);
 	torture_suite_add_2smb2_test(suite, "oplock", test_durable_open_oplock);
diff --git a/source4/torture/smb2/lease.c b/source4/torture/smb2/lease.c
index 564394f..3d3f17d 100644
--- a/source4/torture/smb2/lease.c
+++ b/source4/torture/smb2/lease.c
@@ -550,7 +550,7 @@ static inline uint32_t oplock(const char *op) {
 		case 'x':
 			return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
 		case 'b':
-			return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
+			return SMB2_OPLOCK_LEVEL_BATCH;
 		default:
 			continue;
 		}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list