summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2011-11-15 11:27:56 -0800
committerJeremy Allison <jra@samba.org>2011-11-15 22:44:25 +0100
commit65566dfa8629136eaf0dc1491502dc651d1a4858 (patch)
treeb6695ebf5ca9f45775f33460f8f7cc3d65d138f1
parentc4763385a883dcdec7f2101ae65c5a45642c247c (diff)
downloadsamba-65566dfa8629136eaf0dc1491502dc651d1a4858.tar.gz
samba-65566dfa8629136eaf0dc1491502dc651d1a4858.tar.xz
samba-65566dfa8629136eaf0dc1491502dc651d1a4858.zip
Ensure we correctly calculate reply credits over all returned
SMB2 replies, and do as Windows does and return the total in the last SMB2 reply. Fixes an issue found by Christian M Ambach <christian.ambach@de.ibm.com> (and thanks to Christian for the initial patch this was based on).
-rw-r--r--source3/smbd/smb2_server.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index dbb0089d70..851e2fd7ef 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -517,13 +517,24 @@ static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
struct smbd_smb2_request *outreq)
{
int count, idx;
+ uint16_t total_credits = 0;
count = outreq->out.vector_count;
for (idx=1; idx < count; idx += 3) {
+ uint8_t *outhdr = (uint8_t *)outreq->out.vector[idx].iov_base;
smb2_set_operation_credit(outreq->sconn,
&inreq->in.vector[idx],
&outreq->out.vector[idx]);
+ /* To match Windows, count up what we
+ just granted. */
+ total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
+ /* Set to zero in all but the last reply. */
+ if (idx + 3 < count) {
+ SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
+ } else {
+ SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
+ }
}
}
@@ -1851,11 +1862,9 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
- /* Set credit for this operation (zero credits if this
+ /* Set credit for these operations (zero credits if this
is a final reply for an async operation). */
- smb2_set_operation_credit(req->sconn,
- &req->in.vector[i],
- &req->out.vector[i]);
+ smb2_calculate_credits(req, req);
if (req->do_signing) {
NTSTATUS status;