summaryrefslogtreecommitdiff
path: root/source3/smbd/smb2_server.c
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2015-05-28 09:02:17 +0200
committerRalph Böhme <slow@samba.org>2015-05-28 14:01:30 +0200
commitdfa64b958b201931e0dbe11f153f606f20217594 (patch)
treeda608926debd38b23eb100f4893318406e71874b /source3/smbd/smb2_server.c
parenta4cc7d4746b1fff8bdad489233132bd6f3eef270 (diff)
downloadsamba-dfa64b958b201931e0dbe11f153f606f20217594.tar.gz
s3:smb2: add padding to last command in compound requests
Following Windows behaviour, the last command in a compound request should be padded to an 8 byte boundary and OS X clients crash badly if we don't pad. [MS-SMB2] 3.3.4.1.3, "Sending Compounded Responses", doesn't make it clear whether the padding requirement governs the last command in a compound response, a future MS-SMB2 update will document Windwows product behaviour in a footnote. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11277 Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Signed-off-by: Ralph Boehme <slow@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source3/smbd/smb2_server.c')
-rw-r--r--source3/smbd/smb2_server.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 9e5eff7cb60..38590a9ace5 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2654,8 +2654,13 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
outdyn_v->iov_len = 0;
}
- /* see if we need to recalculate the offset to the next response */
- if (next_command_ofs > 0) {
+ /*
+ * See if we need to recalculate the offset to the next response
+ *
+ * Note that all responses may require padding (including the very last
+ * one).
+ */
+ if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
next_command_ofs = SMB2_HDR_BODY;
next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
@@ -2709,8 +2714,11 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
next_command_ofs += pad_size;
}
- SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
-
+ if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
+ SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
+ } else {
+ SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
+ }
return smbd_smb2_request_reply(req);
}