diff options
-rw-r--r-- | source4/smb_server/smb2/negprot.c | 2 | ||||
-rw-r--r-- | source4/smb_server/smb2/receive.c | 21 | ||||
-rw-r--r-- | source4/smb_server/smb2/sesssetup.c | 14 | ||||
-rw-r--r-- | source4/smb_server/smb_server.h | 7 |
4 files changed, 31 insertions, 13 deletions
diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 3e6e2e1a43..d64b36d659 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -122,7 +122,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 case SMB_SIGNING_REQUIRED: io->out.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; /* force signing on immediately */ - req->smb_conn->doing_signing = true; + req->smb_conn->smb2_signing_required = true; break; } io->out.dialect_revision = SMB2_DIALECT_REVISION; diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c index 2f4e9df2b6..cfd6c1d01a 100644 --- a/source4/smb_server/smb2/receive.c +++ b/source4/smb_server/smb2/receive.c @@ -235,11 +235,8 @@ void smb2srv_send_reply(struct smb2srv_request *req) _smb2_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); } - /* if the request was signed or doing_signing is true, then we - must sign the reply */ - if (req->session && - (req->smb_conn->doing_signing || - (IVAL(req->in.hdr, SMB2_HDR_FLAGS) & SMB2_HDR_FLAG_SIGNED))) { + /* if signing is active on the session then sign the packet */ + if (req->session && req->session->smb2_signing.active) { status = smb2_sign_message(&req->out, req->session->session_info->session_key); if (!NT_STATUS_IS_OK(status)) { @@ -310,18 +307,22 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req) should give a signed reply to any signed request */ if (flags & SMB2_HDR_FLAG_SIGNED) { NTSTATUS status; - if (req->session == NULL) { - /* we can't check signing with no session */ - smb2srv_send_error(req, NT_STATUS_ACCESS_DENIED); - return NT_STATUS_OK; + + if (!req->session) goto nosession; + + if (!req->session->smb2_signing.active) { + /* TODO: workout the correct error code */ + smb2srv_send_error(req, NT_STATUS_FOOBAR); + return NT_STATUS_OK; } + status = smb2_check_signature(&req->in, req->session->session_info->session_key); if (!NT_STATUS_IS_OK(status)) { smb2srv_send_error(req, status); return NT_STATUS_OK; } - } else if (req->smb_conn->doing_signing && req->session != NULL) { + } else if (req->session && req->session->smb2_signing.active) { /* we require signing and this request was not signed */ smb2srv_send_error(req, NT_STATUS_ACCESS_DENIED); return NT_STATUS_OK; diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c index 9fb3220005..6e3e963794 100644 --- a/source4/smb_server/smb2/sesssetup.c +++ b/source4/smb_server/smb2/sesssetup.c @@ -90,6 +90,10 @@ static void smb2srv_sesssetup_callback(struct gensec_update_request *greq, void } req->session = smb_sess; + if (smb_sess->smb2_signing.required) { + /* activate smb2 signing on the session */ + smb_sess->smb2_signing.active = true; + } done: io->smb2.out.uid = smb_sess->vuid; failed: @@ -182,7 +186,15 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses This is deliberate as windows does not set it even when it does set SMB2_NEGOTIATE_SIGNING_REQUIRED */ if (io->smb2.in.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { - req->smb_conn->doing_signing = true; + smb_sess->smb2_signing.required = true; + } else if (req->smb_conn->smb2_signing_required) { + /* + * if required signing was negotiates in SMB2 Negotiate + * then the client made an error not using it here + */ + DEBUG(1, ("SMB2 signing required on the connection but not used on session\n")); + req->status = NT_STATUS_FOOBAR; + goto failed; } return; diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index dd4ec3281b..4676fc3e9c 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -100,6 +100,11 @@ struct smbsrv_session { struct auth_session_info *session_info; + struct { + bool required; + bool active; + } smb2_signing; + /* some statistics for the management tools */ struct { /* the time when the session setup started */ @@ -380,7 +385,7 @@ struct smbsrv_connection { struct loadparm_context *lp_ctx; - bool doing_signing; + bool smb2_signing_required; }; struct model_ops; |