diff options
author | Christian Ambach <ambi@samba.org> | 2012-02-27 17:49:12 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2012-03-09 16:48:15 -0800 |
commit | eec5ece6f59c5ff30de88af0e182c3b2f7b9579c (patch) | |
tree | bef7645ba6993e4d2cb9028536a652e675c12100 /source3/smbd | |
parent | bd0ad2bbb5361a92f349ef42171b9bdd1d99b281 (diff) | |
download | samba-eec5ece6f59c5ff30de88af0e182c3b2f7b9579c.tar.gz samba-eec5ece6f59c5ff30de88af0e182c3b2f7b9579c.tar.bz2 samba-eec5ece6f59c5ff30de88af0e182c3b2f7b9579c.zip |
s3:smb2_server add function to verify creditcharge
Signed-off-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/globals.h | 3 | ||||
-rw-r--r-- | source3/smbd/smb2_server.c | 39 |
2 files changed, 42 insertions, 0 deletions
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 2efaac8330..caf7357df4 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -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); diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 8533157fcb..78b1c8bf76 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -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) { |