[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