>From 7f8f66ed728624fc311369bf369cd826681ce9d3 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 30 Jun 2014 11:28:15 +0100 Subject: [PATCH 3/5] make it possible to dynamically set the max_data in SMB Pipe transaction I've observed WSP requests change the max_data param between requests, additionally those max_data values considerably exceed the TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE limit. --- libcli/smb/tstream_smbXcli_np.c | 22 ++++++++++++++++++---- libcli/smb/tstream_smbXcli_np.h | 3 +++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/libcli/smb/tstream_smbXcli_np.c b/libcli/smb/tstream_smbXcli_np.c index c32fd6f..b2d2e12 100644 --- a/libcli/smb/tstream_smbXcli_np.c +++ b/libcli/smb/tstream_smbXcli_np.c @@ -63,6 +63,7 @@ struct tstream_smbXcli_np { struct tevent_req *read_req; struct tevent_req *write_req; uint16_t setup[2]; + uint32_t max_data; } trans; struct { @@ -354,7 +355,7 @@ NTSTATUS _tstream_smbXcli_np_open_recv(struct tevent_req *req, cli_nps->fnum = state->fnum; cli_nps->fid_persistent = state->fid_persistent; cli_nps->fid_volatile = state->fid_volatile; - + cli_nps->trans.max_data = TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE; talloc_set_destructor(cli_nps, tstream_smbXcli_np_destructor); talloc_set_destructor(cli_nps->conn_ref, tstream_smbXcli_np_ref_destructor); @@ -422,6 +423,14 @@ NTSTATUS tstream_smbXcli_np_use_trans(struct tstream_context *stream) return NT_STATUS_OK; } +void tstream_smbXcli_np_set_trans_maxdata(struct tstream_context *stream, + uint32_t max_data) +{ + struct tstream_smbXcli_np *cli_nps = tstream_context_data(stream, + struct tstream_smbXcli_np); + cli_nps->trans.max_data = max_data; +} + unsigned int tstream_smbXcli_np_set_timeout(struct tstream_context *stream, unsigned int timeout) { @@ -887,6 +896,7 @@ static void tstream_smbXcli_np_readv_trans_start(struct tevent_req *req) tstream_context_data(state->stream, struct tstream_smbXcli_np); struct tevent_req *subreq; + uint32_t max_data = cli_nps->trans.max_data; state->trans.im = tevent_create_immediate(state); if (tevent_req_nomem(state->trans.im, req)) { @@ -909,7 +919,7 @@ static void tstream_smbXcli_np_readv_trans_start(struct tevent_req *req) NULL, 0, 0, cli_nps->write.buf, cli_nps->write.ofs, - TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE); + max_data); } else { DATA_BLOB in_input_buffer = data_blob_null; DATA_BLOB in_output_buffer = data_blob_null; @@ -928,7 +938,7 @@ static void tstream_smbXcli_np_readv_trans_start(struct tevent_req *req) 0, /* in_max_input_length */ &in_input_buffer, /* in_max_output_length */ - TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE, + max_data, &in_output_buffer, SMB2_IOCTL_FLAG_IS_FSCTL); } @@ -955,10 +965,14 @@ static void tstream_smbXcli_np_readv_trans_done(struct tevent_req *subreq) tevent_req_data(req, struct tstream_smbXcli_np_readv_state); struct tstream_smbXcli_np *cli_nps = tstream_context_data(state->stream, struct tstream_smbXcli_np); + uint32_t max_data = cli_nps->trans.max_data; uint8_t *rcvbuf; uint32_t received; NTSTATUS status; + /* reset max_data, should be set different every time (if required) */ + cli_nps->trans.max_data = TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE; + if (cli_nps->is_smb1) { status = smb1cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, NULL, 0, NULL, @@ -984,7 +998,7 @@ static void tstream_smbXcli_np_readv_trans_done(struct tevent_req *subreq) return; } - if (received > TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE) { + if (received > max_data) { tstream_smbXcli_np_readv_disconnect_now(req, EIO, __location__); return; } diff --git a/libcli/smb/tstream_smbXcli_np.h b/libcli/smb/tstream_smbXcli_np.h index e8c5c39..7e25f9f 100644 --- a/libcli/smb/tstream_smbXcli_np.h +++ b/libcli/smb/tstream_smbXcli_np.h @@ -69,4 +69,7 @@ unsigned int tstream_smbXcli_np_set_timeout(struct tstream_context *stream, */ #define TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE 4280 +void tstream_smbXcli_np_set_trans_maxdata(struct tstream_context *stream, + uint32_t max_data); + #endif /* _CLI_NP_TSTREAM_H_ */ -- 1.8.1.4