summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/negprot.c1
-rw-r--r--source3/smbd/proto.h3
-rw-r--r--source3/smbd/sesssetup.c18
-rw-r--r--source3/smbd/signing.c13
4 files changed, 31 insertions, 4 deletions
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 71e0291c77..89ef52c6e8 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -375,7 +375,6 @@ static void reply_nt1(struct smb_request *req, uint16 choice)
capabilities &= ~CAP_RAW_MODE;
if (lp_server_signing() == Required)
secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
- srv_set_signing_negotiated(sconn);
} else {
DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
if (lp_server_signing() == Required) {
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 8edd69507c..3d0665deaf 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -54,7 +54,8 @@ void srv_calculate_sign_mac(struct smbd_server_connection *conn,
char *outbuf, uint32_t seqnum);
void srv_cancel_sign_response(struct smbd_server_connection *conn);
bool srv_init_signing(struct smbd_server_connection *conn);
-void srv_set_signing_negotiated(struct smbd_server_connection *conn);
+void srv_set_signing_negotiated(struct smbd_server_connection *conn,
+ bool allowed, bool mandatory);
bool srv_is_signing_active(struct smbd_server_connection *conn);
bool srv_is_signing_negotiated(struct smbd_server_connection *conn);
void srv_set_signing(struct smbd_server_connection *conn,
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 6dc8609071..28ae24e95f 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -1306,6 +1306,8 @@ void reply_sesssetup_and_X(struct smb_request *req)
struct smbd_server_connection *sconn = req->sconn;
bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
+ bool signing_allowed = false;
+ bool signing_mandatory = false;
START_PROFILE(SMBsesssetupX);
@@ -1315,6 +1317,22 @@ void reply_sesssetup_and_X(struct smb_request *req)
DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
+ if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
+ signing_allowed = true;
+ }
+ if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
+ signing_mandatory = true;
+ }
+
+ /*
+ * We can call srv_set_signing_negotiated() each time.
+ * It finds out when it needs to turn into a noop
+ * itself.
+ */
+ srv_set_signing_negotiated(req->sconn,
+ signing_allowed,
+ signing_mandatory);
+
/* a SPNEGO session setup has 12 command words, whereas a normal
NT1 session setup has 13. See the cifs spec. */
if (req->wct == 12 &&
diff --git a/source3/smbd/signing.c b/source3/smbd/signing.c
index 1ae8ffca36..bdf920c91a 100644
--- a/source3/smbd/signing.c
+++ b/source3/smbd/signing.c
@@ -173,6 +173,14 @@ bool srv_init_signing(struct smbd_server_connection *conn)
break;
}
+ /*
+ * if the client and server allow signing,
+ * we desire to use it.
+ *
+ * This matches Windows behavior and is needed
+ * because not every client that requires signing
+ * sends FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED.
+ */
desired = allowed;
if (lp_async_smb_echo_handler()) {
@@ -210,10 +218,11 @@ bool srv_init_signing(struct smbd_server_connection *conn)
return true;
}
-void srv_set_signing_negotiated(struct smbd_server_connection *conn)
+void srv_set_signing_negotiated(struct smbd_server_connection *conn,
+ bool allowed, bool mandatory)
{
smb_signing_set_negotiated(conn->smb1.signing_state,
- true, false);
+ allowed, mandatory);
}
/***********************************************************