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_schannel.h"
26 #include "../librpc/gen_ndr/ndr_dssetup.h"
27 #include "../libcli/auth/schannel.h"
28 #include "../libcli/auth/spnego.h"
29 #include "../auth/ntlmssp/ntlmssp.h"
30 #include "auth_generic.h"
31 #include "librpc/gen_ndr/ndr_dcerpc.h"
32 #include "librpc/rpc/dcerpc.h"
33 #include "librpc/crypto/spnego.h"
36 #include "libsmb/libsmb.h"
37 #include "auth/gensec/gensec.h"
40 #define DBGC_CLASS DBGC_RPC_CLI
42 /********************************************************************
43 Pipe description for a DEBUG
44 ********************************************************************/
45 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
46 struct rpc_pipe_client *cli)
48 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
55 /********************************************************************
57 ********************************************************************/
59 static uint32 get_rpc_call_id(void)
61 static uint32 call_id = 0;
65 /*******************************************************************
66 Use SMBreadX to get rest of one fragment's worth of rpc data.
67 Reads the whole size or give an error message
68 ********************************************************************/
70 struct rpc_read_state {
71 struct event_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 event_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 event_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 event_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 event_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 event_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);
287 * Ensure we have frag_len bytes of data.
289 if (received < state->frag_len) {
290 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
291 status = NT_STATUS_NO_MEMORY;
294 subreq = rpc_read_send(state, state->ev,
295 state->cli->transport,
296 pdu->data + received,
297 state->frag_len - received);
298 if (subreq == NULL) {
299 status = NT_STATUS_NO_MEMORY;
302 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
307 status = NT_STATUS_OK;
309 if (NT_STATUS_IS_OK(status)) {
310 tevent_req_done(req);
312 tevent_req_nterror(req, status);
314 return tevent_req_post(req, ev);
317 static void get_complete_frag_got_header(struct tevent_req *subreq)
319 struct tevent_req *req = tevent_req_callback_data(
320 subreq, struct tevent_req);
321 struct get_complete_frag_state *state = tevent_req_data(
322 req, struct get_complete_frag_state);
325 status = rpc_read_recv(subreq);
327 if (!NT_STATUS_IS_OK(status)) {
328 tevent_req_nterror(req, status);
332 state->frag_len = dcerpc_get_frag_length(state->pdu);
334 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
335 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
340 * We're here in this piece of code because we've read exactly
341 * RPC_HEADER_LEN bytes into state->pdu.
344 subreq = rpc_read_send(state, state->ev, state->cli->transport,
345 state->pdu->data + RPC_HEADER_LEN,
346 state->frag_len - RPC_HEADER_LEN);
347 if (tevent_req_nomem(subreq, req)) {
350 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
353 static void get_complete_frag_got_rest(struct tevent_req *subreq)
355 struct tevent_req *req = tevent_req_callback_data(
356 subreq, struct tevent_req);
359 status = rpc_read_recv(subreq);
361 if (!NT_STATUS_IS_OK(status)) {
362 tevent_req_nterror(req, status);
365 tevent_req_done(req);
368 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
370 return tevent_req_simple_recv_ntstatus(req);
373 /****************************************************************************
374 Do basic authentication checks on an incoming pdu.
375 ****************************************************************************/
377 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
378 struct rpc_pipe_client *cli,
379 struct ncacn_packet *pkt,
381 uint8_t expected_pkt_type,
383 DATA_BLOB *reply_pdu)
385 struct dcerpc_response *r;
386 NTSTATUS ret = NT_STATUS_OK;
390 * Point the return values at the real data including the RPC
391 * header. Just in case the caller wants it.
395 /* Ensure we have the correct type. */
396 switch (pkt->ptype) {
397 case DCERPC_PKT_ALTER_RESP:
398 case DCERPC_PKT_BIND_ACK:
400 /* Client code never receives this kind of packets */
404 case DCERPC_PKT_RESPONSE:
406 r = &pkt->u.response;
408 /* Here's where we deal with incoming sign/seal. */
409 ret = dcerpc_check_auth(cli->auth, pkt,
410 &r->stub_and_verifier,
411 DCERPC_RESPONSE_LENGTH,
413 if (!NT_STATUS_IS_OK(ret)) {
417 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
418 return NT_STATUS_BUFFER_TOO_SMALL;
421 /* Point the return values at the NDR data. */
422 rdata->data = r->stub_and_verifier.data;
424 if (pkt->auth_length) {
425 /* We've already done integer wrap tests in
426 * dcerpc_check_auth(). */
427 rdata->length = r->stub_and_verifier.length
429 - DCERPC_AUTH_TRAILER_LENGTH
432 rdata->length = r->stub_and_verifier.length;
435 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
436 (long unsigned int)pdu->length,
437 (long unsigned int)rdata->length,
438 (unsigned int)pad_len));
441 * If this is the first reply, and the allocation hint is
442 * reasonable, try and set up the reply_pdu DATA_BLOB to the
446 if ((reply_pdu->length == 0) &&
447 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
448 if (!data_blob_realloc(mem_ctx, reply_pdu,
450 DEBUG(0, ("reply alloc hint %d too "
451 "large to allocate\n",
452 (int)r->alloc_hint));
453 return NT_STATUS_NO_MEMORY;
459 case DCERPC_PKT_BIND_NAK:
460 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
461 rpccli_pipe_txt(talloc_tos(), cli)));
462 /* Use this for now... */
463 return NT_STATUS_NETWORK_ACCESS_DENIED;
465 case DCERPC_PKT_FAULT:
467 DEBUG(1, (__location__ ": RPC fault code %s received "
469 dcerpc_errstr(talloc_tos(),
470 pkt->u.fault.status),
471 rpccli_pipe_txt(talloc_tos(), cli)));
473 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
476 DEBUG(0, (__location__ "Unknown packet type %u received "
478 (unsigned int)pkt->ptype,
479 rpccli_pipe_txt(talloc_tos(), cli)));
480 return NT_STATUS_INVALID_INFO_CLASS;
483 if (pkt->ptype != expected_pkt_type) {
484 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
485 "RPC packet type - %u, not %u\n",
486 rpccli_pipe_txt(talloc_tos(), cli),
487 pkt->ptype, expected_pkt_type));
488 return NT_STATUS_INVALID_INFO_CLASS;
491 /* Do this just before return - we don't want to modify any rpc header
492 data before now as we may have needed to do cryptographic actions on
495 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
496 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
497 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
498 "fragment first/last ON.\n"));
499 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
505 /****************************************************************************
506 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
507 ****************************************************************************/
509 struct cli_api_pipe_state {
510 struct event_context *ev;
511 struct rpc_cli_transport *transport;
516 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
517 static void cli_api_pipe_write_done(struct tevent_req *subreq);
518 static void cli_api_pipe_read_done(struct tevent_req *subreq);
520 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
521 struct event_context *ev,
522 struct rpc_cli_transport *transport,
523 uint8_t *data, size_t data_len,
524 uint32_t max_rdata_len)
526 struct tevent_req *req, *subreq;
527 struct cli_api_pipe_state *state;
530 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
535 state->transport = transport;
537 if (max_rdata_len < RPC_HEADER_LEN) {
539 * For a RPC reply we always need at least RPC_HEADER_LEN
540 * bytes. We check this here because we will receive
541 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
543 status = NT_STATUS_INVALID_PARAMETER;
547 if (transport->trans_send != NULL) {
548 subreq = transport->trans_send(state, ev, data, data_len,
549 max_rdata_len, transport->priv);
550 if (subreq == NULL) {
553 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
558 * If the transport does not provide a "trans" routine, i.e. for
559 * example the ncacn_ip_tcp transport, do the write/read step here.
562 subreq = rpc_write_send(state, ev, transport, data, data_len);
563 if (subreq == NULL) {
566 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
570 tevent_req_nterror(req, status);
571 return tevent_req_post(req, ev);
577 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
579 struct tevent_req *req = tevent_req_callback_data(
580 subreq, struct tevent_req);
581 struct cli_api_pipe_state *state = tevent_req_data(
582 req, struct cli_api_pipe_state);
585 status = state->transport->trans_recv(subreq, state, &state->rdata,
588 if (!NT_STATUS_IS_OK(status)) {
589 tevent_req_nterror(req, status);
592 tevent_req_done(req);
595 static void cli_api_pipe_write_done(struct tevent_req *subreq)
597 struct tevent_req *req = tevent_req_callback_data(
598 subreq, struct tevent_req);
599 struct cli_api_pipe_state *state = tevent_req_data(
600 req, struct cli_api_pipe_state);
603 status = rpc_write_recv(subreq);
605 if (!NT_STATUS_IS_OK(status)) {
606 tevent_req_nterror(req, status);
610 state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
611 if (tevent_req_nomem(state->rdata, req)) {
616 * We don't need to use rpc_read_send here, the upper layer will cope
617 * with a short read, transport->trans_send could also return less
618 * than state->max_rdata_len.
620 subreq = state->transport->read_send(state, state->ev, state->rdata,
622 state->transport->priv);
623 if (tevent_req_nomem(subreq, req)) {
626 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
629 static void cli_api_pipe_read_done(struct tevent_req *subreq)
631 struct tevent_req *req = tevent_req_callback_data(
632 subreq, struct tevent_req);
633 struct cli_api_pipe_state *state = tevent_req_data(
634 req, struct cli_api_pipe_state);
638 status = state->transport->read_recv(subreq, &received);
640 if (!NT_STATUS_IS_OK(status)) {
641 tevent_req_nterror(req, status);
644 state->rdata_len = received;
645 tevent_req_done(req);
648 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
649 uint8_t **prdata, uint32_t *prdata_len)
651 struct cli_api_pipe_state *state = tevent_req_data(
652 req, struct cli_api_pipe_state);
655 if (tevent_req_is_nterror(req, &status)) {
659 *prdata = talloc_move(mem_ctx, &state->rdata);
660 *prdata_len = state->rdata_len;
664 /****************************************************************************
665 Send data on an rpc pipe via trans. The data must be the last
666 pdu fragment of an NDR data stream.
668 Receive response data from an rpc pipe, which may be large...
670 Read the first fragment: unfortunately have to use SMBtrans for the first
671 bit, then SMBreadX for subsequent bits.
673 If first fragment received also wasn't the last fragment, continue
674 getting fragments until we _do_ receive the last fragment.
676 Request/Response PDU's look like the following...
678 |<------------------PDU len----------------------------------------------->|
679 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
681 +------------+-----------------+-------------+---------------+-------------+
682 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
683 +------------+-----------------+-------------+---------------+-------------+
685 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
686 signing & sealing being negotiated.
688 ****************************************************************************/
690 struct rpc_api_pipe_state {
691 struct event_context *ev;
692 struct rpc_pipe_client *cli;
693 uint8_t expected_pkt_type;
695 DATA_BLOB incoming_frag;
696 struct ncacn_packet *pkt;
700 size_t reply_pdu_offset;
704 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
705 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
706 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
708 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
709 struct event_context *ev,
710 struct rpc_pipe_client *cli,
711 DATA_BLOB *data, /* Outgoing PDU */
712 uint8_t expected_pkt_type)
714 struct tevent_req *req, *subreq;
715 struct rpc_api_pipe_state *state;
716 uint16_t max_recv_frag;
719 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
725 state->expected_pkt_type = expected_pkt_type;
726 state->incoming_frag = data_blob_null;
727 state->reply_pdu = data_blob_null;
728 state->reply_pdu_offset = 0;
729 state->endianess = DCERPC_DREP_LE;
732 * Ensure we're not sending too much.
734 if (data->length > cli->max_xmit_frag) {
735 status = NT_STATUS_INVALID_PARAMETER;
739 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
741 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
742 subreq = rpc_write_send(state, ev, cli->transport,
743 data->data, data->length);
744 if (subreq == NULL) {
747 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
751 /* get the header first, then fetch the rest once we have
752 * the frag_length available */
753 max_recv_frag = RPC_HEADER_LEN;
755 subreq = cli_api_pipe_send(state, ev, cli->transport,
756 data->data, data->length, max_recv_frag);
757 if (subreq == NULL) {
760 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
764 tevent_req_nterror(req, status);
765 return tevent_req_post(req, ev);
771 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
773 struct tevent_req *req =
774 tevent_req_callback_data(subreq,
778 status = rpc_write_recv(subreq);
780 if (!NT_STATUS_IS_OK(status)) {
781 tevent_req_nterror(req, status);
785 tevent_req_done(req);
788 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
790 struct tevent_req *req = tevent_req_callback_data(
791 subreq, struct tevent_req);
792 struct rpc_api_pipe_state *state = tevent_req_data(
793 req, struct rpc_api_pipe_state);
795 uint8_t *rdata = NULL;
796 uint32_t rdata_len = 0;
798 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
800 if (!NT_STATUS_IS_OK(status)) {
801 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
802 tevent_req_nterror(req, status);
807 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
808 rpccli_pipe_txt(talloc_tos(), state->cli)));
809 tevent_req_done(req);
814 * Move data on state->incoming_frag.
816 state->incoming_frag.data = talloc_move(state, &rdata);
817 state->incoming_frag.length = rdata_len;
818 if (!state->incoming_frag.data) {
819 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
823 /* Ensure we have enough data for a pdu. */
824 subreq = get_complete_frag_send(state, state->ev, state->cli,
825 &state->incoming_frag);
826 if (tevent_req_nomem(subreq, req)) {
829 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
832 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
834 struct tevent_req *req = tevent_req_callback_data(
835 subreq, struct tevent_req);
836 struct rpc_api_pipe_state *state = tevent_req_data(
837 req, struct rpc_api_pipe_state);
839 DATA_BLOB rdata = data_blob_null;
841 status = get_complete_frag_recv(subreq);
843 if (!NT_STATUS_IS_OK(status)) {
844 DEBUG(5, ("get_complete_frag failed: %s\n",
846 tevent_req_nterror(req, status);
850 state->pkt = talloc(state, struct ncacn_packet);
852 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
856 status = dcerpc_pull_ncacn_packet(state->pkt,
857 &state->incoming_frag,
860 if (!NT_STATUS_IS_OK(status)) {
861 tevent_req_nterror(req, status);
865 if (state->incoming_frag.length != state->pkt->frag_length) {
866 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
867 (unsigned int)state->incoming_frag.length,
868 (unsigned int)state->pkt->frag_length));
869 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
873 status = cli_pipe_validate_current_pdu(state,
874 state->cli, state->pkt,
875 &state->incoming_frag,
876 state->expected_pkt_type,
880 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
881 (unsigned)state->incoming_frag.length,
882 (unsigned)state->reply_pdu_offset,
885 if (!NT_STATUS_IS_OK(status)) {
886 tevent_req_nterror(req, status);
890 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
891 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
893 * Set the data type correctly for big-endian data on the
896 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
898 rpccli_pipe_txt(talloc_tos(), state->cli)));
899 state->endianess = 0x00; /* BIG ENDIAN */
902 * Check endianness on subsequent packets.
904 if (state->endianess != state->pkt->drep[0]) {
905 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
907 state->endianess?"little":"big",
908 state->pkt->drep[0]?"little":"big"));
909 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
913 /* Now copy the data portion out of the pdu into rbuf. */
914 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
915 if (!data_blob_realloc(NULL, &state->reply_pdu,
916 state->reply_pdu_offset + rdata.length)) {
917 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
922 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
923 rdata.data, rdata.length);
924 state->reply_pdu_offset += rdata.length;
926 /* reset state->incoming_frag, there is no need to free it,
927 * it will be reallocated to the right size the next time
929 state->incoming_frag.length = 0;
931 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
932 /* make sure the pdu length is right now that we
933 * have all the data available (alloc hint may
934 * have allocated more than was actually used) */
935 state->reply_pdu.length = state->reply_pdu_offset;
936 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
937 rpccli_pipe_txt(talloc_tos(), state->cli),
938 (unsigned)state->reply_pdu.length));
939 tevent_req_done(req);
943 subreq = get_complete_frag_send(state, state->ev, state->cli,
944 &state->incoming_frag);
945 if (tevent_req_nomem(subreq, req)) {
948 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
951 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
952 struct ncacn_packet **pkt,
953 DATA_BLOB *reply_pdu)
955 struct rpc_api_pipe_state *state = tevent_req_data(
956 req, struct rpc_api_pipe_state);
959 if (tevent_req_is_nterror(req, &status)) {
963 /* return data to caller and assign it ownership of memory */
965 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
966 reply_pdu->length = state->reply_pdu.length;
967 state->reply_pdu.length = 0;
969 data_blob_free(&state->reply_pdu);
973 *pkt = talloc_steal(mem_ctx, state->pkt);
979 /*******************************************************************
980 Creates spnego auth bind.
981 ********************************************************************/
983 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
984 struct pipe_auth_data *auth,
985 DATA_BLOB *auth_token)
987 struct spnego_context *spnego_ctx;
988 DATA_BLOB in_token = data_blob_null;
991 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
992 struct spnego_context);
994 /* Negotiate the initial auth token */
995 status = spnego_get_client_auth_token(mem_ctx, spnego_ctx,
996 &in_token, auth_token);
997 if (!NT_STATUS_IS_OK(status)) {
1001 DEBUG(5, ("Created GSS Authentication Token:\n"));
1002 dump_data(5, auth_token->data, auth_token->length);
1004 return NT_STATUS_OK;
1007 /*******************************************************************
1008 Creates NTLMSSP auth bind.
1009 ********************************************************************/
1011 static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1012 TALLOC_CTX *mem_ctx,
1013 DATA_BLOB *auth_token)
1015 struct gensec_security *gensec_security;
1016 DATA_BLOB null_blob = data_blob_null;
1018 gensec_security = talloc_get_type_abort(cli->auth->auth_ctx,
1019 struct gensec_security);
1021 DEBUG(5, ("create_generic_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1022 return gensec_update(gensec_security, mem_ctx, NULL, null_blob, auth_token);
1025 /*******************************************************************
1026 Creates schannel auth bind.
1027 ********************************************************************/
1029 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1030 DATA_BLOB *auth_token)
1033 struct NL_AUTH_MESSAGE r;
1035 /* Use lp_workgroup() if domain not specified */
1037 if (!cli->auth->domain || !cli->auth->domain[0]) {
1038 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1039 if (cli->auth->domain == NULL) {
1040 return NT_STATUS_NO_MEMORY;
1045 * Now marshall the data into the auth parse_struct.
1048 r.MessageType = NL_NEGOTIATE_REQUEST;
1049 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1050 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1051 r.oem_netbios_domain.a = cli->auth->domain;
1052 r.oem_netbios_computer.a = lp_netbios_name();
1054 status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1055 if (!NT_STATUS_IS_OK(status)) {
1059 return NT_STATUS_OK;
1062 /*******************************************************************
1063 Creates the internals of a DCE/RPC bind request or alter context PDU.
1064 ********************************************************************/
1066 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1067 enum dcerpc_pkt_type ptype,
1069 const struct ndr_syntax_id *abstract,
1070 const struct ndr_syntax_id *transfer,
1071 const DATA_BLOB *auth_info,
1074 uint16 auth_len = auth_info->length;
1076 union dcerpc_payload u;
1077 struct dcerpc_ctx_list ctx_list;
1080 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1083 ctx_list.context_id = 0;
1084 ctx_list.num_transfer_syntaxes = 1;
1085 ctx_list.abstract_syntax = *abstract;
1086 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1088 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1089 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1090 u.bind.assoc_group_id = 0x0;
1091 u.bind.num_contexts = 1;
1092 u.bind.ctx_list = &ctx_list;
1093 u.bind.auth_info = *auth_info;
1095 status = dcerpc_push_ncacn_packet(mem_ctx,
1097 DCERPC_PFC_FLAG_FIRST |
1098 DCERPC_PFC_FLAG_LAST,
1103 if (!NT_STATUS_IS_OK(status)) {
1104 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1108 return NT_STATUS_OK;
1111 /*******************************************************************
1112 Creates a DCE/RPC bind request.
1113 ********************************************************************/
1115 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1116 struct rpc_pipe_client *cli,
1117 struct pipe_auth_data *auth,
1119 const struct ndr_syntax_id *abstract,
1120 const struct ndr_syntax_id *transfer,
1123 DATA_BLOB auth_token = data_blob_null;
1124 DATA_BLOB auth_info = data_blob_null;
1125 NTSTATUS ret = NT_STATUS_OK;
1127 switch (auth->auth_type) {
1128 case DCERPC_AUTH_TYPE_SCHANNEL:
1129 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1130 if (!NT_STATUS_IS_OK(ret)) {
1135 case DCERPC_AUTH_TYPE_NTLMSSP:
1136 case DCERPC_AUTH_TYPE_KRB5:
1137 ret = create_generic_auth_rpc_bind_req(cli, mem_ctx, &auth_token);
1139 if (!NT_STATUS_IS_OK(ret) &&
1140 !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1145 case DCERPC_AUTH_TYPE_SPNEGO:
1146 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1147 if (!NT_STATUS_IS_OK(ret)) {
1152 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1153 auth_token = data_blob_talloc(mem_ctx,
1154 "NCALRPC_AUTH_TOKEN",
1158 case DCERPC_AUTH_TYPE_NONE:
1162 /* "Can't" happen. */
1163 return NT_STATUS_INVALID_INFO_CLASS;
1166 if (auth_token.length != 0) {
1167 ret = dcerpc_push_dcerpc_auth(cli,
1170 0, /* auth_pad_length */
1171 1, /* auth_context_id */
1174 if (!NT_STATUS_IS_OK(ret)) {
1177 data_blob_free(&auth_token);
1180 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1190 /*******************************************************************
1192 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1193 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1194 and deals with signing/sealing details.
1195 ********************************************************************/
1197 struct rpc_api_pipe_req_state {
1198 struct event_context *ev;
1199 struct rpc_pipe_client *cli;
1202 DATA_BLOB *req_data;
1203 uint32_t req_data_sent;
1205 DATA_BLOB reply_pdu;
1208 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1209 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1210 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1211 bool *is_last_frag);
1213 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1214 struct event_context *ev,
1215 struct rpc_pipe_client *cli,
1217 DATA_BLOB *req_data)
1219 struct tevent_req *req, *subreq;
1220 struct rpc_api_pipe_req_state *state;
1224 req = tevent_req_create(mem_ctx, &state,
1225 struct rpc_api_pipe_req_state);
1231 state->op_num = op_num;
1232 state->req_data = req_data;
1233 state->req_data_sent = 0;
1234 state->call_id = get_rpc_call_id();
1235 state->reply_pdu = data_blob_null;
1236 state->rpc_out = data_blob_null;
1238 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1239 + RPC_MAX_SIGN_SIZE) {
1240 /* Server is screwed up ! */
1241 status = NT_STATUS_INVALID_PARAMETER;
1245 status = prepare_next_frag(state, &is_last_frag);
1246 if (!NT_STATUS_IS_OK(status)) {
1251 subreq = rpc_api_pipe_send(state, ev, state->cli,
1253 DCERPC_PKT_RESPONSE);
1254 if (subreq == NULL) {
1257 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1259 subreq = rpc_write_send(state, ev, cli->transport,
1260 state->rpc_out.data,
1261 state->rpc_out.length);
1262 if (subreq == NULL) {
1265 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1271 tevent_req_nterror(req, status);
1272 return tevent_req_post(req, ev);
1278 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1281 size_t data_sent_thistime;
1288 union dcerpc_payload u;
1290 data_left = state->req_data->length - state->req_data_sent;
1292 status = dcerpc_guess_sizes(state->cli->auth,
1293 DCERPC_REQUEST_LENGTH, data_left,
1294 state->cli->max_xmit_frag,
1295 CLIENT_NDR_PADDING_SIZE,
1296 &data_sent_thistime,
1297 &frag_len, &auth_len, &pad_len);
1298 if (!NT_STATUS_IS_OK(status)) {
1302 if (state->req_data_sent == 0) {
1303 flags = DCERPC_PFC_FLAG_FIRST;
1306 if (data_sent_thistime == data_left) {
1307 flags |= DCERPC_PFC_FLAG_LAST;
1310 data_blob_free(&state->rpc_out);
1312 ZERO_STRUCT(u.request);
1314 u.request.alloc_hint = state->req_data->length;
1315 u.request.context_id = 0;
1316 u.request.opnum = state->op_num;
1318 status = dcerpc_push_ncacn_packet(state,
1325 if (!NT_STATUS_IS_OK(status)) {
1329 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1330 * compute it right for requests because the auth trailer is missing
1332 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1334 /* Copy in the data. */
1335 if (!data_blob_append(NULL, &state->rpc_out,
1336 state->req_data->data + state->req_data_sent,
1337 data_sent_thistime)) {
1338 return NT_STATUS_NO_MEMORY;
1341 switch (state->cli->auth->auth_level) {
1342 case DCERPC_AUTH_LEVEL_NONE:
1343 case DCERPC_AUTH_LEVEL_CONNECT:
1344 case DCERPC_AUTH_LEVEL_PACKET:
1346 case DCERPC_AUTH_LEVEL_INTEGRITY:
1347 case DCERPC_AUTH_LEVEL_PRIVACY:
1348 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1350 if (!NT_STATUS_IS_OK(status)) {
1355 return NT_STATUS_INVALID_PARAMETER;
1358 state->req_data_sent += data_sent_thistime;
1359 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1364 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1366 struct tevent_req *req = tevent_req_callback_data(
1367 subreq, struct tevent_req);
1368 struct rpc_api_pipe_req_state *state = tevent_req_data(
1369 req, struct rpc_api_pipe_req_state);
1373 status = rpc_write_recv(subreq);
1374 TALLOC_FREE(subreq);
1375 if (!NT_STATUS_IS_OK(status)) {
1376 tevent_req_nterror(req, status);
1380 status = prepare_next_frag(state, &is_last_frag);
1381 if (!NT_STATUS_IS_OK(status)) {
1382 tevent_req_nterror(req, status);
1387 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1389 DCERPC_PKT_RESPONSE);
1390 if (tevent_req_nomem(subreq, req)) {
1393 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1395 subreq = rpc_write_send(state, state->ev,
1396 state->cli->transport,
1397 state->rpc_out.data,
1398 state->rpc_out.length);
1399 if (tevent_req_nomem(subreq, req)) {
1402 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1407 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1409 struct tevent_req *req = tevent_req_callback_data(
1410 subreq, struct tevent_req);
1411 struct rpc_api_pipe_req_state *state = tevent_req_data(
1412 req, struct rpc_api_pipe_req_state);
1415 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1416 TALLOC_FREE(subreq);
1417 if (!NT_STATUS_IS_OK(status)) {
1418 tevent_req_nterror(req, status);
1421 tevent_req_done(req);
1424 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1425 DATA_BLOB *reply_pdu)
1427 struct rpc_api_pipe_req_state *state = tevent_req_data(
1428 req, struct rpc_api_pipe_req_state);
1431 if (tevent_req_is_nterror(req, &status)) {
1433 * We always have to initialize to reply pdu, even if there is
1434 * none. The rpccli_* caller routines expect this.
1436 *reply_pdu = data_blob_null;
1440 /* return data to caller and assign it ownership of memory */
1441 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1442 reply_pdu->length = state->reply_pdu.length;
1443 state->reply_pdu.length = 0;
1445 return NT_STATUS_OK;
1448 /****************************************************************************
1449 Check the rpc bind acknowledge response.
1450 ****************************************************************************/
1452 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1453 const struct ndr_syntax_id *transfer)
1455 struct dcerpc_ack_ctx ctx;
1457 if (r->secondary_address_size == 0) {
1458 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1461 if (r->num_results < 1 || !r->ctx_list) {
1465 ctx = r->ctx_list[0];
1467 /* check the transfer syntax */
1468 if ((ctx.syntax.if_version != transfer->if_version) ||
1469 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1470 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1474 if (r->num_results != 0x1 || ctx.result != 0) {
1475 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1476 r->num_results, ctx.reason));
1479 DEBUG(5,("check_bind_response: accepted!\n"));
1483 /*******************************************************************
1484 Creates a DCE/RPC bind authentication response.
1485 This is the packet that is sent back to the server once we
1486 have received a BIND-ACK, to finish the third leg of
1487 the authentication handshake.
1488 ********************************************************************/
1490 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1491 struct rpc_pipe_client *cli,
1493 enum dcerpc_AuthType auth_type,
1494 enum dcerpc_AuthLevel auth_level,
1495 DATA_BLOB *pauth_blob,
1499 union dcerpc_payload u;
1503 status = dcerpc_push_dcerpc_auth(mem_ctx,
1506 0, /* auth_pad_length */
1507 1, /* auth_context_id */
1509 &u.auth3.auth_info);
1510 if (!NT_STATUS_IS_OK(status)) {
1514 status = dcerpc_push_ncacn_packet(mem_ctx,
1516 DCERPC_PFC_FLAG_FIRST |
1517 DCERPC_PFC_FLAG_LAST,
1522 data_blob_free(&u.auth3.auth_info);
1523 if (!NT_STATUS_IS_OK(status)) {
1524 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1528 return NT_STATUS_OK;
1531 /*******************************************************************
1532 Creates a DCE/RPC bind alter context authentication request which
1533 may contain a spnego auth blobl
1534 ********************************************************************/
1536 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1537 enum dcerpc_AuthType auth_type,
1538 enum dcerpc_AuthLevel auth_level,
1540 const struct ndr_syntax_id *abstract,
1541 const struct ndr_syntax_id *transfer,
1542 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1545 DATA_BLOB auth_info;
1548 status = dcerpc_push_dcerpc_auth(mem_ctx,
1551 0, /* auth_pad_length */
1552 1, /* auth_context_id */
1555 if (!NT_STATUS_IS_OK(status)) {
1559 status = create_bind_or_alt_ctx_internal(mem_ctx,
1566 data_blob_free(&auth_info);
1570 /****************************************************************************
1572 ****************************************************************************/
1574 struct rpc_pipe_bind_state {
1575 struct event_context *ev;
1576 struct rpc_pipe_client *cli;
1579 uint32_t rpc_call_id;
1582 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1583 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1584 struct rpc_pipe_bind_state *state,
1585 DATA_BLOB *credentials);
1586 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1587 struct rpc_pipe_bind_state *state,
1588 DATA_BLOB *credentials);
1590 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1591 struct event_context *ev,
1592 struct rpc_pipe_client *cli,
1593 struct pipe_auth_data *auth)
1595 struct tevent_req *req, *subreq;
1596 struct rpc_pipe_bind_state *state;
1599 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1604 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1605 rpccli_pipe_txt(talloc_tos(), cli),
1606 (unsigned int)auth->auth_type,
1607 (unsigned int)auth->auth_level ));
1611 state->rpc_call_id = get_rpc_call_id();
1613 cli->auth = talloc_move(cli, &auth);
1615 /* Marshall the outgoing data. */
1616 status = create_rpc_bind_req(state, cli,
1619 &cli->abstract_syntax,
1620 &cli->transfer_syntax,
1623 if (!NT_STATUS_IS_OK(status) &&
1624 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1628 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1629 DCERPC_PKT_BIND_ACK);
1630 if (subreq == NULL) {
1633 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1637 tevent_req_nterror(req, status);
1638 return tevent_req_post(req, ev);
1644 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1646 struct tevent_req *req = tevent_req_callback_data(
1647 subreq, struct tevent_req);
1648 struct rpc_pipe_bind_state *state = tevent_req_data(
1649 req, struct rpc_pipe_bind_state);
1650 struct pipe_auth_data *pauth = state->cli->auth;
1651 struct gensec_security *gensec_security;
1652 struct spnego_context *spnego_ctx;
1653 struct ncacn_packet *pkt = NULL;
1654 struct dcerpc_auth auth;
1655 DATA_BLOB auth_token = data_blob_null;
1658 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1659 TALLOC_FREE(subreq);
1660 if (!NT_STATUS_IS_OK(status)) {
1661 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1662 rpccli_pipe_txt(talloc_tos(), state->cli),
1663 nt_errstr(status)));
1664 tevent_req_nterror(req, status);
1669 tevent_req_done(req);
1673 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1674 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1675 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1679 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1680 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1682 switch(pauth->auth_type) {
1684 case DCERPC_AUTH_TYPE_NONE:
1685 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1686 case DCERPC_AUTH_TYPE_SCHANNEL:
1687 /* Bind complete. */
1688 tevent_req_done(req);
1691 case DCERPC_AUTH_TYPE_NTLMSSP:
1692 case DCERPC_AUTH_TYPE_SPNEGO:
1693 case DCERPC_AUTH_TYPE_KRB5:
1694 /* Paranoid lenght checks */
1695 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1696 + pkt->auth_length) {
1697 tevent_req_nterror(req,
1698 NT_STATUS_INFO_LENGTH_MISMATCH);
1701 /* get auth credentials */
1702 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1703 &pkt->u.bind_ack.auth_info,
1705 if (!NT_STATUS_IS_OK(status)) {
1706 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1707 nt_errstr(status)));
1708 tevent_req_nterror(req, status);
1718 * For authenticated binds we may need to do 3 or 4 leg binds.
1721 switch(pauth->auth_type) {
1723 case DCERPC_AUTH_TYPE_NONE:
1724 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1725 case DCERPC_AUTH_TYPE_SCHANNEL:
1726 /* Bind complete. */
1727 tevent_req_done(req);
1730 case DCERPC_AUTH_TYPE_NTLMSSP:
1731 case DCERPC_AUTH_TYPE_KRB5:
1732 gensec_security = talloc_get_type_abort(pauth->auth_ctx,
1733 struct gensec_security);
1734 status = gensec_update(gensec_security, state, NULL,
1735 auth.credentials, &auth_token);
1736 if (NT_STATUS_EQUAL(status,
1737 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1738 status = rpc_bind_next_send(req, state,
1740 } else if (NT_STATUS_IS_OK(status)) {
1741 if (auth_token.length == 0) {
1742 /* Bind complete. */
1743 tevent_req_done(req);
1746 status = rpc_bind_finish_send(req, state,
1751 case DCERPC_AUTH_TYPE_SPNEGO:
1752 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
1753 struct spnego_context);
1754 status = spnego_get_client_auth_token(state,
1758 if (!NT_STATUS_IS_OK(status)) {
1761 if (auth_token.length == 0) {
1762 /* Bind complete. */
1763 tevent_req_done(req);
1766 if (spnego_require_more_processing(spnego_ctx)) {
1767 status = rpc_bind_next_send(req, state,
1770 status = rpc_bind_finish_send(req, state,
1779 if (!NT_STATUS_IS_OK(status)) {
1780 tevent_req_nterror(req, status);
1785 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1786 (unsigned int)state->cli->auth->auth_type));
1787 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1790 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1791 struct rpc_pipe_bind_state *state,
1792 DATA_BLOB *auth_token)
1794 struct pipe_auth_data *auth = state->cli->auth;
1795 struct tevent_req *subreq;
1798 /* Now prepare the alter context pdu. */
1799 data_blob_free(&state->rpc_out);
1801 status = create_rpc_alter_context(state,
1805 &state->cli->abstract_syntax,
1806 &state->cli->transfer_syntax,
1809 if (!NT_STATUS_IS_OK(status)) {
1813 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1814 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1815 if (subreq == NULL) {
1816 return NT_STATUS_NO_MEMORY;
1818 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1819 return NT_STATUS_OK;
1822 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1823 struct rpc_pipe_bind_state *state,
1824 DATA_BLOB *auth_token)
1826 struct pipe_auth_data *auth = state->cli->auth;
1827 struct tevent_req *subreq;
1830 state->auth3 = true;
1832 /* Now prepare the auth3 context pdu. */
1833 data_blob_free(&state->rpc_out);
1835 status = create_rpc_bind_auth3(state, state->cli,
1841 if (!NT_STATUS_IS_OK(status)) {
1845 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1846 &state->rpc_out, DCERPC_PKT_AUTH3);
1847 if (subreq == NULL) {
1848 return NT_STATUS_NO_MEMORY;
1850 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1851 return NT_STATUS_OK;
1854 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1856 return tevent_req_simple_recv_ntstatus(req);
1859 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1860 struct pipe_auth_data *auth)
1862 TALLOC_CTX *frame = talloc_stackframe();
1863 struct event_context *ev;
1864 struct tevent_req *req;
1865 NTSTATUS status = NT_STATUS_OK;
1867 ev = event_context_init(frame);
1869 status = NT_STATUS_NO_MEMORY;
1873 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1875 status = NT_STATUS_NO_MEMORY;
1879 if (!tevent_req_poll(req, ev)) {
1880 status = map_nt_error_from_unix(errno);
1884 status = rpc_pipe_bind_recv(req);
1890 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1892 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1893 unsigned int timeout)
1897 if (rpc_cli->transport == NULL) {
1898 return RPCCLI_DEFAULT_TIMEOUT;
1901 if (rpc_cli->transport->set_timeout == NULL) {
1902 return RPCCLI_DEFAULT_TIMEOUT;
1905 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1907 return RPCCLI_DEFAULT_TIMEOUT;
1913 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1915 if (rpc_cli == NULL) {
1919 if (rpc_cli->transport == NULL) {
1923 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1926 struct rpccli_bh_state {
1927 struct rpc_pipe_client *rpc_cli;
1930 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1932 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1933 struct rpccli_bh_state);
1935 return rpccli_is_connected(hs->rpc_cli);
1938 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1941 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1942 struct rpccli_bh_state);
1944 return rpccli_set_timeout(hs->rpc_cli, timeout);
1947 struct rpccli_bh_raw_call_state {
1953 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
1955 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
1956 struct tevent_context *ev,
1957 struct dcerpc_binding_handle *h,
1958 const struct GUID *object,
1961 const uint8_t *in_data,
1964 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1965 struct rpccli_bh_state);
1966 struct tevent_req *req;
1967 struct rpccli_bh_raw_call_state *state;
1969 struct tevent_req *subreq;
1971 req = tevent_req_create(mem_ctx, &state,
1972 struct rpccli_bh_raw_call_state);
1976 state->in_data.data = discard_const_p(uint8_t, in_data);
1977 state->in_data.length = in_length;
1979 ok = rpccli_bh_is_connected(h);
1981 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
1982 return tevent_req_post(req, ev);
1985 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
1986 opnum, &state->in_data);
1987 if (tevent_req_nomem(subreq, req)) {
1988 return tevent_req_post(req, ev);
1990 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
1995 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
1997 struct tevent_req *req =
1998 tevent_req_callback_data(subreq,
2000 struct rpccli_bh_raw_call_state *state =
2001 tevent_req_data(req,
2002 struct rpccli_bh_raw_call_state);
2005 state->out_flags = 0;
2007 /* TODO: support bigendian responses */
2009 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2010 TALLOC_FREE(subreq);
2011 if (!NT_STATUS_IS_OK(status)) {
2012 tevent_req_nterror(req, status);
2016 tevent_req_done(req);
2019 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2020 TALLOC_CTX *mem_ctx,
2023 uint32_t *out_flags)
2025 struct rpccli_bh_raw_call_state *state =
2026 tevent_req_data(req,
2027 struct rpccli_bh_raw_call_state);
2030 if (tevent_req_is_nterror(req, &status)) {
2031 tevent_req_received(req);
2035 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2036 *out_length = state->out_data.length;
2037 *out_flags = state->out_flags;
2038 tevent_req_received(req);
2039 return NT_STATUS_OK;
2042 struct rpccli_bh_disconnect_state {
2046 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2047 struct tevent_context *ev,
2048 struct dcerpc_binding_handle *h)
2050 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2051 struct rpccli_bh_state);
2052 struct tevent_req *req;
2053 struct rpccli_bh_disconnect_state *state;
2056 req = tevent_req_create(mem_ctx, &state,
2057 struct rpccli_bh_disconnect_state);
2062 ok = rpccli_bh_is_connected(h);
2064 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2065 return tevent_req_post(req, ev);
2069 * TODO: do a real async disconnect ...
2071 * For now the caller needs to free rpc_cli
2075 tevent_req_done(req);
2076 return tevent_req_post(req, ev);
2079 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2083 if (tevent_req_is_nterror(req, &status)) {
2084 tevent_req_received(req);
2088 tevent_req_received(req);
2089 return NT_STATUS_OK;
2092 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2097 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2099 const void *_struct_ptr,
2100 const struct ndr_interface_call *call)
2102 void *struct_ptr = discard_const(_struct_ptr);
2104 if (DEBUGLEVEL < 10) {
2108 if (ndr_flags & NDR_IN) {
2109 ndr_print_function_debug(call->ndr_print,
2114 if (ndr_flags & NDR_OUT) {
2115 ndr_print_function_debug(call->ndr_print,
2122 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2124 .is_connected = rpccli_bh_is_connected,
2125 .set_timeout = rpccli_bh_set_timeout,
2126 .raw_call_send = rpccli_bh_raw_call_send,
2127 .raw_call_recv = rpccli_bh_raw_call_recv,
2128 .disconnect_send = rpccli_bh_disconnect_send,
2129 .disconnect_recv = rpccli_bh_disconnect_recv,
2131 .ref_alloc = rpccli_bh_ref_alloc,
2132 .do_ndr_print = rpccli_bh_do_ndr_print,
2135 /* initialise a rpc_pipe_client binding handle */
2136 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2138 struct dcerpc_binding_handle *h;
2139 struct rpccli_bh_state *hs;
2141 h = dcerpc_binding_handle_create(c,
2146 struct rpccli_bh_state,
2156 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2157 struct pipe_auth_data **presult)
2159 struct pipe_auth_data *result;
2161 result = talloc(mem_ctx, struct pipe_auth_data);
2162 if (result == NULL) {
2163 return NT_STATUS_NO_MEMORY;
2166 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2167 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2169 result->user_name = talloc_strdup(result, "");
2170 result->domain = talloc_strdup(result, "");
2171 if ((result->user_name == NULL) || (result->domain == NULL)) {
2172 TALLOC_FREE(result);
2173 return NT_STATUS_NO_MEMORY;
2177 return NT_STATUS_OK;
2180 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2181 struct pipe_auth_data **presult)
2183 struct pipe_auth_data *result;
2185 result = talloc(mem_ctx, struct pipe_auth_data);
2186 if (result == NULL) {
2187 return NT_STATUS_NO_MEMORY;
2190 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2191 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2193 result->user_name = talloc_strdup(result, "");
2194 result->domain = talloc_strdup(result, "");
2195 if ((result->user_name == NULL) || (result->domain == NULL)) {
2196 TALLOC_FREE(result);
2197 return NT_STATUS_NO_MEMORY;
2201 return NT_STATUS_OK;
2204 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2205 enum dcerpc_AuthType auth_type,
2206 enum dcerpc_AuthLevel auth_level,
2208 const char *target_service,
2210 const char *username,
2211 const char *password,
2212 struct pipe_auth_data **presult)
2214 struct auth_generic_state *auth_generic_ctx;
2215 struct pipe_auth_data *result;
2218 result = talloc(mem_ctx, struct pipe_auth_data);
2219 if (result == NULL) {
2220 return NT_STATUS_NO_MEMORY;
2223 result->auth_type = auth_type;
2224 result->auth_level = auth_level;
2226 result->user_name = talloc_strdup(result, username);
2227 result->domain = talloc_strdup(result, domain);
2228 if ((result->user_name == NULL) || (result->domain == NULL)) {
2229 status = NT_STATUS_NO_MEMORY;
2233 status = auth_generic_client_prepare(result,
2235 if (!NT_STATUS_IS_OK(status)) {
2239 status = auth_generic_set_username(auth_generic_ctx, username);
2240 if (!NT_STATUS_IS_OK(status)) {
2244 status = auth_generic_set_domain(auth_generic_ctx, domain);
2245 if (!NT_STATUS_IS_OK(status)) {
2249 status = auth_generic_set_password(auth_generic_ctx, password);
2250 if (!NT_STATUS_IS_OK(status)) {
2254 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2255 if (!NT_STATUS_IS_OK(status)) {
2259 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2260 if (!NT_STATUS_IS_OK(status)) {
2264 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2265 if (!NT_STATUS_IS_OK(status)) {
2269 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2270 talloc_free(auth_generic_ctx);
2272 return NT_STATUS_OK;
2275 TALLOC_FREE(result);
2279 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2280 enum dcerpc_AuthLevel auth_level,
2281 struct netlogon_creds_CredentialState *creds,
2282 struct pipe_auth_data **presult)
2284 struct schannel_state *schannel_auth;
2285 struct pipe_auth_data *result;
2287 result = talloc(mem_ctx, struct pipe_auth_data);
2288 if (result == NULL) {
2289 return NT_STATUS_NO_MEMORY;
2292 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2293 result->auth_level = auth_level;
2295 result->user_name = talloc_strdup(result, "");
2296 result->domain = talloc_strdup(result, domain);
2297 if ((result->user_name == NULL) || (result->domain == NULL)) {
2301 schannel_auth = talloc(result, struct schannel_state);
2302 if (schannel_auth == NULL) {
2306 schannel_auth->state = SCHANNEL_STATE_START;
2307 schannel_auth->seq_num = 0;
2308 schannel_auth->initiator = true;
2309 schannel_auth->creds = netlogon_creds_copy(result, creds);
2311 result->auth_ctx = schannel_auth;
2313 return NT_STATUS_OK;
2316 TALLOC_FREE(result);
2317 return NT_STATUS_NO_MEMORY;
2321 * Create an rpc pipe client struct, connecting to a tcp port.
2323 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2325 const struct ndr_syntax_id *abstract_syntax,
2326 struct rpc_pipe_client **presult)
2328 struct rpc_pipe_client *result;
2329 struct sockaddr_storage addr;
2333 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2334 if (result == NULL) {
2335 return NT_STATUS_NO_MEMORY;
2338 result->abstract_syntax = *abstract_syntax;
2339 result->transfer_syntax = ndr_transfer_syntax;
2341 result->desthost = talloc_strdup(result, host);
2342 result->srv_name_slash = talloc_asprintf_strupper_m(
2343 result, "\\\\%s", result->desthost);
2344 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2345 status = NT_STATUS_NO_MEMORY;
2349 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2350 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2352 if (!resolve_name(host, &addr, 0, false)) {
2353 status = NT_STATUS_NOT_FOUND;
2357 status = open_socket_out(&addr, port, 60*1000, &fd);
2358 if (!NT_STATUS_IS_OK(status)) {
2361 set_socket_options(fd, lp_socket_options());
2363 status = rpc_transport_sock_init(result, fd, &result->transport);
2364 if (!NT_STATUS_IS_OK(status)) {
2369 result->transport->transport = NCACN_IP_TCP;
2371 result->binding_handle = rpccli_bh_create(result);
2372 if (result->binding_handle == NULL) {
2373 TALLOC_FREE(result);
2374 return NT_STATUS_NO_MEMORY;
2378 return NT_STATUS_OK;
2381 TALLOC_FREE(result);
2386 * Determine the tcp port on which a dcerpc interface is listening
2387 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2390 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2391 const struct ndr_syntax_id *abstract_syntax,
2395 struct rpc_pipe_client *epm_pipe = NULL;
2396 struct dcerpc_binding_handle *epm_handle = NULL;
2397 struct pipe_auth_data *auth = NULL;
2398 struct dcerpc_binding *map_binding = NULL;
2399 struct dcerpc_binding *res_binding = NULL;
2400 struct epm_twr_t *map_tower = NULL;
2401 struct epm_twr_t *res_towers = NULL;
2402 struct policy_handle *entry_handle = NULL;
2403 uint32_t num_towers = 0;
2404 uint32_t max_towers = 1;
2405 struct epm_twr_p_t towers;
2406 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2407 uint32_t result = 0;
2409 if (pport == NULL) {
2410 status = NT_STATUS_INVALID_PARAMETER;
2414 if (ndr_syntax_id_equal(abstract_syntax,
2415 &ndr_table_epmapper.syntax_id)) {
2417 return NT_STATUS_OK;
2420 /* open the connection to the endpoint mapper */
2421 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2422 &ndr_table_epmapper.syntax_id,
2425 if (!NT_STATUS_IS_OK(status)) {
2428 epm_handle = epm_pipe->binding_handle;
2430 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2431 if (!NT_STATUS_IS_OK(status)) {
2435 status = rpc_pipe_bind(epm_pipe, auth);
2436 if (!NT_STATUS_IS_OK(status)) {
2440 /* create tower for asking the epmapper */
2442 map_binding = talloc_zero(tmp_ctx, struct dcerpc_binding);
2443 if (map_binding == NULL) {
2444 status = NT_STATUS_NO_MEMORY;
2448 map_binding->transport = NCACN_IP_TCP;
2449 map_binding->object = *abstract_syntax;
2450 map_binding->host = host; /* needed? */
2451 map_binding->endpoint = "0"; /* correct? needed? */
2453 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2454 if (map_tower == NULL) {
2455 status = NT_STATUS_NO_MEMORY;
2459 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2460 &(map_tower->tower));
2461 if (!NT_STATUS_IS_OK(status)) {
2465 /* allocate further parameters for the epm_Map call */
2467 res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2468 if (res_towers == NULL) {
2469 status = NT_STATUS_NO_MEMORY;
2472 towers.twr = res_towers;
2474 entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2475 if (entry_handle == NULL) {
2476 status = NT_STATUS_NO_MEMORY;
2480 /* ask the endpoint mapper for the port */
2482 status = dcerpc_epm_Map(epm_handle,
2484 discard_const_p(struct GUID,
2485 &(abstract_syntax->uuid)),
2493 if (!NT_STATUS_IS_OK(status)) {
2497 if (result != EPMAPPER_STATUS_OK) {
2498 status = NT_STATUS_UNSUCCESSFUL;
2502 if (num_towers != 1) {
2503 status = NT_STATUS_UNSUCCESSFUL;
2507 /* extract the port from the answer */
2509 status = dcerpc_binding_from_tower(tmp_ctx,
2510 &(towers.twr->tower),
2512 if (!NT_STATUS_IS_OK(status)) {
2516 /* are further checks here necessary? */
2517 if (res_binding->transport != NCACN_IP_TCP) {
2518 status = NT_STATUS_UNSUCCESSFUL;
2522 *pport = (uint16_t)atoi(res_binding->endpoint);
2525 TALLOC_FREE(tmp_ctx);
2530 * Create a rpc pipe client struct, connecting to a host via tcp.
2531 * The port is determined by asking the endpoint mapper on the given
2534 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2535 const struct ndr_syntax_id *abstract_syntax,
2536 struct rpc_pipe_client **presult)
2541 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2542 if (!NT_STATUS_IS_OK(status)) {
2546 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2547 abstract_syntax, presult);
2550 /********************************************************************
2551 Create a rpc pipe client struct, connecting to a unix domain socket
2552 ********************************************************************/
2553 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2554 const struct ndr_syntax_id *abstract_syntax,
2555 struct rpc_pipe_client **presult)
2557 struct rpc_pipe_client *result;
2558 struct sockaddr_un addr;
2562 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2563 if (result == NULL) {
2564 return NT_STATUS_NO_MEMORY;
2567 result->abstract_syntax = *abstract_syntax;
2568 result->transfer_syntax = ndr_transfer_syntax;
2570 result->desthost = get_myname(result);
2571 result->srv_name_slash = talloc_asprintf_strupper_m(
2572 result, "\\\\%s", result->desthost);
2573 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2574 status = NT_STATUS_NO_MEMORY;
2578 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2579 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2581 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2583 status = map_nt_error_from_unix(errno);
2588 addr.sun_family = AF_UNIX;
2589 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2591 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2592 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2595 return map_nt_error_from_unix(errno);
2598 status = rpc_transport_sock_init(result, fd, &result->transport);
2599 if (!NT_STATUS_IS_OK(status)) {
2604 result->transport->transport = NCALRPC;
2606 result->binding_handle = rpccli_bh_create(result);
2607 if (result->binding_handle == NULL) {
2608 TALLOC_FREE(result);
2609 return NT_STATUS_NO_MEMORY;
2613 return NT_STATUS_OK;
2616 TALLOC_FREE(result);
2620 struct rpc_pipe_client_np_ref {
2621 struct cli_state *cli;
2622 struct rpc_pipe_client *pipe;
2625 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2627 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2631 /****************************************************************************
2632 Open a named pipe over SMB to a remote server.
2634 * CAVEAT CALLER OF THIS FUNCTION:
2635 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2636 * so be sure that this function is called AFTER any structure (vs pointer)
2637 * assignment of the cli. In particular, libsmbclient does structure
2638 * assignments of cli, which invalidates the data in the returned
2639 * rpc_pipe_client if this function is called before the structure assignment
2642 ****************************************************************************/
2644 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2645 const struct ndr_syntax_id *abstract_syntax,
2646 struct rpc_pipe_client **presult)
2648 struct rpc_pipe_client *result;
2650 struct rpc_pipe_client_np_ref *np_ref;
2652 /* sanity check to protect against crashes */
2655 return NT_STATUS_INVALID_HANDLE;
2658 result = talloc_zero(NULL, struct rpc_pipe_client);
2659 if (result == NULL) {
2660 return NT_STATUS_NO_MEMORY;
2663 result->abstract_syntax = *abstract_syntax;
2664 result->transfer_syntax = ndr_transfer_syntax;
2665 result->desthost = talloc_strdup(result, cli_state_remote_name(cli));
2666 result->srv_name_slash = talloc_asprintf_strupper_m(
2667 result, "\\\\%s", result->desthost);
2669 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2670 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2672 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2673 TALLOC_FREE(result);
2674 return NT_STATUS_NO_MEMORY;
2677 status = rpc_transport_np_init(result, cli, abstract_syntax,
2678 &result->transport);
2679 if (!NT_STATUS_IS_OK(status)) {
2680 TALLOC_FREE(result);
2684 result->transport->transport = NCACN_NP;
2686 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2687 if (np_ref == NULL) {
2688 TALLOC_FREE(result);
2689 return NT_STATUS_NO_MEMORY;
2692 np_ref->pipe = result;
2694 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2695 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2697 result->binding_handle = rpccli_bh_create(result);
2698 if (result->binding_handle == NULL) {
2699 TALLOC_FREE(result);
2700 return NT_STATUS_NO_MEMORY;
2704 return NT_STATUS_OK;
2707 /****************************************************************************
2708 Open a pipe to a remote server.
2709 ****************************************************************************/
2711 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2712 enum dcerpc_transport_t transport,
2713 const struct ndr_syntax_id *interface,
2714 struct rpc_pipe_client **presult)
2716 switch (transport) {
2718 return rpc_pipe_open_tcp(NULL, cli_state_remote_name(cli),
2719 interface, presult);
2721 return rpc_pipe_open_np(cli, interface, presult);
2723 return NT_STATUS_NOT_IMPLEMENTED;
2727 /****************************************************************************
2728 Open a named pipe to an SMB server and bind anonymously.
2729 ****************************************************************************/
2731 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2732 enum dcerpc_transport_t transport,
2733 const struct ndr_syntax_id *interface,
2734 struct rpc_pipe_client **presult)
2736 struct rpc_pipe_client *result;
2737 struct pipe_auth_data *auth;
2740 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2741 if (!NT_STATUS_IS_OK(status)) {
2745 status = rpccli_anon_bind_data(result, &auth);
2746 if (!NT_STATUS_IS_OK(status)) {
2747 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2748 nt_errstr(status)));
2749 TALLOC_FREE(result);
2754 * This is a bit of an abstraction violation due to the fact that an
2755 * anonymous bind on an authenticated SMB inherits the user/domain
2756 * from the enclosing SMB creds
2759 TALLOC_FREE(auth->user_name);
2760 TALLOC_FREE(auth->domain);
2762 auth->user_name = talloc_strdup(auth, cli->user_name);
2763 auth->domain = talloc_strdup(auth, cli->domain);
2764 auth->user_session_key = data_blob_talloc(auth,
2765 cli->user_session_key.data,
2766 cli->user_session_key.length);
2768 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2769 TALLOC_FREE(result);
2770 return NT_STATUS_NO_MEMORY;
2773 status = rpc_pipe_bind(result, auth);
2774 if (!NT_STATUS_IS_OK(status)) {
2776 if (ndr_syntax_id_equal(interface,
2777 &ndr_table_dssetup.syntax_id)) {
2778 /* non AD domains just don't have this pipe, avoid
2779 * level 0 statement in that case - gd */
2782 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2783 "%s failed with error %s\n",
2784 get_pipe_name_from_syntax(talloc_tos(), interface),
2785 nt_errstr(status) ));
2786 TALLOC_FREE(result);
2790 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2791 "%s and bound anonymously.\n",
2792 get_pipe_name_from_syntax(talloc_tos(), interface),
2796 return NT_STATUS_OK;
2799 /****************************************************************************
2800 ****************************************************************************/
2802 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2803 const struct ndr_syntax_id *interface,
2804 struct rpc_pipe_client **presult)
2806 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2807 interface, presult);
2810 /****************************************************************************
2811 Open a named pipe to an SMB server and bind using the mech specified
2812 ****************************************************************************/
2814 NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
2815 const struct ndr_interface_table *table,
2816 enum dcerpc_transport_t transport,
2817 enum dcerpc_AuthType auth_type,
2818 enum dcerpc_AuthLevel auth_level,
2821 const char *username,
2822 const char *password,
2823 struct rpc_pipe_client **presult)
2825 struct rpc_pipe_client *result;
2826 struct pipe_auth_data *auth = NULL;
2827 const char *target_service = table->authservices->names[0];
2830 status = cli_rpc_pipe_open(cli, transport, &table->syntax_id, &result);
2831 if (!NT_STATUS_IS_OK(status)) {
2835 status = rpccli_generic_bind_data(result,
2836 auth_type, auth_level,
2837 server, target_service,
2838 domain, username, password,
2840 if (!NT_STATUS_IS_OK(status)) {
2841 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
2842 nt_errstr(status)));
2846 status = rpc_pipe_bind(result, auth);
2847 if (!NT_STATUS_IS_OK(status)) {
2848 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
2849 nt_errstr(status) ));
2853 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
2854 "machine %s and bound as user %s\\%s.\n", table->name,
2855 result->desthost, domain, username));
2858 return NT_STATUS_OK;
2862 TALLOC_FREE(result);
2866 /****************************************************************************
2868 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2869 using session_key. sign and seal.
2871 The *pdc will be stolen onto this new pipe
2872 ****************************************************************************/
2874 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2875 const struct ndr_syntax_id *interface,
2876 enum dcerpc_transport_t transport,
2877 enum dcerpc_AuthLevel auth_level,
2879 struct netlogon_creds_CredentialState **pdc,
2880 struct rpc_pipe_client **presult)
2882 struct rpc_pipe_client *result;
2883 struct pipe_auth_data *auth;
2886 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2887 if (!NT_STATUS_IS_OK(status)) {
2891 status = rpccli_schannel_bind_data(result, domain, auth_level,
2893 if (!NT_STATUS_IS_OK(status)) {
2894 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2895 nt_errstr(status)));
2896 TALLOC_FREE(result);
2900 status = rpc_pipe_bind(result, auth);
2901 if (!NT_STATUS_IS_OK(status)) {
2902 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
2903 "cli_rpc_pipe_bind failed with error %s\n",
2904 nt_errstr(status) ));
2905 TALLOC_FREE(result);
2910 * The credentials on a new netlogon pipe are the ones we are passed
2911 * in - copy them over
2913 result->dc = netlogon_creds_copy(result, *pdc);
2914 if (result->dc == NULL) {
2915 TALLOC_FREE(result);
2916 return NT_STATUS_NO_MEMORY;
2919 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2920 "for domain %s and bound using schannel.\n",
2921 get_pipe_name_from_syntax(talloc_tos(), interface),
2922 result->desthost, domain));
2925 return NT_STATUS_OK;
2928 NTSTATUS cli_rpc_pipe_open_spnego(struct cli_state *cli,
2929 const struct ndr_interface_table *table,
2930 enum dcerpc_transport_t transport,
2932 enum dcerpc_AuthLevel auth_level,
2935 const char *username,
2936 const char *password,
2937 struct rpc_pipe_client **presult)
2939 struct rpc_pipe_client *result;
2940 struct pipe_auth_data *auth;
2941 struct spnego_context *spnego_ctx;
2943 const char *target_service = table->authservices->names[0];
2945 status = cli_rpc_pipe_open(cli, transport, &table->syntax_id, &result);
2946 if (!NT_STATUS_IS_OK(status)) {
2950 auth = talloc(result, struct pipe_auth_data);
2952 status = NT_STATUS_NO_MEMORY;
2955 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
2956 auth->auth_level = auth_level;
2961 auth->user_name = talloc_strdup(auth, username);
2962 if (!auth->user_name) {
2963 status = NT_STATUS_NO_MEMORY;
2970 auth->domain = talloc_strdup(auth, domain);
2971 if (!auth->domain) {
2972 status = NT_STATUS_NO_MEMORY;
2976 status = spnego_generic_init_client(auth,
2978 (auth->auth_level ==
2979 DCERPC_AUTH_LEVEL_INTEGRITY),
2980 (auth->auth_level ==
2981 DCERPC_AUTH_LEVEL_PRIVACY),
2983 server, target_service,
2984 domain, username, password,
2986 if (!NT_STATUS_IS_OK(status)) {
2987 DEBUG(0, ("spnego_init_client returned %s\n",
2988 nt_errstr(status)));
2991 auth->auth_ctx = spnego_ctx;
2993 status = rpc_pipe_bind(result, auth);
2994 if (!NT_STATUS_IS_OK(status)) {
2995 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
2996 nt_errstr(status)));
3001 return NT_STATUS_OK;
3004 TALLOC_FREE(result);
3008 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3009 struct rpc_pipe_client *cli,
3010 DATA_BLOB *session_key)
3013 struct pipe_auth_data *a;
3014 struct schannel_state *schannel_auth;
3015 struct gensec_security *gensec_security;
3016 struct spnego_context *spnego_ctx;
3017 DATA_BLOB sk = data_blob_null;
3018 bool make_dup = false;
3020 if (!session_key || !cli) {
3021 return NT_STATUS_INVALID_PARAMETER;
3027 return NT_STATUS_INVALID_PARAMETER;
3030 switch (cli->auth->auth_type) {
3031 case DCERPC_AUTH_TYPE_SCHANNEL:
3032 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3033 struct schannel_state);
3034 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3037 case DCERPC_AUTH_TYPE_SPNEGO:
3038 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
3039 struct spnego_context);
3040 status = spnego_get_negotiated_mech(spnego_ctx, &gensec_security);
3041 if (!NT_STATUS_IS_OK(status)) {
3044 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3045 if (!NT_STATUS_IS_OK(status)) {
3050 case DCERPC_AUTH_TYPE_NTLMSSP:
3051 case DCERPC_AUTH_TYPE_KRB5:
3052 gensec_security = talloc_get_type_abort(a->auth_ctx,
3053 struct gensec_security);
3054 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3055 if (!NT_STATUS_IS_OK(status)) {
3060 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3061 case DCERPC_AUTH_TYPE_NONE:
3062 sk = data_blob_const(a->user_session_key.data,
3063 a->user_session_key.length);
3071 return NT_STATUS_NO_USER_SESSION_KEY;
3075 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3080 return NT_STATUS_OK;