source4/librpc/rpc/dcerpc.cĀ·bla
authorStefan Metzmacher <metze@samba.org>
Wed, 18 Sep 2013 08:49:39 +0000 (10:49 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 11:14:55 +0000 (13:14 +0200)
source4/librpc/rpc/dcerpc.c

index 03bcbea8004faf758422723362785f6a5a166d9d..2e7f92a0ae286f6736bca718878d2caf5be05393 100644 (file)
@@ -71,6 +71,7 @@ struct rpc_request {
        bool verify_pcontext;
        bool first_pdu_done;
        bool incomplete_request_data;
+       bool incomplete_payload;
        bool last_pdu_done;
 
        struct {
@@ -291,6 +292,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;
@@ -1520,15 +1522,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;
                }
 
@@ -1545,7 +1550,7 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c,
                req->p->verified_pcontext = true;
        }
 
-       req->incomplete_request_data = false;
+       req->incomplete_payload = false;
 
 req_done:
        data_blob_free(raw_packet);
@@ -1861,7 +1866,7 @@ static void dcerpc_ship_next_request(struct dcecli_connection *c)
                }
 
                remaining -= chunk;
-
+               req->last_pdu_done = last_frag;
        }
 
        if (req->request_data_allocated) {
@@ -1870,24 +1875,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,