[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-2192-g7c58a2f

Stefan Metzmacher metze at samba.org
Tue Jun 9 17:43:47 GMT 2009


The branch, master has been updated
       via  7c58a2f23734f8931cb822f71277cac7bb7ffe35 (commit)
       via  8d9588390822745ad43f0df82b29704234c760b9 (commit)
       via  ebf5523b6e2ae00d820d2c2d31c2f24aab020f91 (commit)
      from  38cd0e086f50ce54d88a19aa5a6803469af90489 (commit)

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


- Log -----------------------------------------------------------------
commit 7c58a2f23734f8931cb822f71277cac7bb7ffe35
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jun 9 18:13:53 2009 +0200

    SMB2-COMPOUND: add some tests for invalid requests
    
    TODO: check why the INVALID1 tests fails with --signing=required.
    
    metze

commit 8d9588390822745ad43f0df82b29704234c760b9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jun 9 19:32:30 2009 +0200

    s4:smb2srv: don't allow the related flag on the first request in a compounded chain
    
    metze

commit ebf5523b6e2ae00d820d2c2d31c2f24aab020f91
Author: Sam Liddicott <sam at liddicott.com>
Date:   Tue Jun 9 12:51:44 2009 +0100

    s4: smbcli_transport_send hit the socket right away if possible
    
    [Metze; "make test" on git master outputs exactly the same test summary
    with our without this patch (apart from the "using seed" lines)]
    
    If the transport socket is writable, then push the queue along
    rather than wait until the caller returns back to the tevent loop.
    
    This strategy keeps the sockets piping hot, and is particularly good
    for cases where reading requests from one socket causes lots of
    writes on another socket, or where lots of writes are made in a batch.
    
    It doesn't matter if the socket is not writeable yet, packet_queue_run
    will return quite cheaply in such a case.
    
    Signed-off-by: Sam Liddicott <sam at liddicott.com>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 source4/libcli/raw/clitransport.c |    7 ++
 source4/smb_server/smb2/receive.c |    7 ++
 source4/torture/smb2/compound.c   |  201 +++++++++++++++++++++++++++++++++++++
 3 files changed, 215 insertions(+), 0 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index 0ced607..f5e81cd 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -593,6 +593,13 @@ void smbcli_transport_send(struct smbcli_request *req)
 		return;
 	}
 
+	packet_queue_run(req->transport->packet);
+	if (req->transport->socket->sock == NULL) {
+		req->state = SMBCLI_REQUEST_ERROR;
+		req->status = NT_STATUS_NET_WRITE_FAULT;
+		return;
+	}
+
 	if (req->one_way_request) {
 		req->state = SMBCLI_REQUEST_DONE;
 		smbcli_request_destroy(req);
diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c
index 16f888b..5ac01dc 100644
--- a/source4/smb_server/smb2/receive.c
+++ b/source4/smb_server/smb2/receive.c
@@ -470,6 +470,7 @@ NTSTATUS smbsrv_recv_smb2_request(void *private_data, DATA_BLOB blob)
 	uint32_t protocol_version;
 	uint16_t buffer_code;
 	uint32_t dynamic_size;
+	uint32_t flags;
 
 	smb_conn->statistics.last_request_time = cur_time;
 
@@ -543,6 +544,12 @@ NTSTATUS smbsrv_recv_smb2_request(void *private_data, DATA_BLOB blob)
 	 *       - make sure it's a request
 	 */
 
+	flags = IVAL(req->in.hdr, SMB2_HDR_FLAGS);
+	/* the first request should never have the related flag set */
+	if (flags & SMB2_HDR_FLAG_CHAINED) {
+		req->chain_status = NT_STATUS_INVALID_PARAMETER;
+	}
+
 	return smb2srv_reply(req);
 }
 
diff --git a/source4/torture/smb2/compound.c b/source4/torture/smb2/compound.c
index f92a669..00f6f33 100644
--- a/source4/torture/smb2/compound.c
+++ b/source4/torture/smb2/compound.c
@@ -227,6 +227,204 @@ done:
 	return ret;
 }
 
