From 56211d6deb054acec28c13f226347771c547fc16 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 21 Sep 2013 22:00:29 +0200 Subject: [PATCH] librpc/rpc/binding_handle.c cleanups --- librpc/rpc/binding_handle.c | 74 ++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/librpc/rpc/binding_handle.c b/librpc/rpc/binding_handle.c index 60b93770a8b4..c6d905137a3b 100644 --- a/librpc/rpc/binding_handle.c +++ b/librpc/rpc/binding_handle.c @@ -1113,6 +1113,19 @@ static struct tevent_req *dcerpc_binding_handle_call_params_pull_send(TALLOC_CTX state->chunk_ptr = chunk_ptr; state->is_last_chunk = true; + if (talloc_total_blocks(chunk_mem) != 1) { + /* + * As we typically only have autogenerated callers + * of this function, we can enforce that chunk_mem + * doesn't have any talloc children yet. + * + * This makes the error handling in the + * NDR_ERR_INCOMPLETE_BUFFER case simpler. + */ + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + tevent_req_defer_callback(req, state->ev); talloc_set_destructor(state, @@ -1139,10 +1152,8 @@ static void dcerpc_binding_handle_call_params_pull_notify(struct tevent_req *req tevent_req_data(pp->call_req, struct dcerpc_binding_handle_call_params_state); enum ndr_err_code ndr_err; + struct ndr_push *pipe_pull = NULL; const uint32_t *count = NULL; - uint32_t saved_offset; - size_t saved_ndr_blocks; - size_t saved_mem_blocks; if (call_state->pull == NULL) { return; @@ -1152,49 +1163,44 @@ static void dcerpc_binding_handle_call_params_pull_notify(struct tevent_req *req return; } - /* pull the structure from the blob */ - saved_offset = call_state->pull->offset; - saved_ndr_blocks = talloc_total_blocks(call_state->pull); - saved_mem_blocks = talloc_total_blocks(state->chunk_mem); + /* + * setup a shallow copy subcontext, which we might destroy + */ + ndr_err = ndr_pull_subcontext_start(call_state->pull, &pipe_pull, + 0xFFFFFFFF, 0); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS error; + error = ndr_map_error2ntstatus(ndr_err); + tevent_req_nterror(req, error); + return; + } - call_state->pull->current_mem_ctx = state->chunk_mem; - ndr_err = call_state->call_pipe->ndr_pull(call_state->pull, - NDR_SCALARS|NDR_BUFFERS, - state->chunk_ptr); + /* pull the structure from the subcontext */ + pipe_pull->current_mem_ctx = state->chunk_mem; + ndr_err = pipe_pull->ndr_pull(pipe_pull, + NDR_SCALARS|NDR_BUFFERS, + state->chunk_ptr); if (ndr_err == NDR_ERR_INCOMPLETE_BUFFER) { - SMB_ASSERT(saved_mem_blocks == 1); - SMB_ASSERT(saved_ndr_blocks == talloc_total_blocks(call_state->pull)); + TALLOC_FREE(pipe_pull); talloc_free_children(state->chunk_mem); - call_state->pull->offset = saved_offset; return; } if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS error; error = ndr_map_error2ntstatus(ndr_err); - //if (h->ops->ndr_pull_failed) { - // h->ops->ndr_pull_failed(h, error, - // &state->response, - // state->call); - //} tevent_req_nterror(req, error); return; } - //if (h->ops->do_ndr_print) { - // h->ops->do_ndr_print(h, NDR_OUT, - // state->params->r_ptr, state->call); - //} - - //if (h->ops->ndr_validate_out) { - // error = h->ops->ndr_validate_out(h, - // state->pull, - // state->params->r_ptr, - // state->call); - // if (!NT_STATUS_IS_OK(error)) { - // tevent_req_nterror(req, error); - // return; - // } - //} + ndr_err = ndr_pull_subcontext_end(call_state->pull, pipe_pull, + 0xFFFFFFFF, 0); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS error; + error = ndr_map_error2ntstatus(ndr_err); + tevent_req_nterror(req, error); + return; + } + TALLOC_FREE(pipe_pull); ndr_err = ndr_pull_pop(call_state->pull); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { -- 2.34.1