summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/smb_server/smb2/negprot.c2
-rw-r--r--source4/smb_server/smb2/receive.c21
-rw-r--r--source4/smb_server/smb2/sesssetup.c14
-rw-r--r--source4/smb_server/smb_server.h7
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;