libcli/smb: fix smb2cli_ioctl*() against Windows 2008.
authorStefan Metzmacher <metze@samba.org>
Mon, 28 Oct 2013 14:43:03 +0000 (15:43 +0100)
committerKarolin Seeger <kseeger@samba.org>
Wed, 6 Nov 2013 11:33:54 +0000 (12:33 +0100)
The subsections of [MS-SMB2] "3.2.5.14 Receiving an SMB2 IOCTL Response"
say the client should ignore the InputOffset/InputCount.

We do that only if we ask for max_input_length = 0.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=10232

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Oct 31 01:16:10 CET 2013 on sn-devel-104
(cherry picked from commit 127fc670a39d15eaa3869045fca0287ba7df9efa)

libcli/smb/smb2cli_ioctl.c

index 687c9d5110b867bdb6a51e287d28445ed1264253..90c3a2cd4cc8e2105440cd6700f740327f78281b 100644 (file)
@@ -201,7 +201,21 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
                        return;
                }
 
-               if (input_buffer_length < dyn_len) {
+               ofs = input_buffer_length;
+               ofs = NDR_ROUND(ofs, 8);
+
+               if (state->max_input_length == 0) {
+                       /*
+                        * If max_input_length is 0 we ignore
+                        * the input_buffer_length, because
+                        * Windows 2008 echos the DCERPC request
+                        * from the requested input_buffer
+                        * to the response input_buffer.
+                        */
+                       input_buffer_length = 0;
+               }
+
+               if (input_buffer_length > dyn_len) {
                        tevent_req_nterror(
                                req, NT_STATUS_INVALID_NETWORK_RESPONSE);
                        return;
@@ -216,8 +230,11 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
                state->out_input_buffer.data = dyn;
                state->out_input_buffer.length = input_buffer_length;
 
-               ofs = input_buffer_length;
-               ofs = NDR_ROUND(ofs, 8);
+               if (ofs > dyn_len) {
+                       tevent_req_nterror(
+                               req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+                       return;
+               }
 
                dyn_ofs += ofs;
                dyn += ofs;
@@ -231,7 +248,15 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
                        return;
                }
 
-               if (output_buffer_length < dyn_len) {
+               if (state->max_output_length == 0) {
+                       /*
+                        * We do the same logic as for
+                        * max_input_length.
+                        */
+                       output_buffer_length = 0;
+               }
+
+               if (output_buffer_length > dyn_len) {
                        tevent_req_nterror(
                                req, NT_STATUS_INVALID_NETWORK_RESPONSE);
                        return;