diff options
author | David Disseldorp <ddiss@suse.de> | 2013-01-15 17:23:01 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2013-01-16 23:15:07 +0100 |
commit | 65983aac12e5ecb12157b39c7bec464388716f27 (patch) | |
tree | 1645ad9904b5c477666ccdb050957d2458f90118 /source4/libcli/smb2 | |
parent | e38d9f71d90e6b20a027d91d4768d91378728621 (diff) | |
download | samba-65983aac12e5ecb12157b39c7bec464388716f27.tar.gz samba-65983aac12e5ecb12157b39c7bec464388716f27.tar.bz2 samba-65983aac12e5ecb12157b39c7bec464388716f27.zip |
smb2_ioctl: remove ioctl error response assumptions
MS-SMB2 3.3.4.4 documents cases where a ntstatus indicating an error
should not be considered a failure. In such a case the output data
buffer should be sent to the client rather than an error response
packet.
Add a new fsctl copy_chunk test to confirm field limits are sent back
in response to an oversize chunk request.
Reviewed by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source4/libcli/smb2')
-rw-r--r-- | source4/libcli/smb2/ioctl.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/source4/libcli/smb2/ioctl.c b/source4/libcli/smb2/ioctl.c index d81bca517f..c0a637eb1a 100644 --- a/source4/libcli/smb2/ioctl.c +++ b/source4/libcli/smb2/ioctl.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include "librpc/gen_ndr/ioctl.h" /* send a ioctl request @@ -61,17 +62,47 @@ struct smb2_request *smb2_ioctl_send(struct smb2_tree *tree, struct smb2_ioctl * return req; } +/* + * 3.3.4.4 Sending an Error Response + */ +static bool smb2_ioctl_is_failure(uint32_t ctl_code, NTSTATUS status, + size_t data_size) +{ + if (NT_STATUS_IS_OK(status)) { + return false; + } + + if (NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW) + && ((ctl_code == FSCTL_PIPE_TRANSCEIVE) + || (ctl_code == FSCTL_PIPE_PEEK) + || (ctl_code == FSCTL_DFS_GET_REFERRALS))) { + return false; + } + + if (((ctl_code == FSCTL_SRV_COPYCHUNK) + || (ctl_code == FSCTL_SRV_COPYCHUNK_WRITE)) + && (data_size == sizeof(struct srv_copychunk_rsp))) { + /* + * copychunk responses may come with copychunk data or error + * response data, independent of status. + */ + return false; + } + + return true; +} /* recv a ioctl reply */ -NTSTATUS smb2_ioctl_recv(struct smb2_request *req, +NTSTATUS smb2_ioctl_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_ioctl *io) { NTSTATUS status; - if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + if (!smb2_request_receive(req) || + smb2_ioctl_is_failure(io->in.function, req->status, + req->in.bufinfo.data_size)) { return smb2_request_destroy(req); } |