[PATCHES] SMB3 Multi-Channel: session binding

Michael Adam obnox at samba.org
Fri Jan 22 12:31:04 UTC 2016


Thanks for the feed-backs.

Attached find an updated patchset that addresses all the
comments. Again in two parts.
The second part is a preview , to be pushed after
the interface info ioctl and the connection passing
are also in.

Each single patch compiles with --picky-developer.
(I squashed the two patches. it only did not compile
because the function was not used, which I find
slightly irritating, code-hygiene-wise..)

Thanks - Michael



On 2016-01-22 at 10:21 +0100, Stefan Metzmacher wrote:
> Hi Michael,
> 
> > From 13cd9672032c3d66814d711a8c1b5eb2e2480046 Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
> > Date: Wed, 20 Jan 2016 17:44:45 +0100
> > Subject: [PATCH 1/2] param: add parameter "multi channel", defaults to off.
> 
> Please change this to 'server multi channel support'.
> 
> Thanks!
> metze
> 


-------------- next part --------------
From 5f380ef386d11da030197d2efee962bcef3ef8d4 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 22 Jan 2016 12:51:15 +0100
Subject: [PATCH 1/4] smbXsrv: introduce bool
 smbXsrv_client->multi_channel_capable

defaulting to false.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/librpc/idl/smbXsrv.idl | 1 +
 1 file changed, 1 insertion(+)

diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 8528770..9fa1d63 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -112,6 +112,7 @@ interface smbXsrv
 		 * one in future.
 		 */
 		[ignore] struct smbXsrv_connection	*connections;
+		[ignore] boolean8			multi_channel_capable;
 	} smbXsrv_client;
 
 	/* sessions */
-- 
2.5.0


From fd67bb1640915014a9a64f0a1bfb41d7dc739db9 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 21 Jan 2016 00:16:33 +0100
Subject: [PATCH 2/4] s3:smb2_negprot: announce multi channel support
 (disabled)

This disabled for now. Will be enabled by config setting
once underpinnings are ready.

Pair-Programmed-With: Guenther Deschner <gd at samba.org>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Guenther Deschner <gd at samba.org>
---
 source3/smbd/smb2_negprot.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index c04fbca..8666e88 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -485,6 +485,14 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 		xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
 	}
 
+	if (protocol >= PROTOCOL_SMB2_22 &&
+	    xconn->client->multi_channel_capable)
+	{
+		if (in_capabilities & SMB2_CAP_MULTI_CHANNEL) {
+			capabilities |= SMB2_CAP_MULTI_CHANNEL;
+		}
+	}
+
 	security_offset = SMB2_HDR_BODY + 0x40;
 
 #if 1
-- 
2.5.0


From 4ee00c353006ccf5f6c59cb92cf5075248e6a624 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 29 Jul 2015 17:05:52 +0200
Subject: [PATCH 3/4] s3:smb2_sesssetup: treat BINDING in
 smbd_smb2_session_setup_auth_return

This adds smbd_smb2_bind_auth_return(), a
variant of auth_return for session binding.

