[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Mon Sep 5 11:31:02 MDT 2011


The branch, master has been updated
       via  012c9d0 s3:smb2_server: add basic support for SMB 2.1
       via  1c8e8c7 s3:smb2_server: return NOT_SUPPORTED if we don't find a common dialect with the client
       via  e603929 s3:smb2_server: max_trans, max_read and max_write are limited to 64 kilobytes
       via  a44d3d1 s3:smb2cli: make sure we don't try to send requests on a disconnected cli_state
       via  4dca2ac s3:smb2cli: make sure requests are not finished, when we send when to the network
       via  0b6087c s3:smb2cli: disconnect the connection, if we're out of message ids
       via  5155a15 s3:smb2cli: don't use state->cli->smb2.mid++ as macro argument
      from  3e8c665 s3-smbd: Rename reload_printers() and add documentation.

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


- Log -----------------------------------------------------------------
commit 012c9d06a94b532377e9e96f60b20b5f0975af74
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Sep 5 13:14:40 2011 +0200

    s3:smb2_server: add basic support for SMB 2.1
    
    This adds support for the 2 stage negprot, from SMB 1 to SMB 2.1.
    
    Support for this of for now and "max protocol = SMB2" still maps
    to "max protocol = SMB2_02" PROTOCOL_SMB2_02.
    
    In order to activate smb2.1, you need to use "max protocol = SMB2_10".
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Mon Sep  5 19:30:58 CEST 2011 on sn-devel-104

commit 1c8e8c7e7b4cc00628b91e2e0596bfa428a2bcdb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Sep 5 12:23:51 2011 +0200

    s3:smb2_server: return NOT_SUPPORTED if we don't find a common dialect with the client
    
    metze

commit e603929b9801ad6cc47dead19d27b42fe46489c7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Sep 5 12:14:06 2011 +0200

    s3:smb2_server: max_trans, max_read and max_write are limited to 64 kilobytes
    
    Only if SMB2_CAP_LARGE_MTU is supported we should announce larger limits.
    
    metze

commit a44d3d176400d0c6500fc8d3c05ee73e930fd140
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Sep 5 09:49:53 2011 +0200

    s3:smb2cli: make sure we don't try to send requests on a disconnected cli_state
    
    metze

commit 4dca2acfe43fda00637615548fecab1e3313b204
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Sep 5 09:35:43 2011 +0200

    s3:smb2cli: make sure requests are not finished, when we send when to the network
    
    metze

commit 0b6087c7be01983be96f3f3cb892ba2f32a8266a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Sep 5 09:31:54 2011 +0200

    s3:smb2cli: disconnect the connection, if we're out of message ids
    
    metze

commit 5155a15c5cadd2dec9386576c1b4b566be1e4536
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Sep 3 15:23:44 2011 +0200

    s3:smb2cli: don't use state->cli->smb2.mid++ as macro argument
    
    It gets expanded multiple times.
    
    metze

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

Summary of changes:
 source3/libsmb/smb2cli_base.c |   31 +++++++++++++-
 source3/param/loadparm.c      |    3 +-
 source3/smbd/globals.h        |    2 +
 source3/smbd/negprot.c        |    1 +
 source3/smbd/smb2_negprot.c   |   94 ++++++++++++++++++++++++++++++++++++----
 5 files changed, 118 insertions(+), 13 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/libsmb/smb2cli_base.c b/source3/libsmb/smb2cli_base.c
index 9fc824c..7f4b176 100644
--- a/source3/libsmb/smb2cli_base.c
+++ b/source3/libsmb/smb2cli_base.c
@@ -22,6 +22,7 @@
 #include "client.h"
 #include "read_smb.h"
 #include "smb2cli_base.h"
+#include "libsmb/proto.h"
 #include "lib/async_req/async_sock.h"
 #include "lib/util/tevent_ntstatus.h"
 
@@ -252,10 +253,26 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
 	for (i=0; i<num_reqs; i++) {
 		size_t reqlen;
 		bool ret;
+		uint64_t mid;
+
+		if (!tevent_req_is_in_progress(reqs[i])) {
+			return NT_STATUS_INTERNAL_ERROR;
+		}
 
 		state = tevent_req_data(reqs[i], struct smb2cli_req_state);
 
-		SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, state->cli->smb2.mid++);
+		if (!cli_state_is_connected(state->cli)) {
+			return NT_STATUS_CONNECTION_DISCONNECTED;
+		}
+
+		if (state->cli->smb2.mid == UINT64_MAX) {
+			return NT_STATUS_CONNECTION_ABORTED;
+		}
+
+		mid = state->cli->smb2.mid;
+		state->cli->smb2.mid += 1;
+
+		SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, mid);
 
 		iov[num_iov].iov_base = state->hdr;
 		iov[num_iov].iov_len  = sizeof(state->hdr);
