s3:smb2_server: add smbd_smb2_request_verify_sizes()
authorStefan Metzmacher <metze@samba.org>
Mon, 3 Oct 2011 21:50:48 +0000 (14:50 -0700)
committerKarolin Seeger <kseeger@samba.org>
Wed, 12 Oct 2011 18:48:35 +0000 (20:48 +0200)
metze.

source3/smbd/globals.h
source3/smbd/smb2_server.c

index abeaed41d43a2261c26f4565be0f13ab7d623407..70338489402427c91ed30ca6e9ff8ec755c23e71 100644 (file)
@@ -278,6 +278,9 @@ NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req);
 struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req);
 void remove_smb2_chained_fsp(files_struct *fsp);
 
+NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
+                                       size_t expected_body_size);
+
 NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req);
index cad4ca662a016bcb34af444d0f24c588749201cf..811e6d3d65be06eaee037102b20adb2d03aac74c 100644 (file)
@@ -1125,6 +1125,48 @@ static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
        return NT_STATUS_OK;
 }
 
+NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
+                                       size_t expected_body_size)
+{
+       const uint8_t *inbody;
+       int i = req->current_idx;
+       size_t body_size;
+
+       /*
+        * The following should be checked already.
+        */
+       if ((i+2) > req->in.vector_count) {
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+       if (req->in.vector[i+0].iov_len != SMB2_HDR_BODY) {
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+       if (req->in.vector[i+1].iov_len < 2) {
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       /*
+        * Now check the expected body size,
+        * where the last byte might be in the
+        * dynnamic section..
+        */
+       if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+       if (req->in.vector[i+2].iov_len < (expected_body_size & 0x00000001)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       inbody = (const uint8_t *)req->in.vector[i+1].iov_base;
+
+       body_size = SVAL(inbody, 0x00);
+       if (body_size != expected_body_size) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       return NT_STATUS_OK;
+}
+
 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 {
        const uint8_t *inhdr;