From 3bb299944391633c45d87d5e8ad48c2c14428592 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 1 Jul 2015 17:42:58 +0200 Subject: [PATCH] smbd:smb2: separate between encryption required and enc desired this means we: - accept unencrypted requests if encryption only desired and not required, - but we always send encrypted responses in the desired case, not only when the request was encrypted. For this purpose, the do_encryption in the request structure is separated into was_encrypted and do_encryption. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Signed-off-by: Michael Adam Reviewed-by: Guenther Deschner --- source3/smbd/globals.h | 3 +++ source3/smbd/smb2_server.c | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 3ddafafa49b..2ca23aa37d1 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -654,6 +654,9 @@ struct smbd_smb2_request { int current_idx; bool do_signing; + /* Was the request encrypted? */ + bool was_encrypted; + /* Should we encrypt? */ bool do_encryption; struct tevent_timer *async_te; bool compound_related; diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index a8d54cbd019..97e99a0be3c 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -2000,6 +2000,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) NTSTATUS return_value; struct smbXsrv_session *x = NULL; bool signing_required = false; + bool encryption_desired = false; bool encryption_required = false; inhdr = SMBD_SMB2_IN_HDR_PTR(req); @@ -2047,11 +2048,13 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) x = req->session; if (x != NULL) { signing_required = x->global->signing_required; + encryption_desired = x->encryption_desired; encryption_required = x->global->encryption_required; } req->do_signing = false; req->do_encryption = false; + req->was_encrypted = false; if (intf_v->iov_len == SMB2_TF_HDR_SIZE) { const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req); uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID); @@ -2073,10 +2076,10 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) NT_STATUS_ACCESS_DENIED); } - req->do_encryption = true; + req->was_encrypted = true; } - if (encryption_required && !req->do_encryption) { + if (encryption_required && !req->was_encrypted) { return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED); } @@ -2116,7 +2119,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) req->compat_chain_fsp = NULL; } - if (req->do_encryption) { + if (req->was_encrypted) { signing_required = false; } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) { DATA_BLOB signing_key = data_blob_null; @@ -2202,15 +2205,22 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } + if (req->tcon->encryption_desired) { + encryption_desired = true; + } if (req->tcon->global->encryption_required) { encryption_required = true; } - if (encryption_required && !req->do_encryption) { + if (encryption_required && !req->was_encrypted) { return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED); } } + if (req->was_encrypted || encryption_desired) { + req->do_encryption = true; + } + if (call->fileid_ofs != 0) { size_t needed = call->fileid_ofs + 16; const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req); -- 2.11.4.GIT