Pair-Programmed-With: Michael Adam <obnox at samba.org>
Pair-Programmed-With: Guenther Deschner <gd at samba.org>

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/smbd/smb2_sesssetup.c | 124 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index a6c66e2..4538653 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -554,6 +554,116 @@ static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
+					   struct smbXsrv_session_auth0 **_auth,
+					   struct smbd_smb2_request *smb2req,
+					   struct auth_session_info *session_info,
+					   uint16_t *out_session_flags,
+					   uint64_t *out_session_id)
+{
+	NTSTATUS status;
+	struct smbXsrv_session *x = session;
+	struct smbXsrv_session_auth0 *auth = *_auth;
+	struct smbXsrv_connection *xconn = smb2req->xconn;
+	struct smbXsrv_channel_global0 *c = NULL;
+	uint8_t session_key[16];
+	size_t i;
+	struct _derivation {
+		DATA_BLOB label;
+		DATA_BLOB context;
+	};
+	struct {
+		struct _derivation signing;
+	} derivation = { };
+	bool ok;
+
+	*_auth = NULL;
+
+	if (xconn->protocol >= PROTOCOL_SMB3_10) {
+		struct smbXsrv_preauth *preauth;
+		struct _derivation *d;
+		DATA_BLOB p;
+		struct hc_sha512state sctx;
+
+		preauth = talloc_move(smb2req, &auth->preauth);
+
+		samba_SHA512_Init(&sctx);
+		samba_SHA512_Update(&sctx, preauth->sha512_value,
+				    sizeof(preauth->sha512_value));
+		for (i = 1; i < smb2req->in.vector_count; i++) {
+			samba_SHA512_Update(&sctx,
+					    smb2req->in.vector[i].iov_base,
+					    smb2req->in.vector[i].iov_len);
+		}
+		samba_SHA512_Final(preauth->sha512_value, &sctx);
+
+		p = data_blob_const(preauth->sha512_value,
+				    sizeof(preauth->sha512_value));
+
+		d = &derivation.signing;
+		d->label = data_blob_string_const_null("SMBSigningKey");
+		d->context = p;
+
+	} else if (xconn->protocol >= PROTOCOL_SMB2_24) {
+		struct _derivation *d;
+
+		d = &derivation.signing;
+		d->label = data_blob_string_const_null("SMB2AESCMAC");
+		d->context = data_blob_string_const_null("SmbSign");
+	}
+
+	status = smbXsrv_session_find_channel(session, xconn, &c);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	ok = security_token_is_sid(session_info->security_token,
+			&x->global->auth_session_info->security_token->sids[0]);
+	if (!ok) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (session_info->session_key.length == 0) {
+		/* See [MS-SMB2] 3.3.5.2.4 for the return code. */
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	ZERO_STRUCT(session_key);
+	memcpy(session_key, session_info->session_key.data,
+	       MIN(session_info->session_key.length, sizeof(session_key)));
+
+	c->signing_key = data_blob_talloc(x->global,
+					  session_key,
+					  sizeof(session_key));
+	if (c->signing_key.data == NULL) {
+		ZERO_STRUCT(session_key);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (xconn->protocol >= PROTOCOL_SMB2_24) {
+		struct _derivation *d = &derivation.signing;
+
+		smb2_key_derivation(session_key, sizeof(session_key),
+				    d->label.data, d->label.length,
+				    d->context.data, d->context.length,
+				    c->signing_key.data);
+	}
+	ZERO_STRUCT(session_key);
+
+	TALLOC_FREE(auth);
+	status = smbXsrv_session_update(session);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
+			  (unsigned long long)session->compat->vuid,
+			  nt_errstr(status)));
+		return NT_STATUS_LOGON_FAILURE;
+	}
+
+	*out_session_id = session->global->session_wire_id;
+
+	return NT_STATUS_OK;
+}
+
 struct smbd_smb2_session_setup_state {
 	struct tevent_context *ev;
 	struct smbd_smb2_request *smb2req;
@@ -780,6 +890,20 @@ static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
 		struct smbd_smb2_session_setup_state);
 	NTSTATUS status;
 
+	if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
+		status = smbd_smb2_bind_auth_return(state->session,
+						    &state->auth,
+						    state->smb2req,
+						    state->session_info,
+						    &state->out_session_flags,
+						    &state->out_session_id);
+		if (tevent_req_nterror(req, status)) {
+			return;
+		}
+		tevent_req_done(req);
+		return;
+	}
+
 	if (state->session->global->auth_session_info != NULL) {
 		status = smbd_smb2_reauth_generic_return(state->session,
 							 &state->auth,
-- 
2.5.0


From 6fde190ea1442ef9802937880f730a80f404560e Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 21 Jan 2016 18:59:34 +0100
Subject: [PATCH 4/4] s3:smb2_sesssetup: implement SMB3 session bind (disabled)

This is disabled for now. It will be possible to enabled it
via a config switch once the underpinnings are complete.

Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Pair-Programmed-With: Guenther Deschner <gd at samba.org>

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/smbd/smb2_sesssetup.c | 81 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 78 insertions(+), 3 deletions(-)

diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 4538653..890b8cd 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -699,6 +699,7 @@ static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
 	NTTIME now = timeval_to_nttime(&smb2req->request_time);
 	struct tevent_req *subreq;
 	struct smbXsrv_channel_global0 *c = NULL;
+	enum security_user_level seclvl;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smbd_smb2_session_setup_state);
@@ -719,13 +720,87 @@ static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
 			return tevent_req_post(req, ev);
 		}
 