+static bool test_compound_invalid1(struct torture_context *tctx,
+				   struct smb2_tree *tree)
+{
+	struct smb2_handle hd;
+	struct smb2_create cr;
+	NTSTATUS status;
+	const char *fname = "compound_invalid1.dat";
+	struct smb2_close cl;
+	bool ret = true;
+	struct smb2_request *req[2];
+	DATA_BLOB data;
+
+	smb2_transport_credits_ask_num(tree->session->transport, 2);
+
+	smb2_util_unlink(tree, fname);
+
+	smb2_transport_credits_ask_num(tree->session->transport, 1);
+
+	ZERO_STRUCT(cr);
+	cr.in.security_flags		= 0x00;
+	cr.in.oplock_level		= 0;
+	cr.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
+	cr.in.create_flags		= 0x00000000;
+	cr.in.reserved			= 0x00000000;
+	cr.in.desired_access		= SEC_RIGHTS_FILE_ALL;
+	cr.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
+	cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
+					  NTCREATEX_SHARE_ACCESS_WRITE |
+					  NTCREATEX_SHARE_ACCESS_DELETE;
+	cr.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
+	cr.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
+					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
+					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
+					  0x00200000;
+	cr.in.fname			= fname;
+
+	smb2_transport_compound_start(tree->session->transport, 2);
+
+	/* passing the first request with the related flag is invalid */
+	smb2_transport_compound_set_related(tree->session->transport, true);
+
+	req[0] = smb2_create_send(tree, &cr);
+
+	hd.data[0] = UINT64_MAX;
+	hd.data[1] = UINT64_MAX;
+
+	ZERO_STRUCT(cl);
+	cl.in.file.handle = hd;
+	req[1] = smb2_close_send(tree, &cl);
+
+	status = smb2_create_recv(req[0], tree, &cr);
+	/* TODO: check why this fails with --signing=required */
+	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+	status = smb2_close_recv(req[1], &cl);
+	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+
+	smb2_util_unlink(tree, fname);
+done:
+	return ret;
+}
+
+static bool test_compound_invalid2(struct torture_context *tctx,
+				   struct smb2_tree *tree)
+{
+	struct smb2_handle hd;
+	struct smb2_create cr;
+	NTSTATUS status;
+	const char *fname = "compound_invalid2.dat";
+	struct smb2_close cl;
+	bool ret = true;
+	struct smb2_request *req[5];
+
+	smb2_transport_credits_ask_num(tree->session->transport, 5);
+
+	smb2_util_unlink(tree, fname);
+
+	smb2_transport_credits_ask_num(tree->session->transport, 1);
+
+	ZERO_STRUCT(cr);
+	cr.in.security_flags		= 0x00;
+	cr.in.oplock_level		= 0;
+	cr.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
+	cr.in.create_flags		= 0x00000000;
+	cr.in.reserved			= 0x00000000;
+	cr.in.desired_access		= SEC_RIGHTS_FILE_ALL;
+	cr.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
+	cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
+					  NTCREATEX_SHARE_ACCESS_WRITE |
+					  NTCREATEX_SHARE_ACCESS_DELETE;
+	cr.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
+	cr.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
+					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
+					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
+					  0x00200000;
+	cr.in.fname			= fname;
+
+	smb2_transport_compound_start(tree->session->transport, 5);
+
+	req[0] = smb2_create_send(tree, &cr);
+
+	hd.data[0] = UINT64_MAX;
+	hd.data[1] = UINT64_MAX;
+
+	smb2_transport_compound_set_related(tree->session->transport, true);
+
+	ZERO_STRUCT(cl);
+	cl.in.file.handle = hd;
+	req[1] = smb2_close_send(tree, &cl);
+	/* strange that this is not generating invalid parameter */
+	smb2_transport_compound_set_related(tree->session->transport, false);
+	req[2] = smb2_close_send(tree, &cl);
+	req[3] = smb2_close_send(tree, &cl);
+	smb2_transport_compound_set_related(tree->session->transport, true);
+	req[4] = smb2_close_send(tree, &cl);
+
+	status = smb2_create_recv(req[0], tree, &cr);
+	CHECK_STATUS(status, NT_STATUS_OK);
+	status = smb2_close_recv(req[1], &cl);
+	CHECK_STATUS(status, NT_STATUS_OK);
+	status = smb2_close_recv(req[2], &cl);
+	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
+	status = smb2_close_recv(req[3], &cl);
+	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
+	status = smb2_close_recv(req[4], &cl);
+	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+
+	smb2_util_unlink(tree, fname);
+done:
+	return ret;
+}
+
+static bool test_compound_invalid3(struct torture_context *tctx,
+				   struct smb2_tree *tree)
+{
+	struct smb2_handle hd;
+	struct smb2_create cr;
+	NTSTATUS status;
+	const char *fname = "compound_invalid3.dat";
+	struct smb2_close cl;
+	bool ret = true;
+	struct smb2_request *req[5];
+
+	smb2_transport_credits_ask_num(tree->session->transport, 5);
+
+	smb2_util_unlink(tree, fname);
+
+	smb2_transport_credits_ask_num(tree->session->transport, 1);
+
+	ZERO_STRUCT(cr);
+	cr.in.security_flags		= 0x00;
+	cr.in.oplock_level		= 0;
+	cr.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
+	cr.in.create_flags		= 0x00000000;
+	cr.in.reserved			= 0x00000000;
+	cr.in.desired_access		= SEC_RIGHTS_FILE_ALL;
+	cr.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
+	cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
+					  NTCREATEX_SHARE_ACCESS_WRITE |
+					  NTCREATEX_SHARE_ACCESS_DELETE;
+	cr.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
+	cr.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
+					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
+					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
+					  0x00200000;
+	cr.in.fname			= fname;
+
+	smb2_transport_compound_start(tree->session->transport, 5);
+
+	req[0] = smb2_create_send(tree, &cr);
+
+	hd.data[0] = UINT64_MAX;
+	hd.data[1] = UINT64_MAX;
+
+	ZERO_STRUCT(cl);
+	cl.in.file.handle = hd;
+	req[1] = smb2_close_send(tree, &cl);
+	req[2] = smb2_close_send(tree, &cl);
+	/* flipping the related flag is invalid */
+	smb2_transport_compound_set_related(tree->session->transport, true);
+	req[3] = smb2_close_send(tree, &cl);
+	req[4] = smb2_close_send(tree, &cl);
+
+	status = smb2_create_recv(req[0], tree, &cr);
+	CHECK_STATUS(status, NT_STATUS_OK);
+	status = smb2_close_recv(req[1], &cl);
+	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
+	status = smb2_close_recv(req[2], &cl);
+	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
+	status = smb2_close_recv(req[3], &cl);
+	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+	status = smb2_close_recv(req[4], &cl);
+	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+
+	smb2_util_unlink(tree, fname);
+done:
+	return ret;
+}
+
 struct torture_suite *torture_smb2_compound_init(void)
 {
 	struct torture_suite *suite =
@@ -235,6 +433,9 @@ struct torture_suite *torture_smb2_compound_init(void)
 	torture_suite_add_1smb2_test(suite, "RELATED1", test_compound_related1);
 	torture_suite_add_1smb2_test(suite, "RELATED2", test_compound_related2);
 	torture_suite_add_1smb2_test(suite, "UNRELATED1", test_compound_unrelated1);
+	torture_suite_add_1smb2_test(suite, "INVALID1", test_compound_invalid1);
+	torture_suite_add_1smb2_test(suite, "INVALID2", test_compound_invalid2);
+	torture_suite_add_1smb2_test(suite, "INVALID3", test_compound_invalid3);
 
 	suite->description = talloc_strdup(suite, "SMB2-COMPOUND tests");
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list