librpc/rpc/binding_handle.c deadlock...
authorStefan Metzmacher <metze@samba.org>
Sat, 21 Sep 2013 00:59:24 +0000 (02:59 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 17 Oct 2013 05:17:53 +0000 (07:17 +0200)
librpc/rpc/binding_handle.c

index 94dfcb8b28f939c6551e2f77d302d44f6731b0ec..90df84d5f67ef7085b2d0f629fab01c3f1bcfeab 100644 (file)
@@ -465,6 +465,7 @@ struct dcerpc_binding_handle_call_params_state {
 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);
+static void dcerpc_binding_handle_call_params_response(struct tevent_req *req);
 static void dcerpc_binding_handle_call_params_pipe_setup(struct tevent_req *call_req);
 static void dcerpc_binding_handle_call_params_pipe_notify(struct dcerpc_pipe_handle *p);
 
@@ -588,6 +589,7 @@ 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);
@@ -725,6 +727,16 @@ static void dcerpc_binding_handle_call_params_next_pipe(struct tevent_req *req)
                return;
        }
        state->out_pipe_idx = UINT32_MAX;
+
+       if (state->pull == NULL) {
+               return;
+       }
+
+       if (state->pull->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) {
+               return;
+       }
+
+       dcerpc_binding_handle_call_params_response(req);
 }
 
 static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq)
@@ -803,6 +815,18 @@ static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq)
                return;
        }
 
+       dcerpc_binding_handle_call_params_response(req);
+}
+
+static void dcerpc_binding_handle_call_params_response(struct tevent_req *req)
+{
+       struct dcerpc_binding_handle_call_params_state *state =
+               tevent_req_data(req,
+               struct dcerpc_binding_handle_call_params_state);
+       struct dcerpc_binding_handle *h = state->h;
+       NTSTATUS error;
+       enum ndr_err_code ndr_err;
+
        state->pull->current_mem_ctx = state->params->r_mem;
 
        /* pull the structure from the blob */
@@ -900,6 +924,8 @@ static struct tevent_req *dcerpc_binding_handle_call_params_push_send(TALLOC_CTX
        state->ev = ev;
        state->p = p;
 
+       tevent_req_defer_callback(req, state->ev);
+
        talloc_set_destructor(state,
                              dcerpc_binding_handle_call_params_push_state_destructor);
 
@@ -1007,7 +1033,6 @@ static void dcerpc_binding_handle_call_params_push_done(struct tevent_req *subre
                return;
        }
 
-       tevent_req_defer_callback(req, state->ev);
        tevent_req_done(req);
        dcerpc_binding_handle_call_params_next_pipe(pp->call_req);
 }
@@ -1066,6 +1091,8 @@ static struct tevent_req *dcerpc_binding_handle_call_params_pull_send(TALLOC_CTX
        state->chunk_mem = chunk_mem;
        state->chunk_ptr = chunk_ptr;
 
+       tevent_req_defer_callback(req, state->ev);
+
        dcerpc_binding_handle_call_params_pull_notify(req);
        if (!tevent_req_is_in_progress(req)) {
                return tevent_req_post(req, ev);
@@ -1159,7 +1186,6 @@ static void dcerpc_binding_handle_call_params_pull_notify(struct tevent_req *req
                return;
        }
 
-       tevent_req_defer_callback(req, state->ev);
        tevent_req_done(req);
        dcerpc_binding_handle_call_params_next_pipe(pp->call_req);