STEP03d: source3/rpc_client/cli_pipe.c remove unused
authorStefan Metzmacher <metze@samba.org>
Mon, 13 Jan 2014 09:15:16 +0000 (10:15 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 10:45:39 +0000 (12:45 +0200)
source3/rpc_client/cli_pipe.c

index 217738d53f9e8e5c0423be73e44e89a7864261c3..7760e091dd7c34764863a8cc4f7fbb4e052278fc 100644 (file)
@@ -55,1798 +55,6 @@ static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
        return result;
 }
 
-/********************************************************************
- Rpc pipe call id.
- ********************************************************************/
-
-static uint32_t get_rpc_call_id(void)
-{
-       static uint32_t call_id = 0;
-       return ++call_id;
-}
-
-/*******************************************************************
- Use SMBreadX to get rest of one fragment's worth of rpc data.
- Reads the whole size or give an error message
- ********************************************************************/
-
-struct rpc_read_state {
-       struct tevent_context *ev;
-       struct rpc_cli_transport *transport;
-       uint8_t *data;
-       size_t size;
-       size_t num_read;
-};
-
-static void rpc_read_done(struct tevent_req *subreq);
-
-static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
-                                       struct tevent_context *ev,
-                                       struct rpc_cli_transport *transport,
-                                       uint8_t *data, size_t size)
-{
-       struct tevent_req *req, *subreq;
-       struct rpc_read_state *state;
-
-       req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->ev = ev;
-       state->transport = transport;
-       state->data = data;
-       state->size = size;
-       state->num_read = 0;
-
-       DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
-
-       subreq = transport->read_send(state, ev, (uint8_t *)data, size,
-                                     transport->priv);
-       if (subreq == NULL) {
-               goto fail;
-       }
-       tevent_req_set_callback(subreq, rpc_read_done, req);
-       return req;
-
- fail:
-       TALLOC_FREE(req);
-       return NULL;
-}
-
-static void rpc_read_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct rpc_read_state *state = tevent_req_data(
-               req, struct rpc_read_state);
-       NTSTATUS status;
-       ssize_t received;
-
-       status = state->transport->read_recv(subreq, &received);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       state->num_read += received;
-       if (state->num_read == state->size) {
-               tevent_req_done(req);
-               return;
-       }
-
-       subreq = state->transport->read_send(state, state->ev,
-                                            state->data + state->num_read,
-                                            state->size - state->num_read,
-                                            state->transport->priv);
-       if (tevent_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, rpc_read_done, req);
-}
-
-static NTSTATUS rpc_read_recv(struct tevent_req *req)
-{
-       return tevent_req_simple_recv_ntstatus(req);
-}
-
-struct rpc_write_state {
-       struct tevent_context *ev;
-       struct rpc_cli_transport *transport;
-       const uint8_t *data;
-       size_t size;
-       size_t num_written;
-};
-
-static void rpc_write_done(struct tevent_req *subreq);
-
-static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
-                                        struct tevent_context *ev,
-                                        struct rpc_cli_transport *transport,
-                                        const uint8_t *data, size_t size)
-{
-       struct tevent_req *req, *subreq;
-       struct rpc_write_state *state;
-
-       req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->ev = ev;
-       state->transport = transport;
-       state->data = data;
-       state->size = size;
-       state->num_written = 0;
-
-       DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
-
-       subreq = transport->write_send(state, ev, data, size, transport->priv);
-       if (subreq == NULL) {
-               goto fail;
-       }
-       tevent_req_set_callback(subreq, rpc_write_done, req);
-       return req;
- fail:
-       TALLOC_FREE(req);
-       return NULL;
-}
-
-static void rpc_write_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct rpc_write_state *state = tevent_req_data(
-               req, struct rpc_write_state);
-       NTSTATUS status;
-       ssize_t written;
-
-       status = state->transport->write_recv(subreq, &written);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       state->num_written += written;
-
-       if (state->num_written == state->size) {
-               tevent_req_done(req);
-               return;
-       }
-
-       subreq = state->transport->write_send(state, state->ev,
-                                             state->data + state->num_written,
-                                             state->size - state->num_written,
-                                             state->transport->priv);
-       if (tevent_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, rpc_write_done, req);
-}
-
-static NTSTATUS rpc_write_recv(struct tevent_req *req)
-{
-       return tevent_req_simple_recv_ntstatus(req);
-}
-
-
-/****************************************************************************
- Try and get a PDU's worth of data from current_pdu. If not, then read more
- from the wire.
- ****************************************************************************/
-
-struct get_complete_frag_state {
-       struct tevent_context *ev;
-       struct rpc_pipe_client *cli;
-       uint16_t frag_len;
-       DATA_BLOB *pdu;
-};
-
-static void get_complete_frag_got_header(struct tevent_req *subreq);
-static void get_complete_frag_got_rest(struct tevent_req *subreq);
-
-static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
-                                                struct tevent_context *ev,
-                                                struct rpc_pipe_client *cli,
-                                                DATA_BLOB *pdu)
-{
-       struct tevent_req *req, *subreq;
-       struct get_complete_frag_state *state;
-       size_t received;
-       NTSTATUS status;
-
-       req = tevent_req_create(mem_ctx, &state,
-                               struct get_complete_frag_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->ev = ev;
-       state->cli = cli;
-       state->frag_len = RPC_HEADER_LEN;
-       state->pdu = pdu;
-
-       received = pdu->length;
-       if (received < RPC_HEADER_LEN) {
-               if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto post_status;
-               }
-               subreq = rpc_read_send(state, state->ev,
-                                       state->cli->transport,
-                                       pdu->data + received,
-                                       RPC_HEADER_LEN - received);
-               if (subreq == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto post_status;
-               }
-               tevent_req_set_callback(subreq, get_complete_frag_got_header,
-                                       req);
-               return req;
-       }
-
-       state->frag_len = dcerpc_get_frag_length(pdu);
-       if (state->frag_len < RPC_HEADER_LEN) {
-               tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
-               return tevent_req_post(req, ev);
-       }
-
-       /*
-        * Ensure we have frag_len bytes of data.
-        */
-       if (received < state->frag_len) {
-               if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto post_status;
-               }
-               subreq = rpc_read_send(state, state->ev,
-                                       state->cli->transport,
-                                       pdu->data + received,
-                                       state->frag_len - received);
-               if (subreq == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto post_status;
-               }
-               tevent_req_set_callback(subreq, get_complete_frag_got_rest,
-                                       req);
-               return req;
-       }
-
-       status = NT_STATUS_OK;
- post_status:
-       if (NT_STATUS_IS_OK(status)) {
-               tevent_req_done(req);
-       } else {
-               tevent_req_nterror(req, status);
-       }
-       return tevent_req_post(req, ev);
-}
-
-static void get_complete_frag_got_header(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct get_complete_frag_state *state = tevent_req_data(
-               req, struct get_complete_frag_state);
-       NTSTATUS status;
-
-       status = rpc_read_recv(subreq);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       state->frag_len = dcerpc_get_frag_length(state->pdu);
-       if (state->frag_len < RPC_HEADER_LEN) {
-               tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
-               return;
-       }
-
-       if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
-               tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
-       }
-
-       /*
-        * We're here in this piece of code because we've read exactly
-        * RPC_HEADER_LEN bytes into state->pdu.
-        */
-
-       subreq = rpc_read_send(state, state->ev, state->cli->transport,
-                               state->pdu->data + RPC_HEADER_LEN,
-                               state->frag_len - RPC_HEADER_LEN);
-       if (tevent_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
-}
-
-static void get_complete_frag_got_rest(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       NTSTATUS status;
-
-       status = rpc_read_recv(subreq);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-       tevent_req_done(req);
-}
-
-static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
-{
-       return tevent_req_simple_recv_ntstatus(req);
-}
-
-/****************************************************************************
- Do basic authentication checks on an incoming pdu.
- ****************************************************************************/
-
-static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
-                                               struct rpc_pipe_client *cli,
-                                               struct ncacn_packet *pkt,
-                                               DATA_BLOB *pdu,
-                                               uint8_t expected_pkt_type,
-                                               uint32_t call_id,
-                                               DATA_BLOB *rdata,
-                                               DATA_BLOB *reply_pdu)
-{
-       const struct dcerpc_response *r = NULL;
-       DATA_BLOB tmp_stub = data_blob_null;
-       NTSTATUS ret = NT_STATUS_OK;
-
-       /*
-        * Point the return values at the real data including the RPC
-        * header. Just in case the caller wants it.
-        */
-       *rdata = *pdu;
-
-       if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
-           !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
-               /*
-                * TODO: do we still need this hack which was introduced
-                * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
-                *
-                * I don't even know what AS/U might be...
-                */
-               DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
-                         "fragment first/last ON.\n"));
-               pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
-       }
-
-       /* Ensure we have the correct type. */
-       switch (pkt->ptype) {
-       case DCERPC_PKT_BIND_NAK:
-               DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
-                         rpccli_pipe_txt(talloc_tos(), cli)));
-
-               ret = dcerpc_verify_ncacn_packet_header(pkt,
-                                               DCERPC_PKT_BIND_NAK,
-                                               0, /* max_auth_info */
-                                               DCERPC_PFC_FLAG_FIRST |
-                                               DCERPC_PFC_FLAG_LAST,
-                                               0); /* optional flags */
-               if (!NT_STATUS_IS_OK(ret)) {
-                       DEBUG(1, (__location__ ": Connection to %s got an unexpected "
-                                 "RPC packet type - %u, expected %u: %s\n",
-                                 rpccli_pipe_txt(talloc_tos(), cli),
-                                 pkt->ptype, expected_pkt_type,
-                                 nt_errstr(ret)));
-                       NDR_PRINT_DEBUG(ncacn_packet, pkt);
-                       return ret;
-               }
-
-               /* Use this for now... */
-               return NT_STATUS_NETWORK_ACCESS_DENIED;
-
-       case DCERPC_PKT_BIND_ACK:
-               ret = dcerpc_verify_ncacn_packet_header(pkt,
-                                       expected_pkt_type,
-                                       pkt->u.bind_ack.auth_info.length,
-                                       DCERPC_PFC_FLAG_FIRST |
-                                       DCERPC_PFC_FLAG_LAST,
-                                       DCERPC_PFC_FLAG_CONC_MPX |
-                                       DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
-               if (!NT_STATUS_IS_OK(ret)) {
-                       DEBUG(1, (__location__ ": Connection to %s got an unexpected "
-                                 "RPC packet type - %u, expected %u: %s\n",
-                                 rpccli_pipe_txt(talloc_tos(), cli),
-                                 pkt->ptype, expected_pkt_type,
-                                 nt_errstr(ret)));
-                       NDR_PRINT_DEBUG(ncacn_packet, pkt);
-                       return ret;
-               }
-
-               break;
-
-       case DCERPC_PKT_ALTER_RESP:
-               ret = dcerpc_verify_ncacn_packet_header(pkt,
-                                       expected_pkt_type,
-                                       pkt->u.alter_resp.auth_info.length,
-                                       DCERPC_PFC_FLAG_FIRST |
-                                       DCERPC_PFC_FLAG_LAST,
-                                       DCERPC_PFC_FLAG_CONC_MPX |
-                                       DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
-               if (!NT_STATUS_IS_OK(ret)) {
-                       DEBUG(1, (__location__ ": Connection to %s got an unexpected "
-                                 "RPC packet type - %u, expected %u: %s\n",
-                                 rpccli_pipe_txt(talloc_tos(), cli),
-                                 pkt->ptype, expected_pkt_type,
-                                 nt_errstr(ret)));
-                       NDR_PRINT_DEBUG(ncacn_packet, pkt);
-                       return ret;
-               }
-
-               break;
-
-       case DCERPC_PKT_RESPONSE:
-
-               r = &pkt->u.response;
-
-               ret = dcerpc_verify_ncacn_packet_header(pkt,
-                                               expected_pkt_type,
-                                               r->stub_and_verifier.length,
-                                               0, /* required_flags */
-                                               DCERPC_PFC_FLAG_FIRST |
-                                               DCERPC_PFC_FLAG_LAST);
-               if (!NT_STATUS_IS_OK(ret)) {
-                       DEBUG(1, (__location__ ": Connection to %s got an unexpected "
-                                 "RPC packet type - %u, expected %u: %s\n",
-                                 rpccli_pipe_txt(talloc_tos(), cli),
-                                 pkt->ptype, expected_pkt_type,
-                                 nt_errstr(ret)));
-                       NDR_PRINT_DEBUG(ncacn_packet, pkt);
-                       return ret;
-               }
-
-               tmp_stub.data = r->stub_and_verifier.data;
-               tmp_stub.length = r->stub_and_verifier.length;
-
-               /* Here's where we deal with incoming sign/seal. */
-               ret = dcerpc_check_auth(cli->auth, pkt,
-                                       &tmp_stub,
-                                       DCERPC_RESPONSE_LENGTH,
-                                       pdu);
-               if (!NT_STATUS_IS_OK(ret)) {
-                       DEBUG(1, (__location__ ": Connection to %s got an unexpected "
-                                 "RPC packet type - %u, expected %u: %s\n",
-                                 rpccli_pipe_txt(talloc_tos(), cli),
-                                 pkt->ptype, expected_pkt_type,
-                                 nt_errstr(ret)));
-                       NDR_PRINT_DEBUG(ncacn_packet, pkt);
-                       return ret;
-               }
-
-               /* Point the return values at the NDR data. */
-               *rdata = tmp_stub;
-
-               DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
-                          (long unsigned int)pdu->length,
-                          (long unsigned int)rdata->length));
-
-               /*
-                * If this is the first reply, and the allocation hint is
-                * reasonable, try and set up the reply_pdu DATA_BLOB to the
-                * correct size.
-                */
-
-               if ((reply_pdu->length == 0) &&
-                   r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
-                       if (!data_blob_realloc(mem_ctx, reply_pdu,
-                                                       r->alloc_hint)) {
-                               DEBUG(0, ("reply alloc hint %d too "
-                                         "large to allocate\n",
-                                         (int)r->alloc_hint));
-                               return NT_STATUS_NO_MEMORY;
-                       }
-               }
-
-               break;
-
-       case DCERPC_PKT_FAULT:
-
-               ret = dcerpc_verify_ncacn_packet_header(pkt,
-                                               DCERPC_PKT_FAULT,
-                                               0, /* max_auth_info */
-                                               DCERPC_PFC_FLAG_FIRST |
-                                               DCERPC_PFC_FLAG_LAST,
-                                               DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
-               if (!NT_STATUS_IS_OK(ret)) {
-                       DEBUG(1, (__location__ ": Connection to %s got an unexpected "
-                                 "RPC packet type - %u, expected %u: %s\n",
-                                 rpccli_pipe_txt(talloc_tos(), cli),
-                                 pkt->ptype, expected_pkt_type,
-                                 nt_errstr(ret)));
-                       NDR_PRINT_DEBUG(ncacn_packet, pkt);
-                       return ret;
-               }
-
-               DEBUG(1, (__location__ ": RPC fault code %s received "
-                         "from %s!\n",
-                         dcerpc_errstr(talloc_tos(),
-                         pkt->u.fault.status),
-                         rpccli_pipe_txt(talloc_tos(), cli)));
-
-               return dcerpc_fault_to_nt_status(pkt->u.fault.status);
-
-       default:
-               DEBUG(0, (__location__ "Unknown packet type %u received "
-                         "from %s!\n",
-                         (unsigned int)pkt->ptype,
-                         rpccli_pipe_txt(talloc_tos(), cli)));
-               return NT_STATUS_RPC_PROTOCOL_ERROR;
-       }
-
-
-       if (pkt->call_id != call_id) {
-               DEBUG(3, (__location__ ": Connection to %s got an unexpected "
-                         "RPC call_id - %u, not %u\n",
-                         rpccli_pipe_txt(talloc_tos(), cli),
-                         pkt->call_id, call_id));
-               return NT_STATUS_RPC_PROTOCOL_ERROR;
-       }
-
-       return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Call a remote api on an arbitrary pipe.  takes param, data and setup buffers.
-****************************************************************************/
-
-struct cli_api_pipe_state {
-       struct tevent_context *ev;
-       struct rpc_cli_transport *transport;
-       uint8_t *rdata;
-       uint32_t rdata_len;
-};
-
-static void cli_api_pipe_trans_done(struct tevent_req *subreq);
-static void cli_api_pipe_write_done(struct tevent_req *subreq);
-static void cli_api_pipe_read_done(struct tevent_req *subreq);
-
-static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
-                                           struct tevent_context *ev,
-                                           struct rpc_cli_transport *transport,
-                                           uint8_t *data, size_t data_len,
-                                           uint32_t max_rdata_len)
-{
-       struct tevent_req *req, *subreq;
-       struct cli_api_pipe_state *state;
-       NTSTATUS status;
-
-       req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->ev = ev;
-       state->transport = transport;
-
-       if (max_rdata_len < RPC_HEADER_LEN) {
-               /*
-                * For a RPC reply we always need at least RPC_HEADER_LEN
-                * bytes. We check this here because we will receive
-                * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
-                */
-               status = NT_STATUS_INVALID_PARAMETER;
-               goto post_status;
-       }
-
-       if (transport->trans_send != NULL) {
-               subreq = transport->trans_send(state, ev, data, data_len,
-                                              max_rdata_len, transport->priv);
-               if (subreq == NULL) {
-                       goto fail;
-               }
-               tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
-               return req;
-       }
-
-       /*
-        * If the transport does not provide a "trans" routine, i.e. for
-        * example the ncacn_ip_tcp transport, do the write/read step here.
-        */
-
-       subreq = rpc_write_send(state, ev, transport, data, data_len);
-       if (subreq == NULL) {
-               goto fail;
-       }
-       tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
-       return req;
-
- post_status:
-       tevent_req_nterror(req, status);
-       return tevent_req_post(req, ev);
- fail:
-       TALLOC_FREE(req);
-       return NULL;
-}
-
-static void cli_api_pipe_trans_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct cli_api_pipe_state *state = tevent_req_data(
-               req, struct cli_api_pipe_state);
-       NTSTATUS status;
-
-       status = state->transport->trans_recv(subreq, state, &state->rdata,
-                                             &state->rdata_len);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-       tevent_req_done(req);
-}
-
-static void cli_api_pipe_write_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct cli_api_pipe_state *state = tevent_req_data(
-               req, struct cli_api_pipe_state);
-       NTSTATUS status;
-
-       status = rpc_write_recv(subreq);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
-       if (tevent_req_nomem(state->rdata, req)) {
-               return;
-       }
-
-       /*
-        * We don't need to use rpc_read_send here, the upper layer will cope
-        * with a short read, transport->trans_send could also return less
-        * than state->max_rdata_len.
-        */
-       subreq = state->transport->read_send(state, state->ev, state->rdata,
-                                            RPC_HEADER_LEN,
-                                            state->transport->priv);
-       if (tevent_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
-}
-
-static void cli_api_pipe_read_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct cli_api_pipe_state *state = tevent_req_data(
-               req, struct cli_api_pipe_state);
-       NTSTATUS status;
-       ssize_t received;
-
-       status = state->transport->read_recv(subreq, &received);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-       state->rdata_len = received;
-       tevent_req_done(req);
-}
-
-static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
-                                 uint8_t **prdata, uint32_t *prdata_len)
-{
-       struct cli_api_pipe_state *state = tevent_req_data(
-               req, struct cli_api_pipe_state);
-       NTSTATUS status;
-
-       if (tevent_req_is_nterror(req, &status)) {
-               return status;
-       }
-
-       *prdata = talloc_move(mem_ctx, &state->rdata);
-       *prdata_len = state->rdata_len;
-       return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Send data on an rpc pipe via trans. The data must be the last
- pdu fragment of an NDR data stream.
-
- Receive response data from an rpc pipe, which may be large...
-
- Read the first fragment: unfortunately have to use SMBtrans for the first
- bit, then SMBreadX for subsequent bits.
-
- If first fragment received also wasn't the last fragment, continue
- getting fragments until we _do_ receive the last fragment.
-
- Request/Response PDU's look like the following...
-
- |<------------------PDU len----------------------------------------------->|
- |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
-
- +------------+-----------------+-------------+---------------+-------------+
- | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
- +------------+-----------------+-------------+---------------+-------------+
-
- Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
- signing & sealing being negotiated.
-
- ****************************************************************************/
-
-struct rpc_api_pipe_state {
-       struct tevent_context *ev;
-       struct rpc_pipe_client *cli;
-       uint8_t expected_pkt_type;
-       uint32_t call_id;
-
-       DATA_BLOB incoming_frag;
-       struct ncacn_packet *pkt;
-
-       /* Incoming reply */
-       DATA_BLOB reply_pdu;
-       size_t reply_pdu_offset;
-       uint8_t endianess;
-};
-
-static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
-static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
-static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
-
-static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
-                                           struct tevent_context *ev,
-                                           struct rpc_pipe_client *cli,
-                                           DATA_BLOB *data, /* Outgoing PDU */
-                                           uint8_t expected_pkt_type,
-                                           uint32_t call_id)
-{
-       struct tevent_req *req, *subreq;
-       struct rpc_api_pipe_state *state;
-       uint16_t max_recv_frag;
-       NTSTATUS status;
-
-       req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->ev = ev;
-       state->cli = cli;
-       state->expected_pkt_type = expected_pkt_type;
-       state->call_id = call_id;
-       state->endianess = DCERPC_DREP_LE;
-
-       /*
-        * Ensure we're not sending too much.
-        */
-       if (data->length > cli->max_xmit_frag) {
-               status = NT_STATUS_INVALID_PARAMETER;
-               goto post_status;
-       }
-
-       DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
-
-       if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
-               subreq = rpc_write_send(state, ev, cli->transport,
-                                       data->data, data->length);
-               if (subreq == NULL) {
-                       goto fail;
-               }
-               tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
-               return req;
-       }
-
-       /* get the header first, then fetch the rest once we have
-        * the frag_length available */
-       max_recv_frag = RPC_HEADER_LEN;
-
-       subreq = cli_api_pipe_send(state, ev, cli->transport,
-                                  data->data, data->length, max_recv_frag);
-       if (subreq == NULL) {
-               goto fail;
-       }
-       tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
-       return req;
-
- post_status:
-       tevent_req_nterror(req, status);
-       return tevent_req_post(req, ev);
- fail:
-       TALLOC_FREE(req);
-       return NULL;
-}
-
-static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req =
-               tevent_req_callback_data(subreq,
-               struct tevent_req);
-       NTSTATUS status;
-
-       status = rpc_write_recv(subreq);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       tevent_req_done(req);
-}
-
-static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct rpc_api_pipe_state *state = tevent_req_data(
-               req, struct rpc_api_pipe_state);
-       NTSTATUS status;
-       uint8_t *rdata = NULL;
-       uint32_t rdata_len = 0;
-
-       status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       if (rdata == NULL) {
-               DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
-                        rpccli_pipe_txt(talloc_tos(), state->cli)));
-               tevent_req_done(req);
-               return;
-       }
-
-       /*
-        * Move data on state->incoming_frag.
-        */
-       state->incoming_frag.data = talloc_move(state, &rdata);
-       state->incoming_frag.length = rdata_len;
-       if (!state->incoming_frag.data) {
-               tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
-       }
-
-       /* Ensure we have enough data for a pdu. */
-       subreq = get_complete_frag_send(state, state->ev, state->cli,
-                                       &state->incoming_frag);
-       if (tevent_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
-}
-
-static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct rpc_api_pipe_state *state = tevent_req_data(
-               req, struct rpc_api_pipe_state);
-       NTSTATUS status;
-       DATA_BLOB rdata = data_blob_null;
-
-       status = get_complete_frag_recv(subreq);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(5, ("get_complete_frag failed: %s\n",
-                         nt_errstr(status)));
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       state->pkt = talloc(state, struct ncacn_packet);
-       if (!state->pkt) {
-               /*
-                * TODO: do a real async disconnect ...
-                *
-                * For now do it sync...
-                */
-               TALLOC_FREE(state->cli->transport);
-               tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
-       }
-
-       status = dcerpc_pull_ncacn_packet(state->pkt,
-                                         &state->incoming_frag,
-                                         state->pkt);
-       if (!NT_STATUS_IS_OK(status)) {
-               /*
-                * TODO: do a real async disconnect ...
-                *
-                * For now do it sync...
-                */
-               TALLOC_FREE(state->cli->transport);
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       if (DEBUGLEVEL >= 10) {
-               NDR_PRINT_DEBUG(ncacn_packet, state->pkt);
-       }
-
-       status = cli_pipe_validate_current_pdu(state,
-                                               state->cli, state->pkt,
-                                               &state->incoming_frag,
-                                               state->expected_pkt_type,
-                                               state->call_id,
-                                               &rdata,
-                                               &state->reply_pdu);
-
-       DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
-                 (unsigned)state->incoming_frag.length,
-                 (unsigned)state->reply_pdu_offset,
-                 nt_errstr(status)));
-
-       if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) {
-               /*
-                * TODO: do a real async disconnect ...
-                *
-                * For now do it sync...
-                */
-               TALLOC_FREE(state->cli->transport);
-       } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
-               /*
-                * TODO: do a real async disconnect ...
-                *
-                * For now do it sync...
-                */
-               TALLOC_FREE(state->cli->transport);
-       } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
-               /*
-                * TODO: do a real async disconnect ...
-                *
-                * For now do it sync...
-                */
-               TALLOC_FREE(state->cli->transport);
-       }
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
-           && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
-               /*
-                * Set the data type correctly for big-endian data on the
-                * first packet.
-                */
-               DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
-                         "big-endian.\n",
-                         rpccli_pipe_txt(talloc_tos(), state->cli)));
-               state->endianess = 0x00; /* BIG ENDIAN */
-       }
-       /*
-        * Check endianness on subsequent packets.
-        */
-       if (state->endianess != state->pkt->drep[0]) {
-               DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
-                        "%s\n",
-                        state->endianess?"little":"big",
-                        state->pkt->drep[0]?"little":"big"));
-               /*
-                * TODO: do a real async disconnect ...
-                *
-                * For now do it sync...
-                */
-               TALLOC_FREE(state->cli->transport);
-               tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
-               return;
-       }
-
-       if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) {
-               /*
-                * TODO: do a real async disconnect ...
-                *
-                * For now do it sync...
-                */
-               TALLOC_FREE(state->cli->transport);
-               tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
-               return;
-       }
-
-       /* Now copy the data portion out of the pdu into rbuf. */
-       if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
-               if (!data_blob_realloc(NULL, &state->reply_pdu,
-                               state->reply_pdu_offset + rdata.length)) {
-                       /*
-                        * TODO: do a real async disconnect ...
-                        *
-                        * For now do it sync...
-                        */
-                       TALLOC_FREE(state->cli->transport);
-                       tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
-                       return;
-               }
-       }
-
-       memcpy(state->reply_pdu.data + state->reply_pdu_offset,
-               rdata.data, rdata.length);
-       state->reply_pdu_offset += rdata.length;
-
-       /* reset state->incoming_frag, there is no need to free it,
-        * it will be reallocated to the right size the next time
-        * it is used */
-       state->incoming_frag.length = 0;
-
-       if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
-               /* make sure the pdu length is right now that we
-                * have all the data available (alloc hint may
-                * have allocated more than was actually used) */
-               state->reply_pdu.length = state->reply_pdu_offset;
-               DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
-                         rpccli_pipe_txt(talloc_tos(), state->cli),
-                         (unsigned)state->reply_pdu.length));
-               tevent_req_done(req);
-               return;
-       }
-
-       subreq = get_complete_frag_send(state, state->ev, state->cli,
-                                       &state->incoming_frag);
-       if (subreq == NULL) {
-               /*
-                * TODO: do a real async disconnect ...
-                *
-                * For now do it sync...
-                */
-               TALLOC_FREE(state->cli->transport);
-       }
-       if (tevent_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
-}
-
-static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
-                                 struct ncacn_packet **pkt,
-                                 DATA_BLOB *reply_pdu)
-{
-       struct rpc_api_pipe_state *state = tevent_req_data(
-               req, struct rpc_api_pipe_state);
-       NTSTATUS status;
-
-       if (tevent_req_is_nterror(req, &status)) {
-               return status;
-       }
-
-       /* return data to caller and assign it ownership of memory */
-       if (reply_pdu) {
-               reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
-               reply_pdu->length = state->reply_pdu.length;
-               state->reply_pdu.length = 0;
-       } else {
-               data_blob_free(&state->reply_pdu);
-       }
-
-       if (pkt) {
-               *pkt = talloc_steal(mem_ctx, state->pkt);
-       }
-
-       return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Creates NTLMSSP auth bind.
- ********************************************************************/
-
-static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
-                                                TALLOC_CTX *mem_ctx,
-                                                DATA_BLOB *auth_token,
-                                                bool *client_hdr_signing)
-{
-       struct gensec_security *gensec_security;
-       DATA_BLOB null_blob = data_blob_null;
-       NTSTATUS status;
-
-       gensec_security = cli->auth->auth_ctx;
-
-       DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
-       status = gensec_update(gensec_security, mem_ctx, null_blob, auth_token);
-
-       if (!NT_STATUS_IS_OK(status) &&
-           !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
-       {
-               return status;
-       }
-
-       if (client_hdr_signing == NULL) {
-               return status;
-       }
-
-       if (cli->auth->auth_level < DCERPC_AUTH_LEVEL_PACKET) {
-               *client_hdr_signing = false;
-               return status;
-       }
-
-       *client_hdr_signing = gensec_have_feature(gensec_security,
-                                               GENSEC_FEATURE_SIGN_PKT_HEADER);
-
-       return status;
-}
-
-/*******************************************************************
- Creates the internals of a DCE/RPC bind request or alter context PDU.
- ********************************************************************/
-
-static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
-                                               enum dcerpc_pkt_type ptype,
-                                               uint32_t rpc_call_id,
-                                               const struct ndr_syntax_id *abstract,
-                                               const struct ndr_syntax_id *transfer,
-                                               const DATA_BLOB *auth_info,
-                                               bool client_hdr_signing,
-                                               DATA_BLOB *blob)
-{
-       uint16_t auth_len = auth_info->length;
-       NTSTATUS status;
-       union dcerpc_payload u;
-       struct dcerpc_ctx_list ctx_list;
-       uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
-
-       if (auth_len) {
-               auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
-       }
-
-       if (client_hdr_signing) {
-               pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
-       }
-
-       ctx_list.context_id = 0;
-       ctx_list.num_transfer_syntaxes = 1;
-       ctx_list.abstract_syntax = *abstract;
-       ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
-
-       u.bind.max_xmit_frag    = RPC_MAX_PDU_FRAG_LEN;
-       u.bind.max_recv_frag    = RPC_MAX_PDU_FRAG_LEN;
-       u.bind.assoc_group_id   = 0x0;
-       u.bind.num_contexts     = 1;
-       u.bind.ctx_list         = &ctx_list;
-       u.bind.auth_info        = *auth_info;
-
-       status = dcerpc_push_ncacn_packet(mem_ctx,
-                                         ptype, pfc_flags,
-                                         auth_len,
-                                         rpc_call_id,
-                                         &u,
-                                         blob);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
-               return status;
-       }
-
-       return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Creates a DCE/RPC bind request.
- ********************************************************************/
-
-static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
-                                   struct rpc_pipe_client *cli,
-                                   struct pipe_auth_data *auth,
-                                   uint32_t rpc_call_id,
-                                   const struct ndr_syntax_id *abstract,
-                                   const struct ndr_syntax_id *transfer,
-                                   DATA_BLOB *rpc_out)
-{
-       DATA_BLOB auth_token = data_blob_null;
-       DATA_BLOB auth_info = data_blob_null;
-       NTSTATUS ret = NT_STATUS_OK;
-
-       switch (auth->auth_type) {
-       case DCERPC_AUTH_TYPE_NONE:
-               break;
-
-       default:
-               ret = create_generic_auth_rpc_bind_req(cli, mem_ctx,
-                                                      &auth_token,
-                                                      &auth->client_hdr_signing);
-
-               if (!NT_STATUS_IS_OK(ret) &&
-                   !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-                       return ret;
-               }
-               break;
-       }
-
-       if (auth_token.length != 0) {
-               ret = dcerpc_push_dcerpc_auth(cli,
-                                               auth->auth_type,
-                                               auth->auth_level,
-                                               0, /* auth_pad_length */
-                                               auth->auth_context_id,
-                                               &auth_token,
-                                               &auth_info);
-               if (!NT_STATUS_IS_OK(ret)) {
-                       return ret;
-               }
-               data_blob_free(&auth_token);
-       }
-
-       ret = create_bind_or_alt_ctx_internal(mem_ctx,
-                                             DCERPC_PKT_BIND,
-                                             rpc_call_id,
-                                             abstract,
-                                             transfer,
-                                             &auth_info,
-                                             auth->client_hdr_signing,
-                                             rpc_out);
-       return ret;
-}
-
-/*******************************************************************
- External interface.
- Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
- Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
- and deals with signing/sealing details.
- ********************************************************************/
-
-struct rpc_api_pipe_req_state {
-       struct tevent_context *ev;
-       struct rpc_pipe_client *cli;
-       uint8_t op_num;
-       uint32_t call_id;
-       const DATA_BLOB *req_data;
-       const struct GUID *object_uuid;
-       uint32_t req_data_sent;
-       DATA_BLOB req_trailer;
-       uint32_t req_trailer_sent;
-       bool verify_bitmask1;
-       bool verify_pcontext;
-       DATA_BLOB rpc_out;
-       DATA_BLOB reply_pdu;
-};
-
-static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
-static void rpc_api_pipe_req_done(struct tevent_req *subreq);
-static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
-static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
-                                 bool *is_last_frag);
-
-static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
-                                        struct tevent_context *ev,
-                                        struct rpc_pipe_client *cli,
-                                        uint8_t op_num,
-                                        const struct GUID *object_uuid,
-                                        const DATA_BLOB *req_data)
-{
-       struct tevent_req *req, *subreq;
-       struct rpc_api_pipe_req_state *state;
-       NTSTATUS status;
-       bool is_last_frag;
-
-       req = tevent_req_create(mem_ctx, &state,
-                               struct rpc_api_pipe_req_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->ev = ev;
-       state->cli = cli;
-       state->op_num = op_num;
-       state->object_uuid = object_uuid;
-       state->req_data = req_data;
-       state->req_data_sent = 0;
-       state->call_id = get_rpc_call_id();
-       state->reply_pdu = data_blob_null;
-       state->rpc_out = data_blob_null;
-
-       if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
-                                       + RPC_MAX_SIGN_SIZE) {
-               /* Server is screwed up ! */
-               status = NT_STATUS_INVALID_PARAMETER;
-               goto post_status;
-       }
-
-       status = prepare_verification_trailer(state);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto post_status;
-       }
-
-       status = prepare_next_frag(state, &is_last_frag);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto post_status;
-       }
-
-       if (is_last_frag) {
-               subreq = rpc_api_pipe_send(state, ev, state->cli,
-                                          &state->rpc_out,
-                                          DCERPC_PKT_RESPONSE,
-                                          state->call_id);
-               if (subreq == NULL) {
-                       goto fail;
-               }
-               tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
-       } else {
-               subreq = rpc_write_send(state, ev, cli->transport,
-                                       state->rpc_out.data,
-                                       state->rpc_out.length);
-               if (subreq == NULL) {
-                       goto fail;
-               }
-               tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
-                                       req);
-       }
-       return req;
-
- post_status:
-       tevent_req_nterror(req, status);
-       return tevent_req_post(req, ev);
- fail:
-       TALLOC_FREE(req);
-       return NULL;
-}
-
-static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
-{
-       struct pipe_auth_data *a = state->cli->auth;
-       struct dcerpc_sec_verification_trailer *t;
-       struct dcerpc_sec_vt *c = NULL;
-       struct ndr_push *ndr = NULL;
-       enum ndr_err_code ndr_err;
-       size_t align = 0;
-       size_t pad = 0;
-
-       if (a == NULL) {
-               return NT_STATUS_OK;
-       }
-
-       if (a->auth_level < DCERPC_AUTH_LEVEL_PACKET) {
-               return NT_STATUS_OK;
-       }
-
-       t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
-       if (t == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (!a->verified_bitmask1) {
-               t->commands = talloc_realloc(t, t->commands,
-                                            struct dcerpc_sec_vt,
-                                            t->count.count + 1);
-               if (t->commands == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               c = &t->commands[t->count.count++];
-               ZERO_STRUCTP(c);
-
-               c->command = DCERPC_SEC_VT_COMMAND_BITMASK1;
-               if (a->client_hdr_signing) {
-                       c->u.bitmask1 = DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING;
-               }
-               state->verify_bitmask1 = true;
-       }
-
-       if (!state->cli->verified_pcontext) {
-               t->commands = talloc_realloc(t, t->commands,
-                                            struct dcerpc_sec_vt,
-                                            t->count.count + 1);
-               if (t->commands == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               c = &t->commands[t->count.count++];
-               ZERO_STRUCTP(c);
-
-               c->command = DCERPC_SEC_VT_COMMAND_PCONTEXT;
-               c->u.pcontext.abstract_syntax = state->cli->abstract_syntax;
-               c->u.pcontext.transfer_syntax = state->cli->transfer_syntax;
-
-               state->verify_pcontext = true;
-       }
-
-       if (!a->hdr_signing) {
-               t->commands = talloc_realloc(t, t->commands,
-                                            struct dcerpc_sec_vt,
-                                            t->count.count + 1);
-               if (t->commands == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               c = &t->commands[t->count.count++];
-               ZERO_STRUCTP(c);
-
-               c->command = DCERPC_SEC_VT_COMMAND_HEADER2;
-               c->u.header2.ptype = DCERPC_PKT_REQUEST;
-               c->u.header2.drep[0] = DCERPC_DREP_LE;
-               c->u.header2.drep[1] = 0;
-               c->u.header2.drep[2] = 0;
-               c->u.header2.drep[3] = 0;
-               c->u.header2.call_id = state->call_id;
-               c->u.header2.context_id = 0;
-               c->u.header2.opnum = state->op_num;
-       }
-
-       if (t->count.count == 0) {
-               TALLOC_FREE(t);
-               return NT_STATUS_OK;
-       }
-
-       c = &t->commands[t->count.count - 1];
-       c->command |= DCERPC_SEC_VT_COMMAND_END;
-
-       if (DEBUGLEVEL >= 10) {
-               NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
-       }
-
-       ndr = ndr_push_init_ctx(state);
-       if (ndr == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
-                                               NDR_SCALARS | NDR_BUFFERS,
-                                               t);
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               return ndr_map_error2ntstatus(ndr_err);
-       }
-       state->req_trailer = ndr_push_blob(ndr);
-
-       align = state->req_data->length & 0x3;
-       if (align > 0) {
-               pad = 4 - align;
-       }
-       if (pad > 0) {
-               bool ok;
-               uint8_t *p;
-               const uint8_t zeros[4] = { 0, };
-
-               ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
-               if (!ok) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               /* move the padding to the start */
-               p = state->req_trailer.data;
-               memmove(p + pad, p, state->req_trailer.length - pad);
-               memset(p, 0, pad);
-       }
-
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
-                                 bool *is_last_frag)
-{
-       size_t auth_len;
-       size_t frag_len;
-       uint8_t flags = 0;
-       size_t pad_len;
-       size_t data_left;
-       size_t data_thistime;
-       size_t trailer_left;
-       size_t trailer_thistime = 0;
-       size_t total_left;
-       size_t total_thistime;
-       NTSTATUS status;
-       bool ok;
-       union dcerpc_payload u;
-
-       data_left = state->req_data->length - state->req_data_sent;
-       trailer_left = state->req_trailer.length - state->req_trailer_sent;
-       total_left = data_left + trailer_left;
-       if ((total_left < data_left) || (total_left < trailer_left)) {
-               /*
-                * overflow
-                */
-               return NT_STATUS_INVALID_PARAMETER_MIX;
-       }
-
-       status = dcerpc_guess_sizes(state->cli->auth,
-                                   DCERPC_REQUEST_LENGTH, total_left,
-                                   state->cli->max_xmit_frag,
-                                   &total_thistime,
-                                   &frag_len, &auth_len, &pad_len);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       if (state->req_data_sent == 0) {
-               flags = DCERPC_PFC_FLAG_FIRST;
-       }
-
-       if (total_thistime == total_left) {
-               flags |= DCERPC_PFC_FLAG_LAST;
-       }
-
-       data_thistime = MIN(total_thistime, data_left);
-       if (data_thistime < total_thistime) {
-               trailer_thistime = total_thistime - data_thistime;
-       }
-
-       data_blob_free(&state->rpc_out);
-
-       ZERO_STRUCT(u.request);
-
-       u.request.alloc_hint    = total_left;
-       u.request.context_id    = 0;
-       u.request.opnum         = state->op_num;
-
-       if (state->object_uuid) {
-               flags |= DCERPC_PFC_FLAG_OBJECT_UUID;
-               u.request.object.object = *state->object_uuid;
-               frag_len += ndr_size_GUID(state->object_uuid, 0);
-       }
-
-       status = dcerpc_push_ncacn_packet(state,
-                                         DCERPC_PKT_REQUEST,
-                                         flags,
-                                         auth_len,
-                                         state->call_id,
-                                         &u,
-                                         &state->rpc_out);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
-        * compute it right for requests because the auth trailer is missing
-        * at this stage */
-       dcerpc_set_frag_length(&state->rpc_out, frag_len);
-
-       if (data_thistime > 0) {
-               /* Copy in the data. */
-               ok = data_blob_append(NULL, &state->rpc_out,
-                               state->req_data->data + state->req_data_sent,
-                               data_thistime);
-               if (!ok) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               state->req_data_sent += data_thistime;
-       }
-
-       if (trailer_thistime > 0) {
-               /* Copy in the verification trailer. */
-               ok = data_blob_append(NULL, &state->rpc_out,
-                               state->req_trailer.data + state->req_trailer_sent,
-                               trailer_thistime);
-               if (!ok) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               state->req_trailer_sent += trailer_thistime;
-       }
-
-       switch (state->cli->auth->auth_level) {
-       case DCERPC_AUTH_LEVEL_NONE:
-       case DCERPC_AUTH_LEVEL_CONNECT:
-               break;
-       case DCERPC_AUTH_LEVEL_PACKET:
-       case DCERPC_AUTH_LEVEL_INTEGRITY:
-       case DCERPC_AUTH_LEVEL_PRIVACY:
-               status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
-                                               &state->rpc_out);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-               break;
-       default:
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
-
-       return status;
-}
-
-static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct rpc_api_pipe_req_state *state = tevent_req_data(
-               req, struct rpc_api_pipe_req_state);
-       NTSTATUS status;
-       bool is_last_frag;
-
-       status = rpc_write_recv(subreq);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       status = prepare_next_frag(state, &is_last_frag);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       if (is_last_frag) {
-               subreq = rpc_api_pipe_send(state, state->ev, state->cli,
-                                          &state->rpc_out,
-                                          DCERPC_PKT_RESPONSE,
-                                          state->call_id);
-               if (tevent_req_nomem(subreq, req)) {
-                       return;
-               }
-               tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
-       } else {
-               subreq = rpc_write_send(state, state->ev,
-                                       state->cli->transport,
-                                       state->rpc_out.data,
-                                       state->rpc_out.length);
-               if (tevent_req_nomem(subreq, req)) {
-                       return;
-               }
-               tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
-                                       req);
-       }
-}
-
-static void rpc_api_pipe_req_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct rpc_api_pipe_req_state *state = tevent_req_data(
-               req, struct rpc_api_pipe_req_state);
-       NTSTATUS status;
-
-       status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       if (state->cli->auth == NULL) {
-               tevent_req_done(req);
-               return;
-       }
-
-       if (state->verify_bitmask1) {
-               state->cli->auth->verified_bitmask1 = true;
-       }
-
-       if (state->verify_pcontext) {
-               state->cli->verified_pcontext = true;
-       }
-
-       tevent_req_done(req);
-}
-
-static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
-                              DATA_BLOB *reply_pdu)
-{
-       struct rpc_api_pipe_req_state *state = tevent_req_data(
-               req, struct rpc_api_pipe_req_state);
-       NTSTATUS status;
-
-       if (tevent_req_is_nterror(req, &status)) {
-               /*
-                * We always have to initialize to reply pdu, even if there is
-                * none. The rpccli_* caller routines expect this.
-                */
-               *reply_pdu = data_blob_null;
-               return status;
-       }
-
-       /* return data to caller and assign it ownership of memory */
-       reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
-       reply_pdu->length = state->reply_pdu.length;
-       state->reply_pdu.length = 0;
-
-       return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Check the rpc bind acknowledge response.
-****************************************************************************/
-
-static bool check_bind_response(const struct dcerpc_bind_ack *r,
-                               const struct ndr_syntax_id *transfer)
-{
-       struct dcerpc_ack_ctx ctx;
-
-       if (r->secondary_address_size == 0) {
-               DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
-       }
-
-       if (r->num_results < 1 || !r->ctx_list) {
-               return false;
-       }
-
-       ctx = r->ctx_list[0];
-
-       /* check the transfer syntax */
-       if ((ctx.syntax.if_version != transfer->if_version) ||
-            (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
-               DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
-               return False;
-       }
-
-       if (r->num_results != 0x1 || ctx.result != 0) {
-               DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
-                         r->num_results, ctx.reason.value));
-       }
-
-       DEBUG(5,("check_bind_response: accepted!\n"));
-       return True;
-}
-
-/*******************************************************************
- Creates a DCE/RPC bind authentication response.
- This is the packet that is sent back to the server once we
- have received a BIND-ACK, to finish the third leg of
- the authentication handshake.
- ********************************************************************/
-
-static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
-                               struct rpc_pipe_client *cli,
-                               struct pipe_auth_data *auth,
-                               uint32_t rpc_call_id,
-                               DATA_BLOB *pauth_blob,
-                               DATA_BLOB *rpc_out)
-{
-       NTSTATUS status;
-       union dcerpc_payload u;
-
-       u.auth3._pad = 0;
-
-       status = dcerpc_push_dcerpc_auth(mem_ctx,
-                                        auth->auth_type,
-                                        auth->auth_level,
-                                        0, /* auth_pad_length */
-                                        auth->auth_context_id,
-                                        pauth_blob,
-                                        &u.auth3.auth_info);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = dcerpc_push_ncacn_packet(mem_ctx,
-                                         DCERPC_PKT_AUTH3,
-                                         DCERPC_PFC_FLAG_FIRST |
-                                         DCERPC_PFC_FLAG_LAST,
-                                         pauth_blob->length,
-                                         rpc_call_id,
-                                         &u,
-                                         rpc_out);
-       data_blob_free(&u.auth3.auth_info);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
-               return status;
-       }
-
-       return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Creates a DCE/RPC bind alter context authentication request which
- may contain a spnego auth blobl
- ********************************************************************/
-
-static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
-                                       struct pipe_auth_data *auth,
-                                       uint32_t rpc_call_id,
-                                       const struct ndr_syntax_id *abstract,
-                                       const struct ndr_syntax_id *transfer,
-                                       const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
-                                       DATA_BLOB *rpc_out)
-{
-       DATA_BLOB auth_info;
-       NTSTATUS status;
-
-       status = dcerpc_push_dcerpc_auth(mem_ctx,
-                                        auth->auth_type,
-                                        auth->auth_level,
-                                        0, /* auth_pad_length */
-                                        auth->auth_context_id,
-                                        pauth_blob,
-                                        &auth_info);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = create_bind_or_alt_ctx_internal(mem_ctx,
-                                                DCERPC_PKT_ALTER,
-                                                rpc_call_id,
-                                                abstract,
-                                                transfer,
-                                                &auth_info,
-                                                false, /* client_hdr_signing */
-                                                rpc_out);
-       data_blob_free(&auth_info);
-       return status;
-}
-
 /****************************************************************************
  Do an rpc bind.
 ****************************************************************************/