summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2010-07-12 09:36:39 -0400
committerGünther Deschner <gd@samba.org>2010-07-16 01:51:15 +0200
commit602e10f3fdb5f0f94e5f22b639121220d419d47f (patch)
tree6be8e76aa15c93250336bc67dd23a9c77d6a16fd /source3
parent8ce15b3a71a29fe27b7146c1b802aa11e7c96433 (diff)
downloadsamba-602e10f3fdb5f0f94e5f22b639121220d419d47f.tar.gz
samba-602e10f3fdb5f0f94e5f22b639121220d419d47f.tar.bz2
samba-602e10f3fdb5f0f94e5f22b639121220d419d47f.zip
s3-dcerpc: Delay parsing rpc header in client code
Signed-off-by: Günther Deschner <gd@samba.org>
Diffstat (limited to 'source3')
-rw-r--r--source3/rpc_client/cli_pipe.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 91eb767667..a4b4e79916 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -671,7 +671,7 @@ static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
struct get_complete_frag_state {
struct event_context *ev;
struct rpc_pipe_client *cli;
- struct ncacn_packet_header *prhdr;
+ uint16_t frag_len;
prs_struct *pdu;
};
@@ -681,11 +681,11 @@ static void get_complete_frag_got_rest(struct tevent_req *subreq);
static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
struct rpc_pipe_client *cli,
- struct ncacn_packet_header *prhdr,
prs_struct *pdu)
{
struct tevent_req *req, *subreq;
struct get_complete_frag_state *state;
+ DATA_BLOB blob;
uint32_t pdu_len;
NTSTATUS status;
@@ -696,7 +696,7 @@ static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
}
state->ev = ev;
state->cli = cli;
- state->prhdr = prhdr;
+ state->frag_len = RPC_HEADER_LEN;
state->pdu = pdu;
pdu_len = prs_data_size(pdu);
@@ -719,23 +719,21 @@ static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
return req;
}
- status = parse_rpc_header(cli, prhdr, pdu);
- if (!NT_STATUS_IS_OK(status)) {
- goto post_status;
- }
+ blob = data_blob_const(prs_data_p(state->pdu), pdu_len);
+ state->frag_len = dcerpc_get_frag_length(&blob);
/*
* Ensure we have frag_len bytes of data.
*/
- if (pdu_len < prhdr->frag_length) {
- if (!rpc_grow_buffer(pdu, prhdr->frag_length)) {
+ if (pdu_len < state->frag_len) {
+ if (!rpc_grow_buffer(pdu, state->frag_len)) {
status = NT_STATUS_NO_MEMORY;
goto post_status;
}
subreq = rpc_read_send(state, state->ev,
state->cli->transport,
(uint8_t *)(prs_data_p(pdu) + pdu_len),
- prhdr->frag_length - pdu_len);
+ state->frag_len - pdu_len);
if (subreq == NULL) {
status = NT_STATUS_NO_MEMORY;
goto post_status;
@@ -762,6 +760,7 @@ static void get_complete_frag_got_header(struct tevent_req *subreq)
struct get_complete_frag_state *state = tevent_req_data(
req, struct get_complete_frag_state);
NTSTATUS status;
+ DATA_BLOB pdu;
status = rpc_read_recv(subreq);
TALLOC_FREE(subreq);
@@ -770,13 +769,11 @@ static void get_complete_frag_got_header(struct tevent_req *subreq)
return;
}
- status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
+ pdu = data_blob_const(prs_data_p(state->pdu),
+ prs_data_size(state->pdu));
+ state->frag_len = dcerpc_get_frag_length(&pdu);
- if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_length)) {
+ if (!rpc_grow_buffer(state->pdu, state->frag_len)) {
tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -789,7 +786,7 @@ static void get_complete_frag_got_header(struct tevent_req *subreq)
subreq = rpc_read_send(
state, state->ev, state->cli->transport,
(uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
- state->prhdr->frag_length - RPC_HEADER_LEN);
+ state->frag_len - RPC_HEADER_LEN);
if (tevent_req_nomem(subreq, req)) {
return;
}
@@ -1187,6 +1184,11 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
NTSTATUS ret = NT_STATUS_OK;
uint32 current_pdu_len = prs_data_size(current_pdu);
+ ret = parse_rpc_header(cli, prhdr, current_pdu);
+ if (!NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+
if (current_pdu_len != prhdr->frag_length) {
DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
(unsigned int)current_pdu_len, (unsigned int)prhdr->frag_length));
@@ -1672,7 +1674,7 @@ static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
/* Ensure we have enough data for a pdu. */
subreq = get_complete_frag_send(state, state->ev, state->cli,
- &state->rhdr, &state->incoming_frag);
+ &state->incoming_frag);
if (tevent_req_nomem(subreq, req)) {
return;
}
@@ -1763,7 +1765,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
}
subreq = get_complete_frag_send(state, state->ev, state->cli,
- &state->rhdr, &state->incoming_frag);
+ &state->incoming_frag);
if (tevent_req_nomem(subreq, req)) {
return;
}