[PATCH] smb 3.1.1 : require a signed tcon request

Michael Adam obnox at samba.org
Fri Jun 5 08:34:38 MDT 2015


Attached find a patch by Metze, that has already undergone a
round of review by me. The patch implements the check for
a signed tcon request that SMB 3.1.1 requires.

Further review/push/comments welcome,

Thanks - Michael
-------------- next part --------------
From ebcc1207ce014106214734f7cca317184cadfa24 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 28 May 2015 15:35:25 +0200
Subject: [PATCH] s3:smb2_tcon: require a signed request when authentication is
 used for SMB >= 3.11

Disconnect the client if the request is not signed.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
---
 source3/smbd/smb2_tcon.c | 49 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 40 insertions(+), 9 deletions(-)

diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index 3750bc1..eb66ea0 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -36,7 +36,8 @@ static NTSTATUS smbd_smb2_tree_connect_recv(struct tevent_req *req,
 					    uint32_t *out_share_flags,
 					    uint32_t *out_capabilities,
 					    uint32_t *out_maximal_access,
-					    uint32_t *out_tree_id);
+					    uint32_t *out_tree_id,
+					    bool *disconnect);
 
 static void smbd_smb2_request_tcon_done(struct tevent_req *subreq);
 
@@ -113,6 +114,7 @@ static void smbd_smb2_request_tcon_done(struct tevent_req *subreq)
 	uint32_t out_capabilities = 0;
 	uint32_t out_maximal_access = 0;
 	uint32_t out_tree_id = 0;
+	bool disconnect = false;
 	NTSTATUS status;
 	NTSTATUS error;
 
@@ -121,9 +123,15 @@ static void smbd_smb2_request_tcon_done(struct tevent_req *subreq)
 					     &out_share_flags,
 					     &out_capabilities,
 					     &out_maximal_access,
-					     &out_tree_id);
+					     &out_tree_id,
+					     &disconnect);
 	TALLOC_FREE(subreq);
 	if (!NT_STATUS_IS_OK(status)) {
+		if (disconnect) {
+			smbd_server_connection_terminate(req->xconn,
+							 nt_errstr(status));
+			return;
+		}
 		error = smbd_smb2_request_error(req, status);
 		if (!NT_STATUS_IS_OK(error)) {
 			smbd_server_connection_terminate(req->xconn,
@@ -173,7 +181,8 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 				       uint32_t *out_share_flags,
 				       uint32_t *out_capabilities,
 				       uint32_t *out_maximal_access,
-				       uint32_t *out_tree_id)
+				       uint32_t *out_tree_id,
+				       bool *disconnect)
 {
 	struct smbXsrv_connection *conn = req->xconn;
 	const char *share = in_path;
@@ -186,6 +195,9 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 	NTSTATUS status;
 	bool encryption_required = req->session->global->encryption_required;
 	bool guest_session = false;
+	bool require_signed_tcon = false;
+
+	*disconnect = false;
 
 	if (strncmp(share, "\\\\", 2) == 0) {
 		const char *p = strchr(share+2, '\\');
@@ -197,6 +209,25 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 	DEBUG(10,("smbd_smb2_tree_connect: path[%s] share[%s]\n",
 		  in_path, share));
 
+	if (security_session_user_level(compat_vuser->session_info, NULL) < SECURITY_USER) {
+		guest_session = true;
+	}
+
+	if (conn->protocol >= PROTOCOL_SMB3_11 && !guest_session) {
+		require_signed_tcon = true;
+	}
+
+	if (require_signed_tcon && !req->do_encryption && !req->do_signing) {
+		DEBUG(1, ("smbd_smb2_tree_connect: reject request to share "
+			  "[%s] as '%s\\%s' without encryption or signing. "
+			  "Disconnecting.\n",
+			  share,
+			  req->session->global->auth_session_info->info->domain_name,
+			  req->session->global->auth_session_info->info->account_name));
+		*disconnect = true;
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	service = talloc_strdup(talloc_tos(), share);
 	if(!service) {
 		return NT_STATUS_NO_MEMORY;
@@ -244,10 +275,6 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 		encryption_required = true;
 	}
 
-	if (security_session_user_level(compat_vuser->session_info, NULL) < SECURITY_USER) {
-		guest_session = true;
-	}
-
 	if (guest_session && encryption_required) {
 		DEBUG(1,("reject guest as encryption is required for service %s\n",
 			 service));
@@ -356,6 +383,7 @@ struct smbd_smb2_tree_connect_state {
 	uint32_t out_capabilities;
 	uint32_t out_maximal_access;
 	uint32_t out_tree_id;
+	bool disconnect;
 };
 
 static struct tevent_req *smbd_smb2_tree_connect_send(TALLOC_CTX *mem_ctx,
@@ -380,7 +408,8 @@ static struct tevent_req *smbd_smb2_tree_connect_send(TALLOC_CTX *mem_ctx,
 					&state->out_share_flags,
 					&state->out_capabilities,
 					&state->out_maximal_access,
-					&state->out_tree_id);
+					&state->out_tree_id,
+					&state->disconnect);
 	if (tevent_req_nterror(req, status)) {
 		return tevent_req_post(req, ev);
 	}
@@ -394,7 +423,8 @@ static NTSTATUS smbd_smb2_tree_connect_recv(struct tevent_req *req,
 					    uint32_t *out_share_flags,
 					    uint32_t *out_capabilities,
 					    uint32_t *out_maximal_access,
-					    uint32_t *out_tree_id)
+					    uint32_t *out_tree_id,
+					    bool *disconnect)
 {
 	struct smbd_smb2_tree_connect_state *state =
 		tevent_req_data(req,
@@ -411,6 +441,7 @@ static NTSTATUS smbd_smb2_tree_connect_recv(struct tevent_req *req,
 	*out_capabilities = state->out_capabilities;
 	*out_maximal_access = state->out_maximal_access;
 	*out_tree_id = state->out_tree_id;
+	*disconnect = state->disconnect;
 
 	tevent_req_received(req);
 	return NT_STATUS_OK;
-- 
2.4.2

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


More information about the samba-technical mailing list