]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:smb2: add padding to last command in compound requests
authorRalph Boehme <slow@samba.org>
Thu, 28 May 2015 07:02:17 +0000 (09:02 +0200)
committerKarolin Seeger <kseeger@samba.org>
Mon, 1 Jun 2015 21:46:18 +0000 (23:46 +0200)
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>
(cherry picked from commit dfa64b958b201931e0dbe11f153f606f20217594)

source3/smbd/smb2_server.c

index a4e149fc0df41f8e932744bc224e4167302f769e..eed0b0e380ab49ac0c2bc8a5f21afac70b9559fd 100644 (file)
@@ -2517,8 +2517,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);
@@ -2572,8 +2577,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);
 }