2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client routines
4 * Largely rewritten by Jeremy Allison 2005.
5 * Heavily modified by Simo Sorce 2010.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/ndr_epmapper_c.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
24 #include "../librpc/gen_ndr/ndr_dssetup.h"
25 #include "../libcli/auth/schannel.h"
26 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "ntlmssp_wrap.h"
30 #include "librpc/gen_ndr/ndr_dcerpc.h"
31 #include "librpc/rpc/dcerpc.h"
32 #include "librpc/crypto/gse.h"
33 #include "librpc/crypto/spnego.h"
38 #define DBGC_CLASS DBGC_RPC_CLI
40 /********************************************************************
41 Pipe description for a DEBUG
42 ********************************************************************/
43 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
44 struct rpc_pipe_client *cli)
46 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
53 /********************************************************************
55 ********************************************************************/
57 static uint32 get_rpc_call_id(void)
59 static uint32 call_id = 0;
63 /*******************************************************************
64 Use SMBreadX to get rest of one fragment's worth of rpc data.
65 Reads the whole size or give an error message
66 ********************************************************************/
68 struct rpc_read_state {
69 struct event_context *ev;
70 struct rpc_cli_transport *transport;
76 static void rpc_read_done(struct tevent_req *subreq);
78 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
79 struct event_context *ev,
80 struct rpc_cli_transport *transport,
81 uint8_t *data, size_t size)
83 struct tevent_req *req, *subreq;
84 struct rpc_read_state *state;
86 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
91 state->transport = transport;
96 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
98 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
100 if (subreq == NULL) {
103 tevent_req_set_callback(subreq, rpc_read_done, req);
111 static void rpc_read_done(struct tevent_req *subreq)
113 struct tevent_req *req = tevent_req_callback_data(
114 subreq, struct tevent_req);
115 struct rpc_read_state *state = tevent_req_data(
116 req, struct rpc_read_state);
120 status = state->transport->read_recv(subreq, &received);
122 if (!NT_STATUS_IS_OK(status)) {
123 tevent_req_nterror(req, status);
127 state->num_read += received;
128 if (state->num_read == state->size) {
129 tevent_req_done(req);
133 subreq = state->transport->read_send(state, state->ev,
134 state->data + state->num_read,
135 state->size - state->num_read,
136 state->transport->priv);
137 if (tevent_req_nomem(subreq, req)) {
140 tevent_req_set_callback(subreq, rpc_read_done, req);
143 static NTSTATUS rpc_read_recv(struct tevent_req *req)
145 return tevent_req_simple_recv_ntstatus(req);
148 struct rpc_write_state {
149 struct event_context *ev;
150 struct rpc_cli_transport *transport;
156 static void rpc_write_done(struct tevent_req *subreq);
158 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
159 struct event_context *ev,
160 struct rpc_cli_transport *transport,
161 const uint8_t *data, size_t size)
163 struct tevent_req *req, *subreq;
164 struct rpc_write_state *state;
166 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
171 state->transport = transport;
174 state->num_written = 0;
176 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
178 subreq = transport->write_send(state, ev, data, size, transport->priv);
179 if (subreq == NULL) {
182 tevent_req_set_callback(subreq, rpc_write_done, req);
189 static void rpc_write_done(struct tevent_req *subreq)
191 struct tevent_req *req = tevent_req_callback_data(
192 subreq, struct tevent_req);
193 struct rpc_write_state *state = tevent_req_data(
194 req, struct rpc_write_state);
198 status = state->transport->write_recv(subreq, &written);
200 if (!NT_STATUS_IS_OK(status)) {
201 tevent_req_nterror(req, status);
205 state->num_written += written;
207 if (state->num_written == state->size) {
208 tevent_req_done(req);
212 subreq = state->transport->write_send(state, state->ev,
213 state->data + state->num_written,
214 state->size - state->num_written,
215 state->transport->priv);
216 if (tevent_req_nomem(subreq, req)) {
219 tevent_req_set_callback(subreq, rpc_write_done, req);
222 static NTSTATUS rpc_write_recv(struct tevent_req *req)
224 return tevent_req_simple_recv_ntstatus(req);
228 /****************************************************************************
229 Try and get a PDU's worth of data from current_pdu. If not, then read more
231 ****************************************************************************/
233 struct get_complete_frag_state {
234 struct event_context *ev;
235 struct rpc_pipe_client *cli;
240 static void get_complete_frag_got_header(struct tevent_req *subreq);
241 static void get_complete_frag_got_rest(struct tevent_req *subreq);
243 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
244 struct event_context *ev,
245 struct rpc_pipe_client *cli,
248 struct tevent_req *req, *subreq;
249 struct get_complete_frag_state *state;
253 req = tevent_req_create(mem_ctx, &state,
254 struct get_complete_frag_state);
260 state->frag_len = RPC_HEADER_LEN;
263 received = pdu->length;
264 if (received < RPC_HEADER_LEN) {
265 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
266 status = NT_STATUS_NO_MEMORY;
269 subreq = rpc_read_send(state, state->ev,
270 state->cli->transport,
271 pdu->data + received,
272 RPC_HEADER_LEN - received);
273 if (subreq == NULL) {
274 status = NT_STATUS_NO_MEMORY;
277 tevent_req_set_callback(subreq, get_complete_frag_got_header,
282 state->frag_len = dcerpc_get_frag_length(pdu);
285 * Ensure we have frag_len bytes of data.
287 if (received < state->frag_len) {
288 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
289 status = NT_STATUS_NO_MEMORY;
292 subreq = rpc_read_send(state, state->ev,
293 state->cli->transport,
294 pdu->data + received,
295 state->frag_len - received);
296 if (subreq == NULL) {
297 status = NT_STATUS_NO_MEMORY;
300 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
305 status = NT_STATUS_OK;
307 if (NT_STATUS_IS_OK(status)) {
308 tevent_req_done(req);
310 tevent_req_nterror(req, status);
312 return tevent_req_post(req, ev);
315 static void get_complete_frag_got_header(struct tevent_req *subreq)
317 struct tevent_req *req = tevent_req_callback_data(
318 subreq, struct tevent_req);
319 struct get_complete_frag_state *state = tevent_req_data(
320 req, struct get_complete_frag_state);
323 status = rpc_read_recv(subreq);
325 if (!NT_STATUS_IS_OK(status)) {
326 tevent_req_nterror(req, status);
330 state->frag_len = dcerpc_get_frag_length(state->pdu);
332 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
333 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
338 * We're here in this piece of code because we've read exactly
339 * RPC_HEADER_LEN bytes into state->pdu.
342 subreq = rpc_read_send(state, state->ev, state->cli->transport,
343 state->pdu->data + RPC_HEADER_LEN,
344 state->frag_len - RPC_HEADER_LEN);
345 if (tevent_req_nomem(subreq, req)) {
348 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
351 static void get_complete_frag_got_rest(struct tevent_req *subreq)
353 struct tevent_req *req = tevent_req_callback_data(
354 subreq, struct tevent_req);
357 status = rpc_read_recv(subreq);
359 if (!NT_STATUS_IS_OK(status)) {
360 tevent_req_nterror(req, status);
363 tevent_req_done(req);
366 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
368 return tevent_req_simple_recv_ntstatus(req);
371 /****************************************************************************
372 Do basic authentication checks on an incoming pdu.
373 ****************************************************************************/
375 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
376 struct rpc_pipe_client *cli,
377 struct ncacn_packet *pkt,
379 uint8_t expected_pkt_type,
381 DATA_BLOB *reply_pdu)
383 struct dcerpc_response *r;
384 NTSTATUS ret = NT_STATUS_OK;
388 * Point the return values at the real data including the RPC
389 * header. Just in case the caller wants it.
393 /* Ensure we have the correct type. */
394 switch (pkt->ptype) {
395 case DCERPC_PKT_ALTER_RESP:
396 case DCERPC_PKT_BIND_ACK:
398 /* Client code never receives this kind of packets */
402 case DCERPC_PKT_RESPONSE:
404 r = &pkt->u.response;
406 /* Here's where we deal with incoming sign/seal. */
407 ret = dcerpc_check_auth(cli->auth, pkt,
408 &r->stub_and_verifier,
409 DCERPC_RESPONSE_LENGTH,
411 if (!NT_STATUS_IS_OK(ret)) {
415 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
416 return NT_STATUS_BUFFER_TOO_SMALL;
419 /* Point the return values at the NDR data. */
420 rdata->data = r->stub_and_verifier.data;
422 if (pkt->auth_length) {
423 /* We've already done integer wrap tests in
424 * dcerpc_check_auth(). */
425 rdata->length = r->stub_and_verifier.length
427 - DCERPC_AUTH_TRAILER_LENGTH
430 rdata->length = r->stub_and_verifier.length;
433 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
434 (long unsigned int)pdu->length,
435 (long unsigned int)rdata->length,
436 (unsigned int)pad_len));
439 * If this is the first reply, and the allocation hint is
440 * reasonable, try and set up the reply_pdu DATA_BLOB to the
444 if ((reply_pdu->length == 0) &&
445 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
446 if (!data_blob_realloc(mem_ctx, reply_pdu,
448 DEBUG(0, ("reply alloc hint %d too "
449 "large to allocate\n",
450 (int)r->alloc_hint));
451 return NT_STATUS_NO_MEMORY;
457 case DCERPC_PKT_BIND_NAK:
458 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
459 rpccli_pipe_txt(talloc_tos(), cli)));
460 /* Use this for now... */
461 return NT_STATUS_NETWORK_ACCESS_DENIED;
463 case DCERPC_PKT_FAULT:
465 DEBUG(1, (__location__ ": RPC fault code %s received "
467 dcerpc_errstr(talloc_tos(),
468 pkt->u.fault.status),
469 rpccli_pipe_txt(talloc_tos(), cli)));
471 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
472 return NT_STATUS_UNSUCCESSFUL;
474 return NT_STATUS(pkt->u.fault.status);
478 DEBUG(0, (__location__ "Unknown packet type %u received "
480 (unsigned int)pkt->ptype,
481 rpccli_pipe_txt(talloc_tos(), cli)));
482 return NT_STATUS_INVALID_INFO_CLASS;
485 if (pkt->ptype != expected_pkt_type) {
486 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
487 "RPC packet type - %u, not %u\n",
488 rpccli_pipe_txt(talloc_tos(), cli),
489 pkt->ptype, expected_pkt_type));
490 return NT_STATUS_INVALID_INFO_CLASS;
493 /* Do this just before return - we don't want to modify any rpc header
494 data before now as we may have needed to do cryptographic actions on
497 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
498 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
499 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
500 "fragment first/last ON.\n"));
501 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
507 /****************************************************************************
508 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
509 ****************************************************************************/
511 struct cli_api_pipe_state {
512 struct event_context *ev;
513 struct rpc_cli_transport *transport;
518 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
519 static void cli_api_pipe_write_done(struct tevent_req *subreq);
520 static void cli_api_pipe_read_done(struct tevent_req *subreq);
522 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
523 struct event_context *ev,
524 struct rpc_cli_transport *transport,
525 uint8_t *data, size_t data_len,
526 uint32_t max_rdata_len)
528 struct tevent_req *req, *subreq;
529 struct cli_api_pipe_state *state;
532 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
537 state->transport = transport;
539 if (max_rdata_len < RPC_HEADER_LEN) {
541 * For a RPC reply we always need at least RPC_HEADER_LEN
542 * bytes. We check this here because we will receive
543 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
545 status = NT_STATUS_INVALID_PARAMETER;
549 if (transport->trans_send != NULL) {
550 subreq = transport->trans_send(state, ev, data, data_len,
551 max_rdata_len, transport->priv);
552 if (subreq == NULL) {
555 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
560 * If the transport does not provide a "trans" routine, i.e. for
561 * example the ncacn_ip_tcp transport, do the write/read step here.
564 subreq = rpc_write_send(state, ev, transport, data, data_len);
565 if (subreq == NULL) {
568 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
572 tevent_req_nterror(req, status);
573 return tevent_req_post(req, ev);
579 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
581 struct tevent_req *req = tevent_req_callback_data(
582 subreq, struct tevent_req);
583 struct cli_api_pipe_state *state = tevent_req_data(
584 req, struct cli_api_pipe_state);
587 status = state->transport->trans_recv(subreq, state, &state->rdata,
590 if (!NT_STATUS_IS_OK(status)) {
591 tevent_req_nterror(req, status);
594 tevent_req_done(req);
597 static void cli_api_pipe_write_done(struct tevent_req *subreq)
599 struct tevent_req *req = tevent_req_callback_data(
600 subreq, struct tevent_req);
601 struct cli_api_pipe_state *state = tevent_req_data(
602 req, struct cli_api_pipe_state);
605 status = rpc_write_recv(subreq);
607 if (!NT_STATUS_IS_OK(status)) {
608 tevent_req_nterror(req, status);
612 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
613 if (tevent_req_nomem(state->rdata, req)) {
618 * We don't need to use rpc_read_send here, the upper layer will cope
619 * with a short read, transport->trans_send could also return less
620 * than state->max_rdata_len.
622 subreq = state->transport->read_send(state, state->ev, state->rdata,
624 state->transport->priv);
625 if (tevent_req_nomem(subreq, req)) {
628 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
631 static void cli_api_pipe_read_done(struct tevent_req *subreq)
633 struct tevent_req *req = tevent_req_callback_data(
634 subreq, struct tevent_req);
635 struct cli_api_pipe_state *state = tevent_req_data(
636 req, struct cli_api_pipe_state);
640 status = state->transport->read_recv(subreq, &received);
642 if (!NT_STATUS_IS_OK(status)) {
643 tevent_req_nterror(req, status);
646 state->rdata_len = received;
647 tevent_req_done(req);
650 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
651 uint8_t **prdata, uint32_t *prdata_len)
653 struct cli_api_pipe_state *state = tevent_req_data(
654 req, struct cli_api_pipe_state);
657 if (tevent_req_is_nterror(req, &status)) {
661 *prdata = talloc_move(mem_ctx, &state->rdata);
662 *prdata_len = state->rdata_len;
666 /****************************************************************************
667 Send data on an rpc pipe via trans. The data must be the last
668 pdu fragment of an NDR data stream.
670 Receive response data from an rpc pipe, which may be large...
672 Read the first fragment: unfortunately have to use SMBtrans for the first
673 bit, then SMBreadX for subsequent bits.
675 If first fragment received also wasn't the last fragment, continue
676 getting fragments until we _do_ receive the last fragment.
678 Request/Response PDU's look like the following...
680 |<------------------PDU len----------------------------------------------->|
681 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
683 +------------+-----------------+-------------+---------------+-------------+
684 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
685 +------------+-----------------+-------------+---------------+-------------+
687 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
688 signing & sealing being negotiated.
690 ****************************************************************************/
692 struct rpc_api_pipe_state {
693 struct event_context *ev;
694 struct rpc_pipe_client *cli;
695 uint8_t expected_pkt_type;
697 DATA_BLOB incoming_frag;
698 struct ncacn_packet *pkt;
702 size_t reply_pdu_offset;
706 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
707 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
708 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
710 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
711 struct event_context *ev,
712 struct rpc_pipe_client *cli,
713 DATA_BLOB *data, /* Outgoing PDU */
714 uint8_t expected_pkt_type)
716 struct tevent_req *req, *subreq;
717 struct rpc_api_pipe_state *state;
718 uint16_t max_recv_frag;
721 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
727 state->expected_pkt_type = expected_pkt_type;
728 state->incoming_frag = data_blob_null;
729 state->reply_pdu = data_blob_null;
730 state->reply_pdu_offset = 0;
731 state->endianess = DCERPC_DREP_LE;
734 * Ensure we're not sending too much.
736 if (data->length > cli->max_xmit_frag) {
737 status = NT_STATUS_INVALID_PARAMETER;
741 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
743 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
744 subreq = rpc_write_send(state, ev, cli->transport,
745 data->data, data->length);
746 if (subreq == NULL) {
749 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
753 /* get the header first, then fetch the rest once we have
754 * the frag_length available */
755 max_recv_frag = RPC_HEADER_LEN;
757 subreq = cli_api_pipe_send(state, ev, cli->transport,
758 data->data, data->length, max_recv_frag);
759 if (subreq == NULL) {
762 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
766 tevent_req_nterror(req, status);
767 return tevent_req_post(req, ev);
773 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
775 struct tevent_req *req =
776 tevent_req_callback_data(subreq,
780 status = rpc_write_recv(subreq);
782 if (!NT_STATUS_IS_OK(status)) {
783 tevent_req_nterror(req, status);
787 tevent_req_done(req);
790 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
792 struct tevent_req *req = tevent_req_callback_data(
793 subreq, struct tevent_req);
794 struct rpc_api_pipe_state *state = tevent_req_data(
795 req, struct rpc_api_pipe_state);
797 uint8_t *rdata = NULL;
798 uint32_t rdata_len = 0;
800 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
802 if (!NT_STATUS_IS_OK(status)) {
803 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
804 tevent_req_nterror(req, status);
809 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
810 rpccli_pipe_txt(talloc_tos(), state->cli)));
811 tevent_req_done(req);
816 * Move data on state->incoming_frag.
818 state->incoming_frag.data = talloc_move(state, &rdata);
819 state->incoming_frag.length = rdata_len;
820 if (!state->incoming_frag.data) {
821 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
825 /* Ensure we have enough data for a pdu. */
826 subreq = get_complete_frag_send(state, state->ev, state->cli,
827 &state->incoming_frag);
828 if (tevent_req_nomem(subreq, req)) {
831 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
834 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
836 struct tevent_req *req = tevent_req_callback_data(
837 subreq, struct tevent_req);
838 struct rpc_api_pipe_state *state = tevent_req_data(
839 req, struct rpc_api_pipe_state);
841 DATA_BLOB rdata = data_blob_null;
843 status = get_complete_frag_recv(subreq);
845 if (!NT_STATUS_IS_OK(status)) {
846 DEBUG(5, ("get_complete_frag failed: %s\n",
848 tevent_req_nterror(req, status);
852 state->pkt = talloc(state, struct ncacn_packet);
854 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
858 status = dcerpc_pull_ncacn_packet(state->pkt,
859 &state->incoming_frag,
862 if (!NT_STATUS_IS_OK(status)) {
863 tevent_req_nterror(req, status);
867 if (state->incoming_frag.length != state->pkt->frag_length) {
868 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
869 (unsigned int)state->incoming_frag.length,
870 (unsigned int)state->pkt->frag_length));
871 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
875 status = cli_pipe_validate_current_pdu(state,
876 state->cli, state->pkt,
877 &state->incoming_frag,
878 state->expected_pkt_type,
882 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
883 (unsigned)state->incoming_frag.length,
884 (unsigned)state->reply_pdu_offset,
887 if (!NT_STATUS_IS_OK(status)) {
888 tevent_req_nterror(req, status);
892 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
893 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
895 * Set the data type correctly for big-endian data on the
898 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
900 rpccli_pipe_txt(talloc_tos(), state->cli)));
901 state->endianess = 0x00; /* BIG ENDIAN */
904 * Check endianness on subsequent packets.
906 if (state->endianess != state->pkt->drep[0]) {
907 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
909 state->endianess?"little":"big",
910 state->pkt->drep[0]?"little":"big"));
911 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
915 /* Now copy the data portion out of the pdu into rbuf. */
916 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
917 if (!data_blob_realloc(NULL, &state->reply_pdu,
918 state->reply_pdu_offset + rdata.length)) {
919 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
924 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
925 rdata.data, rdata.length);
926 state->reply_pdu_offset += rdata.length;
928 /* reset state->incoming_frag, there is no need to free it,
929 * it will be reallocated to the right size the next time
931 state->incoming_frag.length = 0;
933 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
934 /* make sure the pdu length is right now that we
935 * have all the data available (alloc hint may
936 * have allocated more than was actually used) */
937 state->reply_pdu.length = state->reply_pdu_offset;
938 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
939 rpccli_pipe_txt(talloc_tos(), state->cli),
940 (unsigned)state->reply_pdu.length));
941 tevent_req_done(req);
945 subreq = get_complete_frag_send(state, state->ev, state->cli,
946 &state->incoming_frag);
947 if (tevent_req_nomem(subreq, req)) {
950 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
953 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
954 struct ncacn_packet **pkt,
955 DATA_BLOB *reply_pdu)
957 struct rpc_api_pipe_state *state = tevent_req_data(
958 req, struct rpc_api_pipe_state);
961 if (tevent_req_is_nterror(req, &status)) {
965 /* return data to caller and assign it ownership of memory */
967 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
968 reply_pdu->length = state->reply_pdu.length;
969 state->reply_pdu.length = 0;
971 data_blob_free(&state->reply_pdu);
975 *pkt = talloc_steal(mem_ctx, state->pkt);
981 /*******************************************************************
982 Creates spnego auth bind.
983 ********************************************************************/
985 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
986 struct pipe_auth_data *auth,
987 DATA_BLOB *auth_token)
989 struct spnego_context *spnego_ctx;
990 DATA_BLOB in_token = data_blob_null;
993 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
994 struct spnego_context);
996 /* Negotiate the initial auth token */
997 status = spnego_get_client_auth_token(mem_ctx, spnego_ctx,
998 &in_token, auth_token);
999 if (!NT_STATUS_IS_OK(status)) {
1003 DEBUG(5, ("Created GSS Authentication Token:\n"));
1004 dump_data(5, auth_token->data, auth_token->length);
1006 return NT_STATUS_OK;
1009 /*******************************************************************
1010 Creates krb5 auth bind.
1011 ********************************************************************/
1013 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
1014 struct pipe_auth_data *auth,
1015 DATA_BLOB *auth_token)
1017 struct gse_context *gse_ctx;
1018 DATA_BLOB in_token = data_blob_null;
1021 gse_ctx = talloc_get_type_abort(auth->auth_ctx,
1022 struct gse_context);
1024 /* Negotiate the initial auth token */
1025 status = gse_get_client_auth_token(mem_ctx, gse_ctx,
1028 if (!NT_STATUS_IS_OK(status)) {
1032 DEBUG(5, ("Created GSS Authentication Token:\n"));
1033 dump_data(5, auth_token->data, auth_token->length);
1035 return NT_STATUS_OK;
1038 /*******************************************************************
1039 Creates NTLMSSP auth bind.
1040 ********************************************************************/
1042 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1043 DATA_BLOB *auth_token)
1045 struct auth_ntlmssp_state *ntlmssp_ctx;
1046 DATA_BLOB null_blob = data_blob_null;
1049 ntlmssp_ctx = talloc_get_type_abort(cli->auth->auth_ctx,
1050 struct auth_ntlmssp_state);
1052 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1053 status = auth_ntlmssp_update(ntlmssp_ctx, null_blob, auth_token);
1055 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1056 data_blob_free(auth_token);
1060 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1061 dump_data(5, auth_token->data, auth_token->length);
1063 return NT_STATUS_OK;
1066 /*******************************************************************
1067 Creates schannel auth bind.
1068 ********************************************************************/
1070 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1071 DATA_BLOB *auth_token)
1074 struct NL_AUTH_MESSAGE r;
1076 /* Use lp_workgroup() if domain not specified */
1078 if (!cli->auth->domain || !cli->auth->domain[0]) {
1079 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1080 if (cli->auth->domain == NULL) {
1081 return NT_STATUS_NO_MEMORY;
1086 * Now marshall the data into the auth parse_struct.
1089 r.MessageType = NL_NEGOTIATE_REQUEST;
1090 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1091 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1092 r.oem_netbios_domain.a = cli->auth->domain;
1093 r.oem_netbios_computer.a = global_myname();
1095 status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1096 if (!NT_STATUS_IS_OK(status)) {
1100 return NT_STATUS_OK;
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,
1110 const struct ndr_syntax_id *abstract,
1111 const struct ndr_syntax_id *transfer,
1112 const DATA_BLOB *auth_info,
1115 uint16 auth_len = auth_info->length;
1117 union dcerpc_payload u;
1118 struct dcerpc_ctx_list ctx_list;
1121 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1124 ctx_list.context_id = 0;
1125 ctx_list.num_transfer_syntaxes = 1;
1126 ctx_list.abstract_syntax = *abstract;
1127 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1129 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1130 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1131 u.bind.assoc_group_id = 0x0;
1132 u.bind.num_contexts = 1;
1133 u.bind.ctx_list = &ctx_list;
1134 u.bind.auth_info = *auth_info;
1136 status = dcerpc_push_ncacn_packet(mem_ctx,
1138 DCERPC_PFC_FLAG_FIRST |
1139 DCERPC_PFC_FLAG_LAST,
1144 if (!NT_STATUS_IS_OK(status)) {
1145 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1149 return NT_STATUS_OK;
1152 /*******************************************************************
1153 Creates a DCE/RPC bind request.
1154 ********************************************************************/
1156 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1157 struct rpc_pipe_client *cli,
1158 struct pipe_auth_data *auth,
1160 const struct ndr_syntax_id *abstract,
1161 const struct ndr_syntax_id *transfer,
1164 DATA_BLOB auth_token = data_blob_null;
1165 DATA_BLOB auth_info = data_blob_null;
1166 NTSTATUS ret = NT_STATUS_OK;
1168 switch (auth->auth_type) {
1169 case DCERPC_AUTH_TYPE_SCHANNEL:
1170 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1171 if (!NT_STATUS_IS_OK(ret)) {
1176 case DCERPC_AUTH_TYPE_NTLMSSP:
1177 ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token);
1178 if (!NT_STATUS_IS_OK(ret)) {
1183 case DCERPC_AUTH_TYPE_SPNEGO:
1184 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1185 if (!NT_STATUS_IS_OK(ret)) {
1190 case DCERPC_AUTH_TYPE_KRB5:
1191 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
1192 if (!NT_STATUS_IS_OK(ret)) {
1197 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1198 auth_token = data_blob_talloc(mem_ctx,
1199 "NCALRPC_AUTH_TOKEN",
1203 case DCERPC_AUTH_TYPE_NONE:
1207 /* "Can't" happen. */
1208 return NT_STATUS_INVALID_INFO_CLASS;
1211 if (auth_token.length != 0) {
1212 ret = dcerpc_push_dcerpc_auth(cli,
1215 0, /* auth_pad_length */
1216 1, /* auth_context_id */
1219 if (!NT_STATUS_IS_OK(ret)) {
1222 data_blob_free(&auth_token);
1225 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1235 /*******************************************************************
1237 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1238 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1239 and deals with signing/sealing details.
1240 ********************************************************************/
1242 struct rpc_api_pipe_req_state {
1243 struct event_context *ev;
1244 struct rpc_pipe_client *cli;
1247 DATA_BLOB *req_data;
1248 uint32_t req_data_sent;
1250 DATA_BLOB reply_pdu;
1253 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1254 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1255 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1256 bool *is_last_frag);
1258 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1259 struct event_context *ev,
1260 struct rpc_pipe_client *cli,
1262 DATA_BLOB *req_data)
1264 struct tevent_req *req, *subreq;
1265 struct rpc_api_pipe_req_state *state;
1269 req = tevent_req_create(mem_ctx, &state,
1270 struct rpc_api_pipe_req_state);
1276 state->op_num = op_num;
1277 state->req_data = req_data;
1278 state->req_data_sent = 0;
1279 state->call_id = get_rpc_call_id();
1280 state->reply_pdu = data_blob_null;
1281 state->rpc_out = data_blob_null;
1283 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1284 + RPC_MAX_SIGN_SIZE) {
1285 /* Server is screwed up ! */
1286 status = NT_STATUS_INVALID_PARAMETER;
1290 status = prepare_next_frag(state, &is_last_frag);
1291 if (!NT_STATUS_IS_OK(status)) {
1296 subreq = rpc_api_pipe_send(state, ev, state->cli,
1298 DCERPC_PKT_RESPONSE);
1299 if (subreq == NULL) {
1302 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1304 subreq = rpc_write_send(state, ev, cli->transport,
1305 state->rpc_out.data,
1306 state->rpc_out.length);
1307 if (subreq == NULL) {
1310 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1316 tevent_req_nterror(req, status);
1317 return tevent_req_post(req, ev);
1323 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1326 size_t data_sent_thistime;
1333 union dcerpc_payload u;
1335 data_left = state->req_data->length - state->req_data_sent;
1337 status = dcerpc_guess_sizes(state->cli->auth,
1338 DCERPC_REQUEST_LENGTH, data_left,
1339 state->cli->max_xmit_frag,
1340 CLIENT_NDR_PADDING_SIZE,
1341 &data_sent_thistime,
1342 &frag_len, &auth_len, &pad_len);
1343 if (!NT_STATUS_IS_OK(status)) {
1347 if (state->req_data_sent == 0) {
1348 flags = DCERPC_PFC_FLAG_FIRST;
1351 if (data_sent_thistime == data_left) {
1352 flags |= DCERPC_PFC_FLAG_LAST;
1355 data_blob_free(&state->rpc_out);
1357 ZERO_STRUCT(u.request);
1359 u.request.alloc_hint = state->req_data->length;
1360 u.request.context_id = 0;
1361 u.request.opnum = state->op_num;
1363 status = dcerpc_push_ncacn_packet(state,
1370 if (!NT_STATUS_IS_OK(status)) {
1374 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1375 * compute it right for requests because the auth trailer is missing
1377 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1379 /* Copy in the data. */
1380 if (!data_blob_append(NULL, &state->rpc_out,
1381 state->req_data->data + state->req_data_sent,
1382 data_sent_thistime)) {
1383 return NT_STATUS_NO_MEMORY;
1386 switch (state->cli->auth->auth_level) {
1387 case DCERPC_AUTH_LEVEL_NONE:
1388 case DCERPC_AUTH_LEVEL_CONNECT:
1389 case DCERPC_AUTH_LEVEL_PACKET:
1391 case DCERPC_AUTH_LEVEL_INTEGRITY:
1392 case DCERPC_AUTH_LEVEL_PRIVACY:
1393 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1395 if (!NT_STATUS_IS_OK(status)) {
1400 return NT_STATUS_INVALID_PARAMETER;
1403 state->req_data_sent += data_sent_thistime;
1404 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1409 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1411 struct tevent_req *req = tevent_req_callback_data(
1412 subreq, struct tevent_req);
1413 struct rpc_api_pipe_req_state *state = tevent_req_data(
1414 req, struct rpc_api_pipe_req_state);
1418 status = rpc_write_recv(subreq);
1419 TALLOC_FREE(subreq);
1420 if (!NT_STATUS_IS_OK(status)) {
1421 tevent_req_nterror(req, status);
1425 status = prepare_next_frag(state, &is_last_frag);
1426 if (!NT_STATUS_IS_OK(status)) {
1427 tevent_req_nterror(req, status);
1432 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1434 DCERPC_PKT_RESPONSE);
1435 if (tevent_req_nomem(subreq, req)) {
1438 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1440 subreq = rpc_write_send(state, state->ev,
1441 state->cli->transport,
1442 state->rpc_out.data,
1443 state->rpc_out.length);
1444 if (tevent_req_nomem(subreq, req)) {
1447 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1452 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1454 struct tevent_req *req = tevent_req_callback_data(
1455 subreq, struct tevent_req);
1456 struct rpc_api_pipe_req_state *state = tevent_req_data(
1457 req, struct rpc_api_pipe_req_state);
1460 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1461 TALLOC_FREE(subreq);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 tevent_req_nterror(req, status);
1466 tevent_req_done(req);
1469 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1470 DATA_BLOB *reply_pdu)
1472 struct rpc_api_pipe_req_state *state = tevent_req_data(
1473 req, struct rpc_api_pipe_req_state);
1476 if (tevent_req_is_nterror(req, &status)) {
1478 * We always have to initialize to reply pdu, even if there is
1479 * none. The rpccli_* caller routines expect this.
1481 *reply_pdu = data_blob_null;
1485 /* return data to caller and assign it ownership of memory */
1486 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1487 reply_pdu->length = state->reply_pdu.length;
1488 state->reply_pdu.length = 0;
1490 return NT_STATUS_OK;
1493 /****************************************************************************
1494 Check the rpc bind acknowledge response.
1495 ****************************************************************************/
1497 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1498 const struct ndr_syntax_id *transfer)
1500 struct dcerpc_ack_ctx ctx;
1502 if (r->secondary_address_size == 0) {
1503 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1506 if (r->num_results < 1 || !r->ctx_list) {
1510 ctx = r->ctx_list[0];
1512 /* check the transfer syntax */
1513 if ((ctx.syntax.if_version != transfer->if_version) ||
1514 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1515 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1519 if (r->num_results != 0x1 || ctx.result != 0) {
1520 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1521 r->num_results, ctx.reason));
1524 DEBUG(5,("check_bind_response: accepted!\n"));
1528 /*******************************************************************
1529 Creates a DCE/RPC bind authentication response.
1530 This is the packet that is sent back to the server once we
1531 have received a BIND-ACK, to finish the third leg of
1532 the authentication handshake.
1533 ********************************************************************/
1535 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1536 struct rpc_pipe_client *cli,
1538 enum dcerpc_AuthType auth_type,
1539 enum dcerpc_AuthLevel auth_level,
1540 DATA_BLOB *pauth_blob,
1544 union dcerpc_payload u;
1548 status = dcerpc_push_dcerpc_auth(mem_ctx,
1551 0, /* auth_pad_length */
1552 1, /* auth_context_id */
1554 &u.auth3.auth_info);
1555 if (!NT_STATUS_IS_OK(status)) {
1559 status = dcerpc_push_ncacn_packet(mem_ctx,
1561 DCERPC_PFC_FLAG_FIRST |
1562 DCERPC_PFC_FLAG_LAST,
1567 data_blob_free(&u.auth3.auth_info);
1568 if (!NT_STATUS_IS_OK(status)) {
1569 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1573 return NT_STATUS_OK;
1576 /*******************************************************************
1577 Creates a DCE/RPC bind alter context authentication request which
1578 may contain a spnego auth blobl
1579 ********************************************************************/
1581 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1582 enum dcerpc_AuthType auth_type,
1583 enum dcerpc_AuthLevel auth_level,
1585 const struct ndr_syntax_id *abstract,
1586 const struct ndr_syntax_id *transfer,
1587 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1590 DATA_BLOB auth_info;
1593 status = dcerpc_push_dcerpc_auth(mem_ctx,
1596 0, /* auth_pad_length */
1597 1, /* auth_context_id */
1600 if (!NT_STATUS_IS_OK(status)) {
1604 status = create_bind_or_alt_ctx_internal(mem_ctx,
1611 data_blob_free(&auth_info);
1615 /****************************************************************************
1617 ****************************************************************************/
1619 struct rpc_pipe_bind_state {
1620 struct event_context *ev;
1621 struct rpc_pipe_client *cli;
1624 uint32_t rpc_call_id;
1627 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1628 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1629 struct rpc_pipe_bind_state *state,
1630 DATA_BLOB *credentials);
1631 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1632 struct rpc_pipe_bind_state *state,
1633 DATA_BLOB *credentials);
1635 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1636 struct event_context *ev,
1637 struct rpc_pipe_client *cli,
1638 struct pipe_auth_data *auth)
1640 struct tevent_req *req, *subreq;
1641 struct rpc_pipe_bind_state *state;
1644 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1649 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1650 rpccli_pipe_txt(talloc_tos(), cli),
1651 (unsigned int)auth->auth_type,
1652 (unsigned int)auth->auth_level ));
1656 state->rpc_call_id = get_rpc_call_id();
1658 cli->auth = talloc_move(cli, &auth);
1660 /* Marshall the outgoing data. */
1661 status = create_rpc_bind_req(state, cli,
1664 &cli->abstract_syntax,
1665 &cli->transfer_syntax,
1668 if (!NT_STATUS_IS_OK(status)) {
1672 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1673 DCERPC_PKT_BIND_ACK);
1674 if (subreq == NULL) {
1677 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1681 tevent_req_nterror(req, status);
1682 return tevent_req_post(req, ev);
1688 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1690 struct tevent_req *req = tevent_req_callback_data(
1691 subreq, struct tevent_req);
1692 struct rpc_pipe_bind_state *state = tevent_req_data(
1693 req, struct rpc_pipe_bind_state);
1694 struct pipe_auth_data *pauth = state->cli->auth;
1695 struct auth_ntlmssp_state *ntlmssp_ctx;
1696 struct spnego_context *spnego_ctx;
1697 struct gse_context *gse_ctx;
1698 struct ncacn_packet *pkt = NULL;
1699 struct dcerpc_auth auth;
1700 DATA_BLOB auth_token = data_blob_null;
1703 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1704 TALLOC_FREE(subreq);
1705 if (!NT_STATUS_IS_OK(status)) {
1706 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1707 rpccli_pipe_txt(talloc_tos(), state->cli),
1708 nt_errstr(status)));
1709 tevent_req_nterror(req, status);
1714 tevent_req_done(req);
1718 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1719 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1720 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1724 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1725 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1727 switch(pauth->auth_type) {
1729 case DCERPC_AUTH_TYPE_NONE:
1730 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1731 case DCERPC_AUTH_TYPE_SCHANNEL:
1732 /* Bind complete. */
1733 tevent_req_done(req);
1736 case DCERPC_AUTH_TYPE_NTLMSSP:
1737 case DCERPC_AUTH_TYPE_SPNEGO:
1738 case DCERPC_AUTH_TYPE_KRB5:
1739 /* Paranoid lenght checks */
1740 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1741 + pkt->auth_length) {
1742 tevent_req_nterror(req,
1743 NT_STATUS_INFO_LENGTH_MISMATCH);
1746 /* get auth credentials */
1747 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1748 &pkt->u.bind_ack.auth_info,
1750 if (!NT_STATUS_IS_OK(status)) {
1751 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1752 nt_errstr(status)));
1753 tevent_req_nterror(req, status);
1763 * For authenticated binds we may need to do 3 or 4 leg binds.
1766 switch(pauth->auth_type) {
1768 case DCERPC_AUTH_TYPE_NONE:
1769 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1770 case DCERPC_AUTH_TYPE_SCHANNEL:
1771 /* Bind complete. */
1772 tevent_req_done(req);
1775 case DCERPC_AUTH_TYPE_NTLMSSP:
1776 ntlmssp_ctx = talloc_get_type_abort(pauth->auth_ctx,
1777 struct auth_ntlmssp_state);
1778 status = auth_ntlmssp_update(ntlmssp_ctx,
1779 auth.credentials, &auth_token);
1780 if (NT_STATUS_EQUAL(status,
1781 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1782 status = rpc_bind_next_send(req, state,
1784 } else if (NT_STATUS_IS_OK(status)) {
1785 status = rpc_bind_finish_send(req, state,
1790 case DCERPC_AUTH_TYPE_SPNEGO:
1791 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
1792 struct spnego_context);
1793 status = spnego_get_client_auth_token(state,
1797 if (!NT_STATUS_IS_OK(status)) {
1800 if (auth_token.length == 0) {
1801 /* Bind complete. */
1802 tevent_req_done(req);
1805 if (spnego_require_more_processing(spnego_ctx)) {
1806 status = rpc_bind_next_send(req, state,
1809 status = rpc_bind_finish_send(req, state,
1814 case DCERPC_AUTH_TYPE_KRB5:
1815 gse_ctx = talloc_get_type_abort(pauth->auth_ctx,
1816 struct gse_context);
1817 status = gse_get_client_auth_token(state,
1821 if (!NT_STATUS_IS_OK(status)) {
1825 if (gse_require_more_processing(gse_ctx)) {
1826 status = rpc_bind_next_send(req, state, &auth_token);
1828 status = rpc_bind_finish_send(req, state, &auth_token);
1836 if (!NT_STATUS_IS_OK(status)) {
1837 tevent_req_nterror(req, status);
1842 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1843 (unsigned int)state->cli->auth->auth_type));
1844 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1847 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1848 struct rpc_pipe_bind_state *state,
1849 DATA_BLOB *auth_token)
1851 struct pipe_auth_data *auth = state->cli->auth;
1852 struct tevent_req *subreq;
1855 /* Now prepare the alter context pdu. */
1856 data_blob_free(&state->rpc_out);
1858 status = create_rpc_alter_context(state,
1862 &state->cli->abstract_syntax,
1863 &state->cli->transfer_syntax,
1866 if (!NT_STATUS_IS_OK(status)) {
1870 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1871 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1872 if (subreq == NULL) {
1873 return NT_STATUS_NO_MEMORY;
1875 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1876 return NT_STATUS_OK;
1879 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1880 struct rpc_pipe_bind_state *state,
1881 DATA_BLOB *auth_token)
1883 struct pipe_auth_data *auth = state->cli->auth;
1884 struct tevent_req *subreq;
1887 state->auth3 = true;
1889 /* Now prepare the auth3 context pdu. */
1890 data_blob_free(&state->rpc_out);
1892 status = create_rpc_bind_auth3(state, state->cli,
1898 if (!NT_STATUS_IS_OK(status)) {
1902 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1903 &state->rpc_out, DCERPC_PKT_AUTH3);
1904 if (subreq == NULL) {
1905 return NT_STATUS_NO_MEMORY;
1907 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1908 return NT_STATUS_OK;
1911 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1913 return tevent_req_simple_recv_ntstatus(req);
1916 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1917 struct pipe_auth_data *auth)
1919 TALLOC_CTX *frame = talloc_stackframe();
1920 struct event_context *ev;
1921 struct tevent_req *req;
1922 NTSTATUS status = NT_STATUS_OK;
1924 ev = event_context_init(frame);
1926 status = NT_STATUS_NO_MEMORY;
1930 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1932 status = NT_STATUS_NO_MEMORY;
1936 if (!tevent_req_poll(req, ev)) {
1937 status = map_nt_error_from_unix(errno);
1941 status = rpc_pipe_bind_recv(req);
1947 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1949 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1950 unsigned int timeout)
1954 if (rpc_cli->transport == NULL) {
1955 return RPCCLI_DEFAULT_TIMEOUT;
1958 if (rpc_cli->transport->set_timeout == NULL) {
1959 return RPCCLI_DEFAULT_TIMEOUT;
1962 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1964 return RPCCLI_DEFAULT_TIMEOUT;
1970 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1972 if (rpc_cli == NULL) {
1976 if (rpc_cli->transport == NULL) {
1980 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1983 struct rpccli_bh_state {
1984 struct rpc_pipe_client *rpc_cli;
1987 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1989 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1990 struct rpccli_bh_state);
1992 return rpccli_is_connected(hs->rpc_cli);
1995 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1998 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1999 struct rpccli_bh_state);
2001 return rpccli_set_timeout(hs->rpc_cli, timeout);
2004 struct rpccli_bh_raw_call_state {
2010 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2012 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2013 struct tevent_context *ev,
2014 struct dcerpc_binding_handle *h,
2015 const struct GUID *object,
2018 const uint8_t *in_data,
2021 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2022 struct rpccli_bh_state);
2023 struct tevent_req *req;
2024 struct rpccli_bh_raw_call_state *state;
2026 struct tevent_req *subreq;
2028 req = tevent_req_create(mem_ctx, &state,
2029 struct rpccli_bh_raw_call_state);
2033 state->in_data.data = discard_const_p(uint8_t, in_data);
2034 state->in_data.length = in_length;
2036 ok = rpccli_bh_is_connected(h);
2038 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2039 return tevent_req_post(req, ev);
2042 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2043 opnum, &state->in_data);
2044 if (tevent_req_nomem(subreq, req)) {
2045 return tevent_req_post(req, ev);
2047 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2052 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2054 struct tevent_req *req =
2055 tevent_req_callback_data(subreq,
2057 struct rpccli_bh_raw_call_state *state =
2058 tevent_req_data(req,
2059 struct rpccli_bh_raw_call_state);
2062 state->out_flags = 0;
2064 /* TODO: support bigendian responses */
2066 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2067 TALLOC_FREE(subreq);
2068 if (!NT_STATUS_IS_OK(status)) {
2069 tevent_req_nterror(req, status);
2073 tevent_req_done(req);
2076 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2077 TALLOC_CTX *mem_ctx,
2080 uint32_t *out_flags)
2082 struct rpccli_bh_raw_call_state *state =
2083 tevent_req_data(req,
2084 struct rpccli_bh_raw_call_state);
2087 if (tevent_req_is_nterror(req, &status)) {
2088 tevent_req_received(req);
2092 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2093 *out_length = state->out_data.length;
2094 *out_flags = state->out_flags;
2095 tevent_req_received(req);
2096 return NT_STATUS_OK;
2099 struct rpccli_bh_disconnect_state {
2103 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2104 struct tevent_context *ev,
2105 struct dcerpc_binding_handle *h)
2107 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2108 struct rpccli_bh_state);
2109 struct tevent_req *req;
2110 struct rpccli_bh_disconnect_state *state;
2113 req = tevent_req_create(mem_ctx, &state,
2114 struct rpccli_bh_disconnect_state);
2119 ok = rpccli_bh_is_connected(h);
2121 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2122 return tevent_req_post(req, ev);
2126 * TODO: do a real async disconnect ...
2128 * For now the caller needs to free rpc_cli
2132 tevent_req_done(req);
2133 return tevent_req_post(req, ev);
2136 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2140 if (tevent_req_is_nterror(req, &status)) {
2141 tevent_req_received(req);
2145 tevent_req_received(req);
2146 return NT_STATUS_OK;
2149 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2154 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2156 const void *_struct_ptr,
2157 const struct ndr_interface_call *call)
2159 void *struct_ptr = discard_const(_struct_ptr);
2161 if (DEBUGLEVEL < 10) {
2165 if (ndr_flags & NDR_IN) {
2166 ndr_print_function_debug(call->ndr_print,
2171 if (ndr_flags & NDR_OUT) {
2172 ndr_print_function_debug(call->ndr_print,
2179 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2181 .is_connected = rpccli_bh_is_connected,
2182 .set_timeout = rpccli_bh_set_timeout,
2183 .raw_call_send = rpccli_bh_raw_call_send,
2184 .raw_call_recv = rpccli_bh_raw_call_recv,
2185 .disconnect_send = rpccli_bh_disconnect_send,
2186 .disconnect_recv = rpccli_bh_disconnect_recv,
2188 .ref_alloc = rpccli_bh_ref_alloc,
2189 .do_ndr_print = rpccli_bh_do_ndr_print,
2192 /* initialise a rpc_pipe_client binding handle */
2193 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2195 struct dcerpc_binding_handle *h;
2196 struct rpccli_bh_state *hs;
2198 h = dcerpc_binding_handle_create(c,
2203 struct rpccli_bh_state,
2213 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2215 struct auth_ntlmssp_state *a = NULL;
2216 struct cli_state *cli;
2218 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2219 a = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2220 struct auth_ntlmssp_state);
2221 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2222 struct spnego_context *spnego_ctx;
2223 enum spnego_mech auth_type;
2227 spnego_ctx = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2228 struct spnego_context);
2229 status = spnego_get_negotiated_mech(spnego_ctx,
2230 &auth_type, &auth_ctx);
2231 if (!NT_STATUS_IS_OK(status)) {
2235 if (auth_type == SPNEGO_NTLMSSP) {
2236 a = talloc_get_type_abort(auth_ctx,
2237 struct auth_ntlmssp_state);
2242 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2246 cli = rpc_pipe_np_smb_conn(rpc_cli);
2250 E_md4hash(cli->password ? cli->password : "", nt_hash);
2254 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2255 struct pipe_auth_data **presult)
2257 struct pipe_auth_data *result;
2259 result = talloc(mem_ctx, struct pipe_auth_data);
2260 if (result == NULL) {
2261 return NT_STATUS_NO_MEMORY;
2264 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2265 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2267 result->user_name = talloc_strdup(result, "");
2268 result->domain = talloc_strdup(result, "");
2269 if ((result->user_name == NULL) || (result->domain == NULL)) {
2270 TALLOC_FREE(result);
2271 return NT_STATUS_NO_MEMORY;
2275 return NT_STATUS_OK;
2278 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2279 struct pipe_auth_data **presult)
2281 struct pipe_auth_data *result;
2283 result = talloc(mem_ctx, struct pipe_auth_data);
2284 if (result == NULL) {
2285 return NT_STATUS_NO_MEMORY;
2288 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2289 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2291 result->user_name = talloc_strdup(result, "");
2292 result->domain = talloc_strdup(result, "");
2293 if ((result->user_name == NULL) || (result->domain == NULL)) {
2294 TALLOC_FREE(result);
2295 return NT_STATUS_NO_MEMORY;
2299 return NT_STATUS_OK;
2302 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2304 TALLOC_FREE(auth->auth_ctx);
2308 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2309 enum dcerpc_AuthType auth_type,
2310 enum dcerpc_AuthLevel auth_level,
2312 const char *username,
2313 const char *password,
2314 struct pipe_auth_data **presult)
2316 struct auth_ntlmssp_state *ntlmssp_ctx;
2317 struct pipe_auth_data *result;
2320 result = talloc(mem_ctx, struct pipe_auth_data);
2321 if (result == NULL) {
2322 return NT_STATUS_NO_MEMORY;
2325 result->auth_type = auth_type;
2326 result->auth_level = auth_level;
2328 result->user_name = talloc_strdup(result, username);
2329 result->domain = talloc_strdup(result, domain);
2330 if ((result->user_name == NULL) || (result->domain == NULL)) {
2331 status = NT_STATUS_NO_MEMORY;
2335 status = auth_ntlmssp_client_start(NULL,
2338 lp_client_ntlmv2_auth(),
2340 if (!NT_STATUS_IS_OK(status)) {
2344 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2346 status = auth_ntlmssp_set_username(ntlmssp_ctx, username);
2347 if (!NT_STATUS_IS_OK(status)) {
2351 status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain);
2352 if (!NT_STATUS_IS_OK(status)) {
2356 status = auth_ntlmssp_set_password(ntlmssp_ctx, password);
2357 if (!NT_STATUS_IS_OK(status)) {
2362 * Turn off sign+seal to allow selected auth level to turn it back on.
2364 auth_ntlmssp_and_flags(ntlmssp_ctx, ~(NTLMSSP_NEGOTIATE_SIGN |
2365 NTLMSSP_NEGOTIATE_SEAL));
2367 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2368 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SIGN);
2369 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2370 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SEAL |
2371 NTLMSSP_NEGOTIATE_SIGN);
2374 result->auth_ctx = ntlmssp_ctx;
2376 return NT_STATUS_OK;
2379 TALLOC_FREE(result);
2383 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2384 enum dcerpc_AuthLevel auth_level,
2385 struct netlogon_creds_CredentialState *creds,
2386 struct pipe_auth_data **presult)
2388 struct schannel_state *schannel_auth;
2389 struct pipe_auth_data *result;
2391 result = talloc(mem_ctx, struct pipe_auth_data);
2392 if (result == NULL) {
2393 return NT_STATUS_NO_MEMORY;
2396 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2397 result->auth_level = auth_level;
2399 result->user_name = talloc_strdup(result, "");
2400 result->domain = talloc_strdup(result, domain);
2401 if ((result->user_name == NULL) || (result->domain == NULL)) {
2405 schannel_auth = talloc(result, struct schannel_state);
2406 if (schannel_auth == NULL) {
2410 schannel_auth->state = SCHANNEL_STATE_START;
2411 schannel_auth->seq_num = 0;
2412 schannel_auth->initiator = true;
2413 schannel_auth->creds = netlogon_creds_copy(result, creds);
2415 result->auth_ctx = schannel_auth;
2417 return NT_STATUS_OK;
2420 TALLOC_FREE(result);
2421 return NT_STATUS_NO_MEMORY;
2425 * Create an rpc pipe client struct, connecting to a tcp port.
2427 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2429 const struct ndr_syntax_id *abstract_syntax,
2430 struct rpc_pipe_client **presult)
2432 struct rpc_pipe_client *result;
2433 struct sockaddr_storage addr;
2437 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2438 if (result == NULL) {
2439 return NT_STATUS_NO_MEMORY;
2442 result->abstract_syntax = *abstract_syntax;
2443 result->transfer_syntax = ndr_transfer_syntax;
2445 result->desthost = talloc_strdup(result, host);
2446 result->srv_name_slash = talloc_asprintf_strupper_m(
2447 result, "\\\\%s", result->desthost);
2448 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2449 status = NT_STATUS_NO_MEMORY;
2453 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2454 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2456 if (!resolve_name(host, &addr, 0, false)) {
2457 status = NT_STATUS_NOT_FOUND;
2461 status = open_socket_out(&addr, port, 60, &fd);
2462 if (!NT_STATUS_IS_OK(status)) {
2465 set_socket_options(fd, lp_socket_options());
2467 status = rpc_transport_sock_init(result, fd, &result->transport);
2468 if (!NT_STATUS_IS_OK(status)) {
2473 result->transport->transport = NCACN_IP_TCP;
2475 result->binding_handle = rpccli_bh_create(result);
2476 if (result->binding_handle == NULL) {
2477 TALLOC_FREE(result);
2478 return NT_STATUS_NO_MEMORY;
2482 return NT_STATUS_OK;
2485 TALLOC_FREE(result);
2490 * Determine the tcp port on which a dcerpc interface is listening
2491 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2494 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2495 const struct ndr_syntax_id *abstract_syntax,
2499 struct rpc_pipe_client *epm_pipe = NULL;
2500 struct dcerpc_binding_handle *epm_handle = NULL;
2501 struct pipe_auth_data *auth = NULL;
2502 struct dcerpc_binding *map_binding = NULL;
2503 struct dcerpc_binding *res_binding = NULL;
2504 struct epm_twr_t *map_tower = NULL;
2505 struct epm_twr_t *res_towers = NULL;
2506 struct policy_handle *entry_handle = NULL;
2507 uint32_t num_towers = 0;
2508 uint32_t max_towers = 1;
2509 struct epm_twr_p_t towers;
2510 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2511 uint32_t result = 0;
2513 if (pport == NULL) {
2514 status = NT_STATUS_INVALID_PARAMETER;
2518 if (ndr_syntax_id_equal(abstract_syntax,
2519 &ndr_table_epmapper.syntax_id)) {
2521 return NT_STATUS_OK;
2524 /* open the connection to the endpoint mapper */
2525 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2526 &ndr_table_epmapper.syntax_id,
2529 if (!NT_STATUS_IS_OK(status)) {
2532 epm_handle = epm_pipe->binding_handle;
2534 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2535 if (!NT_STATUS_IS_OK(status)) {
2539 status = rpc_pipe_bind(epm_pipe, auth);
2540 if (!NT_STATUS_IS_OK(status)) {
2544 /* create tower for asking the epmapper */
2546 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2547 if (map_binding == NULL) {
2548 status = NT_STATUS_NO_MEMORY;
2552 map_binding->transport = NCACN_IP_TCP;
2553 map_binding->object = *abstract_syntax;
2554 map_binding->host = host; /* needed? */
2555 map_binding->endpoint = "0"; /* correct? needed? */
2557 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2558 if (map_tower == NULL) {
2559 status = NT_STATUS_NO_MEMORY;
2563 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2564 &(map_tower->tower));
2565 if (!NT_STATUS_IS_OK(status)) {
2569 /* allocate further parameters for the epm_Map call */
2571 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2572 if (res_towers == NULL) {
2573 status = NT_STATUS_NO_MEMORY;
2576 towers.twr = res_towers;
2578 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2579 if (entry_handle == NULL) {
2580 status = NT_STATUS_NO_MEMORY;
2584 /* ask the endpoint mapper for the port */
2586 status = dcerpc_epm_Map(epm_handle,
2588 CONST_DISCARD(struct GUID *,
2589 &(abstract_syntax->uuid)),
2597 if (!NT_STATUS_IS_OK(status)) {
2601 if (result != EPMAPPER_STATUS_OK) {
2602 status = NT_STATUS_UNSUCCESSFUL;
2606 if (num_towers != 1) {
2607 status = NT_STATUS_UNSUCCESSFUL;
2611 /* extract the port from the answer */
2613 status = dcerpc_binding_from_tower(tmp_ctx,
2614 &(towers.twr->tower),
2616 if (!NT_STATUS_IS_OK(status)) {
2620 /* are further checks here necessary? */
2621 if (res_binding->transport != NCACN_IP_TCP) {
2622 status = NT_STATUS_UNSUCCESSFUL;
2626 *pport = (uint16_t)atoi(res_binding->endpoint);
2629 TALLOC_FREE(tmp_ctx);
2634 * Create a rpc pipe client struct, connecting to a host via tcp.
2635 * The port is determined by asking the endpoint mapper on the given
2638 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2639 const struct ndr_syntax_id *abstract_syntax,
2640 struct rpc_pipe_client **presult)
2645 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2646 if (!NT_STATUS_IS_OK(status)) {
2650 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2651 abstract_syntax, presult);
2654 /********************************************************************
2655 Create a rpc pipe client struct, connecting to a unix domain socket
2656 ********************************************************************/
2657 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2658 const struct ndr_syntax_id *abstract_syntax,
2659 struct rpc_pipe_client **presult)
2661 struct rpc_pipe_client *result;
2662 struct sockaddr_un addr;
2666 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2667 if (result == NULL) {
2668 return NT_STATUS_NO_MEMORY;
2671 result->abstract_syntax = *abstract_syntax;
2672 result->transfer_syntax = ndr_transfer_syntax;
2674 result->desthost = get_myname(result);
2675 result->srv_name_slash = talloc_asprintf_strupper_m(
2676 result, "\\\\%s", result->desthost);
2677 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2678 status = NT_STATUS_NO_MEMORY;
2682 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2683 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2685 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2687 status = map_nt_error_from_unix(errno);
2692 addr.sun_family = AF_UNIX;
2693 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2695 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2696 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2699 return map_nt_error_from_unix(errno);
2702 status = rpc_transport_sock_init(result, fd, &result->transport);
2703 if (!NT_STATUS_IS_OK(status)) {
2708 result->transport->transport = NCALRPC;
2710 result->binding_handle = rpccli_bh_create(result);
2711 if (result->binding_handle == NULL) {
2712 TALLOC_FREE(result);
2713 return NT_STATUS_NO_MEMORY;
2717 return NT_STATUS_OK;
2720 TALLOC_FREE(result);
2724 struct rpc_pipe_client_np_ref {
2725 struct cli_state *cli;
2726 struct rpc_pipe_client *pipe;
2729 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2731 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2735 /****************************************************************************
2736 Open a named pipe over SMB to a remote server.
2738 * CAVEAT CALLER OF THIS FUNCTION:
2739 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2740 * so be sure that this function is called AFTER any structure (vs pointer)
2741 * assignment of the cli. In particular, libsmbclient does structure
2742 * assignments of cli, which invalidates the data in the returned
2743 * rpc_pipe_client if this function is called before the structure assignment
2746 ****************************************************************************/
2748 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2749 const struct ndr_syntax_id *abstract_syntax,
2750 struct rpc_pipe_client **presult)
2752 struct rpc_pipe_client *result;
2754 struct rpc_pipe_client_np_ref *np_ref;
2756 /* sanity check to protect against crashes */
2759 return NT_STATUS_INVALID_HANDLE;
2762 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2763 if (result == NULL) {
2764 return NT_STATUS_NO_MEMORY;
2767 result->abstract_syntax = *abstract_syntax;
2768 result->transfer_syntax = ndr_transfer_syntax;
2769 result->desthost = talloc_strdup(result, cli->desthost);
2770 result->srv_name_slash = talloc_asprintf_strupper_m(
2771 result, "\\\\%s", result->desthost);
2773 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2774 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2776 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2777 TALLOC_FREE(result);
2778 return NT_STATUS_NO_MEMORY;
2781 status = rpc_transport_np_init(result, cli, abstract_syntax,
2782 &result->transport);
2783 if (!NT_STATUS_IS_OK(status)) {
2784 TALLOC_FREE(result);
2788 result->transport->transport = NCACN_NP;
2790 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2791 if (np_ref == NULL) {
2792 TALLOC_FREE(result);
2793 return NT_STATUS_NO_MEMORY;
2796 np_ref->pipe = result;
2798 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2799 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2801 result->binding_handle = rpccli_bh_create(result);
2802 if (result->binding_handle == NULL) {
2803 TALLOC_FREE(result);
2804 return NT_STATUS_NO_MEMORY;
2808 return NT_STATUS_OK;
2811 /****************************************************************************
2812 Open a pipe to a remote server.
2813 ****************************************************************************/
2815 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2816 enum dcerpc_transport_t transport,
2817 const struct ndr_syntax_id *interface,
2818 struct rpc_pipe_client **presult)
2820 switch (transport) {
2822 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2825 return rpc_pipe_open_np(cli, interface, presult);
2827 return NT_STATUS_NOT_IMPLEMENTED;
2831 /****************************************************************************
2832 Open a named pipe to an SMB server and bind anonymously.
2833 ****************************************************************************/
2835 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2836 enum dcerpc_transport_t transport,
2837 const struct ndr_syntax_id *interface,
2838 struct rpc_pipe_client **presult)
2840 struct rpc_pipe_client *result;
2841 struct pipe_auth_data *auth;
2844 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2845 if (!NT_STATUS_IS_OK(status)) {
2849 status = rpccli_anon_bind_data(result, &auth);
2850 if (!NT_STATUS_IS_OK(status)) {
2851 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2852 nt_errstr(status)));
2853 TALLOC_FREE(result);
2858 * This is a bit of an abstraction violation due to the fact that an
2859 * anonymous bind on an authenticated SMB inherits the user/domain
2860 * from the enclosing SMB creds
2863 TALLOC_FREE(auth->user_name);
2864 TALLOC_FREE(auth->domain);
2866 auth->user_name = talloc_strdup(auth, cli->user_name);
2867 auth->domain = talloc_strdup(auth, cli->domain);
2868 auth->user_session_key = data_blob_talloc(auth,
2869 cli->user_session_key.data,
2870 cli->user_session_key.length);
2872 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2873 TALLOC_FREE(result);
2874 return NT_STATUS_NO_MEMORY;
2877 status = rpc_pipe_bind(result, auth);
2878 if (!NT_STATUS_IS_OK(status)) {
2880 if (ndr_syntax_id_equal(interface,
2881 &ndr_table_dssetup.syntax_id)) {
2882 /* non AD domains just don't have this pipe, avoid
2883 * level 0 statement in that case - gd */
2886 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2887 "%s failed with error %s\n",
2888 get_pipe_name_from_syntax(talloc_tos(), interface),
2889 nt_errstr(status) ));
2890 TALLOC_FREE(result);
2894 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2895 "%s and bound anonymously.\n",
2896 get_pipe_name_from_syntax(talloc_tos(), interface),
2900 return NT_STATUS_OK;
2903 /****************************************************************************
2904 ****************************************************************************/
2906 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2907 const struct ndr_syntax_id *interface,
2908 struct rpc_pipe_client **presult)
2910 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2911 interface, presult);
2914 /****************************************************************************
2915 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2916 ****************************************************************************/
2918 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2919 const struct ndr_syntax_id *interface,
2920 enum dcerpc_transport_t transport,
2921 enum dcerpc_AuthLevel auth_level,
2923 const char *username,
2924 const char *password,
2925 struct rpc_pipe_client **presult)
2927 struct rpc_pipe_client *result;
2928 struct pipe_auth_data *auth = NULL;
2929 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2932 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2933 if (!NT_STATUS_IS_OK(status)) {
2937 status = rpccli_ntlmssp_bind_data(result,
2938 auth_type, auth_level,
2939 domain, username, password,
2941 if (!NT_STATUS_IS_OK(status)) {
2942 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2943 nt_errstr(status)));
2947 status = rpc_pipe_bind(result, auth);
2948 if (!NT_STATUS_IS_OK(status)) {
2949 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2950 nt_errstr(status) ));
2954 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2955 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2956 get_pipe_name_from_syntax(talloc_tos(), interface),
2957 cli->desthost, domain, username ));
2960 return NT_STATUS_OK;
2964 TALLOC_FREE(result);
2968 /****************************************************************************
2970 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2971 using session_key. sign and seal.
2973 The *pdc will be stolen onto this new pipe
2974 ****************************************************************************/
2976 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2977 const struct ndr_syntax_id *interface,
2978 enum dcerpc_transport_t transport,
2979 enum dcerpc_AuthLevel auth_level,
2981 struct netlogon_creds_CredentialState **pdc,
2982 struct rpc_pipe_client **presult)
2984 struct rpc_pipe_client *result;
2985 struct pipe_auth_data *auth;
2988 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2989 if (!NT_STATUS_IS_OK(status)) {
2993 status = rpccli_schannel_bind_data(result, domain, auth_level,
2995 if (!NT_STATUS_IS_OK(status)) {
2996 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2997 nt_errstr(status)));
2998 TALLOC_FREE(result);
3002 status = rpc_pipe_bind(result, auth);
3003 if (!NT_STATUS_IS_OK(status)) {
3004 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3005 "cli_rpc_pipe_bind failed with error %s\n",
3006 nt_errstr(status) ));
3007 TALLOC_FREE(result);
3012 * The credentials on a new netlogon pipe are the ones we are passed
3013 * in - copy them over
3015 result->dc = netlogon_creds_copy(result, *pdc);
3016 if (result->dc == NULL) {
3017 TALLOC_FREE(result);
3018 return NT_STATUS_NO_MEMORY;
3021 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3022 "for domain %s and bound using schannel.\n",
3023 get_pipe_name_from_syntax(talloc_tos(), interface),
3024 cli->desthost, domain ));
3027 return NT_STATUS_OK;
3030 /****************************************************************************
3031 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3032 The idea is this can be called with service_princ, username and password all
3033 NULL so long as the caller has a TGT.
3034 ****************************************************************************/
3036 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3037 const struct ndr_syntax_id *interface,
3038 enum dcerpc_transport_t transport,
3039 enum dcerpc_AuthLevel auth_level,
3041 const char *username,
3042 const char *password,
3043 struct rpc_pipe_client **presult)
3045 struct rpc_pipe_client *result;
3046 struct pipe_auth_data *auth;
3047 struct gse_context *gse_ctx;
3050 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3051 if (!NT_STATUS_IS_OK(status)) {
3055 auth = talloc(result, struct pipe_auth_data);
3057 status = NT_STATUS_NO_MEMORY;
3060 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3061 auth->auth_level = auth_level;
3066 auth->user_name = talloc_strdup(auth, username);
3067 if (!auth->user_name) {
3068 status = NT_STATUS_NO_MEMORY;
3072 /* Fixme, should we fetch/set the Realm ? */
3073 auth->domain = talloc_strdup(auth, "");
3074 if (!auth->domain) {
3075 status = NT_STATUS_NO_MEMORY;
3079 status = gse_init_client(auth,
3080 (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
3081 (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
3082 NULL, server, "cifs", username, password,
3083 GSS_C_DCE_STYLE, &gse_ctx);
3084 if (!NT_STATUS_IS_OK(status)) {
3085 DEBUG(0, ("gse_init_client returned %s\n",
3086 nt_errstr(status)));
3089 auth->auth_ctx = gse_ctx;
3091 status = rpc_pipe_bind(result, auth);
3092 if (!NT_STATUS_IS_OK(status)) {
3093 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3094 nt_errstr(status)));
3099 return NT_STATUS_OK;
3102 TALLOC_FREE(result);
3106 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3107 const struct ndr_syntax_id *interface,
3108 enum dcerpc_transport_t transport,
3109 enum dcerpc_AuthLevel auth_level,
3111 const char *username,
3112 const char *password,
3113 struct rpc_pipe_client **presult)
3115 struct rpc_pipe_client *result;
3116 struct pipe_auth_data *auth;
3117 struct spnego_context *spnego_ctx;
3120 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3121 if (!NT_STATUS_IS_OK(status)) {
3125 auth = talloc(result, struct pipe_auth_data);
3127 status = NT_STATUS_NO_MEMORY;
3130 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3131 auth->auth_level = auth_level;
3136 auth->user_name = talloc_strdup(auth, username);
3137 if (!auth->user_name) {
3138 status = NT_STATUS_NO_MEMORY;
3142 /* Fixme, should we fetch/set the Realm ? */
3143 auth->domain = talloc_strdup(auth, "");
3144 if (!auth->domain) {
3145 status = NT_STATUS_NO_MEMORY;
3149 status = spnego_gssapi_init_client(auth,
3150 (auth->auth_level ==
3151 DCERPC_AUTH_LEVEL_INTEGRITY),
3152 (auth->auth_level ==
3153 DCERPC_AUTH_LEVEL_PRIVACY),
3155 NULL, server, "cifs",
3158 if (!NT_STATUS_IS_OK(status)) {
3159 DEBUG(0, ("spnego_init_client returned %s\n",
3160 nt_errstr(status)));
3163 auth->auth_ctx = spnego_ctx;
3165 status = rpc_pipe_bind(result, auth);
3166 if (!NT_STATUS_IS_OK(status)) {
3167 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3168 nt_errstr(status)));
3173 return NT_STATUS_OK;
3176 TALLOC_FREE(result);
3180 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3181 const struct ndr_syntax_id *interface,
3182 enum dcerpc_transport_t transport,
3183 enum dcerpc_AuthLevel auth_level,
3185 const char *username,
3186 const char *password,
3187 struct rpc_pipe_client **presult)
3189 struct rpc_pipe_client *result;
3190 struct pipe_auth_data *auth;
3191 struct spnego_context *spnego_ctx;
3194 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3195 if (!NT_STATUS_IS_OK(status)) {
3199 auth = talloc(result, struct pipe_auth_data);
3201 status = NT_STATUS_NO_MEMORY;
3204 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3205 auth->auth_level = auth_level;
3210 auth->user_name = talloc_strdup(auth, username);
3211 if (!auth->user_name) {
3212 status = NT_STATUS_NO_MEMORY;
3219 auth->domain = talloc_strdup(auth, domain);
3220 if (!auth->domain) {
3221 status = NT_STATUS_NO_MEMORY;
3225 status = spnego_ntlmssp_init_client(auth,
3226 (auth->auth_level ==
3227 DCERPC_AUTH_LEVEL_INTEGRITY),
3228 (auth->auth_level ==
3229 DCERPC_AUTH_LEVEL_PRIVACY),
3231 domain, username, password,
3233 if (!NT_STATUS_IS_OK(status)) {
3234 DEBUG(0, ("spnego_init_client returned %s\n",
3235 nt_errstr(status)));
3238 auth->auth_ctx = spnego_ctx;
3240 status = rpc_pipe_bind(result, auth);
3241 if (!NT_STATUS_IS_OK(status)) {
3242 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3243 nt_errstr(status)));
3248 return NT_STATUS_OK;
3251 TALLOC_FREE(result);
3255 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3256 struct rpc_pipe_client *cli,
3257 DATA_BLOB *session_key)
3259 struct pipe_auth_data *a;
3260 struct schannel_state *schannel_auth;
3261 struct auth_ntlmssp_state *ntlmssp_ctx;
3262 struct spnego_context *spnego_ctx;
3263 struct gse_context *gse_ctx;
3264 DATA_BLOB sk = data_blob_null;
3265 bool make_dup = false;
3267 if (!session_key || !cli) {
3268 return NT_STATUS_INVALID_PARAMETER;
3274 return NT_STATUS_INVALID_PARAMETER;
3277 switch (cli->auth->auth_type) {
3278 case DCERPC_AUTH_TYPE_SCHANNEL:
3279 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3280 struct schannel_state);
3281 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3284 case DCERPC_AUTH_TYPE_SPNEGO:
3285 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
3286 struct spnego_context);
3287 sk = spnego_get_session_key(mem_ctx, spnego_ctx);
3290 case DCERPC_AUTH_TYPE_NTLMSSP:
3291 ntlmssp_ctx = talloc_get_type_abort(a->auth_ctx,
3292 struct auth_ntlmssp_state);
3293 sk = auth_ntlmssp_get_session_key(ntlmssp_ctx);
3296 case DCERPC_AUTH_TYPE_KRB5:
3297 gse_ctx = talloc_get_type_abort(a->auth_ctx,
3298 struct gse_context);
3299 sk = gse_get_session_key(mem_ctx, gse_ctx);
3302 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3303 case DCERPC_AUTH_TYPE_NONE:
3304 sk = data_blob_const(a->user_session_key.data,
3305 a->user_session_key.length);
3313 return NT_STATUS_NO_USER_SESSION_KEY;
3317 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3322 return NT_STATUS_OK;