From b5ec6a91f8d08e2e6c2540dc3ce48cc884649e18 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Oct 2013 15:43:03 +0100 Subject: [PATCH] libcli/smb: fix smb2cli_ioctl*() against Windows 2008. 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 Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison 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 | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/libcli/smb/smb2cli_ioctl.c b/libcli/smb/smb2cli_ioctl.c index 687c9d5..90c3a2c 100644 --- a/libcli/smb/smb2cli_ioctl.c +++ b/libcli/smb/smb2cli_ioctl.c @@ -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; -- 1.7.9.5