summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc/dcerpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/librpc/rpc/dcerpc.c')
-rw-r--r--source4/librpc/rpc/dcerpc.c46
1 files changed, 17 insertions, 29 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index 352972b0b7..2c0dbcd5f3 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -756,6 +756,8 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p,
/*
process a fragment received from the transport layer during a
request
+
+ This function frees the data
*/
static void dcerpc_request_recv_data(struct dcerpc_connection *c,
DATA_BLOB *data,
@@ -766,6 +768,8 @@ static void dcerpc_request_recv_data(struct dcerpc_connection *c,
uint_t length;
if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(data);
+
/* all pending requests get the error */
while (c->pending) {
req = c->pending;
@@ -781,7 +785,7 @@ static void dcerpc_request_recv_data(struct dcerpc_connection *c,
pkt.call_id = 0;
- status = ncacn_pull_request_sign(c, data, (TALLOC_CTX *)data->data, &pkt);
+ status = ncacn_pull_request_sign(c, data, data->data, &pkt);
/* find the matching request. Notice we match before we check
the status. this is ok as a pending call_id can never be
@@ -792,29 +796,20 @@ static void dcerpc_request_recv_data(struct dcerpc_connection *c,
if (req == NULL) {
DEBUG(2,("dcerpc_request: unmatched call_id %u in response packet\n", pkt.call_id));
+ data_blob_free(data);
return;
}
if (!NT_STATUS_IS_OK(status)) {
req->status = status;
- req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(c->pending, req);
- if (req->async.callback) {
- req->async.callback(req);
- }
- return;
+ goto req_done;
}
if (pkt.ptype == DCERPC_PKT_FAULT) {
DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt.u.fault.status)));
req->fault_code = pkt.u.fault.status;
req->status = NT_STATUS_NET_WRITE_FAULT;
- req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(c->pending, req);
- if (req->async.callback) {
- req->async.callback(req);
- }
- return;
+ goto req_done;
}
if (pkt.ptype != DCERPC_PKT_RESPONSE) {
@@ -822,12 +817,7 @@ static void dcerpc_request_recv_data(struct dcerpc_connection *c,
(int)pkt.ptype));
req->fault_code = DCERPC_FAULT_OTHER;
req->status = NT_STATUS_NET_WRITE_FAULT;
- req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(c->pending, req);
- if (req->async.callback) {
- req->async.callback(req);
- }
- return;
+ goto req_done;
}
length = pkt.u.response.stub_and_verifier.length;
@@ -839,12 +829,7 @@ static void dcerpc_request_recv_data(struct dcerpc_connection *c,
req->payload.length + length);
if (!req->payload.data) {
req->status = NT_STATUS_NO_MEMORY;
- req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(c->pending, req);
- if (req->async.callback) {
- req->async.callback(req);
- }
- return;
+ goto req_done;
}
memcpy(req->payload.data+req->payload.length,
pkt.u.response.stub_and_verifier.data, length);
@@ -853,19 +838,22 @@ static void dcerpc_request_recv_data(struct dcerpc_connection *c,
if (!(pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
c->transport.send_read(c);
+ data_blob_free(data);
return;
}
- /* we've got the full payload */
- req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(c->pending, req);
-
if (!(pkt.drep[0] & DCERPC_DREP_LE)) {
req->flags |= DCERPC_PULL_BIGENDIAN;
} else {
req->flags &= ~DCERPC_PULL_BIGENDIAN;
}
+
+req_done:
+ /* we've got the full payload */
+ req->state = RPC_REQUEST_DONE;
+ DLIST_REMOVE(c->pending, req);
+ data_blob_free(data);
if (req->async.callback) {
req->async.callback(req);
}