+		if (!smb2req->xconn->client->multi_channel_capable) {
+			tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
+			return tevent_req_post(req, ev);
+		}
+
+		if (in_session_id == 0) {
+			tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+			return tevent_req_post(req, ev);
+		}
+
+		if (smb2req->session == NULL) {
+			tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
+			return tevent_req_post(req, ev);
+		}
+
+		if (!smb2req->do_signing) {
+			tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+			return tevent_req_post(req, ev);
+		}
+
+		status = smbXsrv_session_find_channel(smb2req->session,
+						      smb2req->xconn,
+						      &c);
+		if (NT_STATUS_IS_OK(status)) {
+			if (c->signing_key.length == 0) {
+				goto auth;
+			}
+			tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
+			return tevent_req_post(req, ev);
+		}
+
 		/*
-		 * We do not support multi channel.
+		 * OLD: 3.00 NEW 3.02 => INVALID_PARAMETER
+		 * OLD: 3.02 NEW 3.00 => INVALID_PARAMETER
+		 * OLD: 2.10 NEW 3.02 => ACCESS_DENIED
+		 * OLD: 3.02 NEW 2.10 => ACCESS_DENIED
 		 */
-		tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
-		return tevent_req_post(req, ev);
+		if (smb2req->session->global->connection_dialect
+		    < SMB2_DIALECT_REVISION_222)
+		{
+			tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+			return tevent_req_post(req, ev);
+		}
+		if (smb2req->xconn->smb2.server.dialect
+		    < SMB2_DIALECT_REVISION_222)
+		{
+			tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+			return tevent_req_post(req, ev);
+		}
+		if (smb2req->session->global->connection_dialect
+		    != smb2req->xconn->smb2.server.dialect)
+		{
+			tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+			return tevent_req_post(req, ev);
+		}
+
+		seclvl = security_session_user_level(
+				smb2req->session->global->auth_session_info,
+				NULL);
+		if (seclvl < SECURITY_USER) {
+			tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+			return tevent_req_post(req, ev);
+		}
+
+		status = smbXsrv_session_add_channel(smb2req->session,
+						     smb2req->xconn,
+						     &c);
+		if (!NT_STATUS_IS_OK(status)) {
+			tevent_req_nterror(req, status);
+			return tevent_req_post(req, ev);
+		}
+
+		status = smbXsrv_session_update(smb2req->session);
+		if (!NT_STATUS_IS_OK(status)) {
+			tevent_req_nterror(req, status);
+			return tevent_req_post(req, ev);
+		}
 	}
 
+auth:
+
 	if (state->in_session_id == 0) {
 		/* create a new session */
 		status = smbXsrv_session_create(state->smb2req->xconn,
-- 
2.5.0

-------------- next part --------------
From 2d198e718d967708bf8ffd90e82fd92f096f76ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
Date: Wed, 20 Jan 2016 17:44:45 +0100
Subject: [PATCH 1/2] param: add parameter "server multi channel support",
 defaults to off.

Guenther

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Guenther Deschner <gd at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 .../smbdotconf/protocol/servermultichannelsupport.xml | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 docs-xml/smbdotconf/protocol/servermultichannelsupport.xml

diff --git a/docs-xml/smbdotconf/protocol/servermultichannelsupport.xml b/docs-xml/smbdotconf/protocol/servermultichannelsupport.xml
new file mode 100644
index 0000000..b85bbd3
--- /dev/null
+++ b/docs-xml/smbdotconf/protocol/servermultichannelsupport.xml
@@ -0,0 +1,19 @@
+<samba:parameter name="server multi channel support"
+                 context="G"
+                 type="boolean"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+    <para>This boolean parameter controls whether
+    <citerefentry><refentrytitle>smbd</refentrytitle>
+    <manvolnum>8</manvolnum></citerefentry> will support
+    SMB3 multi-channel.
+    </para>
+    <para>This parameter has been added with version 4.4.</para>
+    <para>
+    Warning: Note that this feature is considered experimental in Samba 4.4.
+    Use it at your own risk: it may result in data corruption.
+    </para>
+</description>
+
+<value type="default">no</value>
+</samba:parameter>
-- 
2.5.0


From 95eb556462f93abefa944495f168e45fc05b782e Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 22 Jan 2016 01:15:28 +0100
Subject: [PATCH 2/2] smbd: enable multi-channel if 'server multi channel
 support = yes' in the config

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/smbd/process.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index e5c52be..cfc124f 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3913,6 +3913,8 @@ void smbd_process(struct tevent_context *ev_ctx,
 	client->ev_ctx = ev_ctx;
 	client->msg_ctx = msg_ctx;
 
+	client->multi_channel_capable = lp_server_multi_channel_support();
+
 	sconn = talloc_zero(client, struct smbd_server_connection);
 	if (sconn == NULL) {
 		exit_server("failed to create smbd_server_connection");
-- 
2.5.0

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20160122/0e93a36a/signature.sig>


More information about the samba-technical mailing list