diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-11-27 19:10:01 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2015-12-01 00:38:23 +0100 |
commit | 0e8d33fb5ffd6fdb0e503c5ff59e3635bbf10041 (patch) | |
tree | 667d3dc36a333470095cced05252b3a3b51cb963 /libcli | |
parent | 68850f3f56e9b28b298c1bc3a6249f9c26602217 (diff) | |
download | samba-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.c | 53 |
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; } |