s4:librpc/rpc: use tevent_req_defer_callback() in dcerpc_alter_context_*
authorStefan Metzmacher <metze@samba.org>
Tue, 13 Mar 2012 14:41:16 +0000 (15:41 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 15 Mar 2012 06:35:28 +0000 (07:35 +0100)
metze

source4/librpc/rpc/dcerpc.c

index c70340df704a987ce19e5ea0fd418e800bd52b9f..d76b9709e47840a012830e69d06dc8616bd3e3ec 100644 (file)
@@ -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) {