libcli/smb: don't overwrite status code
[vlendec/samba-autobuild/.git] / libcli / smb / smbXcli_base.c
index ea7ca22f6447dea01ff2bbb18c40a3a9486e1847..40480c83aa05b62949b93bae543342f5716880d5 100644 (file)
@@ -3799,14 +3799,29 @@ static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
                                 */
                                signing_key = NULL;
                        }
+
+                       if (!NT_STATUS_IS_OK(status)) {
+                               /*
+                                * Only check the signature of the last response
+                                * of a successfull session auth. This matches
+                                * Windows behaviour for NTLM auth and reauth.
+                                */
+                               state->smb2.require_signed_response = false;
+                       }
                }
 
-               if (state->smb2.should_sign) {
+               if (state->smb2.should_sign ||
+                   state->smb2.require_signed_response)
+               {
                        if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
                                return NT_STATUS_ACCESS_DENIED;
                        }
                }
 
+               if (signing_key == NULL && state->smb2.require_signed_response) {
+                       signing_key = &session->smb2_channel.signing_key;
+               }
+
                if (cur[0].iov_len == SMB2_TF_HDR_SIZE) {
                        const uint8_t *tf = (const uint8_t *)cur[0].iov_base;
                        uint64_t uid = BVAL(tf, SMB2_TF_SESSION_ID);
@@ -3893,15 +3908,17 @@ static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
                }
 
                if (signing_key) {
-                       status = smb2_signing_check_pdu(*signing_key,
-                                                       state->conn->protocol,
-                                                       &cur[1], 3);
-                       if (!NT_STATUS_IS_OK(status)) {
+                       NTSTATUS signing_status;
+
+                       signing_status = smb2_signing_check_pdu(*signing_key,
+                                                               state->conn->protocol,
+                                                               &cur[1], 3);
+                       if (!NT_STATUS_IS_OK(signing_status)) {
                                /*
                                 * If the signing check fails, we disconnect
                                 * the connection.
                                 */
-                               return status;
+                               return signing_status;
                        }
                }