s3:smbd: make use of better SMB signing negotiation
authorStefan Metzmacher <metze@samba.org>
Mon, 12 Sep 2011 07:19:06 +0000 (09:19 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 14 Sep 2011 07:41:02 +0000 (09:41 +0200)
metze

Autobuild-User: Stefan Metzmacher <metze@samba.org>
Autobuild-Date: Wed Sep 14 09:41:02 CEST 2011 on sn-devel-104

source3/smbd/negprot.c
source3/smbd/proto.h
source3/smbd/sesssetup.c
source3/smbd/signing.c

index 71e0291c776c0a2e63066737e9bbaac14b7246f7..89ef52c6e8657fef6badb8bc964cdcdb08b3c366 100644 (file)
@@ -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) {
index 8edd69507ccfd09af1bac4f75b091b76851afc3a..3d0665deafd5049cefe412f4e431d4ba1199f1ef 100644 (file)
@@ -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,
index 6dc8609071d0f3bae3f2541a83baee0a6e53ea80..28ae24e95f8698a448f63382b7ae0982beed3f18 100644 (file)
@@ -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 &&
index 1ae8ffca367329e48c5fe8544fb968d542f29bf0..bdf920c91a87d39bb37f04db0b8c011a64c11634 100644 (file)
@@ -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);
 }
 
 /***********************************************************