@@ -576,7 +593,17 @@ static void smb2cli_inbuf_received(struct tevent_req *subreq)
 
 	num_pending = talloc_array_length(cli->conn.pending);
 	if (num_pending == 0) {
-		/* no more pending requests, so we are done for now */
+		if (state->cli->smb2.mid < UINT64_MAX) {
+			/* no more pending requests, so we are done for now */
+			return;
+		}
+
+		/*
+		 * If there are no more requests possible,
+		 * because we are out of message ids,
+		 * we need to disconnect.
+		 */
+		smb2cli_notify_pending(cli, NT_STATUS_CONNECTION_ABORTED);
 		return;
 	}
 	req = cli->conn.pending[0];
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index b0c64c7..305ff2c 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -312,7 +312,8 @@ static void add_to_file_list(const char *fname, const char *subfname);
 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
 
 static const struct enum_list enum_protocol[] = {
-	{PROTOCOL_SMB2_02, "SMB2"},
+	{PROTOCOL_SMB2_02, "SMB2"}, /* for now keep PROTOCOL_SMB2_02 */
+	{PROTOCOL_SMB2_10, "SMB2_10"},
 	{PROTOCOL_SMB2_02, "SMB2_02"},
 	{PROTOCOL_NT1, "NT1"},
 	{PROTOCOL_LANMAN2, "LANMAN2"},
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 2e59d9b..6ce9835 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -241,6 +241,7 @@ const char *smb2_opcode_name(uint16_t opcode);
 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size);
 
 void reply_smb2002(struct smb_request *req, uint16_t choice);
+void reply_smb20ff(struct smb_request *req, uint16_t choice);
 void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
 			     const uint8_t *inbuf, size_t size);
 
