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 "../lib/util/tevent_ntstatus.h"
23 #include "librpc/gen_ndr/ndr_epmapper_c.h"
24 #include "../librpc/gen_ndr/ndr_schannel.h"
25 #include "../librpc/gen_ndr/ndr_dssetup.h"
26 #include "../libcli/auth/schannel.h"
27 #include "../libcli/auth/spnego.h"
28 #include "../auth/ntlmssp/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"
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 krb5 auth bind.
1009 ********************************************************************/
1011 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
1012 struct pipe_auth_data *auth,
1013 DATA_BLOB *auth_token)
1015 struct gse_context *gse_ctx;
1016 DATA_BLOB in_token = data_blob_null;
1019 gse_ctx = talloc_get_type_abort(auth->auth_ctx,
1020 struct gse_context);
1022 /* Negotiate the initial auth token */
1023 status = gse_get_client_auth_token(mem_ctx, gse_ctx,
1026 if (!NT_STATUS_IS_OK(status)) {
1030 DEBUG(5, ("Created GSS Authentication Token:\n"));
1031 dump_data(5, auth_token->data, auth_token->length);
1033 return NT_STATUS_OK;
1036 /*******************************************************************
1037 Creates NTLMSSP auth bind.
1038 ********************************************************************/
1040 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1041 TALLOC_CTX *mem_ctx,
1042 DATA_BLOB *auth_token)
1044 struct auth_ntlmssp_state *ntlmssp_ctx;
1045 DATA_BLOB null_blob = data_blob_null;
1048 ntlmssp_ctx = talloc_get_type_abort(cli->auth->auth_ctx,
1049 struct auth_ntlmssp_state);
1051 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1052 status = gensec_update(ntlmssp_ctx->gensec_security, mem_ctx, NULL, null_blob, auth_token);
1054 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1055 data_blob_free(auth_token);
1059 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1060 dump_data(5, auth_token->data, auth_token->length);
1062 return NT_STATUS_OK;
1065 /*******************************************************************
1066 Creates schannel auth bind.
1067 ********************************************************************/
1069 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1070 DATA_BLOB *auth_token)
1073 struct NL_AUTH_MESSAGE r;
1075 /* Use lp_workgroup() if domain not specified */
1077 if (!cli->auth->domain || !cli->auth->domain[0]) {
1078 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1079 if (cli->auth->domain == NULL) {
1080 return NT_STATUS_NO_MEMORY;
1085 * Now marshall the data into the auth parse_struct.
1088 r.MessageType = NL_NEGOTIATE_REQUEST;
1089 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1090 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1091 r.oem_netbios_domain.a = cli->auth->domain;
1092 r.oem_netbios_computer.a = lp_netbios_name();
1094 status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1095 if (!NT_STATUS_IS_OK(status)) {
1099 return NT_STATUS_OK;
1102 /*******************************************************************
1103 Creates the internals of a DCE/RPC bind request or alter context PDU.
1104 ********************************************************************/
1106 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1107 enum dcerpc_pkt_type ptype,
1109 const struct ndr_syntax_id *abstract,
1110 const struct ndr_syntax_id *transfer,
1111 const DATA_BLOB *auth_info,
1114 uint16 auth_len = auth_info->length;
1116 union dcerpc_payload u;
1117 struct dcerpc_ctx_list ctx_list;
1120 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1123 ctx_list.context_id = 0;
1124 ctx_list.num_transfer_syntaxes = 1;
1125 ctx_list.abstract_syntax = *abstract;
1126 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1128 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1129 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1130 u.bind.assoc_group_id = 0x0;
1131 u.bind.num_contexts = 1;
1132 u.bind.ctx_list = &ctx_list;
1133 u.bind.auth_info = *auth_info;
1135 status = dcerpc_push_ncacn_packet(mem_ctx,
1137 DCERPC_PFC_FLAG_FIRST |
1138 DCERPC_PFC_FLAG_LAST,
1143 if (!NT_STATUS_IS_OK(status)) {
1144 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1148 return NT_STATUS_OK;
1151 /*******************************************************************
1152 Creates a DCE/RPC bind request.
1153 ********************************************************************/
1155 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1156 struct rpc_pipe_client *cli,
1157 struct pipe_auth_data *auth,
1159 const struct ndr_syntax_id *abstract,
1160 const struct ndr_syntax_id *transfer,
1163 DATA_BLOB auth_token = data_blob_null;
1164 DATA_BLOB auth_info = data_blob_null;
1165 NTSTATUS ret = NT_STATUS_OK;
1167 switch (auth->auth_type) {
1168 case DCERPC_AUTH_TYPE_SCHANNEL:
1169 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1170 if (!NT_STATUS_IS_OK(ret)) {
1175 case DCERPC_AUTH_TYPE_NTLMSSP:
1176 ret = create_ntlmssp_auth_rpc_bind_req(cli, mem_ctx, &auth_token);
1177 if (!NT_STATUS_IS_OK(ret)) {
1182 case DCERPC_AUTH_TYPE_SPNEGO:
1183 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1184 if (!NT_STATUS_IS_OK(ret)) {
1189 case DCERPC_AUTH_TYPE_KRB5:
1190 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
1191 if (!NT_STATUS_IS_OK(ret)) {
1196 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1197 auth_token = data_blob_talloc(mem_ctx,
1198 "NCALRPC_AUTH_TOKEN",
1202 case DCERPC_AUTH_TYPE_NONE:
1206 /* "Can't" happen. */
1207 return NT_STATUS_INVALID_INFO_CLASS;
1210 if (auth_token.length != 0) {
1211 ret = dcerpc_push_dcerpc_auth(cli,
1214 0, /* auth_pad_length */
1215 1, /* auth_context_id */
1218 if (!NT_STATUS_IS_OK(ret)) {
1221 data_blob_free(&auth_token);
1224 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1234 /*******************************************************************
1236 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1237 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1238 and deals with signing/sealing details.
1239 ********************************************************************/
1241 struct rpc_api_pipe_req_state {
1242 struct event_context *ev;
1243 struct rpc_pipe_client *cli;
1246 DATA_BLOB *req_data;
1247 uint32_t req_data_sent;
1249 DATA_BLOB reply_pdu;
1252 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1253 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1254 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1255 bool *is_last_frag);
1257 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1258 struct event_context *ev,
1259 struct rpc_pipe_client *cli,
1261 DATA_BLOB *req_data)
1263 struct tevent_req *req, *subreq;
1264 struct rpc_api_pipe_req_state *state;
1268 req = tevent_req_create(mem_ctx, &state,
1269 struct rpc_api_pipe_req_state);
1275 state->op_num = op_num;
1276 state->req_data = req_data;
1277 state->req_data_sent = 0;
1278 state->call_id = get_rpc_call_id();
1279 state->reply_pdu = data_blob_null;
1280 state->rpc_out = data_blob_null;
1282 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1283 + RPC_MAX_SIGN_SIZE) {
1284 /* Server is screwed up ! */
1285 status = NT_STATUS_INVALID_PARAMETER;
1289 status = prepare_next_frag(state, &is_last_frag);
1290 if (!NT_STATUS_IS_OK(status)) {
1295 subreq = rpc_api_pipe_send(state, ev, state->cli,
1297 DCERPC_PKT_RESPONSE);
1298 if (subreq == NULL) {
1301 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1303 subreq = rpc_write_send(state, ev, cli->transport,
1304 state->rpc_out.data,
1305 state->rpc_out.length);
1306 if (subreq == NULL) {
1309 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1315 tevent_req_nterror(req, status);
1316 return tevent_req_post(req, ev);
1322 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1325 size_t data_sent_thistime;
1332 union dcerpc_payload u;
1334 data_left = state->req_data->length - state->req_data_sent;
1336 status = dcerpc_guess_sizes(state->cli->auth,
1337 DCERPC_REQUEST_LENGTH, data_left,
1338 state->cli->max_xmit_frag,
1339 CLIENT_NDR_PADDING_SIZE,
1340 &data_sent_thistime,
1341 &frag_len, &auth_len, &pad_len);
1342 if (!NT_STATUS_IS_OK(status)) {
1346 if (state->req_data_sent == 0) {
1347 flags = DCERPC_PFC_FLAG_FIRST;
1350 if (data_sent_thistime == data_left) {
1351 flags |= DCERPC_PFC_FLAG_LAST;
1354 data_blob_free(&state->rpc_out);
1356 ZERO_STRUCT(u.request);
1358 u.request.alloc_hint = state->req_data->length;
1359 u.request.context_id = 0;
1360 u.request.opnum = state->op_num;
1362 status = dcerpc_push_ncacn_packet(state,
1369 if (!NT_STATUS_IS_OK(status)) {
1373 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1374 * compute it right for requests because the auth trailer is missing
1376 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1378 /* Copy in the data. */
1379 if (!data_blob_append(NULL, &state->rpc_out,
1380 state->req_data->data + state->req_data_sent,
1381 data_sent_thistime)) {
1382 return NT_STATUS_NO_MEMORY;
1385 switch (state->cli->auth->auth_level) {
1386 case DCERPC_AUTH_LEVEL_NONE:
1387 case DCERPC_AUTH_LEVEL_CONNECT:
1388 case DCERPC_AUTH_LEVEL_PACKET:
1390 case DCERPC_AUTH_LEVEL_INTEGRITY:
1391 case DCERPC_AUTH_LEVEL_PRIVACY:
1392 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1394 if (!NT_STATUS_IS_OK(status)) {
1399 return NT_STATUS_INVALID_PARAMETER;
1402 state->req_data_sent += data_sent_thistime;
1403 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1408 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1410 struct tevent_req *req = tevent_req_callback_data(
1411 subreq, struct tevent_req);
1412 struct rpc_api_pipe_req_state *state = tevent_req_data(
1413 req, struct rpc_api_pipe_req_state);
1417 status = rpc_write_recv(subreq);
1418 TALLOC_FREE(subreq);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 tevent_req_nterror(req, status);
1424 status = prepare_next_frag(state, &is_last_frag);
1425 if (!NT_STATUS_IS_OK(status)) {
1426 tevent_req_nterror(req, status);
1431 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1433 DCERPC_PKT_RESPONSE);
1434 if (tevent_req_nomem(subreq, req)) {
1437 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1439 subreq = rpc_write_send(state, state->ev,
1440 state->cli->transport,
1441 state->rpc_out.data,
1442 state->rpc_out.length);
1443 if (tevent_req_nomem(subreq, req)) {
1446 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1451 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1453 struct tevent_req *req = tevent_req_callback_data(
1454 subreq, struct tevent_req);
1455 struct rpc_api_pipe_req_state *state = tevent_req_data(
1456 req, struct rpc_api_pipe_req_state);
1459 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1460 TALLOC_FREE(subreq);
1461 if (!NT_STATUS_IS_OK(status)) {
1462 tevent_req_nterror(req, status);
1465 tevent_req_done(req);
1468 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1469 DATA_BLOB *reply_pdu)
1471 struct rpc_api_pipe_req_state *state = tevent_req_data(
1472 req, struct rpc_api_pipe_req_state);
1475 if (tevent_req_is_nterror(req, &status)) {
1477 * We always have to initialize to reply pdu, even if there is
1478 * none. The rpccli_* caller routines expect this.
1480 *reply_pdu = data_blob_null;
1484 /* return data to caller and assign it ownership of memory */
1485 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1486 reply_pdu->length = state->reply_pdu.length;
1487 state->reply_pdu.length = 0;
1489 return NT_STATUS_OK;
1492 /****************************************************************************
1493 Check the rpc bind acknowledge response.
1494 ****************************************************************************/
1496 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1497 const struct ndr_syntax_id *transfer)
1499 struct dcerpc_ack_ctx ctx;
1501 if (r->secondary_address_size == 0) {
1502 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1505 if (r->num_results < 1 || !r->ctx_list) {
1509 ctx = r->ctx_list[0];
1511 /* check the transfer syntax */
1512 if ((ctx.syntax.if_version != transfer->if_version) ||
1513 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1514 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1518 if (r->num_results != 0x1 || ctx.result != 0) {
1519 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1520 r->num_results, ctx.reason));
1523 DEBUG(5,("check_bind_response: accepted!\n"));
1527 /*******************************************************************
1528 Creates a DCE/RPC bind authentication response.
1529 This is the packet that is sent back to the server once we
1530 have received a BIND-ACK, to finish the third leg of
1531 the authentication handshake.
1532 ********************************************************************/
1534 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1535 struct rpc_pipe_client *cli,
1537 enum dcerpc_AuthType auth_type,
1538 enum dcerpc_AuthLevel auth_level,
1539 DATA_BLOB *pauth_blob,
1543 union dcerpc_payload u;
1547 status = dcerpc_push_dcerpc_auth(mem_ctx,
1550 0, /* auth_pad_length */
1551 1, /* auth_context_id */
1553 &u.auth3.auth_info);
1554 if (!NT_STATUS_IS_OK(status)) {
1558 status = dcerpc_push_ncacn_packet(mem_ctx,
1560 DCERPC_PFC_FLAG_FIRST |
1561 DCERPC_PFC_FLAG_LAST,
1566 data_blob_free(&u.auth3.auth_info);
1567 if (!NT_STATUS_IS_OK(status)) {
1568 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1572 return NT_STATUS_OK;
1575 /*******************************************************************
1576 Creates a DCE/RPC bind alter context authentication request which
1577 may contain a spnego auth blobl
1578 ********************************************************************/
1580 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1581 enum dcerpc_AuthType auth_type,
1582 enum dcerpc_AuthLevel auth_level,
1584 const struct ndr_syntax_id *abstract,
1585 const struct ndr_syntax_id *transfer,
1586 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1589 DATA_BLOB auth_info;
1592 status = dcerpc_push_dcerpc_auth(mem_ctx,
1595 0, /* auth_pad_length */
1596 1, /* auth_context_id */
1599 if (!NT_STATUS_IS_OK(status)) {
1603 status = create_bind_or_alt_ctx_internal(mem_ctx,
1610 data_blob_free(&auth_info);
1614 /****************************************************************************
1616 ****************************************************************************/
1618 struct rpc_pipe_bind_state {
1619 struct event_context *ev;
1620 struct rpc_pipe_client *cli;
1623 uint32_t rpc_call_id;
1626 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1627 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1628 struct rpc_pipe_bind_state *state,
1629 DATA_BLOB *credentials);
1630 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1631 struct rpc_pipe_bind_state *state,
1632 DATA_BLOB *credentials);
1634 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1635 struct event_context *ev,
1636 struct rpc_pipe_client *cli,
1637 struct pipe_auth_data *auth)
1639 struct tevent_req *req, *subreq;
1640 struct rpc_pipe_bind_state *state;
1643 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1648 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1649 rpccli_pipe_txt(talloc_tos(), cli),
1650 (unsigned int)auth->auth_type,
1651 (unsigned int)auth->auth_level ));
1655 state->rpc_call_id = get_rpc_call_id();
1657 cli->auth = talloc_move(cli, &auth);
1659 /* Marshall the outgoing data. */
1660 status = create_rpc_bind_req(state, cli,
1663 &cli->abstract_syntax,
1664 &cli->transfer_syntax,
1667 if (!NT_STATUS_IS_OK(status)) {
1671 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1672 DCERPC_PKT_BIND_ACK);
1673 if (subreq == NULL) {
1676 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1680 tevent_req_nterror(req, status);
1681 return tevent_req_post(req, ev);
1687 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1689 struct tevent_req *req = tevent_req_callback_data(
1690 subreq, struct tevent_req);
1691 struct rpc_pipe_bind_state *state = tevent_req_data(
1692 req, struct rpc_pipe_bind_state);
1693 struct pipe_auth_data *pauth = state->cli->auth;
1694 struct auth_ntlmssp_state *ntlmssp_ctx;
1695 struct spnego_context *spnego_ctx;
1696 struct gse_context *gse_ctx;
1697 struct ncacn_packet *pkt = NULL;
1698 struct dcerpc_auth auth;
1699 DATA_BLOB auth_token = data_blob_null;
1702 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1703 TALLOC_FREE(subreq);
1704 if (!NT_STATUS_IS_OK(status)) {
1705 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1706 rpccli_pipe_txt(talloc_tos(), state->cli),
1707 nt_errstr(status)));
1708 tevent_req_nterror(req, status);
1713 tevent_req_done(req);
1717 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1718 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1719 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1723 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1724 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1726 switch(pauth->auth_type) {
1728 case DCERPC_AUTH_TYPE_NONE:
1729 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1730 case DCERPC_AUTH_TYPE_SCHANNEL:
1731 /* Bind complete. */
1732 tevent_req_done(req);
1735 case DCERPC_AUTH_TYPE_NTLMSSP:
1736 case DCERPC_AUTH_TYPE_SPNEGO:
1737 case DCERPC_AUTH_TYPE_KRB5:
1738 /* Paranoid lenght checks */
1739 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1740 + pkt->auth_length) {
1741 tevent_req_nterror(req,
1742 NT_STATUS_INFO_LENGTH_MISMATCH);
1745 /* get auth credentials */
1746 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1747 &pkt->u.bind_ack.auth_info,
1749 if (!NT_STATUS_IS_OK(status)) {
1750 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1751 nt_errstr(status)));
1752 tevent_req_nterror(req, status);
1762 * For authenticated binds we may need to do 3 or 4 leg binds.
1765 switch(pauth->auth_type) {
1767 case DCERPC_AUTH_TYPE_NONE:
1768 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1769 case DCERPC_AUTH_TYPE_SCHANNEL:
1770 /* Bind complete. */
1771 tevent_req_done(req);
1774 case DCERPC_AUTH_TYPE_NTLMSSP:
1775 ntlmssp_ctx = talloc_get_type_abort(pauth->auth_ctx,
1776 struct auth_ntlmssp_state);
1777 status = gensec_update(ntlmssp_ctx->gensec_security, state, NULL,
1778 auth.credentials, &auth_token);
1779 if (NT_STATUS_EQUAL(status,
1780 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1781 status = rpc_bind_next_send(req, state,
1783 } else if (NT_STATUS_IS_OK(status)) {
1784 status = rpc_bind_finish_send(req, state,
1789 case DCERPC_AUTH_TYPE_SPNEGO:
1790 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
1791 struct spnego_context);
1792 status = spnego_get_client_auth_token(state,
1796 if (!NT_STATUS_IS_OK(status)) {
1799 if (auth_token.length == 0) {
1800 /* Bind complete. */
1801 tevent_req_done(req);
1804 if (spnego_require_more_processing(spnego_ctx)) {
1805 status = rpc_bind_next_send(req, state,
1808 status = rpc_bind_finish_send(req, state,
1813 case DCERPC_AUTH_TYPE_KRB5:
1814 gse_ctx = talloc_get_type_abort(pauth->auth_ctx,
1815 struct gse_context);
1816 status = gse_get_client_auth_token(state,
1820 if (!NT_STATUS_IS_OK(status)) {
1824 if (gse_require_more_processing(gse_ctx)) {
1825 status = rpc_bind_next_send(req, state, &auth_token);
1827 status = rpc_bind_finish_send(req, state, &auth_token);
1835 if (!NT_STATUS_IS_OK(status)) {
1836 tevent_req_nterror(req, status);
1841 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1842 (unsigned int)state->cli->auth->auth_type));
1843 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1846 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1847 struct rpc_pipe_bind_state *state,
1848 DATA_BLOB *auth_token)
1850 struct pipe_auth_data *auth = state->cli->auth;
1851 struct tevent_req *subreq;
1854 /* Now prepare the alter context pdu. */
1855 data_blob_free(&state->rpc_out);
1857 status = create_rpc_alter_context(state,
1861 &state->cli->abstract_syntax,
1862 &state->cli->transfer_syntax,
1865 if (!NT_STATUS_IS_OK(status)) {
1869 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1870 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1871 if (subreq == NULL) {
1872 return NT_STATUS_NO_MEMORY;
1874 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1875 return NT_STATUS_OK;
1878 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1879 struct rpc_pipe_bind_state *state,
1880 DATA_BLOB *auth_token)
1882 struct pipe_auth_data *auth = state->cli->auth;
1883 struct tevent_req *subreq;
1886 state->auth3 = true;
1888 /* Now prepare the auth3 context pdu. */
1889 data_blob_free(&state->rpc_out);
1891 status = create_rpc_bind_auth3(state, state->cli,
1897 if (!NT_STATUS_IS_OK(status)) {
1901 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1902 &state->rpc_out, DCERPC_PKT_AUTH3);
1903 if (subreq == NULL) {
1904 return NT_STATUS_NO_MEMORY;
1906 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1907 return NT_STATUS_OK;
1910 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1912 return tevent_req_simple_recv_ntstatus(req);
1915 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1916 struct pipe_auth_data *auth)
1918 TALLOC_CTX *frame = talloc_stackframe();
1919 struct event_context *ev;
1920 struct tevent_req *req;
1921 NTSTATUS status = NT_STATUS_OK;
1923 ev = event_context_init(frame);
1925 status = NT_STATUS_NO_MEMORY;
1929 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1931 status = NT_STATUS_NO_MEMORY;
1935 if (!tevent_req_poll(req, ev)) {
1936 status = map_nt_error_from_unix(errno);
1940 status = rpc_pipe_bind_recv(req);
1946 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1948 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1949 unsigned int timeout)
1953 if (rpc_cli->transport == NULL) {
1954 return RPCCLI_DEFAULT_TIMEOUT;
1957 if (rpc_cli->transport->set_timeout == NULL) {
1958 return RPCCLI_DEFAULT_TIMEOUT;
1961 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1963 return RPCCLI_DEFAULT_TIMEOUT;
1969 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1971 if (rpc_cli == NULL) {
1975 if (rpc_cli->transport == NULL) {
1979 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1982 struct rpccli_bh_state {
1983 struct rpc_pipe_client *rpc_cli;
1986 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1988 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1989 struct rpccli_bh_state);
1991 return rpccli_is_connected(hs->rpc_cli);
1994 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1997 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1998 struct rpccli_bh_state);
2000 return rpccli_set_timeout(hs->rpc_cli, timeout);
2003 struct rpccli_bh_raw_call_state {
2009 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2011 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2012 struct tevent_context *ev,
2013 struct dcerpc_binding_handle *h,
2014 const struct GUID *object,
2017 const uint8_t *in_data,
2020 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2021 struct rpccli_bh_state);
2022 struct tevent_req *req;
2023 struct rpccli_bh_raw_call_state *state;
2025 struct tevent_req *subreq;
2027 req = tevent_req_create(mem_ctx, &state,
2028 struct rpccli_bh_raw_call_state);
2032 state->in_data.data = discard_const_p(uint8_t, in_data);
2033 state->in_data.length = in_length;
2035 ok = rpccli_bh_is_connected(h);
2037 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2038 return tevent_req_post(req, ev);
2041 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2042 opnum, &state->in_data);
2043 if (tevent_req_nomem(subreq, req)) {
2044 return tevent_req_post(req, ev);
2046 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2051 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2053 struct tevent_req *req =
2054 tevent_req_callback_data(subreq,
2056 struct rpccli_bh_raw_call_state *state =
2057 tevent_req_data(req,
2058 struct rpccli_bh_raw_call_state);
2061 state->out_flags = 0;
2063 /* TODO: support bigendian responses */
2065 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2066 TALLOC_FREE(subreq);
2067 if (!NT_STATUS_IS_OK(status)) {
2068 tevent_req_nterror(req, status);
2072 tevent_req_done(req);
2075 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2076 TALLOC_CTX *mem_ctx,
2079 uint32_t *out_flags)
2081 struct rpccli_bh_raw_call_state *state =
2082 tevent_req_data(req,
2083 struct rpccli_bh_raw_call_state);
2086 if (tevent_req_is_nterror(req, &status)) {
2087 tevent_req_received(req);
2091 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2092 *out_length = state->out_data.length;
2093 *out_flags = state->out_flags;
2094 tevent_req_received(req);
2095 return NT_STATUS_OK;
2098 struct rpccli_bh_disconnect_state {
2102 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2103 struct tevent_context *ev,
2104 struct dcerpc_binding_handle *h)
2106 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2107 struct rpccli_bh_state);
2108 struct tevent_req *req;
2109 struct rpccli_bh_disconnect_state *state;
2112 req = tevent_req_create(mem_ctx, &state,
2113 struct rpccli_bh_disconnect_state);
2118 ok = rpccli_bh_is_connected(h);
2120 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2121 return tevent_req_post(req, ev);
2125 * TODO: do a real async disconnect ...
2127 * For now the caller needs to free rpc_cli
2131 tevent_req_done(req);
2132 return tevent_req_post(req, ev);
2135 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2139 if (tevent_req_is_nterror(req, &status)) {
2140 tevent_req_received(req);
2144 tevent_req_received(req);
2145 return NT_STATUS_OK;
2148 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2153 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2155 const void *_struct_ptr,
2156 const struct ndr_interface_call *call)
2158 void *struct_ptr = discard_const(_struct_ptr);
2160 if (DEBUGLEVEL < 10) {
2164 if (ndr_flags & NDR_IN) {
2165 ndr_print_function_debug(call->ndr_print,
2170 if (ndr_flags & NDR_OUT) {
2171 ndr_print_function_debug(call->ndr_print,
2178 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2180 .is_connected = rpccli_bh_is_connected,
2181 .set_timeout = rpccli_bh_set_timeout,
2182 .raw_call_send = rpccli_bh_raw_call_send,
2183 .raw_call_recv = rpccli_bh_raw_call_recv,
2184 .disconnect_send = rpccli_bh_disconnect_send,
2185 .disconnect_recv = rpccli_bh_disconnect_recv,
2187 .ref_alloc = rpccli_bh_ref_alloc,
2188 .do_ndr_print = rpccli_bh_do_ndr_print,
2191 /* initialise a rpc_pipe_client binding handle */
2192 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2194 struct dcerpc_binding_handle *h;
2195 struct rpccli_bh_state *hs;
2197 h = dcerpc_binding_handle_create(c,
2202 struct rpccli_bh_state,
2212 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2213 struct pipe_auth_data **presult)
2215 struct pipe_auth_data *result;
2217 result = talloc(mem_ctx, struct pipe_auth_data);
2218 if (result == NULL) {
2219 return NT_STATUS_NO_MEMORY;
2222 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2223 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2225 result->user_name = talloc_strdup(result, "");
2226 result->domain = talloc_strdup(result, "");
2227 if ((result->user_name == NULL) || (result->domain == NULL)) {
2228 TALLOC_FREE(result);
2229 return NT_STATUS_NO_MEMORY;
2233 return NT_STATUS_OK;
2236 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2237 struct pipe_auth_data **presult)
2239 struct pipe_auth_data *result;
2241 result = talloc(mem_ctx, struct pipe_auth_data);
2242 if (result == NULL) {
2243 return NT_STATUS_NO_MEMORY;
2246 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2247 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2249 result->user_name = talloc_strdup(result, "");
2250 result->domain = talloc_strdup(result, "");
2251 if ((result->user_name == NULL) || (result->domain == NULL)) {
2252 TALLOC_FREE(result);
2253 return NT_STATUS_NO_MEMORY;
2257 return NT_STATUS_OK;
2260 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2261 enum dcerpc_AuthType auth_type,
2262 enum dcerpc_AuthLevel auth_level,
2264 const char *username,
2265 const char *password,
2266 struct pipe_auth_data **presult)
2268 struct auth_ntlmssp_state *ntlmssp_ctx;
2269 struct pipe_auth_data *result;
2272 result = talloc(mem_ctx, struct pipe_auth_data);
2273 if (result == NULL) {
2274 return NT_STATUS_NO_MEMORY;
2277 result->auth_type = auth_type;
2278 result->auth_level = auth_level;
2280 result->user_name = talloc_strdup(result, username);
2281 result->domain = talloc_strdup(result, domain);
2282 if ((result->user_name == NULL) || (result->domain == NULL)) {
2283 status = NT_STATUS_NO_MEMORY;
2287 status = auth_ntlmssp_client_prepare(result,
2289 if (!NT_STATUS_IS_OK(status)) {
2293 status = auth_ntlmssp_set_username(ntlmssp_ctx, username);
2294 if (!NT_STATUS_IS_OK(status)) {
2298 status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain);
2299 if (!NT_STATUS_IS_OK(status)) {
2303 status = auth_ntlmssp_set_password(ntlmssp_ctx, password);
2304 if (!NT_STATUS_IS_OK(status)) {
2308 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2309 gensec_want_feature(ntlmssp_ctx->gensec_security, GENSEC_FEATURE_SIGN);
2310 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2311 gensec_want_feature(ntlmssp_ctx->gensec_security, GENSEC_FEATURE_SEAL);
2314 status = auth_ntlmssp_client_start(ntlmssp_ctx);
2315 if (!NT_STATUS_IS_OK(status)) {
2319 result->auth_ctx = ntlmssp_ctx;
2321 return NT_STATUS_OK;
2324 TALLOC_FREE(result);
2328 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2329 enum dcerpc_AuthLevel auth_level,
2330 struct netlogon_creds_CredentialState *creds,
2331 struct pipe_auth_data **presult)
2333 struct schannel_state *schannel_auth;
2334 struct pipe_auth_data *result;
2336 result = talloc(mem_ctx, struct pipe_auth_data);
2337 if (result == NULL) {
2338 return NT_STATUS_NO_MEMORY;
2341 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2342 result->auth_level = auth_level;
2344 result->user_name = talloc_strdup(result, "");
2345 result->domain = talloc_strdup(result, domain);
2346 if ((result->user_name == NULL) || (result->domain == NULL)) {
2350 schannel_auth = talloc(result, struct schannel_state);
2351 if (schannel_auth == NULL) {
2355 schannel_auth->state = SCHANNEL_STATE_START;
2356 schannel_auth->seq_num = 0;
2357 schannel_auth->initiator = true;
2358 schannel_auth->creds = netlogon_creds_copy(result, creds);
2360 result->auth_ctx = schannel_auth;
2362 return NT_STATUS_OK;
2365 TALLOC_FREE(result);
2366 return NT_STATUS_NO_MEMORY;
2370 * Create an rpc pipe client struct, connecting to a tcp port.
2372 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2374 const struct ndr_syntax_id *abstract_syntax,
2375 struct rpc_pipe_client **presult)
2377 struct rpc_pipe_client *result;
2378 struct sockaddr_storage addr;
2382 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2383 if (result == NULL) {
2384 return NT_STATUS_NO_MEMORY;
2387 result->abstract_syntax = *abstract_syntax;
2388 result->transfer_syntax = ndr_transfer_syntax;
2390 result->desthost = talloc_strdup(result, host);
2391 result->srv_name_slash = talloc_asprintf_strupper_m(
2392 result, "\\\\%s", result->desthost);
2393 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2394 status = NT_STATUS_NO_MEMORY;
2398 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2399 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2401 if (!resolve_name(host, &addr, 0, false)) {
2402 status = NT_STATUS_NOT_FOUND;
2406 status = open_socket_out(&addr, port, 60*1000, &fd);
2407 if (!NT_STATUS_IS_OK(status)) {
2410 set_socket_options(fd, lp_socket_options());
2412 status = rpc_transport_sock_init(result, fd, &result->transport);
2413 if (!NT_STATUS_IS_OK(status)) {
2418 result->transport->transport = NCACN_IP_TCP;
2420 result->binding_handle = rpccli_bh_create(result);
2421 if (result->binding_handle == NULL) {
2422 TALLOC_FREE(result);
2423 return NT_STATUS_NO_MEMORY;
2427 return NT_STATUS_OK;
2430 TALLOC_FREE(result);
2435 * Determine the tcp port on which a dcerpc interface is listening
2436 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2439 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2440 const struct ndr_syntax_id *abstract_syntax,
2444 struct rpc_pipe_client *epm_pipe = NULL;
2445 struct dcerpc_binding_handle *epm_handle = NULL;
2446 struct pipe_auth_data *auth = NULL;
2447 struct dcerpc_binding *map_binding = NULL;
2448 struct dcerpc_binding *res_binding = NULL;
2449 struct epm_twr_t *map_tower = NULL;
2450 struct epm_twr_t *res_towers = NULL;
2451 struct policy_handle *entry_handle = NULL;
2452 uint32_t num_towers = 0;
2453 uint32_t max_towers = 1;
2454 struct epm_twr_p_t towers;
2455 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2456 uint32_t result = 0;
2458 if (pport == NULL) {
2459 status = NT_STATUS_INVALID_PARAMETER;
2463 if (ndr_syntax_id_equal(abstract_syntax,
2464 &ndr_table_epmapper.syntax_id)) {
2466 return NT_STATUS_OK;
2469 /* open the connection to the endpoint mapper */
2470 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2471 &ndr_table_epmapper.syntax_id,
2474 if (!NT_STATUS_IS_OK(status)) {
2477 epm_handle = epm_pipe->binding_handle;
2479 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2480 if (!NT_STATUS_IS_OK(status)) {
2484 status = rpc_pipe_bind(epm_pipe, auth);
2485 if (!NT_STATUS_IS_OK(status)) {
2489 /* create tower for asking the epmapper */
2491 map_binding = talloc_zero(tmp_ctx, struct dcerpc_binding);
2492 if (map_binding == NULL) {
2493 status = NT_STATUS_NO_MEMORY;
2497 map_binding->transport = NCACN_IP_TCP;
2498 map_binding->object = *abstract_syntax;
2499 map_binding->host = host; /* needed? */
2500 map_binding->endpoint = "0"; /* correct? needed? */
2502 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2503 if (map_tower == NULL) {
2504 status = NT_STATUS_NO_MEMORY;
2508 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2509 &(map_tower->tower));
2510 if (!NT_STATUS_IS_OK(status)) {
2514 /* allocate further parameters for the epm_Map call */
2516 res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2517 if (res_towers == NULL) {
2518 status = NT_STATUS_NO_MEMORY;
2521 towers.twr = res_towers;
2523 entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2524 if (entry_handle == NULL) {
2525 status = NT_STATUS_NO_MEMORY;
2529 /* ask the endpoint mapper for the port */
2531 status = dcerpc_epm_Map(epm_handle,
2533 discard_const_p(struct GUID,
2534 &(abstract_syntax->uuid)),
2542 if (!NT_STATUS_IS_OK(status)) {
2546 if (result != EPMAPPER_STATUS_OK) {
2547 status = NT_STATUS_UNSUCCESSFUL;
2551 if (num_towers != 1) {
2552 status = NT_STATUS_UNSUCCESSFUL;
2556 /* extract the port from the answer */
2558 status = dcerpc_binding_from_tower(tmp_ctx,
2559 &(towers.twr->tower),
2561 if (!NT_STATUS_IS_OK(status)) {
2565 /* are further checks here necessary? */
2566 if (res_binding->transport != NCACN_IP_TCP) {
2567 status = NT_STATUS_UNSUCCESSFUL;
2571 *pport = (uint16_t)atoi(res_binding->endpoint);
2574 TALLOC_FREE(tmp_ctx);
2579 * Create a rpc pipe client struct, connecting to a host via tcp.
2580 * The port is determined by asking the endpoint mapper on the given
2583 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2584 const struct ndr_syntax_id *abstract_syntax,
2585 struct rpc_pipe_client **presult)
2590 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2591 if (!NT_STATUS_IS_OK(status)) {
2595 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2596 abstract_syntax, presult);
2599 /********************************************************************
2600 Create a rpc pipe client struct, connecting to a unix domain socket
2601 ********************************************************************/
2602 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2603 const struct ndr_syntax_id *abstract_syntax,
2604 struct rpc_pipe_client **presult)
2606 struct rpc_pipe_client *result;
2607 struct sockaddr_un addr;
2611 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2612 if (result == NULL) {
2613 return NT_STATUS_NO_MEMORY;
2616 result->abstract_syntax = *abstract_syntax;
2617 result->transfer_syntax = ndr_transfer_syntax;
2619 result->desthost = get_myname(result);
2620 result->srv_name_slash = talloc_asprintf_strupper_m(
2621 result, "\\\\%s", result->desthost);
2622 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2623 status = NT_STATUS_NO_MEMORY;
2627 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2628 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2630 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2632 status = map_nt_error_from_unix(errno);
2637 addr.sun_family = AF_UNIX;
2638 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2640 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2641 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2644 return map_nt_error_from_unix(errno);
2647 status = rpc_transport_sock_init(result, fd, &result->transport);
2648 if (!NT_STATUS_IS_OK(status)) {
2653 result->transport->transport = NCALRPC;
2655 result->binding_handle = rpccli_bh_create(result);
2656 if (result->binding_handle == NULL) {
2657 TALLOC_FREE(result);
2658 return NT_STATUS_NO_MEMORY;
2662 return NT_STATUS_OK;
2665 TALLOC_FREE(result);
2669 struct rpc_pipe_client_np_ref {
2670 struct cli_state *cli;
2671 struct rpc_pipe_client *pipe;
2674 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2676 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2680 /****************************************************************************
2681 Open a named pipe over SMB to a remote server.
2683 * CAVEAT CALLER OF THIS FUNCTION:
2684 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2685 * so be sure that this function is called AFTER any structure (vs pointer)
2686 * assignment of the cli. In particular, libsmbclient does structure
2687 * assignments of cli, which invalidates the data in the returned
2688 * rpc_pipe_client if this function is called before the structure assignment
2691 ****************************************************************************/
2693 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2694 const struct ndr_syntax_id *abstract_syntax,
2695 struct rpc_pipe_client **presult)
2697 struct rpc_pipe_client *result;
2699 struct rpc_pipe_client_np_ref *np_ref;
2701 /* sanity check to protect against crashes */
2704 return NT_STATUS_INVALID_HANDLE;
2707 result = talloc_zero(NULL, struct rpc_pipe_client);
2708 if (result == NULL) {
2709 return NT_STATUS_NO_MEMORY;
2712 result->abstract_syntax = *abstract_syntax;
2713 result->transfer_syntax = ndr_transfer_syntax;
2714 result->desthost = talloc_strdup(result, cli_state_remote_name(cli));
2715 result->srv_name_slash = talloc_asprintf_strupper_m(
2716 result, "\\\\%s", result->desthost);
2718 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2719 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2721 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2722 TALLOC_FREE(result);
2723 return NT_STATUS_NO_MEMORY;
2726 status = rpc_transport_np_init(result, cli, abstract_syntax,
2727 &result->transport);
2728 if (!NT_STATUS_IS_OK(status)) {
2729 TALLOC_FREE(result);
2733 result->transport->transport = NCACN_NP;
2735 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2736 if (np_ref == NULL) {
2737 TALLOC_FREE(result);
2738 return NT_STATUS_NO_MEMORY;
2741 np_ref->pipe = result;
2743 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2744 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2746 result->binding_handle = rpccli_bh_create(result);
2747 if (result->binding_handle == NULL) {
2748 TALLOC_FREE(result);
2749 return NT_STATUS_NO_MEMORY;
2753 return NT_STATUS_OK;
2756 /****************************************************************************
2757 Open a pipe to a remote server.
2758 ****************************************************************************/
2760 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2761 enum dcerpc_transport_t transport,
2762 const struct ndr_syntax_id *interface,
2763 struct rpc_pipe_client **presult)
2765 switch (transport) {
2767 return rpc_pipe_open_tcp(NULL, cli_state_remote_name(cli),
2768 interface, presult);
2770 return rpc_pipe_open_np(cli, interface, presult);
2772 return NT_STATUS_NOT_IMPLEMENTED;
2776 /****************************************************************************
2777 Open a named pipe to an SMB server and bind anonymously.
2778 ****************************************************************************/
2780 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2781 enum dcerpc_transport_t transport,
2782 const struct ndr_syntax_id *interface,
2783 struct rpc_pipe_client **presult)
2785 struct rpc_pipe_client *result;
2786 struct pipe_auth_data *auth;
2789 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2790 if (!NT_STATUS_IS_OK(status)) {
2794 status = rpccli_anon_bind_data(result, &auth);
2795 if (!NT_STATUS_IS_OK(status)) {
2796 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2797 nt_errstr(status)));
2798 TALLOC_FREE(result);
2803 * This is a bit of an abstraction violation due to the fact that an
2804 * anonymous bind on an authenticated SMB inherits the user/domain
2805 * from the enclosing SMB creds
2808 TALLOC_FREE(auth->user_name);
2809 TALLOC_FREE(auth->domain);
2811 auth->user_name = talloc_strdup(auth, cli->user_name);
2812 auth->domain = talloc_strdup(auth, cli->domain);
2813 auth->user_session_key = data_blob_talloc(auth,
2814 cli->user_session_key.data,
2815 cli->user_session_key.length);
2817 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2818 TALLOC_FREE(result);
2819 return NT_STATUS_NO_MEMORY;
2822 status = rpc_pipe_bind(result, auth);
2823 if (!NT_STATUS_IS_OK(status)) {
2825 if (ndr_syntax_id_equal(interface,
2826 &ndr_table_dssetup.syntax_id)) {
2827 /* non AD domains just don't have this pipe, avoid
2828 * level 0 statement in that case - gd */
2831 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2832 "%s failed with error %s\n",
2833 get_pipe_name_from_syntax(talloc_tos(), interface),
2834 nt_errstr(status) ));
2835 TALLOC_FREE(result);
2839 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2840 "%s and bound anonymously.\n",
2841 get_pipe_name_from_syntax(talloc_tos(), interface),
2845 return NT_STATUS_OK;
2848 /****************************************************************************
2849 ****************************************************************************/
2851 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2852 const struct ndr_syntax_id *interface,
2853 struct rpc_pipe_client **presult)
2855 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2856 interface, presult);
2859 /****************************************************************************
2860 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2861 ****************************************************************************/
2863 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2864 const struct ndr_syntax_id *interface,
2865 enum dcerpc_transport_t transport,
2866 enum dcerpc_AuthLevel auth_level,
2868 const char *username,
2869 const char *password,
2870 struct rpc_pipe_client **presult)
2872 struct rpc_pipe_client *result;
2873 struct pipe_auth_data *auth = NULL;
2874 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2877 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2878 if (!NT_STATUS_IS_OK(status)) {
2882 status = rpccli_ntlmssp_bind_data(result,
2883 auth_type, auth_level,
2884 domain, username, password,
2886 if (!NT_STATUS_IS_OK(status)) {
2887 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2888 nt_errstr(status)));
2892 status = rpc_pipe_bind(result, auth);
2893 if (!NT_STATUS_IS_OK(status)) {
2894 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2895 nt_errstr(status) ));
2899 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2900 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2901 get_pipe_name_from_syntax(talloc_tos(), interface),
2902 result->desthost, domain, username));
2905 return NT_STATUS_OK;
2909 TALLOC_FREE(result);
2913 /****************************************************************************
2915 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2916 using session_key. sign and seal.
2918 The *pdc will be stolen onto this new pipe
2919 ****************************************************************************/
2921 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2922 const struct ndr_syntax_id *interface,
2923 enum dcerpc_transport_t transport,
2924 enum dcerpc_AuthLevel auth_level,
2926 struct netlogon_creds_CredentialState **pdc,
2927 struct rpc_pipe_client **presult)
2929 struct rpc_pipe_client *result;
2930 struct pipe_auth_data *auth;
2933 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2934 if (!NT_STATUS_IS_OK(status)) {
2938 status = rpccli_schannel_bind_data(result, domain, auth_level,
2940 if (!NT_STATUS_IS_OK(status)) {
2941 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2942 nt_errstr(status)));
2943 TALLOC_FREE(result);
2947 status = rpc_pipe_bind(result, auth);
2948 if (!NT_STATUS_IS_OK(status)) {
2949 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
2950 "cli_rpc_pipe_bind failed with error %s\n",
2951 nt_errstr(status) ));
2952 TALLOC_FREE(result);
2957 * The credentials on a new netlogon pipe are the ones we are passed
2958 * in - copy them over
2960 result->dc = netlogon_creds_copy(result, *pdc);
2961 if (result->dc == NULL) {
2962 TALLOC_FREE(result);
2963 return NT_STATUS_NO_MEMORY;
2966 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2967 "for domain %s and bound using schannel.\n",
2968 get_pipe_name_from_syntax(talloc_tos(), interface),
2969 result->desthost, domain));
2972 return NT_STATUS_OK;
2975 /****************************************************************************
2976 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2977 The idea is this can be called with service_princ, username and password all
2978 NULL so long as the caller has a TGT.
2979 ****************************************************************************/
2981 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
2982 const struct ndr_syntax_id *interface,
2983 enum dcerpc_transport_t transport,
2984 enum dcerpc_AuthLevel auth_level,
2986 const char *username,
2987 const char *password,
2988 struct rpc_pipe_client **presult)
2990 struct rpc_pipe_client *result;
2991 struct pipe_auth_data *auth;
2992 struct gse_context *gse_ctx;
2995 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2996 if (!NT_STATUS_IS_OK(status)) {
3000 auth = talloc(result, struct pipe_auth_data);
3002 status = NT_STATUS_NO_MEMORY;
3005 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3006 auth->auth_level = auth_level;
3011 auth->user_name = talloc_strdup(auth, username);
3012 if (!auth->user_name) {
3013 status = NT_STATUS_NO_MEMORY;
3017 /* Fixme, should we fetch/set the Realm ? */
3018 auth->domain = talloc_strdup(auth, "");
3019 if (!auth->domain) {
3020 status = NT_STATUS_NO_MEMORY;
3024 status = gse_init_client(auth,
3025 (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
3026 (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
3027 NULL, server, "cifs", username, password,
3028 GSS_C_DCE_STYLE, &gse_ctx);
3029 if (!NT_STATUS_IS_OK(status)) {
3030 DEBUG(0, ("gse_init_client returned %s\n",
3031 nt_errstr(status)));
3034 auth->auth_ctx = gse_ctx;
3036 status = rpc_pipe_bind(result, auth);
3037 if (!NT_STATUS_IS_OK(status)) {
3038 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3039 nt_errstr(status)));
3044 return NT_STATUS_OK;
3047 TALLOC_FREE(result);
3051 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3052 const struct ndr_syntax_id *interface,
3053 enum dcerpc_transport_t transport,
3054 enum dcerpc_AuthLevel auth_level,
3056 const char *username,
3057 const char *password,
3058 struct rpc_pipe_client **presult)
3060 struct rpc_pipe_client *result;
3061 struct pipe_auth_data *auth;
3062 struct spnego_context *spnego_ctx;
3065 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3066 if (!NT_STATUS_IS_OK(status)) {
3070 auth = talloc(result, struct pipe_auth_data);
3072 status = NT_STATUS_NO_MEMORY;
3075 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3076 auth->auth_level = auth_level;
3081 auth->user_name = talloc_strdup(auth, username);
3082 if (!auth->user_name) {
3083 status = NT_STATUS_NO_MEMORY;
3087 /* Fixme, should we fetch/set the Realm ? */
3088 auth->domain = talloc_strdup(auth, "");
3089 if (!auth->domain) {
3090 status = NT_STATUS_NO_MEMORY;
3094 status = spnego_gssapi_init_client(auth,
3095 (auth->auth_level ==
3096 DCERPC_AUTH_LEVEL_INTEGRITY),
3097 (auth->auth_level ==
3098 DCERPC_AUTH_LEVEL_PRIVACY),
3100 NULL, server, "cifs",
3103 if (!NT_STATUS_IS_OK(status)) {
3104 DEBUG(0, ("spnego_init_client returned %s\n",
3105 nt_errstr(status)));
3108 auth->auth_ctx = spnego_ctx;
3110 status = rpc_pipe_bind(result, auth);
3111 if (!NT_STATUS_IS_OK(status)) {
3112 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3113 nt_errstr(status)));
3118 return NT_STATUS_OK;
3121 TALLOC_FREE(result);
3125 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3126 const struct ndr_syntax_id *interface,
3127 enum dcerpc_transport_t transport,
3128 enum dcerpc_AuthLevel auth_level,
3130 const char *username,
3131 const char *password,
3132 struct rpc_pipe_client **presult)
3134 struct rpc_pipe_client *result;
3135 struct pipe_auth_data *auth;
3136 struct spnego_context *spnego_ctx;
3139 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3140 if (!NT_STATUS_IS_OK(status)) {
3144 auth = talloc(result, struct pipe_auth_data);
3146 status = NT_STATUS_NO_MEMORY;
3149 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3150 auth->auth_level = auth_level;
3155 auth->user_name = talloc_strdup(auth, username);
3156 if (!auth->user_name) {
3157 status = NT_STATUS_NO_MEMORY;
3164 auth->domain = talloc_strdup(auth, domain);
3165 if (!auth->domain) {
3166 status = NT_STATUS_NO_MEMORY;
3170 status = spnego_ntlmssp_init_client(auth,
3171 (auth->auth_level ==
3172 DCERPC_AUTH_LEVEL_INTEGRITY),
3173 (auth->auth_level ==
3174 DCERPC_AUTH_LEVEL_PRIVACY),
3176 domain, username, password,
3178 if (!NT_STATUS_IS_OK(status)) {
3179 DEBUG(0, ("spnego_init_client returned %s\n",
3180 nt_errstr(status)));
3183 auth->auth_ctx = spnego_ctx;
3185 status = rpc_pipe_bind(result, auth);
3186 if (!NT_STATUS_IS_OK(status)) {
3187 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3188 nt_errstr(status)));
3193 return NT_STATUS_OK;
3196 TALLOC_FREE(result);
3200 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3201 struct rpc_pipe_client *cli,
3202 DATA_BLOB *session_key)
3204 struct pipe_auth_data *a;
3205 struct schannel_state *schannel_auth;
3206 struct auth_ntlmssp_state *ntlmssp_ctx;
3207 struct spnego_context *spnego_ctx;
3208 struct gse_context *gse_ctx;
3209 DATA_BLOB sk = data_blob_null;
3210 bool make_dup = false;
3212 if (!session_key || !cli) {
3213 return NT_STATUS_INVALID_PARAMETER;
3219 return NT_STATUS_INVALID_PARAMETER;
3222 switch (cli->auth->auth_type) {
3223 case DCERPC_AUTH_TYPE_SCHANNEL:
3224 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3225 struct schannel_state);
3226 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3229 case DCERPC_AUTH_TYPE_SPNEGO:
3230 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
3231 struct spnego_context);
3232 sk = spnego_get_session_key(mem_ctx, spnego_ctx);
3235 case DCERPC_AUTH_TYPE_NTLMSSP:
3236 ntlmssp_ctx = talloc_get_type_abort(a->auth_ctx,
3237 struct auth_ntlmssp_state);
3238 sk = auth_ntlmssp_get_session_key(ntlmssp_ctx, mem_ctx);
3241 case DCERPC_AUTH_TYPE_KRB5:
3242 gse_ctx = talloc_get_type_abort(a->auth_ctx,
3243 struct gse_context);
3244 sk = gse_get_session_key(mem_ctx, gse_ctx);
3247 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3248 case DCERPC_AUTH_TYPE_NONE:
3249 sk = data_blob_const(a->user_session_key.data,
3250 a->user_session_key.length);
3258 return NT_STATUS_NO_USER_SESSION_KEY;
3262 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3267 return NT_STATUS_OK;