summaryrefslogtreecommitdiff
path: root/libcli
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-11-27 19:10:01 +0100
committerJeremy Allison <jra@samba.org>2015-12-01 00:38:23 +0100
commit0e8d33fb5ffd6fdb0e503c5ff59e3635bbf10041 (patch)
tree667d3dc36a333470095cced05252b3a3b51cb963 /libcli
parent68850f3f56e9b28b298c1bc3a6249f9c26602217 (diff)
downloadsamba-0e8d33fb5ffd6fdb0e503c5ff59e3635bbf10041.tar.gz
libcli/smb: correctly handle STATUS_BUFFER_OVERFLOW in smb1cli_readx*
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11623 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'libcli')
-rw-r--r--libcli/smb/smb1cli_read.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/libcli/smb/smb1cli_read.c b/libcli/smb/smb1cli_read.c
index ab250abf143..d7a7f43e66e 100644
--- a/libcli/smb/smb1cli_read.c
+++ b/libcli/smb/smb1cli_read.c
@@ -26,9 +26,9 @@
struct smb1cli_readx_state {
uint32_t size;
uint16_t vwv[12];
- NTSTATUS status;
uint32_t received;
uint8_t *buf;
+ bool out_valid;
};
static void smb1cli_readx_done(struct tevent_req *subreq);
@@ -131,27 +131,36 @@ static void smb1cli_readx_done(struct tevent_req *subreq)
uint8_t *bytes;
uint16_t data_offset;
uint32_t bytes_offset;
+ NTSTATUS status;
static const struct smb1cli_req_expected_response expected[] = {
{
.status = NT_STATUS_OK,
.wct = 0x0C
},
+ {
+ .status = STATUS_BUFFER_OVERFLOW,
+ .wct = 0x0C
+ },
};
- state->status = smb1cli_req_recv(subreq, state,
- &recv_iov,
- NULL, /* phdr */
- &wct,
- &vwv,
- NULL, /* pvwv_offset */
- &num_bytes,
- &bytes,
- &bytes_offset,
- NULL, /* inbuf */
- expected, ARRAY_SIZE(expected));
+ status = smb1cli_req_recv(subreq, state,
+ &recv_iov,
+ NULL, /* phdr */
+ &wct,
+ &vwv,
+ NULL, /* pvwv_offset */
+ &num_bytes,
+ &bytes,
+ &bytes_offset,
+ NULL, /* inbuf */
+ expected, ARRAY_SIZE(expected));
TALLOC_FREE(subreq);
- if (tevent_req_nterror(req, state->status)) {
- return;
+ if (NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
+ /* no error */
+ } else {
+ if (tevent_req_nterror(req, status)) {
+ return;
+ }
}
/* size is the number of bytes the server returned.
@@ -189,6 +198,12 @@ static void smb1cli_readx_done(struct tevent_req *subreq)
state->buf = bytes + (data_offset - bytes_offset);
+ state->out_valid = true;
+
+ if (tevent_req_nterror(req, status)) {
+ return;
+ }
+
tevent_req_done(req);
}
@@ -205,7 +220,7 @@ static void smb1cli_readx_done(struct tevent_req *subreq)
* @param[out] received The number of bytes received.
* @param[out] rcvbuf Pointer to the bytes received.
*
- * @return NT_STATUS_OK on succsess.
+ * @return NT_STATUS_OK or STATUS_BUFFER_OVERFLOW on succsess.
*/
NTSTATUS smb1cli_readx_recv(struct tevent_req *req,
uint32_t *received,
@@ -213,12 +228,14 @@ NTSTATUS smb1cli_readx_recv(struct tevent_req *req,
{
struct smb1cli_readx_state *state = tevent_req_data(
req, struct smb1cli_readx_state);
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
- if (tevent_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status) && !state->out_valid) {
+ *received = 0;
+ *rcvbuf = NULL;
return status;
}
*received = state->received;
*rcvbuf = state->buf;
- return NT_STATUS_OK;
+ return status;
}