]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:smb2_server add function to verify creditcharge
authorChristian Ambach <ambi@samba.org>
Tue, 28 Feb 2012 01:49:12 +0000 (17:49 -0800)
committerJeremy Allison <jra@samba.org>
Sat, 10 Mar 2012 00:48:15 +0000 (16:48 -0800)
Signed-off-by: Jeremy Allison <jra@samba.org>
source3/smbd/globals.h
source3/smbd/smb2_server.c

index 2efaac8330ca4b6c383bdf796727a9d407af4efd..caf7357df435cc760ddee779ce708edb9d28bbcd 100644 (file)
@@ -258,6 +258,9 @@ NTSTATUS smbd_smb2_request_pending_queue(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_creditcharge(struct smbd_smb2_request *req,
+                                              uint32_t data_length);
+
 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
                                        size_t expected_body_size);
 
index 8533157fcb251002b197858ac3515f1eef58e445..78b1c8bf76a1a6ac1e2f42529c0965f6e2451360 100644 (file)
@@ -1252,6 +1252,45 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
        return NT_STATUS_OK;
 }
 
+NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
+                                               uint32_t data_length)
+{
+       uint16_t needed_charge;
+       uint16_t credit_charge;
+       const uint8_t *inhdr;
+       int i = req->current_idx;
+
+       if (!req->sconn->smb2.supports_multicredit) {
+               if (data_length > 65536) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               return NT_STATUS_OK;
+       }
+
+       inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
+       credit_charge = IVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
+
+       /* requests larger than 64 KB need credit charge */
+       if (credit_charge == 0 && data_length > 65536) {
+               DEBUG(2, ("Request larger than 64KB w/o creditcharge\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       needed_charge = (data_length - 1)/ 65536 + 1;
+
+       DEBUG(10, ("mid %lu, CreditCharge: %d, NeededCharge: %d\n",
+                  BVAL(inhdr, SMB2_HDR_MESSAGE_ID), credit_charge,
+                  needed_charge));
+
+       if (needed_charge > credit_charge) {
+               DEBUG(2, ("CreditCharge too low, given %d, needed %d\n",
+                                       credit_charge, needed_charge));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       return NT_STATUS_OK;
+}
+
 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
                                        size_t expected_body_size)
 {