@@ -578,6 +579,7 @@ struct smbd_server_connection {
 		struct tevent_queue *recv_queue;
 		struct tevent_queue *send_queue;
 		struct tstream_context *stream;
+		bool negprot_2ff;
 		struct {
 			/* an id tree used to allocate vuids */
 			/* this holds info on session vuids that are already
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 49b9420..a38534f 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -536,6 +536,7 @@ static const struct {
 	void (*proto_reply_fn)(struct smb_request *req, uint16 choice);
 	int protocol_level;
 } supported_protocols[] = {
+	{"SMB 2.???",               "SMB2_FF",  reply_smb20ff,  PROTOCOL_SMB2_10},
 	{"SMB 2.002",               "SMB2_02",  reply_smb2002,  PROTOCOL_SMB2_02},
 	{"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
 	{"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 5ae9163..56a30d0 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -25,9 +25,9 @@
 
 /*
  * this is the entry point if SMB2 is selected via
- * the SMB negprot
+ * the SMB negprot and the given dialect.
  */
-void reply_smb2002(struct smb_request *req, uint16_t choice)
+static void reply_smb20xx(struct smb_request *req, uint16_t dialect)
 {
 	uint8_t *smb2_inbuf;
 	uint8_t *smb2_hdr;
@@ -51,7 +51,7 @@ void reply_smb2002(struct smb_request *req, uint16_t choice)
 	SSVAL(smb2_body, 0x00, 0x0024);	/* struct size */
 	SSVAL(smb2_body, 0x02, 0x0001);	/* dialect count */
 
-	SSVAL(smb2_dyn,  0x00, 0x0202);	/* dialect 2.002 */
+	SSVAL(smb2_dyn,  0x00, dialect);
 
 	req->outbuf = NULL;
 
@@ -59,6 +59,25 @@ void reply_smb2002(struct smb_request *req, uint16_t choice)
 	return;
 }
 
+/*
+ * this is the entry point if SMB2 is selected via
+ * the SMB negprot and the "SMB 2.002" dialect.
+ */
+void reply_smb2002(struct smb_request *req, uint16_t choice)
+{
+	reply_smb20xx(req, SMB2_DIALECT_REVISION_202);
+}
+
+/*
+ * this is the entry point if SMB2 is selected via
+ * the SMB negprot and the "SMB 2.???" dialect.
+ */
+void reply_smb20ff(struct smb_request *req, uint16_t choice)
+{
+	req->sconn->smb2.negprot_2ff = true;
+	reply_smb20xx(req, SMB2_DIALECT_REVISION_2FF);
+}
+
 NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 {
 	const uint8_t *inbody;
@@ -77,6 +96,11 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 	uint16_t dialect_count;
 	uint16_t dialect = 0;
 	uint32_t capabilities;
+	enum protocol_types protocol = PROTOCOL_NONE;
+	uint32_t max_limit;
+	uint32_t max_trans = lp_smb2_max_trans();
+	uint32_t max_read = lp_smb2_max_read();
+	uint32_t max_write = lp_smb2_max_write();
 
 /* TODO: drop the connection with INVALID_PARAMETER */
 
@@ -102,18 +126,58 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 	}
 	indyn = (const uint8_t *)req->in.vector[i+2].iov_base;
 
-	for (c=0; c < dialect_count; c++) {
+	for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
+		if (lp_maxprotocol() < PROTOCOL_SMB2_10) {
+			break;
+		}
+		if (lp_minprotocol() > PROTOCOL_SMB2_10) {
+			break;
+		}
+
+		dialect = SVAL(indyn, c*2);
+		if (dialect == SMB2_DIALECT_REVISION_210) {
+			protocol = PROTOCOL_SMB2_10;
+			break;
+		}
+	}
+
+	for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
+		if (lp_maxprotocol() < PROTOCOL_SMB2_02) {
+			break;
+		}
+		if (lp_minprotocol() > PROTOCOL_SMB2_02) {
+			break;
+		}
+
 		dialect = SVAL(indyn, c*2);
 		if (dialect == SMB2_DIALECT_REVISION_202) {
+			protocol = PROTOCOL_SMB2_02;
 			break;
 		}
 	}
 
-	if (dialect != SMB2_DIALECT_REVISION_202) {
-		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
+		if (lp_maxprotocol() < PROTOCOL_SMB2_10) {
+			break;
+		}
+
+		dialect = SVAL(indyn, c*2);
+		if (dialect == SMB2_DIALECT_REVISION_2FF) {
+			if (req->sconn->smb2.negprot_2ff) {
+				req->sconn->smb2.negprot_2ff = false;
+				protocol = PROTOCOL_SMB2_10;
+				break;
+			}
+		}
 	}
 
-	set_Protocol(PROTOCOL_SMB2_02);
+	if (protocol == PROTOCOL_NONE) {
+		return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
+	}
+
+	if (dialect != SMB2_DIALECT_REVISION_2FF) {
+		set_Protocol(protocol);
+	}
 
 	if (get_remote_arch() != RA_SAMBA) {
 		set_remote_arch(RA_VISTA);
@@ -139,6 +203,16 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 		capabilities |= SMB2_CAP_DFS;
 	}
 
+	/*
+	 * Unless we implement SMB2_CAP_LARGE_MTU,
+	 * 0x10000 (65536) is the maximum allowed message size
+	 */
+	max_limit = 0x10000;
+
+	max_trans = MIN(max_limit, max_trans);
+	max_read  = MIN(max_limit, max_read);
+	max_write = MIN(max_limit, max_write);
+
 	security_offset = SMB2_HDR_BODY + 0x40;
 
 #if 1
@@ -164,9 +238,9 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 	       negprot_spnego_blob.data, 16);	/* server guid */
 	SIVAL(outbody.data, 0x18,
 	      capabilities);			/* capabilities */
-	SIVAL(outbody.data, 0x1C, lp_smb2_max_trans());	/* max transact size */
-	SIVAL(outbody.data, 0x20, lp_smb2_max_read());	/* max read size */
-	SIVAL(outbody.data, 0x24, lp_smb2_max_write());	/* max write size */
+	SIVAL(outbody.data, 0x1C, max_trans);	/* max transact size */
+	SIVAL(outbody.data, 0x20, max_trans);	/* max read size */
+	SIVAL(outbody.data, 0x24, max_trans);	/* max write size */
 	SBVAL(outbody.data, 0x28, 0);		/* system time */
 	SBVAL(outbody.data, 0x30, 0);		/* server start time */
 	SSVAL(outbody.data, 0x38,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list