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 auth->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 struct pipe_auth_data *auth,
1699 uint32_t rpc_call_id,
1700 DATA_BLOB *pauth_blob,
1704 union dcerpc_payload u;
1708 status = dcerpc_push_dcerpc_auth(mem_ctx,
1711 0, /* auth_pad_length */
1712 auth->auth_context_id,
1714 &u.auth3.auth_info);
1715 if (!NT_STATUS_IS_OK(status)) {
1719 status = dcerpc_push_ncacn_packet(mem_ctx,
1721 DCERPC_PFC_FLAG_FIRST |
1722 DCERPC_PFC_FLAG_LAST,
1727 data_blob_free(&u.auth3.auth_info);
1728 if (!NT_STATUS_IS_OK(status)) {
1729 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1733 return NT_STATUS_OK;
1736 /*******************************************************************
1737 Creates a DCE/RPC bind alter context authentication request which
1738 may contain a spnego auth blobl
1739 ********************************************************************/
1741 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1742 struct pipe_auth_data *auth,
1743 uint32_t rpc_call_id,
1744 const struct ndr_syntax_id *abstract,
1745 const struct ndr_syntax_id *transfer,
1746 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1749 DATA_BLOB auth_info;
1752 status = dcerpc_push_dcerpc_auth(mem_ctx,
1755 0, /* auth_pad_length */
1756 auth->auth_context_id,
1759 if (!NT_STATUS_IS_OK(status)) {
1763 status = create_bind_or_alt_ctx_internal(mem_ctx,
1769 false, /* client_hdr_signing */
1771 data_blob_free(&auth_info);
1775 /****************************************************************************
1777 ****************************************************************************/
1779 struct rpc_pipe_bind_state {
1780 struct tevent_context *ev;
1781 struct rpc_pipe_client *cli;
1784 uint32_t rpc_call_id;
1787 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1788 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1789 struct rpc_pipe_bind_state *state,
1790 DATA_BLOB *credentials);
1791 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1792 struct rpc_pipe_bind_state *state,
1793 DATA_BLOB *credentials);
1795 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1796 struct tevent_context *ev,
1797 struct rpc_pipe_client *cli,
1798 struct pipe_auth_data *auth)
1800 struct tevent_req *req, *subreq;
1801 struct rpc_pipe_bind_state *state;
1804 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1809 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1810 rpccli_pipe_txt(talloc_tos(), cli),
1811 (unsigned int)auth->auth_type,
1812 (unsigned int)auth->auth_level ));
1816 state->rpc_call_id = get_rpc_call_id();
1818 cli->auth = talloc_move(cli, &auth);
1820 /* Marshall the outgoing data. */
1821 status = create_rpc_bind_req(state, cli,
1824 &cli->abstract_syntax,
1825 &cli->transfer_syntax,
1828 if (!NT_STATUS_IS_OK(status) &&
1829 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1833 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1834 DCERPC_PKT_BIND_ACK, state->rpc_call_id);
1835 if (subreq == NULL) {
1838 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1842 tevent_req_nterror(req, status);
1843 return tevent_req_post(req, ev);
1849 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1851 struct tevent_req *req = tevent_req_callback_data(
1852 subreq, struct tevent_req);
1853 struct rpc_pipe_bind_state *state = tevent_req_data(
1854 req, struct rpc_pipe_bind_state);
1855 struct pipe_auth_data *pauth = state->cli->auth;
1856 struct gensec_security *gensec_security;
1857 struct ncacn_packet *pkt = NULL;
1858 struct dcerpc_auth auth;
1859 DATA_BLOB auth_token = data_blob_null;
1862 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1863 TALLOC_FREE(subreq);
1864 if (!NT_STATUS_IS_OK(status)) {
1865 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1866 rpccli_pipe_txt(talloc_tos(), state->cli),
1867 nt_errstr(status)));
1868 tevent_req_nterror(req, status);
1873 tevent_req_done(req);
1877 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1878 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1879 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1883 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1884 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1886 switch(pauth->auth_type) {
1888 case DCERPC_AUTH_TYPE_NONE:
1889 /* Bind complete. */
1890 tevent_req_done(req);
1894 if (pkt->auth_length == 0) {
1895 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1899 /* get auth credentials */
1900 status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
1901 &pkt->u.bind_ack.auth_info,
1903 if (!NT_STATUS_IS_OK(status)) {
1904 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1905 nt_errstr(status)));
1906 tevent_req_nterror(req, status);
1910 if (auth.auth_type != pauth->auth_type) {
1911 DEBUG(0, (__location__ " Auth type %u mismatch expected %u.\n",
1912 auth.auth_type, pauth->auth_type));
1913 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1917 if (auth.auth_level != pauth->auth_level) {
1918 DEBUG(0, (__location__ " Auth level %u mismatch expected %u.\n",
1919 auth.auth_level, pauth->auth_level));
1920 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1928 * For authenticated binds we may need to do 3 or 4 leg binds.
1931 switch(pauth->auth_type) {
1933 case DCERPC_AUTH_TYPE_NONE:
1934 /* Bind complete. */
1935 tevent_req_done(req);
1939 gensec_security = pauth->auth_ctx;
1941 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
1942 if (pauth->client_hdr_signing) {
1943 pauth->hdr_signing = true;
1944 gensec_want_feature(gensec_security,
1945 GENSEC_FEATURE_SIGN_PKT_HEADER);
1949 status = gensec_update(gensec_security, state,
1950 auth.credentials, &auth_token);
1951 if (NT_STATUS_EQUAL(status,
1952 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1953 status = rpc_bind_next_send(req, state,
1955 } else if (NT_STATUS_IS_OK(status)) {
1956 if (auth_token.length == 0) {
1957 /* Bind complete. */
1958 tevent_req_done(req);
1961 status = rpc_bind_finish_send(req, state,
1967 if (!NT_STATUS_IS_OK(status)) {
1968 tevent_req_nterror(req, status);
1973 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1974 struct rpc_pipe_bind_state *state,
1975 DATA_BLOB *auth_token)
1977 struct pipe_auth_data *auth = state->cli->auth;
1978 struct tevent_req *subreq;
1981 /* Now prepare the alter context pdu. */
1982 data_blob_free(&state->rpc_out);
1984 status = create_rpc_alter_context(state, auth,
1986 &state->cli->abstract_syntax,
1987 &state->cli->transfer_syntax,
1990 if (!NT_STATUS_IS_OK(status)) {
1994 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1995 &state->rpc_out, DCERPC_PKT_ALTER_RESP,
1996 state->rpc_call_id);
1997 if (subreq == NULL) {
1998 return NT_STATUS_NO_MEMORY;
2000 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2001 return NT_STATUS_OK;
2004 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2005 struct rpc_pipe_bind_state *state,
2006 DATA_BLOB *auth_token)
2008 struct pipe_auth_data *auth = state->cli->auth;
2009 struct tevent_req *subreq;
2012 state->auth3 = true;
2014 /* Now prepare the auth3 context pdu. */
2015 data_blob_free(&state->rpc_out);
2017 status = create_rpc_bind_auth3(state, state->cli, auth,
2021 if (!NT_STATUS_IS_OK(status)) {
2025 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2026 &state->rpc_out, DCERPC_PKT_AUTH3,
2027 state->rpc_call_id);
2028 if (subreq == NULL) {
2029 return NT_STATUS_NO_MEMORY;
2031 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2032 return NT_STATUS_OK;
2035 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2037 return tevent_req_simple_recv_ntstatus(req);
2040 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2041 struct pipe_auth_data *auth)
2043 TALLOC_CTX *frame = talloc_stackframe();
2044 struct tevent_context *ev;
2045 struct tevent_req *req;
2046 NTSTATUS status = NT_STATUS_OK;
2048 ev = samba_tevent_context_init(frame);
2050 status = NT_STATUS_NO_MEMORY;
2054 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2056 status = NT_STATUS_NO_MEMORY;
2060 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2064 status = rpc_pipe_bind_recv(req);
2070 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2072 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2073 unsigned int timeout)
2077 if (rpc_cli->transport == NULL) {
2078 return RPCCLI_DEFAULT_TIMEOUT;
2081 if (rpc_cli->transport->set_timeout == NULL) {
2082 return RPCCLI_DEFAULT_TIMEOUT;
2085 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2087 return RPCCLI_DEFAULT_TIMEOUT;
2093 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2095 if (rpc_cli == NULL) {
2099 if (rpc_cli->transport == NULL) {
2103 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2106 struct rpccli_bh_state {
2107 struct rpc_pipe_client *rpc_cli;
2110 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2112 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2113 struct rpccli_bh_state);
2115 return rpccli_is_connected(hs->rpc_cli);
2118 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2121 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2122 struct rpccli_bh_state);
2124 return rpccli_set_timeout(hs->rpc_cli, timeout);
2127 static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
2128 enum dcerpc_AuthType *auth_type,
2129 enum dcerpc_AuthLevel *auth_level)
2131 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2132 struct rpccli_bh_state);
2134 if (hs->rpc_cli == NULL) {
2138 if (hs->rpc_cli->auth == NULL) {
2142 *auth_type = hs->rpc_cli->auth->auth_type;
2143 *auth_level = hs->rpc_cli->auth->auth_level;
2146 struct rpccli_bh_raw_call_state {
2152 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2154 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2155 struct tevent_context *ev,
2156 struct dcerpc_binding_handle *h,
2157 const struct GUID *object,
2160 const uint8_t *in_data,
2163 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2164 struct rpccli_bh_state);
2165 struct tevent_req *req;
2166 struct rpccli_bh_raw_call_state *state;
2168 struct tevent_req *subreq;
2170 req = tevent_req_create(mem_ctx, &state,
2171 struct rpccli_bh_raw_call_state);
2175 state->in_data.data = discard_const_p(uint8_t, in_data);
2176 state->in_data.length = in_length;
2178 ok = rpccli_bh_is_connected(h);
2180 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2181 return tevent_req_post(req, ev);
2184 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2185 opnum, &state->in_data);
2186 if (tevent_req_nomem(subreq, req)) {
2187 return tevent_req_post(req, ev);
2189 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2194 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2196 struct tevent_req *req =
2197 tevent_req_callback_data(subreq,
2199 struct rpccli_bh_raw_call_state *state =
2200 tevent_req_data(req,
2201 struct rpccli_bh_raw_call_state);
2204 state->out_flags = 0;
2206 /* TODO: support bigendian responses */
2208 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2209 TALLOC_FREE(subreq);
2210 if (!NT_STATUS_IS_OK(status)) {
2211 tevent_req_nterror(req, status);
2215 tevent_req_done(req);
2218 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2219 TALLOC_CTX *mem_ctx,
2222 uint32_t *out_flags)
2224 struct rpccli_bh_raw_call_state *state =
2225 tevent_req_data(req,
2226 struct rpccli_bh_raw_call_state);
2229 if (tevent_req_is_nterror(req, &status)) {
2230 tevent_req_received(req);
2234 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2235 *out_length = state->out_data.length;
2236 *out_flags = state->out_flags;
2237 tevent_req_received(req);
2238 return NT_STATUS_OK;
2241 struct rpccli_bh_disconnect_state {
2245 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2246 struct tevent_context *ev,
2247 struct dcerpc_binding_handle *h)
2249 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2250 struct rpccli_bh_state);
2251 struct tevent_req *req;
2252 struct rpccli_bh_disconnect_state *state;
2255 req = tevent_req_create(mem_ctx, &state,
2256 struct rpccli_bh_disconnect_state);
2261 ok = rpccli_bh_is_connected(h);
2263 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2264 return tevent_req_post(req, ev);
2268 * TODO: do a real async disconnect ...
2270 * For now the caller needs to free rpc_cli
2274 tevent_req_done(req);
2275 return tevent_req_post(req, ev);
2278 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2282 if (tevent_req_is_nterror(req, &status)) {
2283 tevent_req_received(req);
2287 tevent_req_received(req);
2288 return NT_STATUS_OK;
2291 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2296 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2298 const void *_struct_ptr,
2299 const struct ndr_interface_call *call)
2301 void *struct_ptr = discard_const(_struct_ptr);
2303 if (DEBUGLEVEL < 10) {
2307 if (ndr_flags & NDR_IN) {
2308 ndr_print_function_debug(call->ndr_print,
2313 if (ndr_flags & NDR_OUT) {
2314 ndr_print_function_debug(call->ndr_print,
2321 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2323 .is_connected = rpccli_bh_is_connected,
2324 .set_timeout = rpccli_bh_set_timeout,
2325 .auth_info = rpccli_bh_auth_info,
2326 .raw_call_send = rpccli_bh_raw_call_send,
2327 .raw_call_recv = rpccli_bh_raw_call_recv,
2328 .disconnect_send = rpccli_bh_disconnect_send,
2329 .disconnect_recv = rpccli_bh_disconnect_recv,
2331 .ref_alloc = rpccli_bh_ref_alloc,
2332 .do_ndr_print = rpccli_bh_do_ndr_print,
2335 /* initialise a rpc_pipe_client binding handle */
2336 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
2337 const struct GUID *object,
2338 const struct ndr_interface_table *table)
2340 struct dcerpc_binding_handle *h;
2341 struct rpccli_bh_state *hs;
2343 h = dcerpc_binding_handle_create(c,
2348 struct rpccli_bh_state,
2358 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2359 struct pipe_auth_data **presult)
2361 struct pipe_auth_data *result;
2362 struct auth_generic_state *auth_generic_ctx;
2365 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2366 if (result == NULL) {
2367 return NT_STATUS_NO_MEMORY;
2370 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2371 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2372 result->auth_context_id = 0;
2374 status = auth_generic_client_prepare(result,
2376 if (!NT_STATUS_IS_OK(status)) {
2377 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2378 nt_errstr(status)));
2381 status = auth_generic_set_username(auth_generic_ctx, "");
2382 if (!NT_STATUS_IS_OK(status)) {
2383 DEBUG(1, ("Failed to set username: %s\n",
2384 nt_errstr(status)));
2387 status = auth_generic_set_domain(auth_generic_ctx, "");
2388 if (!NT_STATUS_IS_OK(status)) {
2389 DEBUG(1, ("Failed to set domain: %s\n",
2390 nt_errstr(status)));
2394 status = gensec_set_credentials(auth_generic_ctx->gensec_security,
2395 auth_generic_ctx->credentials);
2396 if (!NT_STATUS_IS_OK(status)) {
2397 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2398 nt_errstr(status)));
2401 talloc_unlink(auth_generic_ctx, auth_generic_ctx->credentials);
2402 auth_generic_ctx->credentials = NULL;
2404 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2405 talloc_free(auth_generic_ctx);
2407 return NT_STATUS_OK;
2410 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2411 enum dcerpc_AuthType auth_type,
2412 enum dcerpc_AuthLevel auth_level,
2414 const char *target_service,
2416 const char *username,
2417 const char *password,
2418 enum credentials_use_kerberos use_kerberos,
2419 struct netlogon_creds_CredentialState *creds,
2420 struct pipe_auth_data **presult)
2422 struct auth_generic_state *auth_generic_ctx;
2423 struct pipe_auth_data *result;
2426 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2427 if (result == NULL) {
2428 return NT_STATUS_NO_MEMORY;
2431 result->auth_type = auth_type;
2432 result->auth_level = auth_level;
2433 result->auth_context_id = 1;
2435 status = auth_generic_client_prepare(result,
2437 if (!NT_STATUS_IS_OK(status)) {
2441 status = auth_generic_set_username(auth_generic_ctx, username);
2442 if (!NT_STATUS_IS_OK(status)) {
2446 status = auth_generic_set_domain(auth_generic_ctx, domain);
2447 if (!NT_STATUS_IS_OK(status)) {
2451 status = auth_generic_set_password(auth_generic_ctx, password);
2452 if (!NT_STATUS_IS_OK(status)) {
2456 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2457 if (!NT_STATUS_IS_OK(status)) {
2461 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2462 if (!NT_STATUS_IS_OK(status)) {
2466 cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
2467 cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2469 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2470 if (!NT_STATUS_IS_OK(status)) {
2474 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2475 talloc_free(auth_generic_ctx);
2477 return NT_STATUS_OK;
2480 TALLOC_FREE(result);
2484 /* This routine steals the creds pointer that is passed in */
2485 static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx,
2486 enum dcerpc_AuthType auth_type,
2487 enum dcerpc_AuthLevel auth_level,
2489 const char *target_service,
2490 struct cli_credentials *creds,
2491 struct pipe_auth_data **presult)
2493 struct auth_generic_state *auth_generic_ctx;
2494 struct pipe_auth_data *result;
2497 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2498 if (result == NULL) {
2499 return NT_STATUS_NO_MEMORY;
2502 result->auth_type = auth_type;
2503 result->auth_level = auth_level;
2504 result->auth_context_id = 1;
2506 status = auth_generic_client_prepare(result,
2508 if (!NT_STATUS_IS_OK(status)) {
2512 status = auth_generic_set_creds(auth_generic_ctx, creds);
2513 if (!NT_STATUS_IS_OK(status)) {
2517 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2518 if (!NT_STATUS_IS_OK(status)) {
2522 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2523 if (!NT_STATUS_IS_OK(status)) {
2527 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2528 if (!NT_STATUS_IS_OK(status)) {
2532 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2533 talloc_free(auth_generic_ctx);
2535 return NT_STATUS_OK;
2538 TALLOC_FREE(result);
2542 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2543 struct pipe_auth_data **presult)
2545 return rpccli_generic_bind_data(mem_ctx,
2546 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
2547 DCERPC_AUTH_LEVEL_CONNECT,
2549 "host", /* target_service */
2550 NAME_NT_AUTHORITY, /* domain */
2553 CRED_DONT_USE_KERBEROS,
2554 NULL, /* netlogon_creds_CredentialState */
2559 * Create an rpc pipe client struct, connecting to a tcp port.
2561 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2562 const struct sockaddr_storage *ss_addr,
2564 const struct ndr_interface_table *table,
2565 struct rpc_pipe_client **presult)
2567 struct rpc_pipe_client *result;
2568 struct sockaddr_storage addr;
2572 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2573 if (result == NULL) {
2574 return NT_STATUS_NO_MEMORY;
2577 result->abstract_syntax = table->syntax_id;
2578 result->transfer_syntax = ndr_transfer_syntax_ndr;
2580 result->desthost = talloc_strdup(result, host);
2581 result->srv_name_slash = talloc_asprintf_strupper_m(
2582 result, "\\\\%s", result->desthost);
2583 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2584 status = NT_STATUS_NO_MEMORY;
2588 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2589 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2591 if (ss_addr == NULL) {
2592 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2593 status = NT_STATUS_NOT_FOUND;
2600 status = open_socket_out(&addr, port, 60*1000, &fd);
2601 if (!NT_STATUS_IS_OK(status)) {
2604 set_socket_options(fd, lp_socket_options());
2606 status = rpc_transport_sock_init(result, fd, &result->transport);
2607 if (!NT_STATUS_IS_OK(status)) {
2612 result->transport->transport = NCACN_IP_TCP;
2614 result->binding_handle = rpccli_bh_create(result, NULL, table);
2615 if (result->binding_handle == NULL) {
2616 TALLOC_FREE(result);
2617 return NT_STATUS_NO_MEMORY;
2621 return NT_STATUS_OK;
2624 TALLOC_FREE(result);
2629 * Determine the tcp port on which a dcerpc interface is listening
2630 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2633 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2634 const struct sockaddr_storage *addr,
2635 const struct ndr_interface_table *table,
2639 struct rpc_pipe_client *epm_pipe = NULL;
2640 struct dcerpc_binding_handle *epm_handle = NULL;
2641 struct pipe_auth_data *auth = NULL;
2642 struct dcerpc_binding *map_binding = NULL;
2643 struct dcerpc_binding *res_binding = NULL;
2644 enum dcerpc_transport_t transport;
2645 const char *endpoint = NULL;
2646 struct epm_twr_t *map_tower = NULL;
2647 struct epm_twr_t *res_towers = NULL;
2648 struct policy_handle *entry_handle = NULL;
2649 uint32_t num_towers = 0;
2650 uint32_t max_towers = 1;
2651 struct epm_twr_p_t towers;
2652 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2653 uint32_t result = 0;
2655 if (pport == NULL) {
2656 status = NT_STATUS_INVALID_PARAMETER;
2660 if (ndr_syntax_id_equal(&table->syntax_id,
2661 &ndr_table_epmapper.syntax_id)) {
2663 status = NT_STATUS_OK;
2667 /* open the connection to the endpoint mapper */
2668 status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2669 &ndr_table_epmapper,
2672 if (!NT_STATUS_IS_OK(status)) {
2675 epm_handle = epm_pipe->binding_handle;
2677 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2678 if (!NT_STATUS_IS_OK(status)) {
2682 status = rpc_pipe_bind(epm_pipe, auth);
2683 if (!NT_STATUS_IS_OK(status)) {
2687 /* create tower for asking the epmapper */
2689 status = dcerpc_parse_binding(tmp_ctx, "ncacn_ip_tcp:[135]",
2691 if (!NT_STATUS_IS_OK(status)) {
2695 status = dcerpc_binding_set_abstract_syntax(map_binding,
2697 if (!NT_STATUS_IS_OK(status)) {
2701 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2702 if (map_tower == NULL) {
2703 status = NT_STATUS_NO_MEMORY;
2707 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2708 &(map_tower->tower));
2709 if (!NT_STATUS_IS_OK(status)) {
2713 /* allocate further parameters for the epm_Map call */
2715 res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2716 if (res_towers == NULL) {
2717 status = NT_STATUS_NO_MEMORY;
2720 towers.twr = res_towers;
2722 entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2723 if (entry_handle == NULL) {
2724 status = NT_STATUS_NO_MEMORY;
2728 /* ask the endpoint mapper for the port */
2730 status = dcerpc_epm_Map(epm_handle,
2732 discard_const_p(struct GUID,
2733 &(table->syntax_id.uuid)),
2741 if (!NT_STATUS_IS_OK(status)) {
2745 if (result != EPMAPPER_STATUS_OK) {
2746 status = NT_STATUS_UNSUCCESSFUL;
2750 if (num_towers != 1) {
2751 status = NT_STATUS_UNSUCCESSFUL;
2755 /* extract the port from the answer */
2757 status = dcerpc_binding_from_tower(tmp_ctx,
2758 &(towers.twr->tower),
2760 if (!NT_STATUS_IS_OK(status)) {
2764 transport = dcerpc_binding_get_transport(res_binding);
2765 endpoint = dcerpc_binding_get_string_option(res_binding, "endpoint");
2767 /* are further checks here necessary? */
2768 if (transport != NCACN_IP_TCP) {
2769 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2773 if (endpoint == NULL) {
2774 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2778 *pport = (uint16_t)atoi(endpoint);
2781 TALLOC_FREE(tmp_ctx);
2786 * Create a rpc pipe client struct, connecting to a host via tcp.
2787 * The port is determined by asking the endpoint mapper on the given
2790 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2791 const struct sockaddr_storage *addr,
2792 const struct ndr_interface_table *table,
2793 struct rpc_pipe_client **presult)
2798 status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2799 if (!NT_STATUS_IS_OK(status)) {
2803 return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2807 /********************************************************************
2808 Create a rpc pipe client struct, connecting to a unix domain socket
2809 ********************************************************************/
2810 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2811 const struct ndr_interface_table *table,
2812 struct rpc_pipe_client **presult)
2814 struct rpc_pipe_client *result;
2815 struct sockaddr_un addr;
2820 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2821 if (result == NULL) {
2822 return NT_STATUS_NO_MEMORY;
2825 result->abstract_syntax = table->syntax_id;
2826 result->transfer_syntax = ndr_transfer_syntax_ndr;
2828 result->desthost = get_myname(result);
2829 result->srv_name_slash = talloc_asprintf_strupper_m(
2830 result, "\\\\%s", result->desthost);
2831 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2832 status = NT_STATUS_NO_MEMORY;
2836 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2837 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2839 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2841 status = map_nt_error_from_unix(errno);
2846 addr.sun_family = AF_UNIX;
2847 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2848 salen = sizeof(struct sockaddr_un);
2850 if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
2851 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2854 return map_nt_error_from_unix(errno);
2857 status = rpc_transport_sock_init(result, fd, &result->transport);
2858 if (!NT_STATUS_IS_OK(status)) {
2863 result->transport->transport = NCALRPC;
2865 result->binding_handle = rpccli_bh_create(result, NULL, table);
2866 if (result->binding_handle == NULL) {
2867 TALLOC_FREE(result);
2868 return NT_STATUS_NO_MEMORY;
2872 return NT_STATUS_OK;
2875 TALLOC_FREE(result);
2879 struct rpc_pipe_client_np_ref {
2880 struct cli_state *cli;
2881 struct rpc_pipe_client *pipe;
2884 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2886 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2890 /****************************************************************************
2891 Open a named pipe over SMB to a remote server.
2893 * CAVEAT CALLER OF THIS FUNCTION:
2894 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2895 * so be sure that this function is called AFTER any structure (vs pointer)
2896 * assignment of the cli. In particular, libsmbclient does structure
2897 * assignments of cli, which invalidates the data in the returned
2898 * rpc_pipe_client if this function is called before the structure assignment
2901 ****************************************************************************/
2903 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2904 const struct ndr_interface_table *table,
2905 struct rpc_pipe_client **presult)
2907 struct rpc_pipe_client *result;
2909 struct rpc_pipe_client_np_ref *np_ref;
2911 /* sanity check to protect against crashes */
2914 return NT_STATUS_INVALID_HANDLE;
2917 result = talloc_zero(NULL, struct rpc_pipe_client);
2918 if (result == NULL) {
2919 return NT_STATUS_NO_MEMORY;
2922 result->abstract_syntax = table->syntax_id;
2923 result->transfer_syntax = ndr_transfer_syntax_ndr;
2924 result->desthost = talloc_strdup(result, smbXcli_conn_remote_name(cli->conn));
2925 result->srv_name_slash = talloc_asprintf_strupper_m(
2926 result, "\\\\%s", result->desthost);
2928 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2929 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2931 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2932 TALLOC_FREE(result);
2933 return NT_STATUS_NO_MEMORY;
2936 status = rpc_transport_np_init(result, cli, table,
2937 &result->transport);
2938 if (!NT_STATUS_IS_OK(status)) {
2939 TALLOC_FREE(result);
2943 result->transport->transport = NCACN_NP;
2945 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2946 if (np_ref == NULL) {
2947 TALLOC_FREE(result);
2948 return NT_STATUS_NO_MEMORY;
2951 np_ref->pipe = result;
2953 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2954 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2956 result->binding_handle = rpccli_bh_create(result, NULL, table);
2957 if (result->binding_handle == NULL) {
2958 TALLOC_FREE(result);
2959 return NT_STATUS_NO_MEMORY;
2963 return NT_STATUS_OK;
2966 /****************************************************************************
2967 Open a pipe to a remote server.
2968 ****************************************************************************/
2970 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2971 enum dcerpc_transport_t transport,
2972 const struct ndr_interface_table *table,
2973 struct rpc_pipe_client **presult)
2975 switch (transport) {
2977 return rpc_pipe_open_tcp(NULL,
2978 smbXcli_conn_remote_name(cli->conn),
2979 smbXcli_conn_remote_sockaddr(cli->conn),
2982 return rpc_pipe_open_np(cli, table, presult);
2984 return NT_STATUS_NOT_IMPLEMENTED;
2988 /****************************************************************************
2989 Open a named pipe to an SMB server and bind anonymously.
2990 ****************************************************************************/
2992 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2993 enum dcerpc_transport_t transport,
2994 const struct ndr_interface_table *table,
2995 struct rpc_pipe_client **presult)
2997 struct rpc_pipe_client *result;
2998 struct pipe_auth_data *auth;
3001 status = cli_rpc_pipe_open(cli, transport, table, &result);
3002 if (!NT_STATUS_IS_OK(status)) {
3006 status = rpccli_anon_bind_data(result, &auth);
3007 if (!NT_STATUS_IS_OK(status)) {
3008 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3009 nt_errstr(status)));
3010 TALLOC_FREE(result);
3015 * This is a bit of an abstraction violation due to the fact that an
3016 * anonymous bind on an authenticated SMB inherits the user/domain
3017 * from the enclosing SMB creds
3020 if (transport == NCACN_NP) {
3021 struct smbXcli_session *session;
3023 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
3024 session = cli->smb2.session;
3026 session = cli->smb1.session;
3029 status = smbXcli_session_application_key(session, auth,
3030 &auth->transport_session_key);
3031 if (!NT_STATUS_IS_OK(status)) {
3032 auth->transport_session_key = data_blob_null;
3036 status = rpc_pipe_bind(result, auth);
3037 if (!NT_STATUS_IS_OK(status)) {
3039 if (ndr_syntax_id_equal(&table->syntax_id,
3040 &ndr_table_dssetup.syntax_id)) {
3041 /* non AD domains just don't have this pipe, avoid
3042 * level 0 statement in that case - gd */
3045 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3046 "%s failed with error %s\n",
3048 nt_errstr(status) ));
3049 TALLOC_FREE(result);
3053 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3054 "%s and bound anonymously.\n",
3059 return NT_STATUS_OK;
3062 /****************************************************************************
3063 ****************************************************************************/
3065 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3066 const struct ndr_interface_table *table,
3067 struct rpc_pipe_client **presult)
3069 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3073 /****************************************************************************
3074 Open a named pipe to an SMB server and bind using the mech specified
3076 This routine references the creds pointer that is passed in
3077 ****************************************************************************/
3079 NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
3080 const struct ndr_interface_table *table,
3081 enum dcerpc_transport_t transport,
3082 enum dcerpc_AuthType auth_type,
3083 enum dcerpc_AuthLevel auth_level,
3085 struct cli_credentials *creds,
3086 struct rpc_pipe_client **presult)
3088 struct rpc_pipe_client *result;
3089 struct pipe_auth_data *auth = NULL;
3090 const char *target_service = table->authservices->names[0];
3094 status = cli_rpc_pipe_open(cli, transport, table, &result);
3095 if (!NT_STATUS_IS_OK(status)) {
3099 status = rpccli_generic_bind_data_from_creds(result,
3100 auth_type, auth_level,
3101 server, target_service,
3104 if (!NT_STATUS_IS_OK(status)) {
3105 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3106 nt_errstr(status)));
3110 status = rpc_pipe_bind(result, auth);
3111 if (!NT_STATUS_IS_OK(status)) {
3112 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3113 nt_errstr(status) ));
3117 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3118 "machine %s and bound as user %s.\n", table->name,
3119 result->desthost, cli_credentials_get_unparsed_name(creds, talloc_tos())));
3122 return NT_STATUS_OK;
3126 TALLOC_FREE(result);
3130 /****************************************************************************
3131 Open a named pipe to an SMB server and bind using the mech specified
3133 This routine steals the creds pointer that is passed in
3134 ****************************************************************************/
3136 NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
3137 const struct ndr_interface_table *table,
3138 enum dcerpc_transport_t transport,
3139 enum credentials_use_kerberos use_kerberos,
3140 enum dcerpc_AuthType auth_type,
3141 enum dcerpc_AuthLevel auth_level,
3144 const char *username,
3145 const char *password,
3146 struct rpc_pipe_client **presult)
3148 struct rpc_pipe_client *result;
3149 struct pipe_auth_data *auth = NULL;
3150 const char *target_service = table->authservices->names[0];
3154 status = cli_rpc_pipe_open(cli, transport, table, &result);
3155 if (!NT_STATUS_IS_OK(status)) {
3159 status = rpccli_generic_bind_data(result,
3160 auth_type, auth_level,
3161 server, target_service,
3162 domain, username, password,
3163 CRED_AUTO_USE_KERBEROS,
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_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3175 nt_errstr(status) ));
3179 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3180 "machine %s and bound as user %s\\%s.\n", table->name,
3181 result->desthost, domain, username));
3184 return NT_STATUS_OK;
3188 TALLOC_FREE(result);
3192 NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
3193 const struct ndr_interface_table *table,
3194 enum dcerpc_transport_t transport,
3195 struct cli_credentials *cli_creds,
3196 struct netlogon_creds_cli_context *netlogon_creds,
3197 struct rpc_pipe_client **_rpccli)
3199 struct rpc_pipe_client *rpccli;
3200 struct pipe_auth_data *rpcauth;
3201 const char *target_service = table->authservices->names[0];
3202 struct netlogon_creds_CredentialState *ncreds = NULL;
3203 enum dcerpc_AuthLevel auth_level;
3205 int rpc_pipe_bind_dbglvl = 0;
3207 status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
3208 if (!NT_STATUS_IS_OK(status)) {
3212 status = netlogon_creds_cli_lock(netlogon_creds, rpccli, &ncreds);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
3215 nt_errstr(status)));
3216 TALLOC_FREE(rpccli);
3220 auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
3222 cli_credentials_set_netlogon_creds(cli_creds, ncreds);
3224 status = rpccli_generic_bind_data_from_creds(rpccli,
3225 DCERPC_AUTH_TYPE_SCHANNEL,
3231 if (!NT_STATUS_IS_OK(status)) {
3232 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
3233 nt_errstr(status)));
3234 TALLOC_FREE(rpccli);
3238 status = rpc_pipe_bind(rpccli, rpcauth);
3239 cli_credentials_set_netlogon_creds(cli_creds, NULL);
3240 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3241 rpc_pipe_bind_dbglvl = 1;
3242 netlogon_creds_cli_delete(netlogon_creds, &ncreds);
3244 if (!NT_STATUS_IS_OK(status)) {
3245 DEBUG(rpc_pipe_bind_dbglvl,
3246 ("%s: rpc_pipe_bind failed with error %s\n",
3247 __func__, nt_errstr(status)));
3248 TALLOC_FREE(rpccli);
3252 TALLOC_FREE(ncreds);
3254 if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
3258 status = netlogon_creds_cli_check(netlogon_creds,
3259 rpccli->binding_handle);
3260 if (!NT_STATUS_IS_OK(status)) {
3261 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3262 nt_errstr(status)));
3263 TALLOC_FREE(rpccli);
3269 DEBUG(10,("%s: opened pipe %s to machine %s "
3270 "for domain %s and bound using schannel.\n",
3271 __func__, table->name,
3272 rpccli->desthost, cli_credentials_get_domain(cli_creds)));
3275 return NT_STATUS_OK;
3278 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3279 struct rpc_pipe_client *cli,
3280 DATA_BLOB *session_key)
3283 struct pipe_auth_data *a;
3284 struct gensec_security *gensec_security;
3285 DATA_BLOB sk = data_blob_null;
3286 bool make_dup = false;
3288 if (!session_key || !cli) {
3289 return NT_STATUS_INVALID_PARAMETER;
3295 return NT_STATUS_INVALID_PARAMETER;
3298 switch (cli->auth->auth_type) {
3299 case DCERPC_AUTH_TYPE_NONE:
3300 sk = data_blob_const(a->transport_session_key.data,
3301 a->transport_session_key.length);
3305 gensec_security = a->auth_ctx;
3306 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3307 if (!NT_STATUS_IS_OK(status)) {
3315 return NT_STATUS_NO_USER_SESSION_KEY;
3319 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3324 return NT_STATUS_OK;