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_t get_rpc_call_id(void)
61 static uint32_t 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 const struct dcerpc_response *r = NULL;
395 DATA_BLOB tmp_stub = data_blob_null;
396 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 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
405 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
407 * TODO: do we still need this hack which was introduced
408 * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
410 * I don't even know what AS/U might be...
412 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
413 "fragment first/last ON.\n"));
414 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
417 /* Ensure we have the correct type. */
418 switch (pkt->ptype) {
419 case DCERPC_PKT_BIND_NAK:
420 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
421 rpccli_pipe_txt(talloc_tos(), cli)));
423 ret = dcerpc_verify_ncacn_packet_header(pkt,
425 0, /* max_auth_info */
426 DCERPC_PFC_FLAG_FIRST |
427 DCERPC_PFC_FLAG_LAST,
428 0); /* optional flags */
429 if (!NT_STATUS_IS_OK(ret)) {
430 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
431 "RPC packet type - %u, expected %u: %s\n",
432 rpccli_pipe_txt(talloc_tos(), cli),
433 pkt->ptype, expected_pkt_type,
435 NDR_PRINT_DEBUG(ncacn_packet, pkt);
439 /* Use this for now... */
440 return NT_STATUS_NETWORK_ACCESS_DENIED;
442 case DCERPC_PKT_BIND_ACK:
443 ret = dcerpc_verify_ncacn_packet_header(pkt,
445 pkt->u.bind_ack.auth_info.length,
446 DCERPC_PFC_FLAG_FIRST |
447 DCERPC_PFC_FLAG_LAST,
448 DCERPC_PFC_FLAG_CONC_MPX |
449 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
450 if (!NT_STATUS_IS_OK(ret)) {
451 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
452 "RPC packet type - %u, expected %u: %s\n",
453 rpccli_pipe_txt(talloc_tos(), cli),
454 pkt->ptype, expected_pkt_type,
456 NDR_PRINT_DEBUG(ncacn_packet, pkt);
462 case DCERPC_PKT_ALTER_RESP:
463 ret = dcerpc_verify_ncacn_packet_header(pkt,
465 pkt->u.alter_resp.auth_info.length,
466 DCERPC_PFC_FLAG_FIRST |
467 DCERPC_PFC_FLAG_LAST,
468 DCERPC_PFC_FLAG_CONC_MPX |
469 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
470 if (!NT_STATUS_IS_OK(ret)) {
471 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
472 "RPC packet type - %u, expected %u: %s\n",
473 rpccli_pipe_txt(talloc_tos(), cli),
474 pkt->ptype, expected_pkt_type,
476 NDR_PRINT_DEBUG(ncacn_packet, pkt);
482 case DCERPC_PKT_RESPONSE:
484 r = &pkt->u.response;
486 ret = dcerpc_verify_ncacn_packet_header(pkt,
488 r->stub_and_verifier.length,
489 0, /* required_flags */
490 DCERPC_PFC_FLAG_FIRST |
491 DCERPC_PFC_FLAG_LAST);
492 if (!NT_STATUS_IS_OK(ret)) {
493 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
494 "RPC packet type - %u, expected %u: %s\n",
495 rpccli_pipe_txt(talloc_tos(), cli),
496 pkt->ptype, expected_pkt_type,
498 NDR_PRINT_DEBUG(ncacn_packet, pkt);
502 tmp_stub.data = r->stub_and_verifier.data;
503 tmp_stub.length = r->stub_and_verifier.length;
505 /* Here's where we deal with incoming sign/seal. */
506 ret = dcerpc_check_auth(cli->auth, pkt,
508 DCERPC_RESPONSE_LENGTH,
510 if (!NT_STATUS_IS_OK(ret)) {
511 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
512 "RPC packet type - %u, expected %u: %s\n",
513 rpccli_pipe_txt(talloc_tos(), cli),
514 pkt->ptype, expected_pkt_type,
516 NDR_PRINT_DEBUG(ncacn_packet, pkt);
520 /* Point the return values at the NDR data. */
523 DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
524 (long unsigned int)pdu->length,
525 (long unsigned int)rdata->length));
528 * If this is the first reply, and the allocation hint is
529 * reasonable, try and set up the reply_pdu DATA_BLOB to the
533 if ((reply_pdu->length == 0) &&
534 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
535 if (!data_blob_realloc(mem_ctx, reply_pdu,
537 DEBUG(0, ("reply alloc hint %d too "
538 "large to allocate\n",
539 (int)r->alloc_hint));
540 return NT_STATUS_NO_MEMORY;
546 case DCERPC_PKT_FAULT:
548 ret = dcerpc_verify_ncacn_packet_header(pkt,
550 0, /* max_auth_info */
551 DCERPC_PFC_FLAG_FIRST |
552 DCERPC_PFC_FLAG_LAST,
553 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
554 if (!NT_STATUS_IS_OK(ret)) {
555 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
556 "RPC packet type - %u, expected %u: %s\n",
557 rpccli_pipe_txt(talloc_tos(), cli),
558 pkt->ptype, expected_pkt_type,
560 NDR_PRINT_DEBUG(ncacn_packet, pkt);
564 DEBUG(1, (__location__ ": RPC fault code %s received "
566 dcerpc_errstr(talloc_tos(),
567 pkt->u.fault.status),
568 rpccli_pipe_txt(talloc_tos(), cli)));
570 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
573 DEBUG(0, (__location__ "Unknown packet type %u received "
575 (unsigned int)pkt->ptype,
576 rpccli_pipe_txt(talloc_tos(), cli)));
577 return NT_STATUS_RPC_PROTOCOL_ERROR;
581 if (pkt->call_id != call_id) {
582 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
583 "RPC call_id - %u, not %u\n",
584 rpccli_pipe_txt(talloc_tos(), cli),
585 pkt->call_id, call_id));
586 return NT_STATUS_RPC_PROTOCOL_ERROR;
592 /****************************************************************************
593 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
594 ****************************************************************************/
596 struct cli_api_pipe_state {
597 struct tevent_context *ev;
598 struct rpc_cli_transport *transport;
603 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
604 static void cli_api_pipe_write_done(struct tevent_req *subreq);
605 static void cli_api_pipe_read_done(struct tevent_req *subreq);
607 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
608 struct tevent_context *ev,
609 struct rpc_cli_transport *transport,
610 uint8_t *data, size_t data_len,
611 uint32_t max_rdata_len)
613 struct tevent_req *req, *subreq;
614 struct cli_api_pipe_state *state;
617 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
622 state->transport = transport;
624 if (max_rdata_len < RPC_HEADER_LEN) {
626 * For a RPC reply we always need at least RPC_HEADER_LEN
627 * bytes. We check this here because we will receive
628 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
630 status = NT_STATUS_INVALID_PARAMETER;
634 if (transport->trans_send != NULL) {
635 subreq = transport->trans_send(state, ev, data, data_len,
636 max_rdata_len, transport->priv);
637 if (subreq == NULL) {
640 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
645 * If the transport does not provide a "trans" routine, i.e. for
646 * example the ncacn_ip_tcp transport, do the write/read step here.
649 subreq = rpc_write_send(state, ev, transport, data, data_len);
650 if (subreq == NULL) {
653 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
657 tevent_req_nterror(req, status);
658 return tevent_req_post(req, ev);
664 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
666 struct tevent_req *req = tevent_req_callback_data(
667 subreq, struct tevent_req);
668 struct cli_api_pipe_state *state = tevent_req_data(
669 req, struct cli_api_pipe_state);
672 status = state->transport->trans_recv(subreq, state, &state->rdata,
675 if (!NT_STATUS_IS_OK(status)) {
676 tevent_req_nterror(req, status);
679 tevent_req_done(req);
682 static void cli_api_pipe_write_done(struct tevent_req *subreq)
684 struct tevent_req *req = tevent_req_callback_data(
685 subreq, struct tevent_req);
686 struct cli_api_pipe_state *state = tevent_req_data(
687 req, struct cli_api_pipe_state);
690 status = rpc_write_recv(subreq);
692 if (!NT_STATUS_IS_OK(status)) {
693 tevent_req_nterror(req, status);
697 state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
698 if (tevent_req_nomem(state->rdata, req)) {
703 * We don't need to use rpc_read_send here, the upper layer will cope
704 * with a short read, transport->trans_send could also return less
705 * than state->max_rdata_len.
707 subreq = state->transport->read_send(state, state->ev, state->rdata,
709 state->transport->priv);
710 if (tevent_req_nomem(subreq, req)) {
713 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
716 static void cli_api_pipe_read_done(struct tevent_req *subreq)
718 struct tevent_req *req = tevent_req_callback_data(
719 subreq, struct tevent_req);
720 struct cli_api_pipe_state *state = tevent_req_data(
721 req, struct cli_api_pipe_state);
725 status = state->transport->read_recv(subreq, &received);
727 if (!NT_STATUS_IS_OK(status)) {
728 tevent_req_nterror(req, status);
731 state->rdata_len = received;
732 tevent_req_done(req);
735 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
736 uint8_t **prdata, uint32_t *prdata_len)
738 struct cli_api_pipe_state *state = tevent_req_data(
739 req, struct cli_api_pipe_state);
742 if (tevent_req_is_nterror(req, &status)) {
746 *prdata = talloc_move(mem_ctx, &state->rdata);
747 *prdata_len = state->rdata_len;
751 /****************************************************************************
752 Send data on an rpc pipe via trans. The data must be the last
753 pdu fragment of an NDR data stream.
755 Receive response data from an rpc pipe, which may be large...
757 Read the first fragment: unfortunately have to use SMBtrans for the first
758 bit, then SMBreadX for subsequent bits.
760 If first fragment received also wasn't the last fragment, continue
761 getting fragments until we _do_ receive the last fragment.
763 Request/Response PDU's look like the following...
765 |<------------------PDU len----------------------------------------------->|
766 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
768 +------------+-----------------+-------------+---------------+-------------+
769 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
770 +------------+-----------------+-------------+---------------+-------------+
772 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
773 signing & sealing being negotiated.
775 ****************************************************************************/
777 struct rpc_api_pipe_state {
778 struct tevent_context *ev;
779 struct rpc_pipe_client *cli;
780 uint8_t expected_pkt_type;
783 DATA_BLOB incoming_frag;
784 struct ncacn_packet *pkt;
788 size_t reply_pdu_offset;
792 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
793 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
794 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
796 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
797 struct tevent_context *ev,
798 struct rpc_pipe_client *cli,
799 DATA_BLOB *data, /* Outgoing PDU */
800 uint8_t expected_pkt_type,
803 struct tevent_req *req, *subreq;
804 struct rpc_api_pipe_state *state;
805 uint16_t max_recv_frag;
808 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
814 state->expected_pkt_type = expected_pkt_type;
815 state->call_id = call_id;
816 state->endianess = DCERPC_DREP_LE;
819 * Ensure we're not sending too much.
821 if (data->length > cli->max_xmit_frag) {
822 status = NT_STATUS_INVALID_PARAMETER;
826 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
828 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
829 subreq = rpc_write_send(state, ev, cli->transport,
830 data->data, data->length);
831 if (subreq == NULL) {
834 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
838 /* get the header first, then fetch the rest once we have
839 * the frag_length available */
840 max_recv_frag = RPC_HEADER_LEN;
842 subreq = cli_api_pipe_send(state, ev, cli->transport,
843 data->data, data->length, max_recv_frag);
844 if (subreq == NULL) {
847 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
851 tevent_req_nterror(req, status);
852 return tevent_req_post(req, ev);
858 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
860 struct tevent_req *req =
861 tevent_req_callback_data(subreq,
865 status = rpc_write_recv(subreq);
867 if (!NT_STATUS_IS_OK(status)) {
868 tevent_req_nterror(req, status);
872 tevent_req_done(req);
875 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
877 struct tevent_req *req = tevent_req_callback_data(
878 subreq, struct tevent_req);
879 struct rpc_api_pipe_state *state = tevent_req_data(
880 req, struct rpc_api_pipe_state);
882 uint8_t *rdata = NULL;
883 uint32_t rdata_len = 0;
885 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
887 if (!NT_STATUS_IS_OK(status)) {
888 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
889 tevent_req_nterror(req, status);
894 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
895 rpccli_pipe_txt(talloc_tos(), state->cli)));
896 tevent_req_done(req);
901 * Move data on state->incoming_frag.
903 state->incoming_frag.data = talloc_move(state, &rdata);
904 state->incoming_frag.length = rdata_len;
905 if (!state->incoming_frag.data) {
906 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
910 /* Ensure we have enough data for a pdu. */
911 subreq = get_complete_frag_send(state, state->ev, state->cli,
912 &state->incoming_frag);
913 if (tevent_req_nomem(subreq, req)) {
916 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
919 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
921 struct tevent_req *req = tevent_req_callback_data(
922 subreq, struct tevent_req);
923 struct rpc_api_pipe_state *state = tevent_req_data(
924 req, struct rpc_api_pipe_state);
926 DATA_BLOB rdata = data_blob_null;
928 status = get_complete_frag_recv(subreq);
930 if (!NT_STATUS_IS_OK(status)) {
931 DEBUG(5, ("get_complete_frag failed: %s\n",
933 tevent_req_nterror(req, status);
937 state->pkt = talloc(state, struct ncacn_packet);
939 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
943 status = dcerpc_pull_ncacn_packet(state->pkt,
944 &state->incoming_frag,
947 if (!NT_STATUS_IS_OK(status)) {
948 tevent_req_nterror(req, status);
952 status = cli_pipe_validate_current_pdu(state,
953 state->cli, state->pkt,
954 &state->incoming_frag,
955 state->expected_pkt_type,
960 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
961 (unsigned)state->incoming_frag.length,
962 (unsigned)state->reply_pdu_offset,
965 if (!NT_STATUS_IS_OK(status)) {
966 tevent_req_nterror(req, status);
970 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
971 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
973 * Set the data type correctly for big-endian data on the
976 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
978 rpccli_pipe_txt(talloc_tos(), state->cli)));
979 state->endianess = 0x00; /* BIG ENDIAN */
982 * Check endianness on subsequent packets.
984 if (state->endianess != state->pkt->drep[0]) {
985 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
987 state->endianess?"little":"big",
988 state->pkt->drep[0]?"little":"big"));
989 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
993 if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) {
994 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
998 /* Now copy the data portion out of the pdu into rbuf. */
999 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
1000 if (!data_blob_realloc(NULL, &state->reply_pdu,
1001 state->reply_pdu_offset + rdata.length)) {
1002 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1007 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
1008 rdata.data, rdata.length);
1009 state->reply_pdu_offset += rdata.length;
1011 /* reset state->incoming_frag, there is no need to free it,
1012 * it will be reallocated to the right size the next time
1014 state->incoming_frag.length = 0;
1016 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1017 /* make sure the pdu length is right now that we
1018 * have all the data available (alloc hint may
1019 * have allocated more than was actually used) */
1020 state->reply_pdu.length = state->reply_pdu_offset;
1021 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1022 rpccli_pipe_txt(talloc_tos(), state->cli),
1023 (unsigned)state->reply_pdu.length));
1024 tevent_req_done(req);
1028 subreq = get_complete_frag_send(state, state->ev, state->cli,
1029 &state->incoming_frag);
1030 if (tevent_req_nomem(subreq, req)) {
1033 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1036 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1037 struct ncacn_packet **pkt,
1038 DATA_BLOB *reply_pdu)
1040 struct rpc_api_pipe_state *state = tevent_req_data(
1041 req, struct rpc_api_pipe_state);
1044 if (tevent_req_is_nterror(req, &status)) {
1048 /* return data to caller and assign it ownership of memory */
1050 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1051 reply_pdu->length = state->reply_pdu.length;
1052 state->reply_pdu.length = 0;
1054 data_blob_free(&state->reply_pdu);
1058 *pkt = talloc_steal(mem_ctx, state->pkt);
1061 return NT_STATUS_OK;
1064 /*******************************************************************
1065 Creates NTLMSSP auth bind.
1066 ********************************************************************/
1068 static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1069 TALLOC_CTX *mem_ctx,
1070 DATA_BLOB *auth_token,
1071 bool *client_hdr_signing)
1073 struct gensec_security *gensec_security;
1074 DATA_BLOB null_blob = data_blob_null;
1077 gensec_security = cli->auth->auth_ctx;
1079 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1080 status = gensec_update(gensec_security, mem_ctx, null_blob, auth_token);
1082 if (!NT_STATUS_IS_OK(status) &&
1083 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1088 if (client_hdr_signing == NULL) {
1092 if (cli->auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1093 *client_hdr_signing = false;
1097 *client_hdr_signing = gensec_have_feature(gensec_security,
1098 GENSEC_FEATURE_SIGN_PKT_HEADER);
1103 /*******************************************************************
1104 Creates the internals of a DCE/RPC bind request or alter context PDU.
1105 ********************************************************************/
1107 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1108 enum dcerpc_pkt_type ptype,
1109 uint32_t rpc_call_id,
1110 const struct ndr_syntax_id *abstract,
1111 const struct ndr_syntax_id *transfer,
1112 const DATA_BLOB *auth_info,
1113 bool client_hdr_signing,
1116 uint16_t auth_len = auth_info->length;
1118 union dcerpc_payload u;
1119 struct dcerpc_ctx_list ctx_list;
1120 uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1123 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1126 if (client_hdr_signing) {
1127 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
1130 ctx_list.context_id = 0;
1131 ctx_list.num_transfer_syntaxes = 1;
1132 ctx_list.abstract_syntax = *abstract;
1133 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1135 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1136 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1137 u.bind.assoc_group_id = 0x0;
1138 u.bind.num_contexts = 1;
1139 u.bind.ctx_list = &ctx_list;
1140 u.bind.auth_info = *auth_info;
1142 status = dcerpc_push_ncacn_packet(mem_ctx,
1148 if (!NT_STATUS_IS_OK(status)) {
1149 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1153 return NT_STATUS_OK;
1156 /*******************************************************************
1157 Creates a DCE/RPC bind request.
1158 ********************************************************************/
1160 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1161 struct rpc_pipe_client *cli,
1162 struct pipe_auth_data *auth,
1163 uint32_t rpc_call_id,
1164 const struct ndr_syntax_id *abstract,
1165 const struct ndr_syntax_id *transfer,
1168 DATA_BLOB auth_token = data_blob_null;
1169 DATA_BLOB auth_info = data_blob_null;
1170 NTSTATUS ret = NT_STATUS_OK;
1172 switch (auth->auth_type) {
1173 case DCERPC_AUTH_TYPE_NONE:
1177 ret = create_generic_auth_rpc_bind_req(cli, mem_ctx,
1179 &auth->client_hdr_signing);
1181 if (!NT_STATUS_IS_OK(ret) &&
1182 !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1188 if (auth_token.length != 0) {
1189 ret = dcerpc_push_dcerpc_auth(cli,
1192 0, /* auth_pad_length */
1193 1, /* auth_context_id */
1196 if (!NT_STATUS_IS_OK(ret)) {
1199 data_blob_free(&auth_token);
1202 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1208 auth->client_hdr_signing,
1213 /*******************************************************************
1215 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1216 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1217 and deals with signing/sealing details.
1218 ********************************************************************/
1220 struct rpc_api_pipe_req_state {
1221 struct tevent_context *ev;
1222 struct rpc_pipe_client *cli;
1225 const DATA_BLOB *req_data;
1226 uint32_t req_data_sent;
1227 DATA_BLOB req_trailer;
1228 uint32_t req_trailer_sent;
1229 bool verify_bitmask1;
1230 bool verify_pcontext;
1232 DATA_BLOB reply_pdu;
1235 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1236 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1237 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
1238 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1239 bool *is_last_frag);
1241 static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1242 struct tevent_context *ev,
1243 struct rpc_pipe_client *cli,
1245 const DATA_BLOB *req_data)
1247 struct tevent_req *req, *subreq;
1248 struct rpc_api_pipe_req_state *state;
1252 req = tevent_req_create(mem_ctx, &state,
1253 struct rpc_api_pipe_req_state);
1259 state->op_num = op_num;
1260 state->req_data = req_data;
1261 state->req_data_sent = 0;
1262 state->call_id = get_rpc_call_id();
1263 state->reply_pdu = data_blob_null;
1264 state->rpc_out = data_blob_null;
1266 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1267 + RPC_MAX_SIGN_SIZE) {
1268 /* Server is screwed up ! */
1269 status = NT_STATUS_INVALID_PARAMETER;
1273 status = prepare_verification_trailer(state);
1274 if (!NT_STATUS_IS_OK(status)) {
1278 status = prepare_next_frag(state, &is_last_frag);
1279 if (!NT_STATUS_IS_OK(status)) {
1284 subreq = rpc_api_pipe_send(state, ev, state->cli,
1286 DCERPC_PKT_RESPONSE,
1288 if (subreq == NULL) {
1291 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1293 subreq = rpc_write_send(state, ev, cli->transport,
1294 state->rpc_out.data,
1295 state->rpc_out.length);
1296 if (subreq == NULL) {
1299 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1305 tevent_req_nterror(req, status);
1306 return tevent_req_post(req, ev);
1312 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
1314 struct pipe_auth_data *a = state->cli->auth;
1315 struct dcerpc_sec_verification_trailer *t;
1316 struct dcerpc_sec_vt *c = NULL;
1317 struct ndr_push *ndr = NULL;
1318 enum ndr_err_code ndr_err;
1323 return NT_STATUS_OK;
1326 if (a->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1327 return NT_STATUS_OK;
1330 t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
1332 return NT_STATUS_NO_MEMORY;
1335 if (!a->verified_bitmask1) {
1336 t->commands = talloc_realloc(t, t->commands,
1337 struct dcerpc_sec_vt,
1338 t->count.count + 1);
1339 if (t->commands == NULL) {
1340 return NT_STATUS_NO_MEMORY;
1342 c = &t->commands[t->count.count++];
1345 c->command = DCERPC_SEC_VT_COMMAND_BITMASK1;
1346 if (a->client_hdr_signing) {
1347 c->u.bitmask1 = DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING;
1349 state->verify_bitmask1 = true;
1352 if (!state->cli->verified_pcontext) {
1353 t->commands = talloc_realloc(t, t->commands,
1354 struct dcerpc_sec_vt,
1355 t->count.count + 1);
1356 if (t->commands == NULL) {
1357 return NT_STATUS_NO_MEMORY;
1359 c = &t->commands[t->count.count++];
1362 c->command = DCERPC_SEC_VT_COMMAND_PCONTEXT;
1363 c->u.pcontext.abstract_syntax = state->cli->abstract_syntax;
1364 c->u.pcontext.transfer_syntax = state->cli->transfer_syntax;
1366 state->verify_pcontext = true;
1369 if (!a->hdr_signing) {
1370 t->commands = talloc_realloc(t, t->commands,
1371 struct dcerpc_sec_vt,
1372 t->count.count + 1);
1373 if (t->commands == NULL) {
1374 return NT_STATUS_NO_MEMORY;
1376 c = &t->commands[t->count.count++];
1379 c->command = DCERPC_SEC_VT_COMMAND_HEADER2;
1380 c->u.header2.ptype = DCERPC_PKT_REQUEST;
1381 c->u.header2.drep[0] = DCERPC_DREP_LE;
1382 c->u.header2.drep[1] = 0;
1383 c->u.header2.drep[2] = 0;
1384 c->u.header2.drep[3] = 0;
1385 c->u.header2.call_id = state->call_id;
1386 c->u.header2.context_id = 0;
1387 c->u.header2.opnum = state->op_num;
1390 if (t->count.count == 0) {
1392 return NT_STATUS_OK;
1395 c = &t->commands[t->count.count - 1];
1396 c->command |= DCERPC_SEC_VT_COMMAND_END;
1398 if (DEBUGLEVEL >= 10) {
1399 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
1402 ndr = ndr_push_init_ctx(state);
1404 return NT_STATUS_NO_MEMORY;
1407 ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
1408 NDR_SCALARS | NDR_BUFFERS,
1410 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1411 return ndr_map_error2ntstatus(ndr_err);
1413 state->req_trailer = ndr_push_blob(ndr);
1415 align = state->req_data->length & 0x3;
1422 const uint8_t zeros[4] = { 0, };
1424 ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
1426 return NT_STATUS_NO_MEMORY;
1429 /* move the padding to the start */
1430 p = state->req_trailer.data;
1431 memmove(p + pad, p, state->req_trailer.length - pad);
1435 return NT_STATUS_OK;
1438 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1446 size_t data_thistime;
1447 size_t trailer_left;
1448 size_t trailer_thistime = 0;
1450 size_t total_thistime;
1453 union dcerpc_payload u;
1455 data_left = state->req_data->length - state->req_data_sent;
1456 trailer_left = state->req_trailer.length - state->req_trailer_sent;
1457 total_left = data_left + trailer_left;
1458 if ((total_left < data_left) || (total_left < trailer_left)) {
1462 return NT_STATUS_INVALID_PARAMETER_MIX;
1465 status = dcerpc_guess_sizes(state->cli->auth,
1466 DCERPC_REQUEST_LENGTH, total_left,
1467 state->cli->max_xmit_frag,
1469 &frag_len, &auth_len, &pad_len);
1470 if (!NT_STATUS_IS_OK(status)) {
1474 if (state->req_data_sent == 0) {
1475 flags = DCERPC_PFC_FLAG_FIRST;
1478 if (total_thistime == total_left) {
1479 flags |= DCERPC_PFC_FLAG_LAST;
1482 data_thistime = MIN(total_thistime, data_left);
1483 if (data_thistime < total_thistime) {
1484 trailer_thistime = total_thistime - data_thistime;
1487 data_blob_free(&state->rpc_out);
1489 ZERO_STRUCT(u.request);
1491 u.request.alloc_hint = total_left;
1492 u.request.context_id = 0;
1493 u.request.opnum = state->op_num;
1495 status = dcerpc_push_ncacn_packet(state,
1502 if (!NT_STATUS_IS_OK(status)) {
1506 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1507 * compute it right for requests because the auth trailer is missing
1509 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1511 if (data_thistime > 0) {
1512 /* Copy in the data. */
1513 ok = data_blob_append(NULL, &state->rpc_out,
1514 state->req_data->data + state->req_data_sent,
1517 return NT_STATUS_NO_MEMORY;
1519 state->req_data_sent += data_thistime;
1522 if (trailer_thistime > 0) {
1523 /* Copy in the verification trailer. */
1524 ok = data_blob_append(NULL, &state->rpc_out,
1525 state->req_trailer.data + state->req_trailer_sent,
1528 return NT_STATUS_NO_MEMORY;
1530 state->req_trailer_sent += trailer_thistime;
1533 switch (state->cli->auth->auth_level) {
1534 case DCERPC_AUTH_LEVEL_NONE:
1535 case DCERPC_AUTH_LEVEL_CONNECT:
1536 case DCERPC_AUTH_LEVEL_PACKET:
1538 case DCERPC_AUTH_LEVEL_INTEGRITY:
1539 case DCERPC_AUTH_LEVEL_PRIVACY:
1540 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1542 if (!NT_STATUS_IS_OK(status)) {
1547 return NT_STATUS_INVALID_PARAMETER;
1550 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1555 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1557 struct tevent_req *req = tevent_req_callback_data(
1558 subreq, struct tevent_req);
1559 struct rpc_api_pipe_req_state *state = tevent_req_data(
1560 req, struct rpc_api_pipe_req_state);
1564 status = rpc_write_recv(subreq);
1565 TALLOC_FREE(subreq);
1566 if (!NT_STATUS_IS_OK(status)) {
1567 tevent_req_nterror(req, status);
1571 status = prepare_next_frag(state, &is_last_frag);
1572 if (!NT_STATUS_IS_OK(status)) {
1573 tevent_req_nterror(req, status);
1578 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1580 DCERPC_PKT_RESPONSE,
1582 if (tevent_req_nomem(subreq, req)) {
1585 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1587 subreq = rpc_write_send(state, state->ev,
1588 state->cli->transport,
1589 state->rpc_out.data,
1590 state->rpc_out.length);
1591 if (tevent_req_nomem(subreq, req)) {
1594 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1599 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1601 struct tevent_req *req = tevent_req_callback_data(
1602 subreq, struct tevent_req);
1603 struct rpc_api_pipe_req_state *state = tevent_req_data(
1604 req, struct rpc_api_pipe_req_state);
1607 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1608 TALLOC_FREE(subreq);
1609 if (!NT_STATUS_IS_OK(status)) {
1610 tevent_req_nterror(req, status);
1614 if (state->cli->auth == NULL) {
1615 tevent_req_done(req);
1619 if (state->verify_bitmask1) {
1620 state->cli->auth->verified_bitmask1 = true;
1623 if (state->verify_pcontext) {
1624 state->cli->verified_pcontext = true;
1627 tevent_req_done(req);
1630 static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1631 DATA_BLOB *reply_pdu)
1633 struct rpc_api_pipe_req_state *state = tevent_req_data(
1634 req, struct rpc_api_pipe_req_state);
1637 if (tevent_req_is_nterror(req, &status)) {
1639 * We always have to initialize to reply pdu, even if there is
1640 * none. The rpccli_* caller routines expect this.
1642 *reply_pdu = data_blob_null;
1646 /* return data to caller and assign it ownership of memory */
1647 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1648 reply_pdu->length = state->reply_pdu.length;
1649 state->reply_pdu.length = 0;
1651 return NT_STATUS_OK;
1654 /****************************************************************************
1655 Check the rpc bind acknowledge response.
1656 ****************************************************************************/
1658 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1659 const struct ndr_syntax_id *transfer)
1661 struct dcerpc_ack_ctx ctx;
1663 if (r->secondary_address_size == 0) {
1664 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1667 if (r->num_results < 1 || !r->ctx_list) {
1671 ctx = r->ctx_list[0];
1673 /* check the transfer syntax */
1674 if ((ctx.syntax.if_version != transfer->if_version) ||
1675 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1676 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1680 if (r->num_results != 0x1 || ctx.result != 0) {
1681 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1682 r->num_results, ctx.reason.value));
1685 DEBUG(5,("check_bind_response: accepted!\n"));
1689 /*******************************************************************
1690 Creates a DCE/RPC bind authentication response.
1691 This is the packet that is sent back to the server once we
1692 have received a BIND-ACK, to finish the third leg of
1693 the authentication handshake.
1694 ********************************************************************/
1696 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1697 struct rpc_pipe_client *cli,
1698 uint32_t rpc_call_id,
1699 enum dcerpc_AuthType auth_type,
1700 enum dcerpc_AuthLevel auth_level,
1701 DATA_BLOB *pauth_blob,
1705 union dcerpc_payload u;
1709 status = dcerpc_push_dcerpc_auth(mem_ctx,
1712 0, /* auth_pad_length */
1713 1, /* auth_context_id */
1715 &u.auth3.auth_info);
1716 if (!NT_STATUS_IS_OK(status)) {
1720 status = dcerpc_push_ncacn_packet(mem_ctx,
1722 DCERPC_PFC_FLAG_FIRST |
1723 DCERPC_PFC_FLAG_LAST,
1728 data_blob_free(&u.auth3.auth_info);
1729 if (!NT_STATUS_IS_OK(status)) {
1730 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1734 return NT_STATUS_OK;
1737 /*******************************************************************
1738 Creates a DCE/RPC bind alter context authentication request which
1739 may contain a spnego auth blobl
1740 ********************************************************************/
1742 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1743 enum dcerpc_AuthType auth_type,
1744 enum dcerpc_AuthLevel auth_level,
1745 uint32_t rpc_call_id,
1746 const struct ndr_syntax_id *abstract,
1747 const struct ndr_syntax_id *transfer,
1748 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1751 DATA_BLOB auth_info;
1754 status = dcerpc_push_dcerpc_auth(mem_ctx,
1757 0, /* auth_pad_length */
1758 1, /* auth_context_id */
1761 if (!NT_STATUS_IS_OK(status)) {
1765 status = create_bind_or_alt_ctx_internal(mem_ctx,
1771 false, /* client_hdr_signing */
1773 data_blob_free(&auth_info);
1777 /****************************************************************************
1779 ****************************************************************************/
1781 struct rpc_pipe_bind_state {
1782 struct tevent_context *ev;
1783 struct rpc_pipe_client *cli;
1786 uint32_t rpc_call_id;
1789 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1790 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1791 struct rpc_pipe_bind_state *state,
1792 DATA_BLOB *credentials);
1793 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1794 struct rpc_pipe_bind_state *state,
1795 DATA_BLOB *credentials);
1797 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1798 struct tevent_context *ev,
1799 struct rpc_pipe_client *cli,
1800 struct pipe_auth_data *auth)
1802 struct tevent_req *req, *subreq;
1803 struct rpc_pipe_bind_state *state;
1806 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1811 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1812 rpccli_pipe_txt(talloc_tos(), cli),
1813 (unsigned int)auth->auth_type,
1814 (unsigned int)auth->auth_level ));
1818 state->rpc_call_id = get_rpc_call_id();
1820 cli->auth = talloc_move(cli, &auth);
1822 /* Marshall the outgoing data. */
1823 status = create_rpc_bind_req(state, cli,
1826 &cli->abstract_syntax,
1827 &cli->transfer_syntax,
1830 if (!NT_STATUS_IS_OK(status) &&
1831 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1835 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1836 DCERPC_PKT_BIND_ACK, state->rpc_call_id);
1837 if (subreq == NULL) {
1840 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1844 tevent_req_nterror(req, status);
1845 return tevent_req_post(req, ev);
1851 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1853 struct tevent_req *req = tevent_req_callback_data(
1854 subreq, struct tevent_req);
1855 struct rpc_pipe_bind_state *state = tevent_req_data(
1856 req, struct rpc_pipe_bind_state);
1857 struct pipe_auth_data *pauth = state->cli->auth;
1858 struct gensec_security *gensec_security;
1859 struct ncacn_packet *pkt = NULL;
1860 struct dcerpc_auth auth;
1861 DATA_BLOB auth_token = data_blob_null;
1864 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1865 TALLOC_FREE(subreq);
1866 if (!NT_STATUS_IS_OK(status)) {
1867 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1868 rpccli_pipe_txt(talloc_tos(), state->cli),
1869 nt_errstr(status)));
1870 tevent_req_nterror(req, status);
1875 tevent_req_done(req);
1879 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1880 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1881 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1885 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1886 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1888 switch(pauth->auth_type) {
1890 case DCERPC_AUTH_TYPE_NONE:
1891 /* Bind complete. */
1892 tevent_req_done(req);
1896 if (pkt->auth_length == 0) {
1897 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1901 /* get auth credentials */
1902 status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
1903 &pkt->u.bind_ack.auth_info,
1905 if (!NT_STATUS_IS_OK(status)) {
1906 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1907 nt_errstr(status)));
1908 tevent_req_nterror(req, status);
1915 * For authenticated binds we may need to do 3 or 4 leg binds.
1918 switch(pauth->auth_type) {
1920 case DCERPC_AUTH_TYPE_NONE:
1921 /* Bind complete. */
1922 tevent_req_done(req);
1926 gensec_security = pauth->auth_ctx;
1928 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
1929 if (pauth->client_hdr_signing) {
1930 pauth->hdr_signing = true;
1931 gensec_want_feature(gensec_security,
1932 GENSEC_FEATURE_SIGN_PKT_HEADER);
1936 status = gensec_update(gensec_security, state,
1937 auth.credentials, &auth_token);
1938 if (NT_STATUS_EQUAL(status,
1939 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1940 status = rpc_bind_next_send(req, state,
1942 } else if (NT_STATUS_IS_OK(status)) {
1943 if (auth_token.length == 0) {
1944 /* Bind complete. */
1945 tevent_req_done(req);
1948 status = rpc_bind_finish_send(req, state,
1954 if (!NT_STATUS_IS_OK(status)) {
1955 tevent_req_nterror(req, status);
1960 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1961 struct rpc_pipe_bind_state *state,
1962 DATA_BLOB *auth_token)
1964 struct pipe_auth_data *auth = state->cli->auth;
1965 struct tevent_req *subreq;
1968 /* Now prepare the alter context pdu. */
1969 data_blob_free(&state->rpc_out);
1971 status = create_rpc_alter_context(state,
1975 &state->cli->abstract_syntax,
1976 &state->cli->transfer_syntax,
1979 if (!NT_STATUS_IS_OK(status)) {
1983 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1984 &state->rpc_out, DCERPC_PKT_ALTER_RESP,
1985 state->rpc_call_id);
1986 if (subreq == NULL) {
1987 return NT_STATUS_NO_MEMORY;
1989 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1990 return NT_STATUS_OK;
1993 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1994 struct rpc_pipe_bind_state *state,
1995 DATA_BLOB *auth_token)
1997 struct pipe_auth_data *auth = state->cli->auth;
1998 struct tevent_req *subreq;
2001 state->auth3 = true;
2003 /* Now prepare the auth3 context pdu. */
2004 data_blob_free(&state->rpc_out);
2006 status = create_rpc_bind_auth3(state, state->cli,
2012 if (!NT_STATUS_IS_OK(status)) {
2016 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2017 &state->rpc_out, DCERPC_PKT_AUTH3,
2018 state->rpc_call_id);
2019 if (subreq == NULL) {
2020 return NT_STATUS_NO_MEMORY;
2022 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2023 return NT_STATUS_OK;
2026 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2028 return tevent_req_simple_recv_ntstatus(req);
2031 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2032 struct pipe_auth_data *auth)
2034 TALLOC_CTX *frame = talloc_stackframe();
2035 struct tevent_context *ev;
2036 struct tevent_req *req;
2037 NTSTATUS status = NT_STATUS_OK;
2039 ev = samba_tevent_context_init(frame);
2041 status = NT_STATUS_NO_MEMORY;
2045 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2047 status = NT_STATUS_NO_MEMORY;
2051 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2055 status = rpc_pipe_bind_recv(req);
2061 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2063 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2064 unsigned int timeout)
2068 if (rpc_cli->transport == NULL) {
2069 return RPCCLI_DEFAULT_TIMEOUT;
2072 if (rpc_cli->transport->set_timeout == NULL) {
2073 return RPCCLI_DEFAULT_TIMEOUT;
2076 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2078 return RPCCLI_DEFAULT_TIMEOUT;
2084 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2086 if (rpc_cli == NULL) {
2090 if (rpc_cli->transport == NULL) {
2094 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2097 struct rpccli_bh_state {
2098 struct rpc_pipe_client *rpc_cli;
2101 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2103 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2104 struct rpccli_bh_state);
2106 return rpccli_is_connected(hs->rpc_cli);
2109 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2112 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2113 struct rpccli_bh_state);
2115 return rpccli_set_timeout(hs->rpc_cli, timeout);
2118 static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
2119 enum dcerpc_AuthType *auth_type,
2120 enum dcerpc_AuthLevel *auth_level)
2122 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2123 struct rpccli_bh_state);
2125 if (hs->rpc_cli == NULL) {
2129 if (hs->rpc_cli->auth == NULL) {
2133 *auth_type = hs->rpc_cli->auth->auth_type;
2134 *auth_level = hs->rpc_cli->auth->auth_level;
2137 struct rpccli_bh_raw_call_state {
2143 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2145 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2146 struct tevent_context *ev,
2147 struct dcerpc_binding_handle *h,
2148 const struct GUID *object,
2151 const uint8_t *in_data,
2154 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2155 struct rpccli_bh_state);
2156 struct tevent_req *req;
2157 struct rpccli_bh_raw_call_state *state;
2159 struct tevent_req *subreq;
2161 req = tevent_req_create(mem_ctx, &state,
2162 struct rpccli_bh_raw_call_state);
2166 state->in_data.data = discard_const_p(uint8_t, in_data);
2167 state->in_data.length = in_length;
2169 ok = rpccli_bh_is_connected(h);
2171 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2172 return tevent_req_post(req, ev);
2175 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2176 opnum, &state->in_data);
2177 if (tevent_req_nomem(subreq, req)) {
2178 return tevent_req_post(req, ev);
2180 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2185 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2187 struct tevent_req *req =
2188 tevent_req_callback_data(subreq,
2190 struct rpccli_bh_raw_call_state *state =
2191 tevent_req_data(req,
2192 struct rpccli_bh_raw_call_state);
2195 state->out_flags = 0;
2197 /* TODO: support bigendian responses */
2199 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2200 TALLOC_FREE(subreq);
2201 if (!NT_STATUS_IS_OK(status)) {
2202 tevent_req_nterror(req, status);
2206 tevent_req_done(req);
2209 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2210 TALLOC_CTX *mem_ctx,
2213 uint32_t *out_flags)
2215 struct rpccli_bh_raw_call_state *state =
2216 tevent_req_data(req,
2217 struct rpccli_bh_raw_call_state);
2220 if (tevent_req_is_nterror(req, &status)) {
2221 tevent_req_received(req);
2225 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2226 *out_length = state->out_data.length;
2227 *out_flags = state->out_flags;
2228 tevent_req_received(req);
2229 return NT_STATUS_OK;
2232 struct rpccli_bh_disconnect_state {
2236 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2237 struct tevent_context *ev,
2238 struct dcerpc_binding_handle *h)
2240 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2241 struct rpccli_bh_state);
2242 struct tevent_req *req;
2243 struct rpccli_bh_disconnect_state *state;
2246 req = tevent_req_create(mem_ctx, &state,
2247 struct rpccli_bh_disconnect_state);
2252 ok = rpccli_bh_is_connected(h);
2254 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2255 return tevent_req_post(req, ev);
2259 * TODO: do a real async disconnect ...
2261 * For now the caller needs to free rpc_cli
2265 tevent_req_done(req);
2266 return tevent_req_post(req, ev);
2269 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2273 if (tevent_req_is_nterror(req, &status)) {
2274 tevent_req_received(req);
2278 tevent_req_received(req);
2279 return NT_STATUS_OK;
2282 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2287 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2289 const void *_struct_ptr,
2290 const struct ndr_interface_call *call)
2292 void *struct_ptr = discard_const(_struct_ptr);
2294 if (DEBUGLEVEL < 10) {
2298 if (ndr_flags & NDR_IN) {
2299 ndr_print_function_debug(call->ndr_print,
2304 if (ndr_flags & NDR_OUT) {
2305 ndr_print_function_debug(call->ndr_print,
2312 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2314 .is_connected = rpccli_bh_is_connected,
2315 .set_timeout = rpccli_bh_set_timeout,
2316 .auth_info = rpccli_bh_auth_info,
2317 .raw_call_send = rpccli_bh_raw_call_send,
2318 .raw_call_recv = rpccli_bh_raw_call_recv,
2319 .disconnect_send = rpccli_bh_disconnect_send,
2320 .disconnect_recv = rpccli_bh_disconnect_recv,
2322 .ref_alloc = rpccli_bh_ref_alloc,
2323 .do_ndr_print = rpccli_bh_do_ndr_print,
2326 /* initialise a rpc_pipe_client binding handle */
2327 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
2328 const struct GUID *object,
2329 const struct ndr_interface_table *table)
2331 struct dcerpc_binding_handle *h;
2332 struct rpccli_bh_state *hs;
2334 h = dcerpc_binding_handle_create(c,
2339 struct rpccli_bh_state,
2349 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2350 struct pipe_auth_data **presult)
2352 struct pipe_auth_data *result;
2353 struct auth_generic_state *auth_generic_ctx;
2356 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2357 if (result == NULL) {
2358 return NT_STATUS_NO_MEMORY;
2361 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2362 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2364 status = auth_generic_client_prepare(result,
2366 if (!NT_STATUS_IS_OK(status)) {
2367 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2368 nt_errstr(status)));
2371 status = auth_generic_set_username(auth_generic_ctx, "");
2372 if (!NT_STATUS_IS_OK(status)) {
2373 DEBUG(1, ("Failed to set username: %s\n",
2374 nt_errstr(status)));
2377 status = auth_generic_set_domain(auth_generic_ctx, "");
2378 if (!NT_STATUS_IS_OK(status)) {
2379 DEBUG(1, ("Failed to set domain: %s\n",
2380 nt_errstr(status)));
2384 status = gensec_set_credentials(auth_generic_ctx->gensec_security,
2385 auth_generic_ctx->credentials);
2386 if (!NT_STATUS_IS_OK(status)) {
2387 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2388 nt_errstr(status)));
2391 talloc_unlink(auth_generic_ctx, auth_generic_ctx->credentials);
2392 auth_generic_ctx->credentials = NULL;
2394 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2395 talloc_free(auth_generic_ctx);
2397 return NT_STATUS_OK;
2400 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2401 enum dcerpc_AuthType auth_type,
2402 enum dcerpc_AuthLevel auth_level,
2404 const char *target_service,
2406 const char *username,
2407 const char *password,
2408 enum credentials_use_kerberos use_kerberos,
2409 struct netlogon_creds_CredentialState *creds,
2410 struct pipe_auth_data **presult)
2412 struct auth_generic_state *auth_generic_ctx;
2413 struct pipe_auth_data *result;
2416 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2417 if (result == NULL) {
2418 return NT_STATUS_NO_MEMORY;
2421 result->auth_type = auth_type;
2422 result->auth_level = auth_level;
2424 status = auth_generic_client_prepare(result,
2426 if (!NT_STATUS_IS_OK(status)) {
2430 status = auth_generic_set_username(auth_generic_ctx, username);
2431 if (!NT_STATUS_IS_OK(status)) {
2435 status = auth_generic_set_domain(auth_generic_ctx, domain);
2436 if (!NT_STATUS_IS_OK(status)) {
2440 status = auth_generic_set_password(auth_generic_ctx, password);
2441 if (!NT_STATUS_IS_OK(status)) {
2445 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2446 if (!NT_STATUS_IS_OK(status)) {
2450 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2451 if (!NT_STATUS_IS_OK(status)) {
2455 cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
2456 cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2458 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2459 if (!NT_STATUS_IS_OK(status)) {
2463 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2464 talloc_free(auth_generic_ctx);
2466 return NT_STATUS_OK;
2469 TALLOC_FREE(result);
2473 /* This routine steals the creds pointer that is passed in */
2474 static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx,
2475 enum dcerpc_AuthType auth_type,
2476 enum dcerpc_AuthLevel auth_level,
2478 const char *target_service,
2479 struct cli_credentials *creds,
2480 struct pipe_auth_data **presult)
2482 struct auth_generic_state *auth_generic_ctx;
2483 struct pipe_auth_data *result;
2486 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2487 if (result == NULL) {
2488 return NT_STATUS_NO_MEMORY;
2491 result->auth_type = auth_type;
2492 result->auth_level = auth_level;
2494 status = auth_generic_client_prepare(result,
2496 if (!NT_STATUS_IS_OK(status)) {
2500 status = auth_generic_set_creds(auth_generic_ctx, creds);
2501 if (!NT_STATUS_IS_OK(status)) {
2505 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2506 if (!NT_STATUS_IS_OK(status)) {
2510 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2511 if (!NT_STATUS_IS_OK(status)) {
2515 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2516 if (!NT_STATUS_IS_OK(status)) {
2520 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2521 talloc_free(auth_generic_ctx);
2523 return NT_STATUS_OK;
2526 TALLOC_FREE(result);
2530 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2531 struct pipe_auth_data **presult)
2533 return rpccli_generic_bind_data(mem_ctx,
2534 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
2535 DCERPC_AUTH_LEVEL_CONNECT,
2537 "host", /* target_service */
2538 NAME_NT_AUTHORITY, /* domain */
2541 CRED_DONT_USE_KERBEROS,
2542 NULL, /* netlogon_creds_CredentialState */
2547 * Create an rpc pipe client struct, connecting to a tcp port.
2549 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2550 const struct sockaddr_storage *ss_addr,
2552 const struct ndr_interface_table *table,
2553 struct rpc_pipe_client **presult)
2555 struct rpc_pipe_client *result;
2556 struct sockaddr_storage addr;
2560 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2561 if (result == NULL) {
2562 return NT_STATUS_NO_MEMORY;
2565 result->abstract_syntax = table->syntax_id;
2566 result->transfer_syntax = ndr_transfer_syntax_ndr;
2568 result->desthost = talloc_strdup(result, host);
2569 result->srv_name_slash = talloc_asprintf_strupper_m(
2570 result, "\\\\%s", result->desthost);
2571 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2572 status = NT_STATUS_NO_MEMORY;
2576 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2577 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2579 if (ss_addr == NULL) {
2580 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2581 status = NT_STATUS_NOT_FOUND;
2588 status = open_socket_out(&addr, port, 60*1000, &fd);
2589 if (!NT_STATUS_IS_OK(status)) {
2592 set_socket_options(fd, lp_socket_options());
2594 status = rpc_transport_sock_init(result, fd, &result->transport);
2595 if (!NT_STATUS_IS_OK(status)) {
2600 result->transport->transport = NCACN_IP_TCP;
2602 result->binding_handle = rpccli_bh_create(result, NULL, table);
2603 if (result->binding_handle == NULL) {
2604 TALLOC_FREE(result);
2605 return NT_STATUS_NO_MEMORY;
2609 return NT_STATUS_OK;
2612 TALLOC_FREE(result);
2617 * Determine the tcp port on which a dcerpc interface is listening
2618 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2621 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2622 const struct sockaddr_storage *addr,
2623 const struct ndr_interface_table *table,
2627 struct rpc_pipe_client *epm_pipe = NULL;
2628 struct dcerpc_binding_handle *epm_handle = NULL;
2629 struct pipe_auth_data *auth = NULL;
2630 struct dcerpc_binding *map_binding = NULL;
2631 struct dcerpc_binding *res_binding = NULL;
2632 enum dcerpc_transport_t transport;
2633 const char *endpoint = NULL;
2634 struct epm_twr_t *map_tower = NULL;
2635 struct epm_twr_t *res_towers = NULL;
2636 struct policy_handle *entry_handle = NULL;
2637 uint32_t num_towers = 0;
2638 uint32_t max_towers = 1;
2639 struct epm_twr_p_t towers;
2640 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2641 uint32_t result = 0;
2643 if (pport == NULL) {
2644 status = NT_STATUS_INVALID_PARAMETER;
2648 if (ndr_syntax_id_equal(&table->syntax_id,
2649 &ndr_table_epmapper.syntax_id)) {
2651 status = NT_STATUS_OK;
2655 /* open the connection to the endpoint mapper */
2656 status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2657 &ndr_table_epmapper,
2660 if (!NT_STATUS_IS_OK(status)) {
2663 epm_handle = epm_pipe->binding_handle;
2665 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2666 if (!NT_STATUS_IS_OK(status)) {
2670 status = rpc_pipe_bind(epm_pipe, auth);
2671 if (!NT_STATUS_IS_OK(status)) {
2675 /* create tower for asking the epmapper */
2677 status = dcerpc_parse_binding(tmp_ctx, "ncacn_ip_tcp:[135]",
2679 if (!NT_STATUS_IS_OK(status)) {
2683 status = dcerpc_binding_set_abstract_syntax(map_binding,
2685 if (!NT_STATUS_IS_OK(status)) {
2689 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2690 if (map_tower == NULL) {
2691 status = NT_STATUS_NO_MEMORY;
2695 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2696 &(map_tower->tower));
2697 if (!NT_STATUS_IS_OK(status)) {
2701 /* allocate further parameters for the epm_Map call */
2703 res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2704 if (res_towers == NULL) {
2705 status = NT_STATUS_NO_MEMORY;
2708 towers.twr = res_towers;
2710 entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2711 if (entry_handle == NULL) {
2712 status = NT_STATUS_NO_MEMORY;
2716 /* ask the endpoint mapper for the port */
2718 status = dcerpc_epm_Map(epm_handle,
2720 discard_const_p(struct GUID,
2721 &(table->syntax_id.uuid)),
2729 if (!NT_STATUS_IS_OK(status)) {
2733 if (result != EPMAPPER_STATUS_OK) {
2734 status = NT_STATUS_UNSUCCESSFUL;
2738 if (num_towers != 1) {
2739 status = NT_STATUS_UNSUCCESSFUL;
2743 /* extract the port from the answer */
2745 status = dcerpc_binding_from_tower(tmp_ctx,
2746 &(towers.twr->tower),
2748 if (!NT_STATUS_IS_OK(status)) {
2752 transport = dcerpc_binding_get_transport(res_binding);
2753 endpoint = dcerpc_binding_get_string_option(res_binding, "endpoint");
2755 /* are further checks here necessary? */
2756 if (transport != NCACN_IP_TCP) {
2757 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2761 if (endpoint == NULL) {
2762 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2766 *pport = (uint16_t)atoi(endpoint);
2769 TALLOC_FREE(tmp_ctx);
2774 * Create a rpc pipe client struct, connecting to a host via tcp.
2775 * The port is determined by asking the endpoint mapper on the given
2778 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2779 const struct sockaddr_storage *addr,
2780 const struct ndr_interface_table *table,
2781 struct rpc_pipe_client **presult)
2786 status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2787 if (!NT_STATUS_IS_OK(status)) {
2791 return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2795 /********************************************************************
2796 Create a rpc pipe client struct, connecting to a unix domain socket
2797 ********************************************************************/
2798 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2799 const struct ndr_interface_table *table,
2800 struct rpc_pipe_client **presult)
2802 struct rpc_pipe_client *result;
2803 struct sockaddr_un addr;
2808 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2809 if (result == NULL) {
2810 return NT_STATUS_NO_MEMORY;
2813 result->abstract_syntax = table->syntax_id;
2814 result->transfer_syntax = ndr_transfer_syntax_ndr;
2816 result->desthost = get_myname(result);
2817 result->srv_name_slash = talloc_asprintf_strupper_m(
2818 result, "\\\\%s", result->desthost);
2819 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2820 status = NT_STATUS_NO_MEMORY;
2824 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2825 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2827 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2829 status = map_nt_error_from_unix(errno);
2834 addr.sun_family = AF_UNIX;
2835 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2836 salen = sizeof(struct sockaddr_un);
2838 if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
2839 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2842 return map_nt_error_from_unix(errno);
2845 status = rpc_transport_sock_init(result, fd, &result->transport);
2846 if (!NT_STATUS_IS_OK(status)) {
2851 result->transport->transport = NCALRPC;
2853 result->binding_handle = rpccli_bh_create(result, NULL, table);
2854 if (result->binding_handle == NULL) {
2855 TALLOC_FREE(result);
2856 return NT_STATUS_NO_MEMORY;
2860 return NT_STATUS_OK;
2863 TALLOC_FREE(result);
2867 struct rpc_pipe_client_np_ref {
2868 struct cli_state *cli;
2869 struct rpc_pipe_client *pipe;
2872 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2874 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2878 /****************************************************************************
2879 Open a named pipe over SMB to a remote server.
2881 * CAVEAT CALLER OF THIS FUNCTION:
2882 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2883 * so be sure that this function is called AFTER any structure (vs pointer)
2884 * assignment of the cli. In particular, libsmbclient does structure
2885 * assignments of cli, which invalidates the data in the returned
2886 * rpc_pipe_client if this function is called before the structure assignment
2889 ****************************************************************************/
2891 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2892 const struct ndr_interface_table *table,
2893 struct rpc_pipe_client **presult)
2895 struct rpc_pipe_client *result;
2897 struct rpc_pipe_client_np_ref *np_ref;
2899 /* sanity check to protect against crashes */
2902 return NT_STATUS_INVALID_HANDLE;
2905 result = talloc_zero(NULL, struct rpc_pipe_client);
2906 if (result == NULL) {
2907 return NT_STATUS_NO_MEMORY;
2910 result->abstract_syntax = table->syntax_id;
2911 result->transfer_syntax = ndr_transfer_syntax_ndr;
2912 result->desthost = talloc_strdup(result, smbXcli_conn_remote_name(cli->conn));
2913 result->srv_name_slash = talloc_asprintf_strupper_m(
2914 result, "\\\\%s", result->desthost);
2916 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2917 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2919 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2920 TALLOC_FREE(result);
2921 return NT_STATUS_NO_MEMORY;
2924 status = rpc_transport_np_init(result, cli, table,
2925 &result->transport);
2926 if (!NT_STATUS_IS_OK(status)) {
2927 TALLOC_FREE(result);
2931 result->transport->transport = NCACN_NP;
2933 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2934 if (np_ref == NULL) {
2935 TALLOC_FREE(result);
2936 return NT_STATUS_NO_MEMORY;
2939 np_ref->pipe = result;
2941 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2942 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2944 result->binding_handle = rpccli_bh_create(result, NULL, table);
2945 if (result->binding_handle == NULL) {
2946 TALLOC_FREE(result);
2947 return NT_STATUS_NO_MEMORY;
2951 return NT_STATUS_OK;
2954 /****************************************************************************
2955 Open a pipe to a remote server.
2956 ****************************************************************************/
2958 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2959 enum dcerpc_transport_t transport,
2960 const struct ndr_interface_table *table,
2961 struct rpc_pipe_client **presult)
2963 switch (transport) {
2965 return rpc_pipe_open_tcp(NULL,
2966 smbXcli_conn_remote_name(cli->conn),
2967 smbXcli_conn_remote_sockaddr(cli->conn),
2970 return rpc_pipe_open_np(cli, table, presult);
2972 return NT_STATUS_NOT_IMPLEMENTED;
2976 /****************************************************************************
2977 Open a named pipe to an SMB server and bind anonymously.
2978 ****************************************************************************/
2980 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2981 enum dcerpc_transport_t transport,
2982 const struct ndr_interface_table *table,
2983 struct rpc_pipe_client **presult)
2985 struct rpc_pipe_client *result;
2986 struct pipe_auth_data *auth;
2989 status = cli_rpc_pipe_open(cli, transport, table, &result);
2990 if (!NT_STATUS_IS_OK(status)) {
2994 status = rpccli_anon_bind_data(result, &auth);
2995 if (!NT_STATUS_IS_OK(status)) {
2996 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2997 nt_errstr(status)));
2998 TALLOC_FREE(result);
3003 * This is a bit of an abstraction violation due to the fact that an
3004 * anonymous bind on an authenticated SMB inherits the user/domain
3005 * from the enclosing SMB creds
3008 if (transport == NCACN_NP) {
3009 struct smbXcli_session *session;
3011 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
3012 session = cli->smb2.session;
3014 session = cli->smb1.session;
3017 status = smbXcli_session_application_key(session, auth,
3018 &auth->transport_session_key);
3019 if (!NT_STATUS_IS_OK(status)) {
3020 auth->transport_session_key = data_blob_null;
3024 status = rpc_pipe_bind(result, auth);
3025 if (!NT_STATUS_IS_OK(status)) {
3027 if (ndr_syntax_id_equal(&table->syntax_id,
3028 &ndr_table_dssetup.syntax_id)) {
3029 /* non AD domains just don't have this pipe, avoid
3030 * level 0 statement in that case - gd */
3033 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3034 "%s failed with error %s\n",
3036 nt_errstr(status) ));
3037 TALLOC_FREE(result);
3041 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3042 "%s and bound anonymously.\n",
3047 return NT_STATUS_OK;
3050 /****************************************************************************
3051 ****************************************************************************/
3053 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3054 const struct ndr_interface_table *table,
3055 struct rpc_pipe_client **presult)
3057 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3061 /****************************************************************************
3062 Open a named pipe to an SMB server and bind using the mech specified
3064 This routine references the creds pointer that is passed in
3065 ****************************************************************************/
3067 NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
3068 const struct ndr_interface_table *table,
3069 enum dcerpc_transport_t transport,
3070 enum dcerpc_AuthType auth_type,
3071 enum dcerpc_AuthLevel auth_level,
3073 struct cli_credentials *creds,
3074 struct rpc_pipe_client **presult)
3076 struct rpc_pipe_client *result;
3077 struct pipe_auth_data *auth = NULL;
3078 const char *target_service = table->authservices->names[0];
3082 status = cli_rpc_pipe_open(cli, transport, table, &result);
3083 if (!NT_STATUS_IS_OK(status)) {
3087 status = rpccli_generic_bind_data_from_creds(result,
3088 auth_type, auth_level,
3089 server, target_service,
3092 if (!NT_STATUS_IS_OK(status)) {
3093 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3094 nt_errstr(status)));
3098 status = rpc_pipe_bind(result, auth);
3099 if (!NT_STATUS_IS_OK(status)) {
3100 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3101 nt_errstr(status) ));
3105 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3106 "machine %s and bound as user %s.\n", table->name,
3107 result->desthost, cli_credentials_get_unparsed_name(creds, talloc_tos())));
3110 return NT_STATUS_OK;
3114 TALLOC_FREE(result);
3118 /****************************************************************************
3119 Open a named pipe to an SMB server and bind using the mech specified
3121 This routine steals the creds pointer that is passed in
3122 ****************************************************************************/
3124 NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
3125 const struct ndr_interface_table *table,
3126 enum dcerpc_transport_t transport,
3127 enum credentials_use_kerberos use_kerberos,
3128 enum dcerpc_AuthType auth_type,
3129 enum dcerpc_AuthLevel auth_level,
3132 const char *username,
3133 const char *password,
3134 struct rpc_pipe_client **presult)
3136 struct rpc_pipe_client *result;
3137 struct pipe_auth_data *auth = NULL;
3138 const char *target_service = table->authservices->names[0];
3142 status = cli_rpc_pipe_open(cli, transport, table, &result);
3143 if (!NT_STATUS_IS_OK(status)) {
3147 status = rpccli_generic_bind_data(result,
3148 auth_type, auth_level,
3149 server, target_service,
3150 domain, username, password,
3151 CRED_AUTO_USE_KERBEROS,
3154 if (!NT_STATUS_IS_OK(status)) {
3155 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3156 nt_errstr(status)));
3160 status = rpc_pipe_bind(result, auth);
3161 if (!NT_STATUS_IS_OK(status)) {
3162 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3163 nt_errstr(status) ));
3167 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3168 "machine %s and bound as user %s\\%s.\n", table->name,
3169 result->desthost, domain, username));
3172 return NT_STATUS_OK;
3176 TALLOC_FREE(result);
3180 NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
3181 const struct ndr_interface_table *table,
3182 enum dcerpc_transport_t transport,
3183 struct cli_credentials *cli_creds,
3184 struct netlogon_creds_cli_context *netlogon_creds,
3185 struct rpc_pipe_client **_rpccli)
3187 struct rpc_pipe_client *rpccli;
3188 struct pipe_auth_data *rpcauth;
3189 const char *target_service = table->authservices->names[0];
3190 struct netlogon_creds_CredentialState *ncreds = NULL;
3191 enum dcerpc_AuthLevel auth_level;
3193 int rpc_pipe_bind_dbglvl = 0;
3195 status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
3196 if (!NT_STATUS_IS_OK(status)) {
3200 status = netlogon_creds_cli_lock(netlogon_creds, rpccli, &ncreds);
3201 if (!NT_STATUS_IS_OK(status)) {
3202 DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
3203 nt_errstr(status)));
3204 TALLOC_FREE(rpccli);
3208 auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
3210 cli_credentials_set_netlogon_creds(cli_creds, ncreds);
3212 status = rpccli_generic_bind_data_from_creds(rpccli,
3213 DCERPC_AUTH_TYPE_SCHANNEL,
3219 if (!NT_STATUS_IS_OK(status)) {
3220 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
3221 nt_errstr(status)));
3222 TALLOC_FREE(rpccli);
3226 status = rpc_pipe_bind(rpccli, rpcauth);
3227 cli_credentials_set_netlogon_creds(cli_creds, NULL);
3228 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3229 rpc_pipe_bind_dbglvl = 1;
3230 netlogon_creds_cli_delete(netlogon_creds, &ncreds);
3232 if (!NT_STATUS_IS_OK(status)) {
3233 DEBUG(rpc_pipe_bind_dbglvl,
3234 ("%s: rpc_pipe_bind failed with error %s\n",
3235 __func__, nt_errstr(status)));
3236 TALLOC_FREE(rpccli);
3240 TALLOC_FREE(ncreds);
3242 if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
3246 status = netlogon_creds_cli_check(netlogon_creds,
3247 rpccli->binding_handle);
3248 if (!NT_STATUS_IS_OK(status)) {
3249 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3250 nt_errstr(status)));
3251 TALLOC_FREE(rpccli);
3257 DEBUG(10,("%s: opened pipe %s to machine %s "
3258 "for domain %s and bound using schannel.\n",
3259 __func__, table->name,
3260 rpccli->desthost, cli_credentials_get_domain(cli_creds)));
3263 return NT_STATUS_OK;
3266 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3267 struct rpc_pipe_client *cli,
3268 DATA_BLOB *session_key)
3271 struct pipe_auth_data *a;
3272 struct gensec_security *gensec_security;
3273 DATA_BLOB sk = data_blob_null;
3274 bool make_dup = false;
3276 if (!session_key || !cli) {
3277 return NT_STATUS_INVALID_PARAMETER;
3283 return NT_STATUS_INVALID_PARAMETER;
3286 switch (cli->auth->auth_type) {
3287 case DCERPC_AUTH_TYPE_NONE:
3288 sk = data_blob_const(a->transport_session_key.data,
3289 a->transport_session_key.length);
3293 gensec_security = a->auth_ctx;
3294 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3295 if (!NT_STATUS_IS_OK(status)) {
3303 return NT_STATUS_NO_USER_SESSION_KEY;
3307 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3312 return NT_STATUS_OK;