source4/librpc/rpc/dcerpc.cĀ·bla
authorStefan Metzmacher <metze@samba.org>
Wed, 18 Sep 2013 08:49:39 +0000 (10:49 +0200)
committerMatthieu Patou <mat@matws.net>
Fri, 3 Oct 2014 19:16:34 +0000 (12:16 -0700)
source4/librpc/rpc/dcerpc.c

index 4efe06a65ec5ead918f4699180c8f245fd29deea..6c249180c0219d2bcb64524b8d52215fd12afe88 100644 (file)
@@ -69,6 +69,7 @@ struct rpc_request {
        bool wait_for_sync;
        bool first_pdu_done;
        bool incomplete_request_data;
+       bool incomplete_payload;
        bool last_pdu_done;
 
        struct {
@@ -290,6 +291,7 @@ static struct tevent_req *dcerpc_bh_raw_call_send(TALLOC_CTX *mem_ctx,
 
        if (state->in_flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) {
                state->subreq->incomplete_request_data = true;
+               state->subreq->incomplete_payload = true;
        }
 
        return req;
@@ -1625,15 +1627,18 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c,
                req->payload.length += length;
        }
 
-       if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
-               data_blob_free(raw_packet);
+       if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
+               req->last_pdu_done = true;
+       }
 
+       if (!req->last_pdu_done) {
+               data_blob_free(raw_packet);
                req->status = dcerpc_send_read(c);
                if (!NT_STATUS_IS_OK(req->status)) {
                        goto req_done;
                }
 
-               if (!req->incomplete_request_data) {
+               if (!req->incomplete_payload) {
                        return;
                }
 
@@ -1643,7 +1648,7 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c,
                return;
        }
 
-       req->incomplete_request_data = false;
+       req->incomplete_payload = false;
 
 req_done:
        data_blob_free(raw_packet);
@@ -1848,7 +1853,7 @@ static void dcerpc_ship_next_request(struct dcecli_connection *c)
                }
 
                remaining -= chunk;
-
+               req->last_pdu_done = last_frag;
        }
 
        if (req->request_data_allocated) {
@@ -1857,24 +1862,23 @@ static void dcerpc_ship_next_request(struct dcecli_connection *c)
        req->request_data_allocated = false;
        req->request_data = data_blob_null;
 
-       if (!req->incomplete_request_data) {
+       if (req->last_pdu_done) {
                DLIST_REMOVE(c->request_queue, req);
                DLIST_ADD(c->pending, req);
                req->state = RPC_REQUEST_PENDING;
                /*
-                * we reuse first_pdu_done for the receive side
+                * we reuse *_pdu_done for the receive side
                 */
                req->first_pdu_done = false;
+               req->last_pdu_done = false;
        }
 
-               if (req->stub_subreq == NULL) {
-                       return;
-               }
-
-               tevent_req_done(req->stub_subreq);
+       if (req->stub_subreq == NULL) {
                return;
        }
 
+       tevent_req_done(req->stub_subreq);
+       return;
 }
 
 static void dcerpc_io_trigger(struct tevent_context *ctx,