diff options
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index c70340df70..d76b9709e4 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1940,6 +1940,7 @@ uint32_t dcerpc_auth_level(struct dcecli_connection *c) } struct dcerpc_alter_context_state { + struct tevent_context *ev; struct dcerpc_pipe *p; }; @@ -1967,6 +1968,7 @@ struct tevent_req *dcerpc_alter_context_send(TALLOC_CTX *mem_ctx, return NULL; } + state->ev = ev; state->p = p; p->syntax = *syntax; @@ -2045,10 +2047,25 @@ static void dcerpc_alter_context_fail_handler(struct rpc_request *subreq) struct tevent_req *req = talloc_get_type_abort(subreq->async.private_data, struct tevent_req); + struct dcerpc_alter_context_state *state = + tevent_req_data(req, + struct dcerpc_alter_context_state); NTSTATUS status = subreq->status; TALLOC_FREE(subreq); + /* + * We trigger the callback in the next event run + * because the code in this file might trigger + * multiple request callbacks from within a single + * while loop. + * + * In order to avoid segfaults from within + * dcerpc_connection_dead() we call + * tevent_req_defer_callback(). + */ + tevent_req_defer_callback(req, state->ev); + tevent_req_nterror(req, status); } @@ -2072,6 +2089,18 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, talloc_steal(state, raw_packet->data); TALLOC_FREE(subreq); + /* + * We trigger the callback in the next event run + * because the code in this file might trigger + * multiple request callbacks from within a single + * while loop. + * + * In order to avoid segfaults from within + * dcerpc_connection_dead() we call + * tevent_req_defer_callback(). + */ + tevent_req_defer_callback(req, state->ev); + if (pkt->ptype == DCERPC_PKT_ALTER_RESP && pkt->u.alter_resp.num_results == 1 && pkt->u.alter_resp.ctx_list[0].result != 0) { |