static void named_pipe_packet_process(struct tevent_req *subreq) { struct named_pipe_client *npc = tevent_req_callback_data(subreq, struct named_pipe_client); struct _output_data *out = &npc->p->out_data; DATA_BLOB recv_buffer = data_blob_null; struct ncacn_packet *pkt; NTSTATUS status; ssize_t data_left; ssize_t data_used; char *data; uint32_t to_send; size_t i; bool ok; status = dcerpc_read_ncacn_packet_recv(subreq, npc, &pkt, &recv_buffer); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { goto fail; } data_left = recv_buffer.length; data = (char *)recv_buffer.data; while (data_left) { data_used = process_incoming_data(npc->p, data, data_left); if (data_used < 0) { DEBUG(3, ("Failed to process dceprc request!\n")); status = NT_STATUS_UNEXPECTED_IO_ERROR; goto fail; } data_left -= data_used; data += data_used; } /* Do not leak this buffer, npc is a long lived context */ talloc_free(recv_buffer.data); talloc_free(pkt); /* this is needed because of the way DCERPC Binds work in * the RPC marshalling code */ to_send = out->frag.length - out->current_pdu_sent; if (to_send > 0) { npc->iov = talloc_zero(npc, struct iovec); if (!npc->iov) { status = NT_STATUS_NO_MEMORY; goto fail; } npc->count = 1; npc->iov[0].iov_base = out->frag.data + out->current_pdu_sent; npc->iov[0].iov_len = to_send; out->current_pdu_sent += to_send; }
void named_pipe_packet_process(struct tevent_req *subreq) { struct named_pipe_client *npc = tevent_req_callback_data(subreq, struct named_pipe_client); struct _output_data *out = &npc->p->out_data; DATA_BLOB recv_buffer = data_blob_null; struct ncacn_packet *pkt; NTSTATUS status; uint32_t to_send; size_t i; bool ok; status = dcerpc_read_ncacn_packet_recv(subreq, npc, &pkt, &recv_buffer); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { goto fail; } /* dcerpc_read_ncacn_packet_recv() returns a full PDU */ npc->p->in_data.pdu_needed_len = 0; npc->p->in_data.pdu = recv_buffer; if (dcerpc_get_endian_flag(&recv_buffer) & DCERPC_DREP_LE) { npc->p->endian = RPC_LITTLE_ENDIAN; } else { npc->p->endian = RPC_BIG_ENDIAN; } DEBUG(10, ("PDU is in %s Endian format!\n", npc->p->endian ? "Big" : "Little")); process_complete_pdu(npc->p, pkt); /* reset pipe state and free PDU */ npc->p->in_data.pdu.length = 0; talloc_free(recv_buffer.data); talloc_free(pkt); /* this is needed because of the way DCERPC Binds work in * the RPC marshalling code */ to_send = out->frag.length - out->current_pdu_sent; if (to_send > 0) { npc->iov = talloc_zero(npc, struct iovec); if (!npc->iov) { status = NT_STATUS_NO_MEMORY; goto fail; } npc->count = 1; npc->iov[0].iov_base = out->frag.data + out->current_pdu_sent; npc->iov[0].iov_len = to_send; out->current_pdu_sent += to_send; }