[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Sat Jan 23 02:23:02 UTC 2016


The branch, master has been updated
       via  a1a8746 s3:smb2_sesssetup: implement SMB3 session bind (disabled)
       via  edd781d s3:smb2_sesssetup: treat BINDING in smbd_smb2_session_setup_auth_return
       via  91770e3 s3:smb2_negprot: announce multi channel support (disabled)
       via  d60ffcf smbXsrv: introduce bool smbXsrv_client->server_multi_channel_enabled
      from  3e08469 build: fix ldbsearch panic on FC22

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


- Log -----------------------------------------------------------------
commit a1a8746174dff0b80ef4620894001a610b78f208
Author: Michael Adam <obnox at samba.org>
Date:   Thu Jan 21 18:59:34 2016 +0100

    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>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Michael Adam <obnox at samba.org>
    Autobuild-Date(master): Sat Jan 23 03:22:18 CET 2016 on sn-devel-144

commit edd781d5a886aab4a5002280321006cfbc2c7bc9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jul 29 17:05:52 2015 +0200

    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>
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 91770e3fa76d23b522929c09aa5b587a8d9ffd4f
Author: Michael Adam <obnox at samba.org>
Date:   Thu Jan 21 00:16:33 2016 +0100

    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>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit d60ffcfe440c17f30be9e97d7049650d988c9395
Author: Michael Adam <obnox at samba.org>
Date:   Fri Jan 22 12:51:15 2016 +0100

    smbXsrv: introduce bool smbXsrv_client->server_multi_channel_enabled
    
    defaulting to false.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 source3/librpc/idl/smbXsrv.idl |   1 +
 source3/smbd/smb2_negprot.c    |   8 ++
 source3/smbd/smb2_sesssetup.c  | 205 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 211 insertions(+), 3 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 8528770..5fc3603 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;
+		boolean8		server_multi_channel_enabled;
 	} smbXsrv_client;
 
 	/* sessions */
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index c04fbca..1582072 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->server_multi_channel_enabled)
+	{
+		if (in_capabilities & SMB2_CAP_MULTI_CHANNEL) {
+			capabilities |= SMB2_CAP_MULTI_CHANNEL;
+		}
+	}
+
 	security_offset = SMB2_HDR_BODY + 0x40;
 
 #if 1
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index a6c66e2..a95f8a1 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;
@@ -589,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);
@@ -609,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->server_multi_channel_enabled) {
+			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,
@@ -780,6 +965,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,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list