From 9553ccc67cd41933987a424e5d16bc677bb608b7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 21 Sep 2013 10:19:14 +0200 Subject: [PATCH] librpc/rpc/binding_handle.c --- librpc/rpc/binding_handle.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/librpc/rpc/binding_handle.c b/librpc/rpc/binding_handle.c index 78760635f850..6e8373b6f132 100644 --- a/librpc/rpc/binding_handle.c +++ b/librpc/rpc/binding_handle.c @@ -453,6 +453,7 @@ NTSTATUS dcerpc_binding_handle_disconnect_recv(struct tevent_req *req) } struct dcerpc_binding_handle_call_params_state { + struct tevent_context *ev; struct dcerpc_binding_handle *h; const struct ndr_interface_call *call; struct dcerpc_binding_handle_call_params *params; @@ -470,6 +471,7 @@ struct dcerpc_binding_handle_call_params_state { uint32_t out_pipe_idx; }; +static void dcerpc_binding_handle_call_params_cleanup(struct tevent_req *req); static void dcerpc_binding_handle_call_params_in_done(struct tevent_req *subreq); static void dcerpc_binding_handle_call_params_next_pipe(struct tevent_req *req); static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq); @@ -505,6 +507,7 @@ struct tevent_req *dcerpc_binding_handle_call_params_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + state->ev = ev; state->h = h; state->call = &table->calls[opnum]; state->params = params; @@ -519,6 +522,8 @@ struct tevent_req *dcerpc_binding_handle_call_params_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + tevent_req_defer_callback(req, ev); + /* setup for a ndr_push_* call */ state->push = ndr_push_init_ctx(state); if (tevent_req_nomem(state->push, req)) { @@ -595,7 +600,6 @@ struct tevent_req *dcerpc_binding_handle_call_params_send(TALLOC_CTX *mem_ctx, } if (state->in_flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) { - tevent_req_defer_callback(req, ev); dcerpc_binding_handle_call_params_pipe_setup(req); if (!tevent_req_is_in_progress(req)) { return tevent_req_post(req, ev); @@ -667,6 +671,19 @@ struct tevent_req *dcerpc_binding_handle_call_params_send(TALLOC_CTX *mem_ctx, return req; } +static void dcerpc_binding_handle_call_params_cleanup(struct tevent_req *req) +{ + struct dcerpc_binding_handle_call_params_state *state = + tevent_req_data(req, + struct dcerpc_binding_handle_call_params_state); + + dcerpc_pipe_handle_connection_disconnect(state->pc); + state->pc = NULL; + state->call_pipe = NULL; + + tevent_req_post(req, state->ev); +} + static void dcerpc_binding_handle_call_params_in_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, @@ -676,6 +693,7 @@ static void dcerpc_binding_handle_call_params_in_done(struct tevent_req *subreq) error = dcerpc_binding_handle_raw_call_in_recv(subreq); TALLOC_FREE(subreq); if (tevent_req_nterror(req, error)) { + dcerpc_binding_handle_call_params_cleanup(req); return; } @@ -708,6 +726,7 @@ static void dcerpc_binding_handle_call_params_next_pipe(struct tevent_req *req) state->ph); if (!ok) { tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + dcerpc_binding_handle_call_params_cleanup(req); return; } @@ -727,6 +746,7 @@ static void dcerpc_binding_handle_call_params_next_pipe(struct tevent_req *req) state->ph); if (!ok) { tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + dcerpc_binding_handle_call_params_cleanup(req); return; } @@ -764,10 +784,8 @@ static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq) subreq = NULL; if (!NT_STATUS_IS_OK(error)) { TALLOC_FREE(state->subreq); - dcerpc_pipe_handle_connection_disconnect(state->pc); - state->pc = NULL; - state->call_pipe = NULL; tevent_req_nterror(req, error); + dcerpc_binding_handle_call_params_cleanup(req); return; } @@ -781,12 +799,14 @@ static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq) * this is a protocol error */ tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); + dcerpc_binding_handle_call_params_cleanup(req); return; } if (state->pull == NULL) { state->pull = ndr_pull_init_blob(&state->response, state); if (tevent_req_nomem(state->pull, req)) { + dcerpc_binding_handle_call_params_cleanup(req); return; } state->pull->flags = state->push->flags; @@ -815,6 +835,7 @@ static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq) state->call); } tevent_req_nterror(req, error); + dcerpc_binding_handle_call_params_cleanup(req); return; } } @@ -849,6 +870,7 @@ static void dcerpc_binding_handle_call_params_response(struct tevent_req *req) state->call); } tevent_req_nterror(req, error); + dcerpc_binding_handle_call_params_cleanup(req); return; } @@ -864,6 +886,7 @@ static void dcerpc_binding_handle_call_params_response(struct tevent_req *req) state->call); if (!NT_STATUS_IS_OK(error)) { tevent_req_nterror(req, error); + dcerpc_binding_handle_call_params_cleanup(req); return; } } @@ -1167,7 +1190,7 @@ static void dcerpc_binding_handle_call_params_pull_notify(struct tevent_req *req // } //} - //ndr_err = ndr_pull_pop(call_state->pull); + ndr_err = ndr_pull_pop(call_state->pull); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS error; error = ndr_map_error2ntstatus(ndr_err); -- 2.34.1