summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/rpc/dcerpc.c29
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) {