2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client routines
4 * Largely rewritten by Jeremy Allison 2005.
5 * Heavily modified by Simo Sorce 2010.
6 * Copyright Andrew Bartlett 2011.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "../lib/util/tevent_ntstatus.h"
24 #include "librpc/gen_ndr/ndr_epmapper_c.h"
25 #include "../librpc/gen_ndr/ndr_dssetup.h"
26 #include "../libcli/auth/schannel.h"
27 #include "../libcli/auth/netlogon_creds_cli.h"
28 #include "auth_generic.h"
29 #include "librpc/gen_ndr/ndr_dcerpc.h"
30 #include "librpc/gen_ndr/ndr_netlogon_c.h"
31 #include "librpc/rpc/dcerpc.h"
34 #include "libsmb/libsmb.h"
35 #include "auth/gensec/gensec.h"
36 #include "auth/credentials/credentials.h"
37 #include "../libcli/smb/smbXcli_base.h"
40 #define DBGC_CLASS DBGC_RPC_CLI
42 /********************************************************************
43 Pipe description for a DEBUG
44 ********************************************************************/
45 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
46 struct rpc_pipe_client *cli)
48 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
55 /********************************************************************
57 ********************************************************************/
59 static uint32 get_rpc_call_id(void)
61 static uint32 call_id = 0;
65 /*******************************************************************
66 Use SMBreadX to get rest of one fragment's worth of rpc data.
67 Reads the whole size or give an error message
68 ********************************************************************/
70 struct rpc_read_state {
71 struct tevent_context *ev;
72 struct rpc_cli_transport *transport;
78 static void rpc_read_done(struct tevent_req *subreq);
80 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
81 struct tevent_context *ev,
82 struct rpc_cli_transport *transport,
83 uint8_t *data, size_t size)
85 struct tevent_req *req, *subreq;
86 struct rpc_read_state *state;
88 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
93 state->transport = transport;
98 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
100 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
102 if (subreq == NULL) {
105 tevent_req_set_callback(subreq, rpc_read_done, req);
113 static void rpc_read_done(struct tevent_req *subreq)
115 struct tevent_req *req = tevent_req_callback_data(
116 subreq, struct tevent_req);
117 struct rpc_read_state *state = tevent_req_data(
118 req, struct rpc_read_state);
122 status = state->transport->read_recv(subreq, &received);
124 if (!NT_STATUS_IS_OK(status)) {
125 tevent_req_nterror(req, status);
129 state->num_read += received;
130 if (state->num_read == state->size) {
131 tevent_req_done(req);
135 subreq = state->transport->read_send(state, state->ev,
136 state->data + state->num_read,
137 state->size - state->num_read,
138 state->transport->priv);
139 if (tevent_req_nomem(subreq, req)) {
142 tevent_req_set_callback(subreq, rpc_read_done, req);
145 static NTSTATUS rpc_read_recv(struct tevent_req *req)
147 return tevent_req_simple_recv_ntstatus(req);
150 struct rpc_write_state {
151 struct tevent_context *ev;
152 struct rpc_cli_transport *transport;
158 static void rpc_write_done(struct tevent_req *subreq);
160 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
161 struct tevent_context *ev,
162 struct rpc_cli_transport *transport,
163 const uint8_t *data, size_t size)
165 struct tevent_req *req, *subreq;
166 struct rpc_write_state *state;
168 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
173 state->transport = transport;
176 state->num_written = 0;
178 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
180 subreq = transport->write_send(state, ev, data, size, transport->priv);
181 if (subreq == NULL) {
184 tevent_req_set_callback(subreq, rpc_write_done, req);
191 static void rpc_write_done(struct tevent_req *subreq)
193 struct tevent_req *req = tevent_req_callback_data(
194 subreq, struct tevent_req);
195 struct rpc_write_state *state = tevent_req_data(
196 req, struct rpc_write_state);
200 status = state->transport->write_recv(subreq, &written);
202 if (!NT_STATUS_IS_OK(status)) {
203 tevent_req_nterror(req, status);
207 state->num_written += written;
209 if (state->num_written == state->size) {
210 tevent_req_done(req);
214 subreq = state->transport->write_send(state, state->ev,
215 state->data + state->num_written,
216 state->size - state->num_written,
217 state->transport->priv);
218 if (tevent_req_nomem(subreq, req)) {
221 tevent_req_set_callback(subreq, rpc_write_done, req);
224 static NTSTATUS rpc_write_recv(struct tevent_req *req)
226 return tevent_req_simple_recv_ntstatus(req);
230 /****************************************************************************
231 Try and get a PDU's worth of data from current_pdu. If not, then read more
233 ****************************************************************************/
235 struct get_complete_frag_state {
236 struct tevent_context *ev;
237 struct rpc_pipe_client *cli;
242 static void get_complete_frag_got_header(struct tevent_req *subreq);
243 static void get_complete_frag_got_rest(struct tevent_req *subreq);
245 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
246 struct tevent_context *ev,
247 struct rpc_pipe_client *cli,
250 struct tevent_req *req, *subreq;
251 struct get_complete_frag_state *state;
255 req = tevent_req_create(mem_ctx, &state,
256 struct get_complete_frag_state);
262 state->frag_len = RPC_HEADER_LEN;
265 received = pdu->length;
266 if (received < RPC_HEADER_LEN) {
267 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
268 status = NT_STATUS_NO_MEMORY;
271 subreq = rpc_read_send(state, state->ev,
272 state->cli->transport,
273 pdu->data + received,
274 RPC_HEADER_LEN - received);
275 if (subreq == NULL) {
276 status = NT_STATUS_NO_MEMORY;
279 tevent_req_set_callback(subreq, get_complete_frag_got_header,
284 state->frag_len = dcerpc_get_frag_length(pdu);
285 if (state->frag_len < RPC_HEADER_LEN) {
286 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
287 return tevent_req_post(req, ev);
291 * Ensure we have frag_len bytes of data.
293 if (received < state->frag_len) {
294 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
295 status = NT_STATUS_NO_MEMORY;
298 subreq = rpc_read_send(state, state->ev,
299 state->cli->transport,
300 pdu->data + received,
301 state->frag_len - received);
302 if (subreq == NULL) {
303 status = NT_STATUS_NO_MEMORY;
306 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
311 status = NT_STATUS_OK;
313 if (NT_STATUS_IS_OK(status)) {
314 tevent_req_done(req);
316 tevent_req_nterror(req, status);
318 return tevent_req_post(req, ev);
321 static void get_complete_frag_got_header(struct tevent_req *subreq)
323 struct tevent_req *req = tevent_req_callback_data(
324 subreq, struct tevent_req);
325 struct get_complete_frag_state *state = tevent_req_data(
326 req, struct get_complete_frag_state);
329 status = rpc_read_recv(subreq);
331 if (!NT_STATUS_IS_OK(status)) {
332 tevent_req_nterror(req, status);
336 state->frag_len = dcerpc_get_frag_length(state->pdu);
337 if (state->frag_len < RPC_HEADER_LEN) {
338 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
342 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
343 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
348 * We're here in this piece of code because we've read exactly
349 * RPC_HEADER_LEN bytes into state->pdu.
352 subreq = rpc_read_send(state, state->ev, state->cli->transport,
353 state->pdu->data + RPC_HEADER_LEN,
354 state->frag_len - RPC_HEADER_LEN);
355 if (tevent_req_nomem(subreq, req)) {
358 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
361 static void get_complete_frag_got_rest(struct tevent_req *subreq)
363 struct tevent_req *req = tevent_req_callback_data(
364 subreq, struct tevent_req);
367 status = rpc_read_recv(subreq);
369 if (!NT_STATUS_IS_OK(status)) {
370 tevent_req_nterror(req, status);
373 tevent_req_done(req);
376 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
378 return tevent_req_simple_recv_ntstatus(req);
381 /****************************************************************************
382 Do basic authentication checks on an incoming pdu.
383 ****************************************************************************/
385 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
386 struct rpc_pipe_client *cli,
387 struct ncacn_packet *pkt,
389 uint8_t expected_pkt_type,
392 DATA_BLOB *reply_pdu)
394 struct dcerpc_response *r;
395 NTSTATUS ret = NT_STATUS_OK;
399 * Point the return values at the real data including the RPC
400 * header. Just in case the caller wants it.
404 /* Ensure we have the correct type. */
405 switch (pkt->ptype) {
406 case DCERPC_PKT_ALTER_RESP:
407 case DCERPC_PKT_BIND_ACK:
409 /* Client code never receives this kind of packets */
413 case DCERPC_PKT_RESPONSE:
415 r = &pkt->u.response;
417 /* Here's where we deal with incoming sign/seal. */
418 ret = dcerpc_check_auth(cli->auth, pkt,
419 &r->stub_and_verifier,
420 DCERPC_RESPONSE_LENGTH,
422 if (!NT_STATUS_IS_OK(ret)) {
426 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
427 return NT_STATUS_BUFFER_TOO_SMALL;
430 /* Point the return values at the NDR data. */
431 rdata->data = r->stub_and_verifier.data;
433 if (pkt->auth_length) {
434 /* We've already done integer wrap tests in
435 * dcerpc_check_auth(). */
436 rdata->length = r->stub_and_verifier.length
438 - DCERPC_AUTH_TRAILER_LENGTH
441 rdata->length = r->stub_and_verifier.length;
444 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
445 (long unsigned int)pdu->length,
446 (long unsigned int)rdata->length,
447 (unsigned int)pad_len));
450 * If this is the first reply, and the allocation hint is
451 * reasonable, try and set up the reply_pdu DATA_BLOB to the
455 if ((reply_pdu->length == 0) &&
456 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
457 if (!data_blob_realloc(mem_ctx, reply_pdu,
459 DEBUG(0, ("reply alloc hint %d too "
460 "large to allocate\n",
461 (int)r->alloc_hint));
462 return NT_STATUS_NO_MEMORY;
468 case DCERPC_PKT_BIND_NAK:
469 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
470 rpccli_pipe_txt(talloc_tos(), cli)));
471 /* Use this for now... */
472 return NT_STATUS_NETWORK_ACCESS_DENIED;
474 case DCERPC_PKT_FAULT:
476 DEBUG(1, (__location__ ": RPC fault code %s received "
478 dcerpc_errstr(talloc_tos(),
479 pkt->u.fault.status),
480 rpccli_pipe_txt(talloc_tos(), cli)));
482 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
485 DEBUG(0, (__location__ "Unknown packet type %u received "
487 (unsigned int)pkt->ptype,
488 rpccli_pipe_txt(talloc_tos(), cli)));
489 return NT_STATUS_RPC_PROTOCOL_ERROR;
492 if (pkt->ptype != expected_pkt_type) {
493 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
494 "RPC packet type - %u, not %u\n",
495 rpccli_pipe_txt(talloc_tos(), cli),
496 pkt->ptype, expected_pkt_type));
497 return NT_STATUS_RPC_PROTOCOL_ERROR;
500 if (pkt->call_id != call_id) {
501 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
502 "RPC call_id - %u, not %u\n",
503 rpccli_pipe_txt(talloc_tos(), cli),
504 pkt->call_id, call_id));
505 return NT_STATUS_RPC_PROTOCOL_ERROR;
508 /* Do this just before return - we don't want to modify any rpc header
509 data before now as we may have needed to do cryptographic actions on
512 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
513 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
514 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
515 "fragment first/last ON.\n"));
516 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
522 /****************************************************************************
523 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
524 ****************************************************************************/
526 struct cli_api_pipe_state {
527 struct tevent_context *ev;
528 struct rpc_cli_transport *transport;
533 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
534 static void cli_api_pipe_write_done(struct tevent_req *subreq);
535 static void cli_api_pipe_read_done(struct tevent_req *subreq);
537 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
538 struct tevent_context *ev,
539 struct rpc_cli_transport *transport,
540 uint8_t *data, size_t data_len,
541 uint32_t max_rdata_len)
543 struct tevent_req *req, *subreq;
544 struct cli_api_pipe_state *state;
547 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
552 state->transport = transport;
554 if (max_rdata_len < RPC_HEADER_LEN) {
556 * For a RPC reply we always need at least RPC_HEADER_LEN
557 * bytes. We check this here because we will receive
558 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
560 status = NT_STATUS_INVALID_PARAMETER;
564 if (transport->trans_send != NULL) {
565 subreq = transport->trans_send(state, ev, data, data_len,
566 max_rdata_len, transport->priv);
567 if (subreq == NULL) {
570 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
575 * If the transport does not provide a "trans" routine, i.e. for
576 * example the ncacn_ip_tcp transport, do the write/read step here.
579 subreq = rpc_write_send(state, ev, transport, data, data_len);
580 if (subreq == NULL) {
583 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
587 tevent_req_nterror(req, status);
588 return tevent_req_post(req, ev);
594 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
596 struct tevent_req *req = tevent_req_callback_data(
597 subreq, struct tevent_req);
598 struct cli_api_pipe_state *state = tevent_req_data(
599 req, struct cli_api_pipe_state);
602 status = state->transport->trans_recv(subreq, state, &state->rdata,
605 if (!NT_STATUS_IS_OK(status)) {
606 tevent_req_nterror(req, status);
609 tevent_req_done(req);
612 static void cli_api_pipe_write_done(struct tevent_req *subreq)
614 struct tevent_req *req = tevent_req_callback_data(
615 subreq, struct tevent_req);
616 struct cli_api_pipe_state *state = tevent_req_data(
617 req, struct cli_api_pipe_state);
620 status = rpc_write_recv(subreq);
622 if (!NT_STATUS_IS_OK(status)) {
623 tevent_req_nterror(req, status);
627 state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
628 if (tevent_req_nomem(state->rdata, req)) {
633 * We don't need to use rpc_read_send here, the upper layer will cope
634 * with a short read, transport->trans_send could also return less
635 * than state->max_rdata_len.
637 subreq = state->transport->read_send(state, state->ev, state->rdata,
639 state->transport->priv);
640 if (tevent_req_nomem(subreq, req)) {
643 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
646 static void cli_api_pipe_read_done(struct tevent_req *subreq)
648 struct tevent_req *req = tevent_req_callback_data(
649 subreq, struct tevent_req);
650 struct cli_api_pipe_state *state = tevent_req_data(
651 req, struct cli_api_pipe_state);
655 status = state->transport->read_recv(subreq, &received);
657 if (!NT_STATUS_IS_OK(status)) {
658 tevent_req_nterror(req, status);
661 state->rdata_len = received;
662 tevent_req_done(req);
665 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
666 uint8_t **prdata, uint32_t *prdata_len)
668 struct cli_api_pipe_state *state = tevent_req_data(
669 req, struct cli_api_pipe_state);
672 if (tevent_req_is_nterror(req, &status)) {
676 *prdata = talloc_move(mem_ctx, &state->rdata);
677 *prdata_len = state->rdata_len;
681 /****************************************************************************
682 Send data on an rpc pipe via trans. The data must be the last
683 pdu fragment of an NDR data stream.
685 Receive response data from an rpc pipe, which may be large...
687 Read the first fragment: unfortunately have to use SMBtrans for the first
688 bit, then SMBreadX for subsequent bits.
690 If first fragment received also wasn't the last fragment, continue
691 getting fragments until we _do_ receive the last fragment.
693 Request/Response PDU's look like the following...
695 |<------------------PDU len----------------------------------------------->|
696 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
698 +------------+-----------------+-------------+---------------+-------------+
699 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
700 +------------+-----------------+-------------+---------------+-------------+
702 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
703 signing & sealing being negotiated.
705 ****************************************************************************/
707 struct rpc_api_pipe_state {
708 struct tevent_context *ev;
709 struct rpc_pipe_client *cli;
710 uint8_t expected_pkt_type;
713 DATA_BLOB incoming_frag;
714 struct ncacn_packet *pkt;
718 size_t reply_pdu_offset;
722 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
723 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
724 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
726 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
727 struct tevent_context *ev,
728 struct rpc_pipe_client *cli,
729 DATA_BLOB *data, /* Outgoing PDU */
730 uint8_t expected_pkt_type,
733 struct tevent_req *req, *subreq;
734 struct rpc_api_pipe_state *state;
735 uint16_t max_recv_frag;
738 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
744 state->expected_pkt_type = expected_pkt_type;
745 state->call_id = call_id;
746 state->endianess = DCERPC_DREP_LE;
749 * Ensure we're not sending too much.
751 if (data->length > cli->max_xmit_frag) {
752 status = NT_STATUS_INVALID_PARAMETER;
756 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
758 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
759 subreq = rpc_write_send(state, ev, cli->transport,
760 data->data, data->length);
761 if (subreq == NULL) {
764 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
768 /* get the header first, then fetch the rest once we have
769 * the frag_length available */
770 max_recv_frag = RPC_HEADER_LEN;
772 subreq = cli_api_pipe_send(state, ev, cli->transport,
773 data->data, data->length, max_recv_frag);
774 if (subreq == NULL) {
777 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
781 tevent_req_nterror(req, status);
782 return tevent_req_post(req, ev);
788 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
790 struct tevent_req *req =
791 tevent_req_callback_data(subreq,
795 status = rpc_write_recv(subreq);
797 if (!NT_STATUS_IS_OK(status)) {
798 tevent_req_nterror(req, status);
802 tevent_req_done(req);
805 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
807 struct tevent_req *req = tevent_req_callback_data(
808 subreq, struct tevent_req);
809 struct rpc_api_pipe_state *state = tevent_req_data(
810 req, struct rpc_api_pipe_state);
812 uint8_t *rdata = NULL;
813 uint32_t rdata_len = 0;
815 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
817 if (!NT_STATUS_IS_OK(status)) {
818 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
819 tevent_req_nterror(req, status);
824 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
825 rpccli_pipe_txt(talloc_tos(), state->cli)));
826 tevent_req_done(req);
831 * Move data on state->incoming_frag.
833 state->incoming_frag.data = talloc_move(state, &rdata);
834 state->incoming_frag.length = rdata_len;
835 if (!state->incoming_frag.data) {
836 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
840 /* Ensure we have enough data for a pdu. */
841 subreq = get_complete_frag_send(state, state->ev, state->cli,
842 &state->incoming_frag);
843 if (tevent_req_nomem(subreq, req)) {
846 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
849 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
851 struct tevent_req *req = tevent_req_callback_data(
852 subreq, struct tevent_req);
853 struct rpc_api_pipe_state *state = tevent_req_data(
854 req, struct rpc_api_pipe_state);
856 DATA_BLOB rdata = data_blob_null;
858 status = get_complete_frag_recv(subreq);
860 if (!NT_STATUS_IS_OK(status)) {
861 DEBUG(5, ("get_complete_frag failed: %s\n",
863 tevent_req_nterror(req, status);
867 state->pkt = talloc(state, struct ncacn_packet);
869 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
873 status = dcerpc_pull_ncacn_packet(state->pkt,
874 &state->incoming_frag,
877 if (!NT_STATUS_IS_OK(status)) {
878 tevent_req_nterror(req, status);
882 if (state->incoming_frag.length != state->pkt->frag_length) {
883 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
884 (unsigned int)state->incoming_frag.length,
885 (unsigned int)state->pkt->frag_length));
886 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
890 status = cli_pipe_validate_current_pdu(state,
891 state->cli, state->pkt,
892 &state->incoming_frag,
893 state->expected_pkt_type,
898 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
899 (unsigned)state->incoming_frag.length,
900 (unsigned)state->reply_pdu_offset,
903 if (!NT_STATUS_IS_OK(status)) {
904 tevent_req_nterror(req, status);
908 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
909 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
911 * Set the data type correctly for big-endian data on the
914 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
916 rpccli_pipe_txt(talloc_tos(), state->cli)));
917 state->endianess = 0x00; /* BIG ENDIAN */
920 * Check endianness on subsequent packets.
922 if (state->endianess != state->pkt->drep[0]) {
923 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
925 state->endianess?"little":"big",
926 state->pkt->drep[0]?"little":"big"));
927 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
931 /* Now copy the data portion out of the pdu into rbuf. */
932 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
933 if (!data_blob_realloc(NULL, &state->reply_pdu,
934 state->reply_pdu_offset + rdata.length)) {
935 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
940 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
941 rdata.data, rdata.length);
942 state->reply_pdu_offset += rdata.length;
944 /* reset state->incoming_frag, there is no need to free it,
945 * it will be reallocated to the right size the next time
947 state->incoming_frag.length = 0;
949 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
950 /* make sure the pdu length is right now that we
951 * have all the data available (alloc hint may
952 * have allocated more than was actually used) */
953 state->reply_pdu.length = state->reply_pdu_offset;
954 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
955 rpccli_pipe_txt(talloc_tos(), state->cli),
956 (unsigned)state->reply_pdu.length));
957 tevent_req_done(req);
961 subreq = get_complete_frag_send(state, state->ev, state->cli,
962 &state->incoming_frag);
963 if (tevent_req_nomem(subreq, req)) {
966 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
969 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
970 struct ncacn_packet **pkt,
971 DATA_BLOB *reply_pdu)
973 struct rpc_api_pipe_state *state = tevent_req_data(
974 req, struct rpc_api_pipe_state);
977 if (tevent_req_is_nterror(req, &status)) {
981 /* return data to caller and assign it ownership of memory */
983 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
984 reply_pdu->length = state->reply_pdu.length;
985 state->reply_pdu.length = 0;
987 data_blob_free(&state->reply_pdu);
991 *pkt = talloc_steal(mem_ctx, state->pkt);
997 /*******************************************************************
998 Creates NTLMSSP auth bind.
999 ********************************************************************/
1001 static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1002 TALLOC_CTX *mem_ctx,
1003 DATA_BLOB *auth_token,
1004 bool *client_hdr_signing)
1006 struct gensec_security *gensec_security;
1007 DATA_BLOB null_blob = data_blob_null;
1010 gensec_security = talloc_get_type_abort(cli->auth->auth_ctx,
1011 struct gensec_security);
1013 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1014 status = gensec_update(gensec_security, mem_ctx, null_blob, auth_token);
1016 if (!NT_STATUS_IS_OK(status) &&
1017 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1022 if (client_hdr_signing == NULL) {
1026 if (cli->auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1027 *client_hdr_signing = false;
1031 *client_hdr_signing = gensec_have_feature(gensec_security,
1032 GENSEC_FEATURE_SIGN_PKT_HEADER);
1037 /*******************************************************************
1038 Creates the internals of a DCE/RPC bind request or alter context PDU.
1039 ********************************************************************/
1041 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1042 enum dcerpc_pkt_type ptype,
1044 const struct ndr_syntax_id *abstract,
1045 const struct ndr_syntax_id *transfer,
1046 const DATA_BLOB *auth_info,
1047 bool client_hdr_signing,
1050 uint16 auth_len = auth_info->length;
1052 union dcerpc_payload u;
1053 struct dcerpc_ctx_list ctx_list;
1054 uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1057 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1060 if (client_hdr_signing) {
1061 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
1064 ctx_list.context_id = 0;
1065 ctx_list.num_transfer_syntaxes = 1;
1066 ctx_list.abstract_syntax = *abstract;
1067 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1069 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1070 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1071 u.bind.assoc_group_id = 0x0;
1072 u.bind.num_contexts = 1;
1073 u.bind.ctx_list = &ctx_list;
1074 u.bind.auth_info = *auth_info;
1076 status = dcerpc_push_ncacn_packet(mem_ctx,
1082 if (!NT_STATUS_IS_OK(status)) {
1083 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1087 return NT_STATUS_OK;
1090 /*******************************************************************
1091 Creates a DCE/RPC bind request.
1092 ********************************************************************/
1094 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1095 struct rpc_pipe_client *cli,
1096 struct pipe_auth_data *auth,
1098 const struct ndr_syntax_id *abstract,
1099 const struct ndr_syntax_id *transfer,
1102 DATA_BLOB auth_token = data_blob_null;
1103 DATA_BLOB auth_info = data_blob_null;
1104 NTSTATUS ret = NT_STATUS_OK;
1106 switch (auth->auth_type) {
1107 case DCERPC_AUTH_TYPE_SCHANNEL:
1108 case DCERPC_AUTH_TYPE_NTLMSSP:
1109 case DCERPC_AUTH_TYPE_KRB5:
1110 case DCERPC_AUTH_TYPE_SPNEGO:
1111 ret = create_generic_auth_rpc_bind_req(cli, mem_ctx,
1113 &auth->client_hdr_signing);
1115 if (!NT_STATUS_IS_OK(ret) &&
1116 !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1121 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1122 auth_token = data_blob_talloc(mem_ctx,
1123 "NCALRPC_AUTH_TOKEN",
1127 case DCERPC_AUTH_TYPE_NONE:
1131 /* "Can't" happen. */
1132 return NT_STATUS_INVALID_INFO_CLASS;
1135 if (auth_token.length != 0) {
1136 ret = dcerpc_push_dcerpc_auth(cli,
1139 0, /* auth_pad_length */
1140 1, /* auth_context_id */
1143 if (!NT_STATUS_IS_OK(ret)) {
1146 data_blob_free(&auth_token);
1149 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1155 auth->client_hdr_signing,
1160 /*******************************************************************
1162 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1163 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1164 and deals with signing/sealing details.
1165 ********************************************************************/
1167 struct rpc_api_pipe_req_state {
1168 struct tevent_context *ev;
1169 struct rpc_pipe_client *cli;
1172 const DATA_BLOB *req_data;
1173 uint32_t req_data_sent;
1174 DATA_BLOB req_trailer;
1175 uint32_t req_trailer_sent;
1176 bool verify_bitmask1;
1177 bool verify_pcontext;
1179 DATA_BLOB reply_pdu;
1182 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1183 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1184 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
1185 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1186 bool *is_last_frag);
1188 static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1189 struct tevent_context *ev,
1190 struct rpc_pipe_client *cli,
1192 const DATA_BLOB *req_data)
1194 struct tevent_req *req, *subreq;
1195 struct rpc_api_pipe_req_state *state;
1199 req = tevent_req_create(mem_ctx, &state,
1200 struct rpc_api_pipe_req_state);
1206 state->op_num = op_num;
1207 state->req_data = req_data;
1208 state->req_data_sent = 0;
1209 state->call_id = get_rpc_call_id();
1210 state->reply_pdu = data_blob_null;
1211 state->rpc_out = data_blob_null;
1213 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1214 + RPC_MAX_SIGN_SIZE) {
1215 /* Server is screwed up ! */
1216 status = NT_STATUS_INVALID_PARAMETER;
1220 status = prepare_verification_trailer(state);
1221 if (!NT_STATUS_IS_OK(status)) {
1225 status = prepare_next_frag(state, &is_last_frag);
1226 if (!NT_STATUS_IS_OK(status)) {
1231 subreq = rpc_api_pipe_send(state, ev, state->cli,
1233 DCERPC_PKT_RESPONSE,
1235 if (subreq == NULL) {
1238 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1240 subreq = rpc_write_send(state, ev, cli->transport,
1241 state->rpc_out.data,
1242 state->rpc_out.length);
1243 if (subreq == NULL) {
1246 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1252 tevent_req_nterror(req, status);
1253 return tevent_req_post(req, ev);
1259 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
1261 struct pipe_auth_data *a = state->cli->auth;
1262 struct dcerpc_sec_verification_trailer *t;
1263 struct dcerpc_sec_vt *c = NULL;
1264 struct ndr_push *ndr = NULL;
1265 enum ndr_err_code ndr_err;
1270 return NT_STATUS_OK;
1273 if (a->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1274 return NT_STATUS_OK;
1277 t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
1279 return NT_STATUS_NO_MEMORY;
1282 if (!a->verified_bitmask1) {
1283 t->commands = talloc_realloc(t, t->commands,
1284 struct dcerpc_sec_vt,
1285 t->count.count + 1);
1286 if (t->commands == NULL) {
1287 return NT_STATUS_NO_MEMORY;
1289 c = &t->commands[t->count.count++];
1292 c->command = DCERPC_SEC_VT_COMMAND_BITMASK1;
1293 if (a->client_hdr_signing) {
1294 c->u.bitmask1 = DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING;
1296 state->verify_bitmask1 = true;
1299 if (!state->cli->verified_pcontext) {
1300 t->commands = talloc_realloc(t, t->commands,
1301 struct dcerpc_sec_vt,
1302 t->count.count + 1);
1303 if (t->commands == NULL) {
1304 return NT_STATUS_NO_MEMORY;
1306 c = &t->commands[t->count.count++];
1309 c->command = DCERPC_SEC_VT_COMMAND_PCONTEXT;
1310 c->u.pcontext.abstract_syntax = state->cli->abstract_syntax;
1311 c->u.pcontext.transfer_syntax = state->cli->transfer_syntax;
1313 state->verify_pcontext = true;
1316 if (!a->hdr_signing) {
1317 t->commands = talloc_realloc(t, t->commands,
1318 struct dcerpc_sec_vt,
1319 t->count.count + 1);
1320 if (t->commands == NULL) {
1321 return NT_STATUS_NO_MEMORY;
1323 c = &t->commands[t->count.count++];
1326 c->command = DCERPC_SEC_VT_COMMAND_HEADER2;
1327 c->u.header2.ptype = DCERPC_PKT_REQUEST;
1328 c->u.header2.drep[0] = DCERPC_DREP_LE;
1329 c->u.header2.drep[1] = 0;
1330 c->u.header2.drep[2] = 0;
1331 c->u.header2.drep[3] = 0;
1332 c->u.header2.call_id = state->call_id;
1333 c->u.header2.context_id = 0;
1334 c->u.header2.opnum = state->op_num;
1337 if (t->count.count == 0) {
1339 return NT_STATUS_OK;
1342 c = &t->commands[t->count.count - 1];
1343 c->command |= DCERPC_SEC_VT_COMMAND_END;
1345 if (DEBUGLEVEL >= 10) {
1346 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
1349 ndr = ndr_push_init_ctx(state);
1351 return NT_STATUS_NO_MEMORY;
1354 ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
1355 NDR_SCALARS | NDR_BUFFERS,
1357 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1358 return ndr_map_error2ntstatus(ndr_err);
1360 state->req_trailer = ndr_push_blob(ndr);
1362 align = state->req_data->length & 0x3;
1369 const uint8_t zeros[4] = { 0, };
1371 ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
1373 return NT_STATUS_NO_MEMORY;
1376 /* move the padding to the start */
1377 p = state->req_trailer.data;
1378 memmove(p + pad, p, state->req_trailer.length - pad);
1382 return NT_STATUS_OK;
1385 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1393 size_t data_thistime;
1394 size_t trailer_left;
1395 size_t trailer_thistime = 0;
1397 size_t total_thistime;
1400 union dcerpc_payload u;
1402 data_left = state->req_data->length - state->req_data_sent;
1403 trailer_left = state->req_trailer.length - state->req_trailer_sent;
1404 total_left = data_left + trailer_left;
1405 if ((total_left < data_left) || (total_left < trailer_left)) {
1409 return NT_STATUS_INVALID_PARAMETER_MIX;
1412 status = dcerpc_guess_sizes(state->cli->auth,
1413 DCERPC_REQUEST_LENGTH, total_left,
1414 state->cli->max_xmit_frag,
1415 CLIENT_NDR_PADDING_SIZE,
1417 &frag_len, &auth_len, &pad_len);
1418 if (!NT_STATUS_IS_OK(status)) {
1422 if (state->req_data_sent == 0) {
1423 flags = DCERPC_PFC_FLAG_FIRST;
1426 if (total_thistime == total_left) {
1427 flags |= DCERPC_PFC_FLAG_LAST;
1430 data_thistime = MIN(total_thistime, data_left);
1431 if (data_thistime < total_thistime) {
1432 trailer_thistime = total_thistime - data_thistime;
1435 data_blob_free(&state->rpc_out);
1437 ZERO_STRUCT(u.request);
1439 u.request.alloc_hint = total_left;
1440 u.request.context_id = 0;
1441 u.request.opnum = state->op_num;
1443 status = dcerpc_push_ncacn_packet(state,
1450 if (!NT_STATUS_IS_OK(status)) {
1454 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1455 * compute it right for requests because the auth trailer is missing
1457 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1459 if (data_thistime > 0) {
1460 /* Copy in the data. */
1461 ok = data_blob_append(NULL, &state->rpc_out,
1462 state->req_data->data + state->req_data_sent,
1465 return NT_STATUS_NO_MEMORY;
1467 state->req_data_sent += data_thistime;
1470 if (trailer_thistime > 0) {
1471 /* Copy in the verification trailer. */
1472 ok = data_blob_append(NULL, &state->rpc_out,
1473 state->req_trailer.data + state->req_trailer_sent,
1476 return NT_STATUS_NO_MEMORY;
1478 state->req_trailer_sent += trailer_thistime;
1481 switch (state->cli->auth->auth_level) {
1482 case DCERPC_AUTH_LEVEL_NONE:
1483 case DCERPC_AUTH_LEVEL_CONNECT:
1484 case DCERPC_AUTH_LEVEL_PACKET:
1486 case DCERPC_AUTH_LEVEL_INTEGRITY:
1487 case DCERPC_AUTH_LEVEL_PRIVACY:
1488 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1490 if (!NT_STATUS_IS_OK(status)) {
1495 return NT_STATUS_INVALID_PARAMETER;
1498 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1503 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1505 struct tevent_req *req = tevent_req_callback_data(
1506 subreq, struct tevent_req);
1507 struct rpc_api_pipe_req_state *state = tevent_req_data(
1508 req, struct rpc_api_pipe_req_state);
1512 status = rpc_write_recv(subreq);
1513 TALLOC_FREE(subreq);
1514 if (!NT_STATUS_IS_OK(status)) {
1515 tevent_req_nterror(req, status);
1519 status = prepare_next_frag(state, &is_last_frag);
1520 if (!NT_STATUS_IS_OK(status)) {
1521 tevent_req_nterror(req, status);
1526 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1528 DCERPC_PKT_RESPONSE,
1530 if (tevent_req_nomem(subreq, req)) {
1533 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1535 subreq = rpc_write_send(state, state->ev,
1536 state->cli->transport,
1537 state->rpc_out.data,
1538 state->rpc_out.length);
1539 if (tevent_req_nomem(subreq, req)) {
1542 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1547 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1549 struct tevent_req *req = tevent_req_callback_data(
1550 subreq, struct tevent_req);
1551 struct rpc_api_pipe_req_state *state = tevent_req_data(
1552 req, struct rpc_api_pipe_req_state);
1555 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1556 TALLOC_FREE(subreq);
1557 if (!NT_STATUS_IS_OK(status)) {
1558 tevent_req_nterror(req, status);
1562 if (state->cli->auth == NULL) {
1563 tevent_req_done(req);
1567 if (state->verify_bitmask1) {
1568 state->cli->auth->verified_bitmask1 = true;
1571 if (state->verify_pcontext) {
1572 state->cli->verified_pcontext = true;
1575 tevent_req_done(req);
1578 static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1579 DATA_BLOB *reply_pdu)
1581 struct rpc_api_pipe_req_state *state = tevent_req_data(
1582 req, struct rpc_api_pipe_req_state);
1585 if (tevent_req_is_nterror(req, &status)) {
1587 * We always have to initialize to reply pdu, even if there is
1588 * none. The rpccli_* caller routines expect this.
1590 *reply_pdu = data_blob_null;
1594 /* return data to caller and assign it ownership of memory */
1595 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1596 reply_pdu->length = state->reply_pdu.length;
1597 state->reply_pdu.length = 0;
1599 return NT_STATUS_OK;
1602 /****************************************************************************
1603 Check the rpc bind acknowledge response.
1604 ****************************************************************************/
1606 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1607 const struct ndr_syntax_id *transfer)
1609 struct dcerpc_ack_ctx ctx;
1611 if (r->secondary_address_size == 0) {
1612 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1615 if (r->num_results < 1 || !r->ctx_list) {
1619 ctx = r->ctx_list[0];
1621 /* check the transfer syntax */
1622 if ((ctx.syntax.if_version != transfer->if_version) ||
1623 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1624 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1628 if (r->num_results != 0x1 || ctx.result != 0) {
1629 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1630 r->num_results, ctx.reason.value));
1633 DEBUG(5,("check_bind_response: accepted!\n"));
1637 /*******************************************************************
1638 Creates a DCE/RPC bind authentication response.
1639 This is the packet that is sent back to the server once we
1640 have received a BIND-ACK, to finish the third leg of
1641 the authentication handshake.
1642 ********************************************************************/
1644 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1645 struct rpc_pipe_client *cli,
1647 enum dcerpc_AuthType auth_type,
1648 enum dcerpc_AuthLevel auth_level,
1649 DATA_BLOB *pauth_blob,
1653 union dcerpc_payload u;
1657 status = dcerpc_push_dcerpc_auth(mem_ctx,
1660 0, /* auth_pad_length */
1661 1, /* auth_context_id */
1663 &u.auth3.auth_info);
1664 if (!NT_STATUS_IS_OK(status)) {
1668 status = dcerpc_push_ncacn_packet(mem_ctx,
1670 DCERPC_PFC_FLAG_FIRST |
1671 DCERPC_PFC_FLAG_LAST,
1676 data_blob_free(&u.auth3.auth_info);
1677 if (!NT_STATUS_IS_OK(status)) {
1678 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1682 return NT_STATUS_OK;
1685 /*******************************************************************
1686 Creates a DCE/RPC bind alter context authentication request which
1687 may contain a spnego auth blobl
1688 ********************************************************************/
1690 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1691 enum dcerpc_AuthType auth_type,
1692 enum dcerpc_AuthLevel auth_level,
1694 const struct ndr_syntax_id *abstract,
1695 const struct ndr_syntax_id *transfer,
1696 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1699 DATA_BLOB auth_info;
1702 status = dcerpc_push_dcerpc_auth(mem_ctx,
1705 0, /* auth_pad_length */
1706 1, /* auth_context_id */
1709 if (!NT_STATUS_IS_OK(status)) {
1713 status = create_bind_or_alt_ctx_internal(mem_ctx,
1719 false, /* client_hdr_signing */
1721 data_blob_free(&auth_info);
1725 /****************************************************************************
1727 ****************************************************************************/
1729 struct rpc_pipe_bind_state {
1730 struct tevent_context *ev;
1731 struct rpc_pipe_client *cli;
1734 uint32_t rpc_call_id;
1737 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1738 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1739 struct rpc_pipe_bind_state *state,
1740 DATA_BLOB *credentials);
1741 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1742 struct rpc_pipe_bind_state *state,
1743 DATA_BLOB *credentials);
1745 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1746 struct tevent_context *ev,
1747 struct rpc_pipe_client *cli,
1748 struct pipe_auth_data *auth)
1750 struct tevent_req *req, *subreq;
1751 struct rpc_pipe_bind_state *state;
1754 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1759 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1760 rpccli_pipe_txt(talloc_tos(), cli),
1761 (unsigned int)auth->auth_type,
1762 (unsigned int)auth->auth_level ));
1766 state->rpc_call_id = get_rpc_call_id();
1768 cli->auth = talloc_move(cli, &auth);
1770 /* Marshall the outgoing data. */
1771 status = create_rpc_bind_req(state, cli,
1774 &cli->abstract_syntax,
1775 &cli->transfer_syntax,
1778 if (!NT_STATUS_IS_OK(status) &&
1779 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1783 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1784 DCERPC_PKT_BIND_ACK, state->rpc_call_id);
1785 if (subreq == NULL) {
1788 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1792 tevent_req_nterror(req, status);
1793 return tevent_req_post(req, ev);
1799 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1801 struct tevent_req *req = tevent_req_callback_data(
1802 subreq, struct tevent_req);
1803 struct rpc_pipe_bind_state *state = tevent_req_data(
1804 req, struct rpc_pipe_bind_state);
1805 struct pipe_auth_data *pauth = state->cli->auth;
1806 struct gensec_security *gensec_security;
1807 struct ncacn_packet *pkt = NULL;
1808 struct dcerpc_auth auth;
1809 DATA_BLOB auth_token = data_blob_null;
1812 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1813 TALLOC_FREE(subreq);
1814 if (!NT_STATUS_IS_OK(status)) {
1815 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1816 rpccli_pipe_txt(talloc_tos(), state->cli),
1817 nt_errstr(status)));
1818 tevent_req_nterror(req, status);
1823 tevent_req_done(req);
1827 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1828 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1829 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1833 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1834 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1836 switch(pauth->auth_type) {
1838 case DCERPC_AUTH_TYPE_NONE:
1839 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1840 /* Bind complete. */
1841 tevent_req_done(req);
1844 case DCERPC_AUTH_TYPE_SCHANNEL:
1845 case DCERPC_AUTH_TYPE_NTLMSSP:
1846 case DCERPC_AUTH_TYPE_SPNEGO:
1847 case DCERPC_AUTH_TYPE_KRB5:
1848 /* Paranoid lenght checks */
1849 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1850 + pkt->auth_length) {
1851 tevent_req_nterror(req,
1852 NT_STATUS_INFO_LENGTH_MISMATCH);
1855 /* get auth credentials */
1856 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1857 &pkt->u.bind_ack.auth_info,
1859 if (!NT_STATUS_IS_OK(status)) {
1860 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1861 nt_errstr(status)));
1862 tevent_req_nterror(req, status);
1872 * For authenticated binds we may need to do 3 or 4 leg binds.
1875 switch(pauth->auth_type) {
1877 case DCERPC_AUTH_TYPE_NONE:
1878 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1879 /* Bind complete. */
1880 tevent_req_done(req);
1883 case DCERPC_AUTH_TYPE_SCHANNEL:
1884 case DCERPC_AUTH_TYPE_NTLMSSP:
1885 case DCERPC_AUTH_TYPE_KRB5:
1886 case DCERPC_AUTH_TYPE_SPNEGO:
1887 gensec_security = talloc_get_type_abort(pauth->auth_ctx,
1888 struct gensec_security);
1890 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
1891 if (pauth->client_hdr_signing) {
1892 pauth->hdr_signing = true;
1893 gensec_want_feature(gensec_security,
1894 GENSEC_FEATURE_SIGN_PKT_HEADER);
1898 status = gensec_update(gensec_security, state,
1899 auth.credentials, &auth_token);
1900 if (NT_STATUS_EQUAL(status,
1901 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1902 status = rpc_bind_next_send(req, state,
1904 } else if (NT_STATUS_IS_OK(status)) {
1905 if (auth_token.length == 0) {
1906 /* Bind complete. */
1907 tevent_req_done(req);
1910 status = rpc_bind_finish_send(req, state,
1919 if (!NT_STATUS_IS_OK(status)) {
1920 tevent_req_nterror(req, status);
1925 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1926 (unsigned int)state->cli->auth->auth_type));
1927 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1930 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1931 struct rpc_pipe_bind_state *state,
1932 DATA_BLOB *auth_token)
1934 struct pipe_auth_data *auth = state->cli->auth;
1935 struct tevent_req *subreq;
1938 /* Now prepare the alter context pdu. */
1939 data_blob_free(&state->rpc_out);
1941 status = create_rpc_alter_context(state,
1945 &state->cli->abstract_syntax,
1946 &state->cli->transfer_syntax,
1949 if (!NT_STATUS_IS_OK(status)) {
1953 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1954 &state->rpc_out, DCERPC_PKT_ALTER_RESP,
1955 state->rpc_call_id);
1956 if (subreq == NULL) {
1957 return NT_STATUS_NO_MEMORY;
1959 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1960 return NT_STATUS_OK;
1963 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1964 struct rpc_pipe_bind_state *state,
1965 DATA_BLOB *auth_token)
1967 struct pipe_auth_data *auth = state->cli->auth;
1968 struct tevent_req *subreq;
1971 state->auth3 = true;
1973 /* Now prepare the auth3 context pdu. */
1974 data_blob_free(&state->rpc_out);
1976 status = create_rpc_bind_auth3(state, state->cli,
1982 if (!NT_STATUS_IS_OK(status)) {
1986 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1987 &state->rpc_out, DCERPC_PKT_AUTH3,
1988 state->rpc_call_id);
1989 if (subreq == NULL) {
1990 return NT_STATUS_NO_MEMORY;
1992 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1993 return NT_STATUS_OK;
1996 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1998 return tevent_req_simple_recv_ntstatus(req);
2001 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2002 struct pipe_auth_data *auth)
2004 TALLOC_CTX *frame = talloc_stackframe();
2005 struct tevent_context *ev;
2006 struct tevent_req *req;
2007 NTSTATUS status = NT_STATUS_OK;
2009 ev = samba_tevent_context_init(frame);
2011 status = NT_STATUS_NO_MEMORY;
2015 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2017 status = NT_STATUS_NO_MEMORY;
2021 if (!tevent_req_poll(req, ev)) {
2022 status = map_nt_error_from_unix(errno);
2026 status = rpc_pipe_bind_recv(req);
2032 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2034 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2035 unsigned int timeout)
2039 if (rpc_cli->transport == NULL) {
2040 return RPCCLI_DEFAULT_TIMEOUT;
2043 if (rpc_cli->transport->set_timeout == NULL) {
2044 return RPCCLI_DEFAULT_TIMEOUT;
2047 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2049 return RPCCLI_DEFAULT_TIMEOUT;
2055 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2057 if (rpc_cli == NULL) {
2061 if (rpc_cli->transport == NULL) {
2065 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2068 struct rpccli_bh_state {
2069 struct rpc_pipe_client *rpc_cli;
2072 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2074 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2075 struct rpccli_bh_state);
2077 return rpccli_is_connected(hs->rpc_cli);
2080 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2083 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2084 struct rpccli_bh_state);
2086 return rpccli_set_timeout(hs->rpc_cli, timeout);
2089 static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
2090 enum dcerpc_AuthType *auth_type,
2091 enum dcerpc_AuthLevel *auth_level)
2093 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2094 struct rpccli_bh_state);
2096 if (hs->rpc_cli == NULL) {
2100 if (hs->rpc_cli->auth == NULL) {
2104 *auth_type = hs->rpc_cli->auth->auth_type;
2105 *auth_level = hs->rpc_cli->auth->auth_level;
2108 struct rpccli_bh_raw_call_state {
2114 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2116 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2117 struct tevent_context *ev,
2118 struct dcerpc_binding_handle *h,
2119 const struct GUID *object,
2122 const uint8_t *in_data,
2125 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2126 struct rpccli_bh_state);
2127 struct tevent_req *req;
2128 struct rpccli_bh_raw_call_state *state;
2130 struct tevent_req *subreq;
2132 req = tevent_req_create(mem_ctx, &state,
2133 struct rpccli_bh_raw_call_state);
2137 state->in_data.data = discard_const_p(uint8_t, in_data);
2138 state->in_data.length = in_length;
2140 ok = rpccli_bh_is_connected(h);
2142 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2143 return tevent_req_post(req, ev);
2146 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2147 opnum, &state->in_data);
2148 if (tevent_req_nomem(subreq, req)) {
2149 return tevent_req_post(req, ev);
2151 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2156 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2158 struct tevent_req *req =
2159 tevent_req_callback_data(subreq,
2161 struct rpccli_bh_raw_call_state *state =
2162 tevent_req_data(req,
2163 struct rpccli_bh_raw_call_state);
2166 state->out_flags = 0;
2168 /* TODO: support bigendian responses */
2170 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2171 TALLOC_FREE(subreq);
2172 if (!NT_STATUS_IS_OK(status)) {
2173 tevent_req_nterror(req, status);
2177 tevent_req_done(req);
2180 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2181 TALLOC_CTX *mem_ctx,
2184 uint32_t *out_flags)
2186 struct rpccli_bh_raw_call_state *state =
2187 tevent_req_data(req,
2188 struct rpccli_bh_raw_call_state);
2191 if (tevent_req_is_nterror(req, &status)) {
2192 tevent_req_received(req);
2196 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2197 *out_length = state->out_data.length;
2198 *out_flags = state->out_flags;
2199 tevent_req_received(req);
2200 return NT_STATUS_OK;
2203 struct rpccli_bh_disconnect_state {
2207 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2208 struct tevent_context *ev,
2209 struct dcerpc_binding_handle *h)
2211 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2212 struct rpccli_bh_state);
2213 struct tevent_req *req;
2214 struct rpccli_bh_disconnect_state *state;
2217 req = tevent_req_create(mem_ctx, &state,
2218 struct rpccli_bh_disconnect_state);
2223 ok = rpccli_bh_is_connected(h);
2225 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2226 return tevent_req_post(req, ev);
2230 * TODO: do a real async disconnect ...
2232 * For now the caller needs to free rpc_cli
2236 tevent_req_done(req);
2237 return tevent_req_post(req, ev);
2240 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2244 if (tevent_req_is_nterror(req, &status)) {
2245 tevent_req_received(req);
2249 tevent_req_received(req);
2250 return NT_STATUS_OK;
2253 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2258 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2260 const void *_struct_ptr,
2261 const struct ndr_interface_call *call)
2263 void *struct_ptr = discard_const(_struct_ptr);
2265 if (DEBUGLEVEL < 10) {
2269 if (ndr_flags & NDR_IN) {
2270 ndr_print_function_debug(call->ndr_print,
2275 if (ndr_flags & NDR_OUT) {
2276 ndr_print_function_debug(call->ndr_print,
2283 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2285 .is_connected = rpccli_bh_is_connected,
2286 .set_timeout = rpccli_bh_set_timeout,
2287 .auth_info = rpccli_bh_auth_info,
2288 .raw_call_send = rpccli_bh_raw_call_send,
2289 .raw_call_recv = rpccli_bh_raw_call_recv,
2290 .disconnect_send = rpccli_bh_disconnect_send,
2291 .disconnect_recv = rpccli_bh_disconnect_recv,
2293 .ref_alloc = rpccli_bh_ref_alloc,
2294 .do_ndr_print = rpccli_bh_do_ndr_print,
2297 /* initialise a rpc_pipe_client binding handle */
2298 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
2299 const struct GUID *object,
2300 const struct ndr_interface_table *table)
2302 struct dcerpc_binding_handle *h;
2303 struct rpccli_bh_state *hs;
2305 h = dcerpc_binding_handle_create(c,
2310 struct rpccli_bh_state,
2320 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2321 struct pipe_auth_data **presult)
2323 struct pipe_auth_data *result;
2325 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2326 if (result == NULL) {
2327 return NT_STATUS_NO_MEMORY;
2330 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2331 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2333 result->user_name = talloc_strdup(result, "");
2334 result->domain = talloc_strdup(result, "");
2335 if ((result->user_name == NULL) || (result->domain == NULL)) {
2336 TALLOC_FREE(result);
2337 return NT_STATUS_NO_MEMORY;
2341 return NT_STATUS_OK;
2344 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2345 struct pipe_auth_data **presult)
2347 struct pipe_auth_data *result;
2349 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2350 if (result == NULL) {
2351 return NT_STATUS_NO_MEMORY;
2354 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2355 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2357 result->user_name = talloc_strdup(result, "");
2358 result->domain = talloc_strdup(result, "");
2359 if ((result->user_name == NULL) || (result->domain == NULL)) {
2360 TALLOC_FREE(result);
2361 return NT_STATUS_NO_MEMORY;
2365 return NT_STATUS_OK;
2368 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2369 enum dcerpc_AuthType auth_type,
2370 enum dcerpc_AuthLevel auth_level,
2372 const char *target_service,
2374 const char *username,
2375 const char *password,
2376 enum credentials_use_kerberos use_kerberos,
2377 struct netlogon_creds_CredentialState *creds,
2378 struct pipe_auth_data **presult)
2380 struct auth_generic_state *auth_generic_ctx;
2381 struct pipe_auth_data *result;
2384 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2385 if (result == NULL) {
2386 return NT_STATUS_NO_MEMORY;
2389 result->auth_type = auth_type;
2390 result->auth_level = auth_level;
2392 result->user_name = talloc_strdup(result, username);
2393 result->domain = talloc_strdup(result, domain);
2394 if ((result->user_name == NULL) || (result->domain == NULL)) {
2395 status = NT_STATUS_NO_MEMORY;
2399 status = auth_generic_client_prepare(result,
2401 if (!NT_STATUS_IS_OK(status)) {
2405 status = auth_generic_set_username(auth_generic_ctx, username);
2406 if (!NT_STATUS_IS_OK(status)) {
2410 status = auth_generic_set_domain(auth_generic_ctx, domain);
2411 if (!NT_STATUS_IS_OK(status)) {
2415 status = auth_generic_set_password(auth_generic_ctx, password);
2416 if (!NT_STATUS_IS_OK(status)) {
2420 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2421 if (!NT_STATUS_IS_OK(status)) {
2425 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2426 if (!NT_STATUS_IS_OK(status)) {
2430 cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
2431 cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2433 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2434 if (!NT_STATUS_IS_OK(status)) {
2438 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2439 talloc_free(auth_generic_ctx);
2441 return NT_STATUS_OK;
2444 TALLOC_FREE(result);
2449 * Create an rpc pipe client struct, connecting to a tcp port.
2451 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2452 const struct sockaddr_storage *ss_addr,
2454 const struct ndr_interface_table *table,
2455 struct rpc_pipe_client **presult)
2457 struct rpc_pipe_client *result;
2458 struct sockaddr_storage addr;
2462 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2463 if (result == NULL) {
2464 return NT_STATUS_NO_MEMORY;
2467 result->abstract_syntax = table->syntax_id;
2468 result->transfer_syntax = ndr_transfer_syntax_ndr;
2470 result->desthost = talloc_strdup(result, host);
2471 result->srv_name_slash = talloc_asprintf_strupper_m(
2472 result, "\\\\%s", result->desthost);
2473 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2474 status = NT_STATUS_NO_MEMORY;
2478 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2479 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2481 if (ss_addr == NULL) {
2482 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2483 status = NT_STATUS_NOT_FOUND;
2490 status = open_socket_out(&addr, port, 60*1000, &fd);
2491 if (!NT_STATUS_IS_OK(status)) {
2494 set_socket_options(fd, lp_socket_options());
2496 status = rpc_transport_sock_init(result, fd, &result->transport);
2497 if (!NT_STATUS_IS_OK(status)) {
2502 result->transport->transport = NCACN_IP_TCP;
2504 result->binding_handle = rpccli_bh_create(result, NULL, table);
2505 if (result->binding_handle == NULL) {
2506 TALLOC_FREE(result);
2507 return NT_STATUS_NO_MEMORY;
2511 return NT_STATUS_OK;
2514 TALLOC_FREE(result);
2519 * Determine the tcp port on which a dcerpc interface is listening
2520 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2523 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2524 const struct sockaddr_storage *addr,
2525 const struct ndr_interface_table *table,
2529 struct rpc_pipe_client *epm_pipe = NULL;
2530 struct dcerpc_binding_handle *epm_handle = NULL;
2531 struct pipe_auth_data *auth = NULL;
2532 struct dcerpc_binding *map_binding = NULL;
2533 struct dcerpc_binding *res_binding = NULL;
2534 enum dcerpc_transport_t transport;
2535 const char *endpoint = NULL;
2536 struct epm_twr_t *map_tower = NULL;
2537 struct epm_twr_t *res_towers = NULL;
2538 struct policy_handle *entry_handle = NULL;
2539 uint32_t num_towers = 0;
2540 uint32_t max_towers = 1;
2541 struct epm_twr_p_t towers;
2542 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2543 uint32_t result = 0;
2545 if (pport == NULL) {
2546 status = NT_STATUS_INVALID_PARAMETER;
2550 if (ndr_syntax_id_equal(&table->syntax_id,
2551 &ndr_table_epmapper.syntax_id)) {
2553 status = NT_STATUS_OK;
2557 /* open the connection to the endpoint mapper */
2558 status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2559 &ndr_table_epmapper,
2562 if (!NT_STATUS_IS_OK(status)) {
2565 epm_handle = epm_pipe->binding_handle;
2567 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2568 if (!NT_STATUS_IS_OK(status)) {
2572 status = rpc_pipe_bind(epm_pipe, auth);
2573 if (!NT_STATUS_IS_OK(status)) {
2577 /* create tower for asking the epmapper */
2579 status = dcerpc_parse_binding(tmp_ctx, "ncacn_ip_tcp:[135]",
2581 if (!NT_STATUS_IS_OK(status)) {
2585 status = dcerpc_binding_set_abstract_syntax(map_binding,
2587 if (!NT_STATUS_IS_OK(status)) {
2591 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2592 if (map_tower == NULL) {
2593 status = NT_STATUS_NO_MEMORY;
2597 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2598 &(map_tower->tower));
2599 if (!NT_STATUS_IS_OK(status)) {
2603 /* allocate further parameters for the epm_Map call */
2605 res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2606 if (res_towers == NULL) {
2607 status = NT_STATUS_NO_MEMORY;
2610 towers.twr = res_towers;
2612 entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2613 if (entry_handle == NULL) {
2614 status = NT_STATUS_NO_MEMORY;
2618 /* ask the endpoint mapper for the port */
2620 status = dcerpc_epm_Map(epm_handle,
2622 discard_const_p(struct GUID,
2623 &(table->syntax_id.uuid)),
2631 if (!NT_STATUS_IS_OK(status)) {
2635 if (result != EPMAPPER_STATUS_OK) {
2636 status = NT_STATUS_UNSUCCESSFUL;
2640 if (num_towers != 1) {
2641 status = NT_STATUS_UNSUCCESSFUL;
2645 /* extract the port from the answer */
2647 status = dcerpc_binding_from_tower(tmp_ctx,
2648 &(towers.twr->tower),
2650 if (!NT_STATUS_IS_OK(status)) {
2654 transport = dcerpc_binding_get_transport(res_binding);
2655 endpoint = dcerpc_binding_get_string_option(res_binding, "endpoint");
2657 /* are further checks here necessary? */
2658 if (transport != NCACN_IP_TCP) {
2659 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2663 if (endpoint == NULL) {
2664 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2668 *pport = (uint16_t)atoi(endpoint);
2671 TALLOC_FREE(tmp_ctx);
2676 * Create a rpc pipe client struct, connecting to a host via tcp.
2677 * The port is determined by asking the endpoint mapper on the given
2680 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2681 const struct sockaddr_storage *addr,
2682 const struct ndr_interface_table *table,
2683 struct rpc_pipe_client **presult)
2688 status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2689 if (!NT_STATUS_IS_OK(status)) {
2693 return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2697 /********************************************************************
2698 Create a rpc pipe client struct, connecting to a unix domain socket
2699 ********************************************************************/
2700 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2701 const struct ndr_interface_table *table,
2702 struct rpc_pipe_client **presult)
2704 struct rpc_pipe_client *result;
2705 struct sockaddr_un addr;
2710 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2711 if (result == NULL) {
2712 return NT_STATUS_NO_MEMORY;
2715 result->abstract_syntax = table->syntax_id;
2716 result->transfer_syntax = ndr_transfer_syntax_ndr;
2718 result->desthost = get_myname(result);
2719 result->srv_name_slash = talloc_asprintf_strupper_m(
2720 result, "\\\\%s", result->desthost);
2721 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2722 status = NT_STATUS_NO_MEMORY;
2726 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2727 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2729 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2731 status = map_nt_error_from_unix(errno);
2736 addr.sun_family = AF_UNIX;
2737 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2738 salen = sizeof(struct sockaddr_un);
2740 if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
2741 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2744 return map_nt_error_from_unix(errno);
2747 status = rpc_transport_sock_init(result, fd, &result->transport);
2748 if (!NT_STATUS_IS_OK(status)) {
2753 result->transport->transport = NCALRPC;
2755 result->binding_handle = rpccli_bh_create(result, NULL, table);
2756 if (result->binding_handle == NULL) {
2757 TALLOC_FREE(result);
2758 return NT_STATUS_NO_MEMORY;
2762 return NT_STATUS_OK;
2765 TALLOC_FREE(result);
2769 struct rpc_pipe_client_np_ref {
2770 struct cli_state *cli;
2771 struct rpc_pipe_client *pipe;
2774 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2776 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2780 /****************************************************************************
2781 Open a named pipe over SMB to a remote server.
2783 * CAVEAT CALLER OF THIS FUNCTION:
2784 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2785 * so be sure that this function is called AFTER any structure (vs pointer)
2786 * assignment of the cli. In particular, libsmbclient does structure
2787 * assignments of cli, which invalidates the data in the returned
2788 * rpc_pipe_client if this function is called before the structure assignment
2791 ****************************************************************************/
2793 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2794 const struct ndr_interface_table *table,
2795 struct rpc_pipe_client **presult)
2797 struct rpc_pipe_client *result;
2799 struct rpc_pipe_client_np_ref *np_ref;
2801 /* sanity check to protect against crashes */
2804 return NT_STATUS_INVALID_HANDLE;
2807 result = talloc_zero(NULL, struct rpc_pipe_client);
2808 if (result == NULL) {
2809 return NT_STATUS_NO_MEMORY;
2812 result->abstract_syntax = table->syntax_id;
2813 result->transfer_syntax = ndr_transfer_syntax_ndr;
2814 result->desthost = talloc_strdup(result, smbXcli_conn_remote_name(cli->conn));
2815 result->srv_name_slash = talloc_asprintf_strupper_m(
2816 result, "\\\\%s", result->desthost);
2818 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2819 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2821 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2822 TALLOC_FREE(result);
2823 return NT_STATUS_NO_MEMORY;
2826 status = rpc_transport_np_init(result, cli, table,
2827 &result->transport);
2828 if (!NT_STATUS_IS_OK(status)) {
2829 TALLOC_FREE(result);
2833 result->transport->transport = NCACN_NP;
2835 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2836 if (np_ref == NULL) {
2837 TALLOC_FREE(result);
2838 return NT_STATUS_NO_MEMORY;
2841 np_ref->pipe = result;
2843 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2844 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2846 result->binding_handle = rpccli_bh_create(result, NULL, table);
2847 if (result->binding_handle == NULL) {
2848 TALLOC_FREE(result);
2849 return NT_STATUS_NO_MEMORY;
2853 return NT_STATUS_OK;
2856 /****************************************************************************
2857 Open a pipe to a remote server.
2858 ****************************************************************************/
2860 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2861 enum dcerpc_transport_t transport,
2862 const struct ndr_interface_table *table,
2863 struct rpc_pipe_client **presult)
2865 switch (transport) {
2867 return rpc_pipe_open_tcp(NULL,
2868 smbXcli_conn_remote_name(cli->conn),
2869 smbXcli_conn_remote_sockaddr(cli->conn),
2872 return rpc_pipe_open_np(cli, table, presult);
2874 return NT_STATUS_NOT_IMPLEMENTED;
2878 /****************************************************************************
2879 Open a named pipe to an SMB server and bind anonymously.
2880 ****************************************************************************/
2882 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2883 enum dcerpc_transport_t transport,
2884 const struct ndr_interface_table *table,
2885 struct rpc_pipe_client **presult)
2887 struct rpc_pipe_client *result;
2888 struct pipe_auth_data *auth;
2891 status = cli_rpc_pipe_open(cli, transport, table, &result);
2892 if (!NT_STATUS_IS_OK(status)) {
2896 status = rpccli_anon_bind_data(result, &auth);
2897 if (!NT_STATUS_IS_OK(status)) {
2898 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2899 nt_errstr(status)));
2900 TALLOC_FREE(result);
2905 * This is a bit of an abstraction violation due to the fact that an
2906 * anonymous bind on an authenticated SMB inherits the user/domain
2907 * from the enclosing SMB creds
2910 TALLOC_FREE(auth->user_name);
2911 TALLOC_FREE(auth->domain);
2913 auth->user_name = talloc_strdup(auth, cli->user_name);
2914 auth->domain = talloc_strdup(auth, cli->domain);
2916 if (transport == NCACN_NP) {
2917 struct smbXcli_session *session;
2919 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2920 session = cli->smb2.session;
2922 session = cli->smb1.session;
2925 status = smbXcli_session_application_key(session, auth,
2926 &auth->transport_session_key);
2927 if (!NT_STATUS_IS_OK(status)) {
2928 auth->transport_session_key = data_blob_null;
2932 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2933 TALLOC_FREE(result);
2934 return NT_STATUS_NO_MEMORY;
2937 status = rpc_pipe_bind(result, auth);
2938 if (!NT_STATUS_IS_OK(status)) {
2940 if (ndr_syntax_id_equal(&table->syntax_id,
2941 &ndr_table_dssetup.syntax_id)) {
2942 /* non AD domains just don't have this pipe, avoid
2943 * level 0 statement in that case - gd */
2946 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2947 "%s failed with error %s\n",
2949 nt_errstr(status) ));
2950 TALLOC_FREE(result);
2954 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2955 "%s and bound anonymously.\n",
2960 return NT_STATUS_OK;
2963 /****************************************************************************
2964 ****************************************************************************/
2966 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2967 const struct ndr_interface_table *table,
2968 struct rpc_pipe_client **presult)
2970 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2974 /****************************************************************************
2975 Open a named pipe to an SMB server and bind using the mech specified
2976 ****************************************************************************/
2978 NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
2979 const struct ndr_interface_table *table,
2980 enum dcerpc_transport_t transport,
2981 enum dcerpc_AuthType auth_type,
2982 enum dcerpc_AuthLevel auth_level,
2985 const char *username,
2986 const char *password,
2987 struct rpc_pipe_client **presult)
2989 struct rpc_pipe_client *result;
2990 struct pipe_auth_data *auth = NULL;
2991 const char *target_service = table->authservices->names[0];
2995 status = cli_rpc_pipe_open(cli, transport, table, &result);
2996 if (!NT_STATUS_IS_OK(status)) {
3000 status = rpccli_generic_bind_data(result,
3001 auth_type, auth_level,
3002 server, target_service,
3003 domain, username, password,
3004 CRED_AUTO_USE_KERBEROS,
3007 if (!NT_STATUS_IS_OK(status)) {
3008 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3009 nt_errstr(status)));
3013 status = rpc_pipe_bind(result, auth);
3014 if (!NT_STATUS_IS_OK(status)) {
3015 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3016 nt_errstr(status) ));
3020 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3021 "machine %s and bound as user %s\\%s.\n", table->name,
3022 result->desthost, domain, username));
3025 return NT_STATUS_OK;
3029 TALLOC_FREE(result);
3033 /****************************************************************************
3035 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3036 using session_key. sign and seal.
3038 The *pdc will be stolen onto this new pipe
3039 ****************************************************************************/
3041 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3042 const struct ndr_interface_table *table,
3043 enum dcerpc_transport_t transport,
3045 struct netlogon_creds_cli_context *netlogon_creds,
3046 struct rpc_pipe_client **_rpccli)
3048 struct rpc_pipe_client *rpccli;
3049 struct pipe_auth_data *rpcauth;
3050 struct netlogon_creds_CredentialState *creds = NULL;
3051 enum dcerpc_AuthLevel auth_level;
3053 const char *target_service = table->authservices->names[0];
3054 int rpc_pipe_bind_dbglvl = 0;
3056 status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
3057 if (!NT_STATUS_IS_OK(status)) {
3061 status = netlogon_creds_cli_lock(netlogon_creds, rpccli, &creds);
3062 if (!NT_STATUS_IS_OK(status)) {
3063 DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
3064 nt_errstr(status)));
3065 TALLOC_FREE(rpccli);
3069 auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
3071 status = rpccli_generic_bind_data(rpccli,
3072 DCERPC_AUTH_TYPE_SCHANNEL,
3077 creds->computer_name,
3079 CRED_AUTO_USE_KERBEROS,
3082 if (!NT_STATUS_IS_OK(status)) {
3083 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3084 nt_errstr(status)));
3085 TALLOC_FREE(rpccli);
3089 status = rpc_pipe_bind(rpccli, rpcauth);
3090 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3091 rpc_pipe_bind_dbglvl = 1;
3092 netlogon_creds_cli_delete(netlogon_creds, &creds);
3094 if (!NT_STATUS_IS_OK(status)) {
3095 DEBUG(rpc_pipe_bind_dbglvl,
3096 ("cli_rpc_pipe_open_schannel_with_key: "
3097 "rpc_pipe_bind failed with error %s\n",
3098 nt_errstr(status)));
3099 TALLOC_FREE(rpccli);
3105 if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
3109 status = netlogon_creds_cli_check(netlogon_creds,
3110 rpccli->binding_handle);
3111 if (!NT_STATUS_IS_OK(status)) {
3112 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3113 nt_errstr(status)));
3114 TALLOC_FREE(rpccli);
3120 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3121 "for domain %s and bound using schannel.\n",
3123 rpccli->desthost, domain));
3126 return NT_STATUS_OK;
3129 NTSTATUS cli_rpc_pipe_open_spnego(struct cli_state *cli,
3130 const struct ndr_interface_table *table,
3131 enum dcerpc_transport_t transport,
3133 enum dcerpc_AuthLevel auth_level,
3136 const char *username,
3137 const char *password,
3138 struct rpc_pipe_client **presult)
3140 struct rpc_pipe_client *result;
3141 struct pipe_auth_data *auth = NULL;
3142 const char *target_service = table->authservices->names[0];
3145 enum credentials_use_kerberos use_kerberos;
3147 if (strcmp(oid, GENSEC_OID_KERBEROS5) == 0) {
3148 use_kerberos = CRED_MUST_USE_KERBEROS;
3149 } else if (strcmp(oid, GENSEC_OID_NTLMSSP) == 0) {
3150 use_kerberos = CRED_DONT_USE_KERBEROS;
3152 return NT_STATUS_INVALID_PARAMETER;
3155 status = cli_rpc_pipe_open(cli, transport, table, &result);
3156 if (!NT_STATUS_IS_OK(status)) {
3160 status = rpccli_generic_bind_data(result,
3161 DCERPC_AUTH_TYPE_SPNEGO, auth_level,
3162 server, target_service,
3163 domain, username, password,
3166 if (!NT_STATUS_IS_OK(status)) {
3167 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3168 nt_errstr(status)));
3172 status = rpc_pipe_bind(result, auth);
3173 if (!NT_STATUS_IS_OK(status)) {
3174 DEBUG(0, ("cli_rpc_pipe_open_spnego: cli_rpc_pipe_bind failed with error %s\n",
3175 nt_errstr(status) ));
3179 DEBUG(10,("cli_rpc_pipe_open_spnego: opened pipe %s to "
3180 "machine %s.\n", table->name,
3184 return NT_STATUS_OK;
3188 TALLOC_FREE(result);
3192 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3193 struct rpc_pipe_client *cli,
3194 DATA_BLOB *session_key)
3197 struct pipe_auth_data *a;
3198 struct gensec_security *gensec_security;
3199 DATA_BLOB sk = data_blob_null;
3200 bool make_dup = false;
3202 if (!session_key || !cli) {
3203 return NT_STATUS_INVALID_PARAMETER;
3209 return NT_STATUS_INVALID_PARAMETER;
3212 switch (cli->auth->auth_type) {
3213 case DCERPC_AUTH_TYPE_SPNEGO:
3214 case DCERPC_AUTH_TYPE_NTLMSSP:
3215 case DCERPC_AUTH_TYPE_KRB5:
3216 gensec_security = talloc_get_type_abort(a->auth_ctx,
3217 struct gensec_security);
3218 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3219 if (!NT_STATUS_IS_OK(status)) {
3224 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3225 case DCERPC_AUTH_TYPE_NONE:
3226 sk = data_blob_const(a->transport_session_key.data,
3227 a->transport_session_key.length);
3235 return NT_STATUS_NO_USER_SESSION_KEY;
3239 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3244 return NT_STATUS_OK;