smbd: Process error reply if SMB1 negprot parsing fails
authorDavid Mulder <dmulder@suse.com>
Wed, 30 Mar 2022 08:57:21 +0000 (02:57 -0600)
committerJeremy Allison <jra@samba.org>
Thu, 7 Apr 2022 17:37:30 +0000 (17:37 +0000)
Signed-off-by: David Mulder <dmulder@suse.com>
Signed-off-by: Jeremy Allison <jra@samba.org>
source3/smbd/globals.h
source3/smbd/smb2_negprot.c
source3/smbd/smb2_process.c

index eb2fcdfb154c4874fbe5016c8c96d926da7ca1d7..7719d9297f56bda82fe2b94339701b2deb07c533 100644 (file)
@@ -249,7 +249,7 @@ NTSTATUS reply_smb20ff(struct smb_request *req, uint16_t choice);
 NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
                               uint64_t expected_seq_low,
                               const uint8_t *inpdu, size_t size);
-void smb2_multi_protocol_reply_negprot(struct smb_request *req);
+NTSTATUS smb2_multi_protocol_reply_negprot(struct smb_request *req);
 
 DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size);
 
index 01ffc4ad84ae28b6a1408e04d7ecd12c65dbf0aa..4abc4b7b01c181fb70e0655724b2990279b8d177 100644 (file)
@@ -1047,7 +1047,7 @@ static const struct {
  conn POINTER CAN BE NULL HERE !
 ****************************************************************************/
 
-void smb2_multi_protocol_reply_negprot(struct smb_request *req)
+NTSTATUS smb2_multi_protocol_reply_negprot(struct smb_request *req)
 {
        size_t choice = 0;
        bool choice_set = false;
@@ -1070,14 +1070,14 @@ void smb2_multi_protocol_reply_negprot(struct smb_request *req)
                DEBUG(0, ("negprot got no protocols\n"));
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBnegprot);
-               return;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        if (req->buf[req->buflen-1] != '\0') {
                DEBUG(0, ("negprot protocols not 0-terminated\n"));
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBnegprot);
-               return;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        p = (const char *)req->buf + 1;
@@ -1096,7 +1096,7 @@ void smb2_multi_protocol_reply_negprot(struct smb_request *req)
                        TALLOC_FREE(cliprotos);
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
                        END_PROFILE(SMBnegprot);
-                       return;
+                       return NT_STATUS_NO_MEMORY;
                }
 
                cliprotos = tmp;
@@ -1107,7 +1107,7 @@ void smb2_multi_protocol_reply_negprot(struct smb_request *req)
                        TALLOC_FREE(cliprotos);
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
                        END_PROFILE(SMBnegprot);
-                       return;
+                       return NT_STATUS_NO_MEMORY;
                }
 
                DEBUG(3, ("Requested protocol [%s]\n",
@@ -1191,5 +1191,5 @@ void smb2_multi_protocol_reply_negprot(struct smb_request *req)
        TALLOC_FREE(cliprotos);
 
        END_PROFILE(SMBnegprot);
-       return;
+       return NT_STATUS_OK;
 }
index 64b3bcaf83e47ab0719fee8afcf1923ecff687ff..b6da2c6a87bc59671a59d3034190491e5fa7c1a1 100644 (file)
@@ -828,6 +828,7 @@ static void construct_reply_smb1negprot(struct smbXsrv_connection *xconn,
 {
        struct smbd_server_connection *sconn = xconn->client->sconn;
        struct smb_request *req;
+       NTSTATUS status;
 
        if (!(req = talloc(talloc_tos(), struct smb_request))) {
                smb_panic("could not allocate smb_request");
@@ -840,16 +841,28 @@ static void construct_reply_smb1negprot(struct smbXsrv_connection *xconn,
 
        req->inbuf  = (uint8_t *)talloc_move(req, &inbuf);
 
-       smb2_multi_protocol_reply_negprot(req);
+       status = smb2_multi_protocol_reply_negprot(req);
        if (req->outbuf == NULL) {
                /*
                * req->outbuf == NULL means we bootstrapped into SMB2.
                */
                return;
        }
-       /* This code path should only *ever* bootstrap into SMB2. */
-       exit_server_cleanly("Internal error SMB1negprot didn't reply "
-                           "with an SMB2 packet");
+       if (!NT_STATUS_IS_OK(status)) {
+               if (!srv_send_smb(req->xconn,
+                                 (char *)req->outbuf,
+                                 true, req->seqnum+1,
+                                 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
+                                 &req->pcd)) {
+                       exit_server_cleanly("construct_reply_smb1negprot: "
+                                           "srv_send_smb failed.");
+               }
+               TALLOC_FREE(req);
+       } else {
+               /* This code path should only *ever* bootstrap into SMB2. */
+               exit_server_cleanly("Internal error SMB1negprot didn't reply "
+                                   "with an SMB2 packet");
+       }
 }
 
 static void smbd_server_connection_write_handler(