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 "../libcli/auth/ntlmssp.h"
29 #include "ntlmssp_wrap.h"
30 #include "librpc/gen_ndr/ndr_dcerpc.h"
31 #include "librpc/rpc/dcerpc.h"
32 #include "librpc/crypto/gse.h"
33 #include "librpc/crypto/spnego.h"
38 #define DBGC_CLASS DBGC_RPC_CLI
40 /********************************************************************
41 Pipe description for a DEBUG
42 ********************************************************************/
43 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
44 struct rpc_pipe_client *cli)
46 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
53 /********************************************************************
55 ********************************************************************/
57 static uint32 get_rpc_call_id(void)
59 static uint32 call_id = 0;
63 /*******************************************************************
64 Use SMBreadX to get rest of one fragment's worth of rpc data.
65 Reads the whole size or give an error message
66 ********************************************************************/
68 struct rpc_read_state {
69 struct event_context *ev;
70 struct rpc_cli_transport *transport;
76 static void rpc_read_done(struct tevent_req *subreq);
78 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
79 struct event_context *ev,
80 struct rpc_cli_transport *transport,
81 uint8_t *data, size_t size)
83 struct tevent_req *req, *subreq;
84 struct rpc_read_state *state;
86 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
91 state->transport = transport;
96 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
98 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
100 if (subreq == NULL) {
103 tevent_req_set_callback(subreq, rpc_read_done, req);
111 static void rpc_read_done(struct tevent_req *subreq)
113 struct tevent_req *req = tevent_req_callback_data(
114 subreq, struct tevent_req);
115 struct rpc_read_state *state = tevent_req_data(
116 req, struct rpc_read_state);
120 status = state->transport->read_recv(subreq, &received);
122 if (!NT_STATUS_IS_OK(status)) {
123 tevent_req_nterror(req, status);
127 state->num_read += received;
128 if (state->num_read == state->size) {
129 tevent_req_done(req);
133 subreq = state->transport->read_send(state, state->ev,
134 state->data + state->num_read,
135 state->size - state->num_read,
136 state->transport->priv);
137 if (tevent_req_nomem(subreq, req)) {
140 tevent_req_set_callback(subreq, rpc_read_done, req);
143 static NTSTATUS rpc_read_recv(struct tevent_req *req)
145 return tevent_req_simple_recv_ntstatus(req);
148 struct rpc_write_state {
149 struct event_context *ev;
150 struct rpc_cli_transport *transport;
156 static void rpc_write_done(struct tevent_req *subreq);
158 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
159 struct event_context *ev,
160 struct rpc_cli_transport *transport,
161 const uint8_t *data, size_t size)
163 struct tevent_req *req, *subreq;
164 struct rpc_write_state *state;
166 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
171 state->transport = transport;
174 state->num_written = 0;
176 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
178 subreq = transport->write_send(state, ev, data, size, transport->priv);
179 if (subreq == NULL) {
182 tevent_req_set_callback(subreq, rpc_write_done, req);
189 static void rpc_write_done(struct tevent_req *subreq)
191 struct tevent_req *req = tevent_req_callback_data(
192 subreq, struct tevent_req);
193 struct rpc_write_state *state = tevent_req_data(
194 req, struct rpc_write_state);
198 status = state->transport->write_recv(subreq, &written);
200 if (!NT_STATUS_IS_OK(status)) {
201 tevent_req_nterror(req, status);
205 state->num_written += written;
207 if (state->num_written == state->size) {
208 tevent_req_done(req);
212 subreq = state->transport->write_send(state, state->ev,
213 state->data + state->num_written,
214 state->size - state->num_written,
215 state->transport->priv);
216 if (tevent_req_nomem(subreq, req)) {
219 tevent_req_set_callback(subreq, rpc_write_done, req);
222 static NTSTATUS rpc_write_recv(struct tevent_req *req)
224 return tevent_req_simple_recv_ntstatus(req);
228 /****************************************************************************
229 Try and get a PDU's worth of data from current_pdu. If not, then read more
231 ****************************************************************************/
233 struct get_complete_frag_state {
234 struct event_context *ev;
235 struct rpc_pipe_client *cli;
240 static void get_complete_frag_got_header(struct tevent_req *subreq);
241 static void get_complete_frag_got_rest(struct tevent_req *subreq);
243 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
244 struct event_context *ev,
245 struct rpc_pipe_client *cli,
248 struct tevent_req *req, *subreq;
249 struct get_complete_frag_state *state;
253 req = tevent_req_create(mem_ctx, &state,
254 struct get_complete_frag_state);
260 state->frag_len = RPC_HEADER_LEN;
263 received = pdu->length;
264 if (received < RPC_HEADER_LEN) {
265 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
266 status = NT_STATUS_NO_MEMORY;
269 subreq = rpc_read_send(state, state->ev,
270 state->cli->transport,
271 pdu->data + received,
272 RPC_HEADER_LEN - received);
273 if (subreq == NULL) {
274 status = NT_STATUS_NO_MEMORY;
277 tevent_req_set_callback(subreq, get_complete_frag_got_header,
282 state->frag_len = dcerpc_get_frag_length(pdu);
285 * Ensure we have frag_len bytes of data.
287 if (received < state->frag_len) {
288 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
289 status = NT_STATUS_NO_MEMORY;
292 subreq = rpc_read_send(state, state->ev,
293 state->cli->transport,
294 pdu->data + received,
295 state->frag_len - received);
296 if (subreq == NULL) {
297 status = NT_STATUS_NO_MEMORY;
300 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
305 status = NT_STATUS_OK;
307 if (NT_STATUS_IS_OK(status)) {
308 tevent_req_done(req);
310 tevent_req_nterror(req, status);
312 return tevent_req_post(req, ev);
315 static void get_complete_frag_got_header(struct tevent_req *subreq)
317 struct tevent_req *req = tevent_req_callback_data(
318 subreq, struct tevent_req);
319 struct get_complete_frag_state *state = tevent_req_data(
320 req, struct get_complete_frag_state);
323 status = rpc_read_recv(subreq);
325 if (!NT_STATUS_IS_OK(status)) {
326 tevent_req_nterror(req, status);
330 state->frag_len = dcerpc_get_frag_length(state->pdu);
332 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
333 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
338 * We're here in this piece of code because we've read exactly
339 * RPC_HEADER_LEN bytes into state->pdu.
342 subreq = rpc_read_send(state, state->ev, state->cli->transport,
343 state->pdu->data + RPC_HEADER_LEN,
344 state->frag_len - RPC_HEADER_LEN);
345 if (tevent_req_nomem(subreq, req)) {
348 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
351 static void get_complete_frag_got_rest(struct tevent_req *subreq)
353 struct tevent_req *req = tevent_req_callback_data(
354 subreq, struct tevent_req);
357 status = rpc_read_recv(subreq);
359 if (!NT_STATUS_IS_OK(status)) {
360 tevent_req_nterror(req, status);
363 tevent_req_done(req);
366 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
368 return tevent_req_simple_recv_ntstatus(req);
371 /****************************************************************************
372 Do basic authentication checks on an incoming pdu.
373 ****************************************************************************/
375 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
376 struct rpc_pipe_client *cli,
377 struct ncacn_packet *pkt,
379 uint8_t expected_pkt_type,
381 DATA_BLOB *reply_pdu)
383 struct dcerpc_response *r;
384 NTSTATUS ret = NT_STATUS_OK;
388 * Point the return values at the real data including the RPC
389 * header. Just in case the caller wants it.
393 /* Ensure we have the correct type. */
394 switch (pkt->ptype) {
395 case DCERPC_PKT_ALTER_RESP:
396 case DCERPC_PKT_BIND_ACK:
398 /* Client code never receives this kind of packets */
402 case DCERPC_PKT_RESPONSE:
404 r = &pkt->u.response;
406 /* Here's where we deal with incoming sign/seal. */
407 ret = dcerpc_check_auth(cli->auth, pkt,
408 &r->stub_and_verifier,
409 DCERPC_RESPONSE_LENGTH,
411 if (!NT_STATUS_IS_OK(ret)) {
415 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
416 return NT_STATUS_BUFFER_TOO_SMALL;
419 /* Point the return values at the NDR data. */
420 rdata->data = r->stub_and_verifier.data;
422 if (pkt->auth_length) {
423 /* We've already done integer wrap tests in
424 * dcerpc_check_auth(). */
425 rdata->length = r->stub_and_verifier.length
427 - DCERPC_AUTH_TRAILER_LENGTH
430 rdata->length = r->stub_and_verifier.length;
433 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
434 (long unsigned int)pdu->length,
435 (long unsigned int)rdata->length,
436 (unsigned int)pad_len));
439 * If this is the first reply, and the allocation hint is
440 * reasonable, try and set up the reply_pdu DATA_BLOB to the
444 if ((reply_pdu->length == 0) &&
445 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
446 if (!data_blob_realloc(mem_ctx, reply_pdu,
448 DEBUG(0, ("reply alloc hint %d too "
449 "large to allocate\n",
450 (int)r->alloc_hint));
451 return NT_STATUS_NO_MEMORY;
457 case DCERPC_PKT_BIND_NAK:
458 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
459 rpccli_pipe_txt(talloc_tos(), cli)));
460 /* Use this for now... */
461 return NT_STATUS_NETWORK_ACCESS_DENIED;
463 case DCERPC_PKT_FAULT:
465 DEBUG(1, (__location__ ": RPC fault code %s received "
467 dcerpc_errstr(talloc_tos(),
468 pkt->u.fault.status),
469 rpccli_pipe_txt(talloc_tos(), cli)));
471 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
474 DEBUG(0, (__location__ "Unknown packet type %u received "
476 (unsigned int)pkt->ptype,
477 rpccli_pipe_txt(talloc_tos(), cli)));
478 return NT_STATUS_INVALID_INFO_CLASS;
481 if (pkt->ptype != expected_pkt_type) {
482 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
483 "RPC packet type - %u, not %u\n",
484 rpccli_pipe_txt(talloc_tos(), cli),
485 pkt->ptype, expected_pkt_type));
486 return NT_STATUS_INVALID_INFO_CLASS;
489 /* Do this just before return - we don't want to modify any rpc header
490 data before now as we may have needed to do cryptographic actions on
493 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
494 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
495 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
496 "fragment first/last ON.\n"));
497 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
503 /****************************************************************************
504 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
505 ****************************************************************************/
507 struct cli_api_pipe_state {
508 struct event_context *ev;
509 struct rpc_cli_transport *transport;
514 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
515 static void cli_api_pipe_write_done(struct tevent_req *subreq);
516 static void cli_api_pipe_read_done(struct tevent_req *subreq);
518 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
519 struct event_context *ev,
520 struct rpc_cli_transport *transport,
521 uint8_t *data, size_t data_len,
522 uint32_t max_rdata_len)
524 struct tevent_req *req, *subreq;
525 struct cli_api_pipe_state *state;
528 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
533 state->transport = transport;
535 if (max_rdata_len < RPC_HEADER_LEN) {
537 * For a RPC reply we always need at least RPC_HEADER_LEN
538 * bytes. We check this here because we will receive
539 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
541 status = NT_STATUS_INVALID_PARAMETER;
545 if (transport->trans_send != NULL) {
546 subreq = transport->trans_send(state, ev, data, data_len,
547 max_rdata_len, transport->priv);
548 if (subreq == NULL) {
551 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
556 * If the transport does not provide a "trans" routine, i.e. for
557 * example the ncacn_ip_tcp transport, do the write/read step here.
560 subreq = rpc_write_send(state, ev, transport, data, data_len);
561 if (subreq == NULL) {
564 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
568 tevent_req_nterror(req, status);
569 return tevent_req_post(req, ev);
575 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
577 struct tevent_req *req = tevent_req_callback_data(
578 subreq, struct tevent_req);
579 struct cli_api_pipe_state *state = tevent_req_data(
580 req, struct cli_api_pipe_state);
583 status = state->transport->trans_recv(subreq, state, &state->rdata,
586 if (!NT_STATUS_IS_OK(status)) {
587 tevent_req_nterror(req, status);
590 tevent_req_done(req);
593 static void cli_api_pipe_write_done(struct tevent_req *subreq)
595 struct tevent_req *req = tevent_req_callback_data(
596 subreq, struct tevent_req);
597 struct cli_api_pipe_state *state = tevent_req_data(
598 req, struct cli_api_pipe_state);
601 status = rpc_write_recv(subreq);
603 if (!NT_STATUS_IS_OK(status)) {
604 tevent_req_nterror(req, status);
608 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
609 if (tevent_req_nomem(state->rdata, req)) {
614 * We don't need to use rpc_read_send here, the upper layer will cope
615 * with a short read, transport->trans_send could also return less
616 * than state->max_rdata_len.
618 subreq = state->transport->read_send(state, state->ev, state->rdata,
620 state->transport->priv);
621 if (tevent_req_nomem(subreq, req)) {
624 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
627 static void cli_api_pipe_read_done(struct tevent_req *subreq)
629 struct tevent_req *req = tevent_req_callback_data(
630 subreq, struct tevent_req);
631 struct cli_api_pipe_state *state = tevent_req_data(
632 req, struct cli_api_pipe_state);
636 status = state->transport->read_recv(subreq, &received);
638 if (!NT_STATUS_IS_OK(status)) {
639 tevent_req_nterror(req, status);
642 state->rdata_len = received;
643 tevent_req_done(req);
646 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
647 uint8_t **prdata, uint32_t *prdata_len)
649 struct cli_api_pipe_state *state = tevent_req_data(
650 req, struct cli_api_pipe_state);
653 if (tevent_req_is_nterror(req, &status)) {
657 *prdata = talloc_move(mem_ctx, &state->rdata);
658 *prdata_len = state->rdata_len;
662 /****************************************************************************
663 Send data on an rpc pipe via trans. The data must be the last
664 pdu fragment of an NDR data stream.
666 Receive response data from an rpc pipe, which may be large...
668 Read the first fragment: unfortunately have to use SMBtrans for the first
669 bit, then SMBreadX for subsequent bits.
671 If first fragment received also wasn't the last fragment, continue
672 getting fragments until we _do_ receive the last fragment.
674 Request/Response PDU's look like the following...
676 |<------------------PDU len----------------------------------------------->|
677 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
679 +------------+-----------------+-------------+---------------+-------------+
680 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
681 +------------+-----------------+-------------+---------------+-------------+
683 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
684 signing & sealing being negotiated.
686 ****************************************************************************/
688 struct rpc_api_pipe_state {
689 struct event_context *ev;
690 struct rpc_pipe_client *cli;
691 uint8_t expected_pkt_type;
693 DATA_BLOB incoming_frag;
694 struct ncacn_packet *pkt;
698 size_t reply_pdu_offset;
702 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
703 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
704 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
706 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
707 struct event_context *ev,
708 struct rpc_pipe_client *cli,
709 DATA_BLOB *data, /* Outgoing PDU */
710 uint8_t expected_pkt_type)
712 struct tevent_req *req, *subreq;
713 struct rpc_api_pipe_state *state;
714 uint16_t max_recv_frag;
717 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
723 state->expected_pkt_type = expected_pkt_type;
724 state->incoming_frag = data_blob_null;
725 state->reply_pdu = data_blob_null;
726 state->reply_pdu_offset = 0;
727 state->endianess = DCERPC_DREP_LE;
730 * Ensure we're not sending too much.
732 if (data->length > cli->max_xmit_frag) {
733 status = NT_STATUS_INVALID_PARAMETER;
737 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
739 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
740 subreq = rpc_write_send(state, ev, cli->transport,
741 data->data, data->length);
742 if (subreq == NULL) {
745 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
749 /* get the header first, then fetch the rest once we have
750 * the frag_length available */
751 max_recv_frag = RPC_HEADER_LEN;
753 subreq = cli_api_pipe_send(state, ev, cli->transport,
754 data->data, data->length, max_recv_frag);
755 if (subreq == NULL) {
758 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
762 tevent_req_nterror(req, status);
763 return tevent_req_post(req, ev);
769 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
771 struct tevent_req *req =
772 tevent_req_callback_data(subreq,
776 status = rpc_write_recv(subreq);
778 if (!NT_STATUS_IS_OK(status)) {
779 tevent_req_nterror(req, status);
783 tevent_req_done(req);
786 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
788 struct tevent_req *req = tevent_req_callback_data(
789 subreq, struct tevent_req);
790 struct rpc_api_pipe_state *state = tevent_req_data(
791 req, struct rpc_api_pipe_state);
793 uint8_t *rdata = NULL;
794 uint32_t rdata_len = 0;
796 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
798 if (!NT_STATUS_IS_OK(status)) {
799 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
800 tevent_req_nterror(req, status);
805 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
806 rpccli_pipe_txt(talloc_tos(), state->cli)));
807 tevent_req_done(req);
812 * Move data on state->incoming_frag.
814 state->incoming_frag.data = talloc_move(state, &rdata);
815 state->incoming_frag.length = rdata_len;
816 if (!state->incoming_frag.data) {
817 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
821 /* Ensure we have enough data for a pdu. */
822 subreq = get_complete_frag_send(state, state->ev, state->cli,
823 &state->incoming_frag);
824 if (tevent_req_nomem(subreq, req)) {
827 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
830 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
832 struct tevent_req *req = tevent_req_callback_data(
833 subreq, struct tevent_req);
834 struct rpc_api_pipe_state *state = tevent_req_data(
835 req, struct rpc_api_pipe_state);
837 DATA_BLOB rdata = data_blob_null;
839 status = get_complete_frag_recv(subreq);
841 if (!NT_STATUS_IS_OK(status)) {
842 DEBUG(5, ("get_complete_frag failed: %s\n",
844 tevent_req_nterror(req, status);
848 state->pkt = talloc(state, struct ncacn_packet);
850 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
854 status = dcerpc_pull_ncacn_packet(state->pkt,
855 &state->incoming_frag,
858 if (!NT_STATUS_IS_OK(status)) {
859 tevent_req_nterror(req, status);
863 if (state->incoming_frag.length != state->pkt->frag_length) {
864 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
865 (unsigned int)state->incoming_frag.length,
866 (unsigned int)state->pkt->frag_length));
867 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
871 status = cli_pipe_validate_current_pdu(state,
872 state->cli, state->pkt,
873 &state->incoming_frag,
874 state->expected_pkt_type,
878 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
879 (unsigned)state->incoming_frag.length,
880 (unsigned)state->reply_pdu_offset,
883 if (!NT_STATUS_IS_OK(status)) {
884 tevent_req_nterror(req, status);
888 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
889 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
891 * Set the data type correctly for big-endian data on the
894 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
896 rpccli_pipe_txt(talloc_tos(), state->cli)));
897 state->endianess = 0x00; /* BIG ENDIAN */
900 * Check endianness on subsequent packets.
902 if (state->endianess != state->pkt->drep[0]) {
903 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
905 state->endianess?"little":"big",
906 state->pkt->drep[0]?"little":"big"));
907 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
911 /* Now copy the data portion out of the pdu into rbuf. */
912 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
913 if (!data_blob_realloc(NULL, &state->reply_pdu,
914 state->reply_pdu_offset + rdata.length)) {
915 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
920 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
921 rdata.data, rdata.length);
922 state->reply_pdu_offset += rdata.length;
924 /* reset state->incoming_frag, there is no need to free it,
925 * it will be reallocated to the right size the next time
927 state->incoming_frag.length = 0;
929 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
930 /* make sure the pdu length is right now that we
931 * have all the data available (alloc hint may
932 * have allocated more than was actually used) */
933 state->reply_pdu.length = state->reply_pdu_offset;
934 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
935 rpccli_pipe_txt(talloc_tos(), state->cli),
936 (unsigned)state->reply_pdu.length));
937 tevent_req_done(req);
941 subreq = get_complete_frag_send(state, state->ev, state->cli,
942 &state->incoming_frag);
943 if (tevent_req_nomem(subreq, req)) {
946 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
949 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
950 struct ncacn_packet **pkt,
951 DATA_BLOB *reply_pdu)
953 struct rpc_api_pipe_state *state = tevent_req_data(
954 req, struct rpc_api_pipe_state);
957 if (tevent_req_is_nterror(req, &status)) {
961 /* return data to caller and assign it ownership of memory */
963 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
964 reply_pdu->length = state->reply_pdu.length;
965 state->reply_pdu.length = 0;
967 data_blob_free(&state->reply_pdu);
971 *pkt = talloc_steal(mem_ctx, state->pkt);
977 /*******************************************************************
978 Creates spnego auth bind.
979 ********************************************************************/
981 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
982 struct pipe_auth_data *auth,
983 DATA_BLOB *auth_token)
985 struct spnego_context *spnego_ctx;
986 DATA_BLOB in_token = data_blob_null;
989 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
990 struct spnego_context);
992 /* Negotiate the initial auth token */
993 status = spnego_get_client_auth_token(mem_ctx, spnego_ctx,
994 &in_token, auth_token);
995 if (!NT_STATUS_IS_OK(status)) {
999 DEBUG(5, ("Created GSS Authentication Token:\n"));
1000 dump_data(5, auth_token->data, auth_token->length);
1002 return NT_STATUS_OK;
1005 /*******************************************************************
1006 Creates krb5 auth bind.
1007 ********************************************************************/
1009 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
1010 struct pipe_auth_data *auth,
1011 DATA_BLOB *auth_token)
1013 struct gse_context *gse_ctx;
1014 DATA_BLOB in_token = data_blob_null;
1017 gse_ctx = talloc_get_type_abort(auth->auth_ctx,
1018 struct gse_context);
1020 /* Negotiate the initial auth token */
1021 status = gse_get_client_auth_token(mem_ctx, gse_ctx,
1024 if (!NT_STATUS_IS_OK(status)) {
1028 DEBUG(5, ("Created GSS Authentication Token:\n"));
1029 dump_data(5, auth_token->data, auth_token->length);
1031 return NT_STATUS_OK;
1034 /*******************************************************************
1035 Creates NTLMSSP auth bind.
1036 ********************************************************************/
1038 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1039 DATA_BLOB *auth_token)
1041 struct auth_ntlmssp_state *ntlmssp_ctx;
1042 DATA_BLOB null_blob = data_blob_null;
1045 ntlmssp_ctx = talloc_get_type_abort(cli->auth->auth_ctx,
1046 struct auth_ntlmssp_state);
1048 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1049 status = auth_ntlmssp_update(ntlmssp_ctx, null_blob, auth_token);
1051 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1052 data_blob_free(auth_token);
1056 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1057 dump_data(5, auth_token->data, auth_token->length);
1059 return NT_STATUS_OK;
1062 /*******************************************************************
1063 Creates schannel auth bind.
1064 ********************************************************************/
1066 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1067 DATA_BLOB *auth_token)
1070 struct NL_AUTH_MESSAGE r;
1072 /* Use lp_workgroup() if domain not specified */
1074 if (!cli->auth->domain || !cli->auth->domain[0]) {
1075 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1076 if (cli->auth->domain == NULL) {
1077 return NT_STATUS_NO_MEMORY;
1082 * Now marshall the data into the auth parse_struct.
1085 r.MessageType = NL_NEGOTIATE_REQUEST;
1086 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1087 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1088 r.oem_netbios_domain.a = cli->auth->domain;
1089 r.oem_netbios_computer.a = global_myname();
1091 status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1092 if (!NT_STATUS_IS_OK(status)) {
1096 return NT_STATUS_OK;
1099 /*******************************************************************
1100 Creates the internals of a DCE/RPC bind request or alter context PDU.
1101 ********************************************************************/
1103 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1104 enum dcerpc_pkt_type ptype,
1106 const struct ndr_syntax_id *abstract,
1107 const struct ndr_syntax_id *transfer,
1108 const DATA_BLOB *auth_info,
1111 uint16 auth_len = auth_info->length;
1113 union dcerpc_payload u;
1114 struct dcerpc_ctx_list ctx_list;
1117 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1120 ctx_list.context_id = 0;
1121 ctx_list.num_transfer_syntaxes = 1;
1122 ctx_list.abstract_syntax = *abstract;
1123 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1125 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1126 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1127 u.bind.assoc_group_id = 0x0;
1128 u.bind.num_contexts = 1;
1129 u.bind.ctx_list = &ctx_list;
1130 u.bind.auth_info = *auth_info;
1132 status = dcerpc_push_ncacn_packet(mem_ctx,
1134 DCERPC_PFC_FLAG_FIRST |
1135 DCERPC_PFC_FLAG_LAST,
1140 if (!NT_STATUS_IS_OK(status)) {
1141 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1145 return NT_STATUS_OK;
1148 /*******************************************************************
1149 Creates a DCE/RPC bind request.
1150 ********************************************************************/
1152 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1153 struct rpc_pipe_client *cli,
1154 struct pipe_auth_data *auth,
1156 const struct ndr_syntax_id *abstract,
1157 const struct ndr_syntax_id *transfer,
1160 DATA_BLOB auth_token = data_blob_null;
1161 DATA_BLOB auth_info = data_blob_null;
1162 NTSTATUS ret = NT_STATUS_OK;
1164 switch (auth->auth_type) {
1165 case DCERPC_AUTH_TYPE_SCHANNEL:
1166 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1167 if (!NT_STATUS_IS_OK(ret)) {
1172 case DCERPC_AUTH_TYPE_NTLMSSP:
1173 ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token);
1174 if (!NT_STATUS_IS_OK(ret)) {
1179 case DCERPC_AUTH_TYPE_SPNEGO:
1180 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1181 if (!NT_STATUS_IS_OK(ret)) {
1186 case DCERPC_AUTH_TYPE_KRB5:
1187 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
1188 if (!NT_STATUS_IS_OK(ret)) {
1193 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1194 auth_token = data_blob_talloc(mem_ctx,
1195 "NCALRPC_AUTH_TOKEN",
1199 case DCERPC_AUTH_TYPE_NONE:
1203 /* "Can't" happen. */
1204 return NT_STATUS_INVALID_INFO_CLASS;
1207 if (auth_token.length != 0) {
1208 ret = dcerpc_push_dcerpc_auth(cli,
1211 0, /* auth_pad_length */
1212 1, /* auth_context_id */
1215 if (!NT_STATUS_IS_OK(ret)) {
1218 data_blob_free(&auth_token);
1221 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1231 /*******************************************************************
1233 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1234 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1235 and deals with signing/sealing details.
1236 ********************************************************************/
1238 struct rpc_api_pipe_req_state {
1239 struct event_context *ev;
1240 struct rpc_pipe_client *cli;
1243 DATA_BLOB *req_data;
1244 uint32_t req_data_sent;
1246 DATA_BLOB reply_pdu;
1249 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1250 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1251 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1252 bool *is_last_frag);
1254 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1255 struct event_context *ev,
1256 struct rpc_pipe_client *cli,
1258 DATA_BLOB *req_data)
1260 struct tevent_req *req, *subreq;
1261 struct rpc_api_pipe_req_state *state;
1265 req = tevent_req_create(mem_ctx, &state,
1266 struct rpc_api_pipe_req_state);
1272 state->op_num = op_num;
1273 state->req_data = req_data;
1274 state->req_data_sent = 0;
1275 state->call_id = get_rpc_call_id();
1276 state->reply_pdu = data_blob_null;
1277 state->rpc_out = data_blob_null;
1279 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1280 + RPC_MAX_SIGN_SIZE) {
1281 /* Server is screwed up ! */
1282 status = NT_STATUS_INVALID_PARAMETER;
1286 status = prepare_next_frag(state, &is_last_frag);
1287 if (!NT_STATUS_IS_OK(status)) {
1292 subreq = rpc_api_pipe_send(state, ev, state->cli,
1294 DCERPC_PKT_RESPONSE);
1295 if (subreq == NULL) {
1298 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1300 subreq = rpc_write_send(state, ev, cli->transport,
1301 state->rpc_out.data,
1302 state->rpc_out.length);
1303 if (subreq == NULL) {
1306 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1312 tevent_req_nterror(req, status);
1313 return tevent_req_post(req, ev);
1319 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1322 size_t data_sent_thistime;
1329 union dcerpc_payload u;
1331 data_left = state->req_data->length - state->req_data_sent;
1333 status = dcerpc_guess_sizes(state->cli->auth,
1334 DCERPC_REQUEST_LENGTH, data_left,
1335 state->cli->max_xmit_frag,
1336 CLIENT_NDR_PADDING_SIZE,
1337 &data_sent_thistime,
1338 &frag_len, &auth_len, &pad_len);
1339 if (!NT_STATUS_IS_OK(status)) {
1343 if (state->req_data_sent == 0) {
1344 flags = DCERPC_PFC_FLAG_FIRST;
1347 if (data_sent_thistime == data_left) {
1348 flags |= DCERPC_PFC_FLAG_LAST;
1351 data_blob_free(&state->rpc_out);
1353 ZERO_STRUCT(u.request);
1355 u.request.alloc_hint = state->req_data->length;
1356 u.request.context_id = 0;
1357 u.request.opnum = state->op_num;
1359 status = dcerpc_push_ncacn_packet(state,
1366 if (!NT_STATUS_IS_OK(status)) {
1370 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1371 * compute it right for requests because the auth trailer is missing
1373 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1375 /* Copy in the data. */
1376 if (!data_blob_append(NULL, &state->rpc_out,
1377 state->req_data->data + state->req_data_sent,
1378 data_sent_thistime)) {
1379 return NT_STATUS_NO_MEMORY;
1382 switch (state->cli->auth->auth_level) {
1383 case DCERPC_AUTH_LEVEL_NONE:
1384 case DCERPC_AUTH_LEVEL_CONNECT:
1385 case DCERPC_AUTH_LEVEL_PACKET:
1387 case DCERPC_AUTH_LEVEL_INTEGRITY:
1388 case DCERPC_AUTH_LEVEL_PRIVACY:
1389 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1391 if (!NT_STATUS_IS_OK(status)) {
1396 return NT_STATUS_INVALID_PARAMETER;
1399 state->req_data_sent += data_sent_thistime;
1400 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1405 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1407 struct tevent_req *req = tevent_req_callback_data(
1408 subreq, struct tevent_req);
1409 struct rpc_api_pipe_req_state *state = tevent_req_data(
1410 req, struct rpc_api_pipe_req_state);
1414 status = rpc_write_recv(subreq);
1415 TALLOC_FREE(subreq);
1416 if (!NT_STATUS_IS_OK(status)) {
1417 tevent_req_nterror(req, status);
1421 status = prepare_next_frag(state, &is_last_frag);
1422 if (!NT_STATUS_IS_OK(status)) {
1423 tevent_req_nterror(req, status);
1428 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1430 DCERPC_PKT_RESPONSE);
1431 if (tevent_req_nomem(subreq, req)) {
1434 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1436 subreq = rpc_write_send(state, state->ev,
1437 state->cli->transport,
1438 state->rpc_out.data,
1439 state->rpc_out.length);
1440 if (tevent_req_nomem(subreq, req)) {
1443 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1448 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1450 struct tevent_req *req = tevent_req_callback_data(
1451 subreq, struct tevent_req);
1452 struct rpc_api_pipe_req_state *state = tevent_req_data(
1453 req, struct rpc_api_pipe_req_state);
1456 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1457 TALLOC_FREE(subreq);
1458 if (!NT_STATUS_IS_OK(status)) {
1459 tevent_req_nterror(req, status);
1462 tevent_req_done(req);
1465 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1466 DATA_BLOB *reply_pdu)
1468 struct rpc_api_pipe_req_state *state = tevent_req_data(
1469 req, struct rpc_api_pipe_req_state);
1472 if (tevent_req_is_nterror(req, &status)) {
1474 * We always have to initialize to reply pdu, even if there is
1475 * none. The rpccli_* caller routines expect this.
1477 *reply_pdu = data_blob_null;
1481 /* return data to caller and assign it ownership of memory */
1482 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1483 reply_pdu->length = state->reply_pdu.length;
1484 state->reply_pdu.length = 0;
1486 return NT_STATUS_OK;
1489 /****************************************************************************
1490 Check the rpc bind acknowledge response.
1491 ****************************************************************************/
1493 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1494 const struct ndr_syntax_id *transfer)
1496 struct dcerpc_ack_ctx ctx;
1498 if (r->secondary_address_size == 0) {
1499 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1502 if (r->num_results < 1 || !r->ctx_list) {
1506 ctx = r->ctx_list[0];
1508 /* check the transfer syntax */
1509 if ((ctx.syntax.if_version != transfer->if_version) ||
1510 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1511 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1515 if (r->num_results != 0x1 || ctx.result != 0) {
1516 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1517 r->num_results, ctx.reason));
1520 DEBUG(5,("check_bind_response: accepted!\n"));
1524 /*******************************************************************
1525 Creates a DCE/RPC bind authentication response.
1526 This is the packet that is sent back to the server once we
1527 have received a BIND-ACK, to finish the third leg of
1528 the authentication handshake.
1529 ********************************************************************/
1531 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1532 struct rpc_pipe_client *cli,
1534 enum dcerpc_AuthType auth_type,
1535 enum dcerpc_AuthLevel auth_level,
1536 DATA_BLOB *pauth_blob,
1540 union dcerpc_payload u;
1544 status = dcerpc_push_dcerpc_auth(mem_ctx,
1547 0, /* auth_pad_length */
1548 1, /* auth_context_id */
1550 &u.auth3.auth_info);
1551 if (!NT_STATUS_IS_OK(status)) {
1555 status = dcerpc_push_ncacn_packet(mem_ctx,
1557 DCERPC_PFC_FLAG_FIRST |
1558 DCERPC_PFC_FLAG_LAST,
1563 data_blob_free(&u.auth3.auth_info);
1564 if (!NT_STATUS_IS_OK(status)) {
1565 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1569 return NT_STATUS_OK;
1572 /*******************************************************************
1573 Creates a DCE/RPC bind alter context authentication request which
1574 may contain a spnego auth blobl
1575 ********************************************************************/
1577 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1578 enum dcerpc_AuthType auth_type,
1579 enum dcerpc_AuthLevel auth_level,
1581 const struct ndr_syntax_id *abstract,
1582 const struct ndr_syntax_id *transfer,
1583 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1586 DATA_BLOB auth_info;
1589 status = dcerpc_push_dcerpc_auth(mem_ctx,
1592 0, /* auth_pad_length */
1593 1, /* auth_context_id */
1596 if (!NT_STATUS_IS_OK(status)) {
1600 status = create_bind_or_alt_ctx_internal(mem_ctx,
1607 data_blob_free(&auth_info);
1611 /****************************************************************************
1613 ****************************************************************************/
1615 struct rpc_pipe_bind_state {
1616 struct event_context *ev;
1617 struct rpc_pipe_client *cli;
1620 uint32_t rpc_call_id;
1623 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1624 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1625 struct rpc_pipe_bind_state *state,
1626 DATA_BLOB *credentials);
1627 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1628 struct rpc_pipe_bind_state *state,
1629 DATA_BLOB *credentials);
1631 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1632 struct event_context *ev,
1633 struct rpc_pipe_client *cli,
1634 struct pipe_auth_data *auth)
1636 struct tevent_req *req, *subreq;
1637 struct rpc_pipe_bind_state *state;
1640 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1645 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1646 rpccli_pipe_txt(talloc_tos(), cli),
1647 (unsigned int)auth->auth_type,
1648 (unsigned int)auth->auth_level ));
1652 state->rpc_call_id = get_rpc_call_id();
1654 cli->auth = talloc_move(cli, &auth);
1656 /* Marshall the outgoing data. */
1657 status = create_rpc_bind_req(state, cli,
1660 &cli->abstract_syntax,
1661 &cli->transfer_syntax,
1664 if (!NT_STATUS_IS_OK(status)) {
1668 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1669 DCERPC_PKT_BIND_ACK);
1670 if (subreq == NULL) {
1673 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1677 tevent_req_nterror(req, status);
1678 return tevent_req_post(req, ev);
1684 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1686 struct tevent_req *req = tevent_req_callback_data(
1687 subreq, struct tevent_req);
1688 struct rpc_pipe_bind_state *state = tevent_req_data(
1689 req, struct rpc_pipe_bind_state);
1690 struct pipe_auth_data *pauth = state->cli->auth;
1691 struct auth_ntlmssp_state *ntlmssp_ctx;
1692 struct spnego_context *spnego_ctx;
1693 struct gse_context *gse_ctx;
1694 struct ncacn_packet *pkt = NULL;
1695 struct dcerpc_auth auth;
1696 DATA_BLOB auth_token = data_blob_null;
1699 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1700 TALLOC_FREE(subreq);
1701 if (!NT_STATUS_IS_OK(status)) {
1702 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1703 rpccli_pipe_txt(talloc_tos(), state->cli),
1704 nt_errstr(status)));
1705 tevent_req_nterror(req, status);
1710 tevent_req_done(req);
1714 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1715 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1716 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1720 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1721 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1723 switch(pauth->auth_type) {
1725 case DCERPC_AUTH_TYPE_NONE:
1726 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1727 case DCERPC_AUTH_TYPE_SCHANNEL:
1728 /* Bind complete. */
1729 tevent_req_done(req);
1732 case DCERPC_AUTH_TYPE_NTLMSSP:
1733 case DCERPC_AUTH_TYPE_SPNEGO:
1734 case DCERPC_AUTH_TYPE_KRB5:
1735 /* Paranoid lenght checks */
1736 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1737 + pkt->auth_length) {
1738 tevent_req_nterror(req,
1739 NT_STATUS_INFO_LENGTH_MISMATCH);
1742 /* get auth credentials */
1743 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1744 &pkt->u.bind_ack.auth_info,
1746 if (!NT_STATUS_IS_OK(status)) {
1747 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1748 nt_errstr(status)));
1749 tevent_req_nterror(req, status);
1759 * For authenticated binds we may need to do 3 or 4 leg binds.
1762 switch(pauth->auth_type) {
1764 case DCERPC_AUTH_TYPE_NONE:
1765 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1766 case DCERPC_AUTH_TYPE_SCHANNEL:
1767 /* Bind complete. */
1768 tevent_req_done(req);
1771 case DCERPC_AUTH_TYPE_NTLMSSP:
1772 ntlmssp_ctx = talloc_get_type_abort(pauth->auth_ctx,
1773 struct auth_ntlmssp_state);
1774 status = auth_ntlmssp_update(ntlmssp_ctx,
1775 auth.credentials, &auth_token);
1776 if (NT_STATUS_EQUAL(status,
1777 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1778 status = rpc_bind_next_send(req, state,
1780 } else if (NT_STATUS_IS_OK(status)) {
1781 status = rpc_bind_finish_send(req, state,
1786 case DCERPC_AUTH_TYPE_SPNEGO:
1787 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
1788 struct spnego_context);
1789 status = spnego_get_client_auth_token(state,
1793 if (!NT_STATUS_IS_OK(status)) {
1796 if (auth_token.length == 0) {
1797 /* Bind complete. */
1798 tevent_req_done(req);
1801 if (spnego_require_more_processing(spnego_ctx)) {
1802 status = rpc_bind_next_send(req, state,
1805 status = rpc_bind_finish_send(req, state,
1810 case DCERPC_AUTH_TYPE_KRB5:
1811 gse_ctx = talloc_get_type_abort(pauth->auth_ctx,
1812 struct gse_context);
1813 status = gse_get_client_auth_token(state,
1817 if (!NT_STATUS_IS_OK(status)) {
1821 if (gse_require_more_processing(gse_ctx)) {
1822 status = rpc_bind_next_send(req, state, &auth_token);
1824 status = rpc_bind_finish_send(req, state, &auth_token);
1832 if (!NT_STATUS_IS_OK(status)) {
1833 tevent_req_nterror(req, status);
1838 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1839 (unsigned int)state->cli->auth->auth_type));
1840 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1843 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1844 struct rpc_pipe_bind_state *state,
1845 DATA_BLOB *auth_token)
1847 struct pipe_auth_data *auth = state->cli->auth;
1848 struct tevent_req *subreq;
1851 /* Now prepare the alter context pdu. */
1852 data_blob_free(&state->rpc_out);
1854 status = create_rpc_alter_context(state,
1858 &state->cli->abstract_syntax,
1859 &state->cli->transfer_syntax,
1862 if (!NT_STATUS_IS_OK(status)) {
1866 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1867 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1868 if (subreq == NULL) {
1869 return NT_STATUS_NO_MEMORY;
1871 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1872 return NT_STATUS_OK;
1875 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1876 struct rpc_pipe_bind_state *state,
1877 DATA_BLOB *auth_token)
1879 struct pipe_auth_data *auth = state->cli->auth;
1880 struct tevent_req *subreq;
1883 state->auth3 = true;
1885 /* Now prepare the auth3 context pdu. */
1886 data_blob_free(&state->rpc_out);
1888 status = create_rpc_bind_auth3(state, state->cli,
1894 if (!NT_STATUS_IS_OK(status)) {
1898 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1899 &state->rpc_out, DCERPC_PKT_AUTH3);
1900 if (subreq == NULL) {
1901 return NT_STATUS_NO_MEMORY;
1903 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1904 return NT_STATUS_OK;
1907 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1909 return tevent_req_simple_recv_ntstatus(req);
1912 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1913 struct pipe_auth_data *auth)
1915 TALLOC_CTX *frame = talloc_stackframe();
1916 struct event_context *ev;
1917 struct tevent_req *req;
1918 NTSTATUS status = NT_STATUS_OK;
1920 ev = event_context_init(frame);
1922 status = NT_STATUS_NO_MEMORY;
1926 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1928 status = NT_STATUS_NO_MEMORY;
1932 if (!tevent_req_poll(req, ev)) {
1933 status = map_nt_error_from_unix(errno);
1937 status = rpc_pipe_bind_recv(req);
1943 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1945 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1946 unsigned int timeout)
1950 if (rpc_cli->transport == NULL) {
1951 return RPCCLI_DEFAULT_TIMEOUT;
1954 if (rpc_cli->transport->set_timeout == NULL) {
1955 return RPCCLI_DEFAULT_TIMEOUT;
1958 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1960 return RPCCLI_DEFAULT_TIMEOUT;
1966 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1968 if (rpc_cli == NULL) {
1972 if (rpc_cli->transport == NULL) {
1976 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1979 struct rpccli_bh_state {
1980 struct rpc_pipe_client *rpc_cli;
1983 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1985 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1986 struct rpccli_bh_state);
1988 return rpccli_is_connected(hs->rpc_cli);
1991 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1994 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1995 struct rpccli_bh_state);
1997 return rpccli_set_timeout(hs->rpc_cli, timeout);
2000 struct rpccli_bh_raw_call_state {
2006 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2008 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2009 struct tevent_context *ev,
2010 struct dcerpc_binding_handle *h,
2011 const struct GUID *object,
2014 const uint8_t *in_data,
2017 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2018 struct rpccli_bh_state);
2019 struct tevent_req *req;
2020 struct rpccli_bh_raw_call_state *state;
2022 struct tevent_req *subreq;
2024 req = tevent_req_create(mem_ctx, &state,
2025 struct rpccli_bh_raw_call_state);
2029 state->in_data.data = discard_const_p(uint8_t, in_data);
2030 state->in_data.length = in_length;
2032 ok = rpccli_bh_is_connected(h);
2034 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2035 return tevent_req_post(req, ev);
2038 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2039 opnum, &state->in_data);
2040 if (tevent_req_nomem(subreq, req)) {
2041 return tevent_req_post(req, ev);
2043 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2048 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2050 struct tevent_req *req =
2051 tevent_req_callback_data(subreq,
2053 struct rpccli_bh_raw_call_state *state =
2054 tevent_req_data(req,
2055 struct rpccli_bh_raw_call_state);
2058 state->out_flags = 0;
2060 /* TODO: support bigendian responses */
2062 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2063 TALLOC_FREE(subreq);
2064 if (!NT_STATUS_IS_OK(status)) {
2065 tevent_req_nterror(req, status);
2069 tevent_req_done(req);
2072 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2073 TALLOC_CTX *mem_ctx,
2076 uint32_t *out_flags)
2078 struct rpccli_bh_raw_call_state *state =
2079 tevent_req_data(req,
2080 struct rpccli_bh_raw_call_state);
2083 if (tevent_req_is_nterror(req, &status)) {
2084 tevent_req_received(req);
2088 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2089 *out_length = state->out_data.length;
2090 *out_flags = state->out_flags;
2091 tevent_req_received(req);
2092 return NT_STATUS_OK;
2095 struct rpccli_bh_disconnect_state {
2099 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2100 struct tevent_context *ev,
2101 struct dcerpc_binding_handle *h)
2103 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2104 struct rpccli_bh_state);
2105 struct tevent_req *req;
2106 struct rpccli_bh_disconnect_state *state;
2109 req = tevent_req_create(mem_ctx, &state,
2110 struct rpccli_bh_disconnect_state);
2115 ok = rpccli_bh_is_connected(h);
2117 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2118 return tevent_req_post(req, ev);
2122 * TODO: do a real async disconnect ...
2124 * For now the caller needs to free rpc_cli
2128 tevent_req_done(req);
2129 return tevent_req_post(req, ev);
2132 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2136 if (tevent_req_is_nterror(req, &status)) {
2137 tevent_req_received(req);
2141 tevent_req_received(req);
2142 return NT_STATUS_OK;
2145 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2150 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2152 const void *_struct_ptr,
2153 const struct ndr_interface_call *call)
2155 void *struct_ptr = discard_const(_struct_ptr);
2157 if (DEBUGLEVEL < 10) {
2161 if (ndr_flags & NDR_IN) {
2162 ndr_print_function_debug(call->ndr_print,
2167 if (ndr_flags & NDR_OUT) {
2168 ndr_print_function_debug(call->ndr_print,
2175 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2177 .is_connected = rpccli_bh_is_connected,
2178 .set_timeout = rpccli_bh_set_timeout,
2179 .raw_call_send = rpccli_bh_raw_call_send,
2180 .raw_call_recv = rpccli_bh_raw_call_recv,
2181 .disconnect_send = rpccli_bh_disconnect_send,
2182 .disconnect_recv = rpccli_bh_disconnect_recv,
2184 .ref_alloc = rpccli_bh_ref_alloc,
2185 .do_ndr_print = rpccli_bh_do_ndr_print,
2188 /* initialise a rpc_pipe_client binding handle */
2189 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2191 struct dcerpc_binding_handle *h;
2192 struct rpccli_bh_state *hs;
2194 h = dcerpc_binding_handle_create(c,
2199 struct rpccli_bh_state,
2209 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2211 struct auth_ntlmssp_state *a = NULL;
2212 struct cli_state *cli;
2214 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2215 a = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2216 struct auth_ntlmssp_state);
2217 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2218 struct spnego_context *spnego_ctx;
2219 enum spnego_mech auth_type;
2223 spnego_ctx = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2224 struct spnego_context);
2225 status = spnego_get_negotiated_mech(spnego_ctx,
2226 &auth_type, &auth_ctx);
2227 if (!NT_STATUS_IS_OK(status)) {
2231 if (auth_type == SPNEGO_NTLMSSP) {
2232 a = talloc_get_type_abort(auth_ctx,
2233 struct auth_ntlmssp_state);
2238 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2242 cli = rpc_pipe_np_smb_conn(rpc_cli);
2246 E_md4hash(cli->password ? cli->password : "", nt_hash);
2250 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2251 struct pipe_auth_data **presult)
2253 struct pipe_auth_data *result;
2255 result = talloc(mem_ctx, struct pipe_auth_data);
2256 if (result == NULL) {
2257 return NT_STATUS_NO_MEMORY;
2260 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2261 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2263 result->user_name = talloc_strdup(result, "");
2264 result->domain = talloc_strdup(result, "");
2265 if ((result->user_name == NULL) || (result->domain == NULL)) {
2266 TALLOC_FREE(result);
2267 return NT_STATUS_NO_MEMORY;
2271 return NT_STATUS_OK;
2274 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2275 struct pipe_auth_data **presult)
2277 struct pipe_auth_data *result;
2279 result = talloc(mem_ctx, struct pipe_auth_data);
2280 if (result == NULL) {
2281 return NT_STATUS_NO_MEMORY;
2284 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2285 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2287 result->user_name = talloc_strdup(result, "");
2288 result->domain = talloc_strdup(result, "");
2289 if ((result->user_name == NULL) || (result->domain == NULL)) {
2290 TALLOC_FREE(result);
2291 return NT_STATUS_NO_MEMORY;
2295 return NT_STATUS_OK;
2298 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2300 TALLOC_FREE(auth->auth_ctx);
2304 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2305 enum dcerpc_AuthType auth_type,
2306 enum dcerpc_AuthLevel auth_level,
2308 const char *username,
2309 const char *password,
2310 struct pipe_auth_data **presult)
2312 struct auth_ntlmssp_state *ntlmssp_ctx;
2313 struct pipe_auth_data *result;
2316 result = talloc(mem_ctx, struct pipe_auth_data);
2317 if (result == NULL) {
2318 return NT_STATUS_NO_MEMORY;
2321 result->auth_type = auth_type;
2322 result->auth_level = auth_level;
2324 result->user_name = talloc_strdup(result, username);
2325 result->domain = talloc_strdup(result, domain);
2326 if ((result->user_name == NULL) || (result->domain == NULL)) {
2327 status = NT_STATUS_NO_MEMORY;
2331 status = auth_ntlmssp_client_start(NULL,
2334 lp_client_ntlmv2_auth(),
2336 if (!NT_STATUS_IS_OK(status)) {
2340 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2342 status = auth_ntlmssp_set_username(ntlmssp_ctx, username);
2343 if (!NT_STATUS_IS_OK(status)) {
2347 status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain);
2348 if (!NT_STATUS_IS_OK(status)) {
2352 status = auth_ntlmssp_set_password(ntlmssp_ctx, password);
2353 if (!NT_STATUS_IS_OK(status)) {
2358 * Turn off sign+seal to allow selected auth level to turn it back on.
2360 auth_ntlmssp_and_flags(ntlmssp_ctx, ~(NTLMSSP_NEGOTIATE_SIGN |
2361 NTLMSSP_NEGOTIATE_SEAL));
2363 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2364 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SIGN);
2365 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2366 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SEAL |
2367 NTLMSSP_NEGOTIATE_SIGN);
2370 result->auth_ctx = ntlmssp_ctx;
2372 return NT_STATUS_OK;
2375 TALLOC_FREE(result);
2379 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2380 enum dcerpc_AuthLevel auth_level,
2381 struct netlogon_creds_CredentialState *creds,
2382 struct pipe_auth_data **presult)
2384 struct schannel_state *schannel_auth;
2385 struct pipe_auth_data *result;
2387 result = talloc(mem_ctx, struct pipe_auth_data);
2388 if (result == NULL) {
2389 return NT_STATUS_NO_MEMORY;
2392 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2393 result->auth_level = auth_level;
2395 result->user_name = talloc_strdup(result, "");
2396 result->domain = talloc_strdup(result, domain);
2397 if ((result->user_name == NULL) || (result->domain == NULL)) {
2401 schannel_auth = talloc(result, struct schannel_state);
2402 if (schannel_auth == NULL) {
2406 schannel_auth->state = SCHANNEL_STATE_START;
2407 schannel_auth->seq_num = 0;
2408 schannel_auth->initiator = true;
2409 schannel_auth->creds = netlogon_creds_copy(result, creds);
2411 result->auth_ctx = schannel_auth;
2413 return NT_STATUS_OK;
2416 TALLOC_FREE(result);
2417 return NT_STATUS_NO_MEMORY;
2421 * Create an rpc pipe client struct, connecting to a tcp port.
2423 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2425 const struct ndr_syntax_id *abstract_syntax,
2426 struct rpc_pipe_client **presult)
2428 struct rpc_pipe_client *result;
2429 struct sockaddr_storage addr;
2433 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2434 if (result == NULL) {
2435 return NT_STATUS_NO_MEMORY;
2438 result->abstract_syntax = *abstract_syntax;
2439 result->transfer_syntax = ndr_transfer_syntax;
2441 result->desthost = talloc_strdup(result, host);
2442 result->srv_name_slash = talloc_asprintf_strupper_m(
2443 result, "\\\\%s", result->desthost);
2444 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2445 status = NT_STATUS_NO_MEMORY;
2449 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2450 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2452 if (!resolve_name(host, &addr, 0, false)) {
2453 status = NT_STATUS_NOT_FOUND;
2457 status = open_socket_out(&addr, port, 60*1000, &fd);
2458 if (!NT_STATUS_IS_OK(status)) {
2461 set_socket_options(fd, lp_socket_options());
2463 status = rpc_transport_sock_init(result, fd, &result->transport);
2464 if (!NT_STATUS_IS_OK(status)) {
2469 result->transport->transport = NCACN_IP_TCP;
2471 result->binding_handle = rpccli_bh_create(result);
2472 if (result->binding_handle == NULL) {
2473 TALLOC_FREE(result);
2474 return NT_STATUS_NO_MEMORY;
2478 return NT_STATUS_OK;
2481 TALLOC_FREE(result);
2486 * Determine the tcp port on which a dcerpc interface is listening
2487 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2490 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2491 const struct ndr_syntax_id *abstract_syntax,
2495 struct rpc_pipe_client *epm_pipe = NULL;
2496 struct dcerpc_binding_handle *epm_handle = NULL;
2497 struct pipe_auth_data *auth = NULL;
2498 struct dcerpc_binding *map_binding = NULL;
2499 struct dcerpc_binding *res_binding = NULL;
2500 struct epm_twr_t *map_tower = NULL;
2501 struct epm_twr_t *res_towers = NULL;
2502 struct policy_handle *entry_handle = NULL;
2503 uint32_t num_towers = 0;
2504 uint32_t max_towers = 1;
2505 struct epm_twr_p_t towers;
2506 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2507 uint32_t result = 0;
2509 if (pport == NULL) {
2510 status = NT_STATUS_INVALID_PARAMETER;
2514 if (ndr_syntax_id_equal(abstract_syntax,
2515 &ndr_table_epmapper.syntax_id)) {
2517 return NT_STATUS_OK;
2520 /* open the connection to the endpoint mapper */
2521 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2522 &ndr_table_epmapper.syntax_id,
2525 if (!NT_STATUS_IS_OK(status)) {
2528 epm_handle = epm_pipe->binding_handle;
2530 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2531 if (!NT_STATUS_IS_OK(status)) {
2535 status = rpc_pipe_bind(epm_pipe, auth);
2536 if (!NT_STATUS_IS_OK(status)) {
2540 /* create tower for asking the epmapper */
2542 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2543 if (map_binding == NULL) {
2544 status = NT_STATUS_NO_MEMORY;
2548 map_binding->transport = NCACN_IP_TCP;
2549 map_binding->object = *abstract_syntax;
2550 map_binding->host = host; /* needed? */
2551 map_binding->endpoint = "0"; /* correct? needed? */
2553 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2554 if (map_tower == NULL) {
2555 status = NT_STATUS_NO_MEMORY;
2559 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2560 &(map_tower->tower));
2561 if (!NT_STATUS_IS_OK(status)) {
2565 /* allocate further parameters for the epm_Map call */
2567 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2568 if (res_towers == NULL) {
2569 status = NT_STATUS_NO_MEMORY;
2572 towers.twr = res_towers;
2574 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2575 if (entry_handle == NULL) {
2576 status = NT_STATUS_NO_MEMORY;
2580 /* ask the endpoint mapper for the port */
2582 status = dcerpc_epm_Map(epm_handle,
2584 discard_const_p(struct GUID,
2585 &(abstract_syntax->uuid)),
2593 if (!NT_STATUS_IS_OK(status)) {
2597 if (result != EPMAPPER_STATUS_OK) {
2598 status = NT_STATUS_UNSUCCESSFUL;
2602 if (num_towers != 1) {
2603 status = NT_STATUS_UNSUCCESSFUL;
2607 /* extract the port from the answer */
2609 status = dcerpc_binding_from_tower(tmp_ctx,
2610 &(towers.twr->tower),
2612 if (!NT_STATUS_IS_OK(status)) {
2616 /* are further checks here necessary? */
2617 if (res_binding->transport != NCACN_IP_TCP) {
2618 status = NT_STATUS_UNSUCCESSFUL;
2622 *pport = (uint16_t)atoi(res_binding->endpoint);
2625 TALLOC_FREE(tmp_ctx);
2630 * Create a rpc pipe client struct, connecting to a host via tcp.
2631 * The port is determined by asking the endpoint mapper on the given
2634 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2635 const struct ndr_syntax_id *abstract_syntax,
2636 struct rpc_pipe_client **presult)
2641 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2642 if (!NT_STATUS_IS_OK(status)) {
2646 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2647 abstract_syntax, presult);
2650 /********************************************************************
2651 Create a rpc pipe client struct, connecting to a unix domain socket
2652 ********************************************************************/
2653 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2654 const struct ndr_syntax_id *abstract_syntax,
2655 struct rpc_pipe_client **presult)
2657 struct rpc_pipe_client *result;
2658 struct sockaddr_un addr;
2662 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2663 if (result == NULL) {
2664 return NT_STATUS_NO_MEMORY;
2667 result->abstract_syntax = *abstract_syntax;
2668 result->transfer_syntax = ndr_transfer_syntax;
2670 result->desthost = get_myname(result);
2671 result->srv_name_slash = talloc_asprintf_strupper_m(
2672 result, "\\\\%s", result->desthost);
2673 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2674 status = NT_STATUS_NO_MEMORY;
2678 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2679 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2681 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2683 status = map_nt_error_from_unix(errno);
2688 addr.sun_family = AF_UNIX;
2689 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2691 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2692 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2695 return map_nt_error_from_unix(errno);
2698 status = rpc_transport_sock_init(result, fd, &result->transport);
2699 if (!NT_STATUS_IS_OK(status)) {
2704 result->transport->transport = NCALRPC;
2706 result->binding_handle = rpccli_bh_create(result);
2707 if (result->binding_handle == NULL) {
2708 TALLOC_FREE(result);
2709 return NT_STATUS_NO_MEMORY;
2713 return NT_STATUS_OK;
2716 TALLOC_FREE(result);
2720 struct rpc_pipe_client_np_ref {
2721 struct cli_state *cli;
2722 struct rpc_pipe_client *pipe;
2725 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2727 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2731 /****************************************************************************
2732 Open a named pipe over SMB to a remote server.
2734 * CAVEAT CALLER OF THIS FUNCTION:
2735 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2736 * so be sure that this function is called AFTER any structure (vs pointer)
2737 * assignment of the cli. In particular, libsmbclient does structure
2738 * assignments of cli, which invalidates the data in the returned
2739 * rpc_pipe_client if this function is called before the structure assignment
2742 ****************************************************************************/
2744 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2745 const struct ndr_syntax_id *abstract_syntax,
2746 struct rpc_pipe_client **presult)
2748 struct rpc_pipe_client *result;
2750 struct rpc_pipe_client_np_ref *np_ref;
2752 /* sanity check to protect against crashes */
2755 return NT_STATUS_INVALID_HANDLE;
2758 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2759 if (result == NULL) {
2760 return NT_STATUS_NO_MEMORY;
2763 result->abstract_syntax = *abstract_syntax;
2764 result->transfer_syntax = ndr_transfer_syntax;
2765 result->desthost = talloc_strdup(result, cli->desthost);
2766 result->srv_name_slash = talloc_asprintf_strupper_m(
2767 result, "\\\\%s", result->desthost);
2769 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2770 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2772 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2773 TALLOC_FREE(result);
2774 return NT_STATUS_NO_MEMORY;
2777 status = rpc_transport_np_init(result, cli, abstract_syntax,
2778 &result->transport);
2779 if (!NT_STATUS_IS_OK(status)) {
2780 TALLOC_FREE(result);
2784 result->transport->transport = NCACN_NP;
2786 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2787 if (np_ref == NULL) {
2788 TALLOC_FREE(result);
2789 return NT_STATUS_NO_MEMORY;
2792 np_ref->pipe = result;
2794 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2795 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2797 result->binding_handle = rpccli_bh_create(result);
2798 if (result->binding_handle == NULL) {
2799 TALLOC_FREE(result);
2800 return NT_STATUS_NO_MEMORY;
2804 return NT_STATUS_OK;
2807 /****************************************************************************
2808 Open a pipe to a remote server.
2809 ****************************************************************************/
2811 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2812 enum dcerpc_transport_t transport,
2813 const struct ndr_syntax_id *interface,
2814 struct rpc_pipe_client **presult)
2816 switch (transport) {
2818 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2821 return rpc_pipe_open_np(cli, interface, presult);
2823 return NT_STATUS_NOT_IMPLEMENTED;
2827 /****************************************************************************
2828 Open a named pipe to an SMB server and bind anonymously.
2829 ****************************************************************************/
2831 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2832 enum dcerpc_transport_t transport,
2833 const struct ndr_syntax_id *interface,
2834 struct rpc_pipe_client **presult)
2836 struct rpc_pipe_client *result;
2837 struct pipe_auth_data *auth;
2840 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2841 if (!NT_STATUS_IS_OK(status)) {
2845 status = rpccli_anon_bind_data(result, &auth);
2846 if (!NT_STATUS_IS_OK(status)) {
2847 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2848 nt_errstr(status)));
2849 TALLOC_FREE(result);
2854 * This is a bit of an abstraction violation due to the fact that an
2855 * anonymous bind on an authenticated SMB inherits the user/domain
2856 * from the enclosing SMB creds
2859 TALLOC_FREE(auth->user_name);
2860 TALLOC_FREE(auth->domain);
2862 auth->user_name = talloc_strdup(auth, cli->user_name);
2863 auth->domain = talloc_strdup(auth, cli->domain);
2864 auth->user_session_key = data_blob_talloc(auth,
2865 cli->user_session_key.data,
2866 cli->user_session_key.length);
2868 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2869 TALLOC_FREE(result);
2870 return NT_STATUS_NO_MEMORY;
2873 status = rpc_pipe_bind(result, auth);
2874 if (!NT_STATUS_IS_OK(status)) {
2876 if (ndr_syntax_id_equal(interface,
2877 &ndr_table_dssetup.syntax_id)) {
2878 /* non AD domains just don't have this pipe, avoid
2879 * level 0 statement in that case - gd */
2882 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2883 "%s failed with error %s\n",
2884 get_pipe_name_from_syntax(talloc_tos(), interface),
2885 nt_errstr(status) ));
2886 TALLOC_FREE(result);
2890 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2891 "%s and bound anonymously.\n",
2892 get_pipe_name_from_syntax(talloc_tos(), interface),
2896 return NT_STATUS_OK;
2899 /****************************************************************************
2900 ****************************************************************************/
2902 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2903 const struct ndr_syntax_id *interface,
2904 struct rpc_pipe_client **presult)
2906 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2907 interface, presult);
2910 /****************************************************************************
2911 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2912 ****************************************************************************/
2914 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2915 const struct ndr_syntax_id *interface,
2916 enum dcerpc_transport_t transport,
2917 enum dcerpc_AuthLevel auth_level,
2919 const char *username,
2920 const char *password,
2921 struct rpc_pipe_client **presult)
2923 struct rpc_pipe_client *result;
2924 struct pipe_auth_data *auth = NULL;
2925 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2928 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2929 if (!NT_STATUS_IS_OK(status)) {
2933 status = rpccli_ntlmssp_bind_data(result,
2934 auth_type, auth_level,
2935 domain, username, password,
2937 if (!NT_STATUS_IS_OK(status)) {
2938 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2939 nt_errstr(status)));
2943 status = rpc_pipe_bind(result, auth);
2944 if (!NT_STATUS_IS_OK(status)) {
2945 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2946 nt_errstr(status) ));
2950 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2951 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2952 get_pipe_name_from_syntax(talloc_tos(), interface),
2953 cli->desthost, domain, username ));
2956 return NT_STATUS_OK;
2960 TALLOC_FREE(result);
2964 /****************************************************************************
2966 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2967 using session_key. sign and seal.
2969 The *pdc will be stolen onto this new pipe
2970 ****************************************************************************/
2972 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2973 const struct ndr_syntax_id *interface,
2974 enum dcerpc_transport_t transport,
2975 enum dcerpc_AuthLevel auth_level,
2977 struct netlogon_creds_CredentialState **pdc,
2978 struct rpc_pipe_client **presult)
2980 struct rpc_pipe_client *result;
2981 struct pipe_auth_data *auth;
2984 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2985 if (!NT_STATUS_IS_OK(status)) {
2989 status = rpccli_schannel_bind_data(result, domain, auth_level,
2991 if (!NT_STATUS_IS_OK(status)) {
2992 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2993 nt_errstr(status)));
2994 TALLOC_FREE(result);
2998 status = rpc_pipe_bind(result, auth);
2999 if (!NT_STATUS_IS_OK(status)) {
3000 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3001 "cli_rpc_pipe_bind failed with error %s\n",
3002 nt_errstr(status) ));
3003 TALLOC_FREE(result);
3008 * The credentials on a new netlogon pipe are the ones we are passed
3009 * in - copy them over
3011 result->dc = netlogon_creds_copy(result, *pdc);
3012 if (result->dc == NULL) {
3013 TALLOC_FREE(result);
3014 return NT_STATUS_NO_MEMORY;
3017 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3018 "for domain %s and bound using schannel.\n",
3019 get_pipe_name_from_syntax(talloc_tos(), interface),
3020 cli->desthost, domain ));
3023 return NT_STATUS_OK;
3026 /****************************************************************************
3027 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3028 The idea is this can be called with service_princ, username and password all
3029 NULL so long as the caller has a TGT.
3030 ****************************************************************************/
3032 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3033 const struct ndr_syntax_id *interface,
3034 enum dcerpc_transport_t transport,
3035 enum dcerpc_AuthLevel auth_level,
3037 const char *username,
3038 const char *password,
3039 struct rpc_pipe_client **presult)
3041 struct rpc_pipe_client *result;
3042 struct pipe_auth_data *auth;
3043 struct gse_context *gse_ctx;
3046 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3047 if (!NT_STATUS_IS_OK(status)) {
3051 auth = talloc(result, struct pipe_auth_data);
3053 status = NT_STATUS_NO_MEMORY;
3056 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3057 auth->auth_level = auth_level;
3062 auth->user_name = talloc_strdup(auth, username);
3063 if (!auth->user_name) {
3064 status = NT_STATUS_NO_MEMORY;
3068 /* Fixme, should we fetch/set the Realm ? */
3069 auth->domain = talloc_strdup(auth, "");
3070 if (!auth->domain) {
3071 status = NT_STATUS_NO_MEMORY;
3075 status = gse_init_client(auth,
3076 (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
3077 (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
3078 NULL, server, "cifs", username, password,
3079 GSS_C_DCE_STYLE, &gse_ctx);
3080 if (!NT_STATUS_IS_OK(status)) {
3081 DEBUG(0, ("gse_init_client returned %s\n",
3082 nt_errstr(status)));
3085 auth->auth_ctx = gse_ctx;
3087 status = rpc_pipe_bind(result, auth);
3088 if (!NT_STATUS_IS_OK(status)) {
3089 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3090 nt_errstr(status)));
3095 return NT_STATUS_OK;
3098 TALLOC_FREE(result);
3102 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3103 const struct ndr_syntax_id *interface,
3104 enum dcerpc_transport_t transport,
3105 enum dcerpc_AuthLevel auth_level,
3107 const char *username,
3108 const char *password,
3109 struct rpc_pipe_client **presult)
3111 struct rpc_pipe_client *result;
3112 struct pipe_auth_data *auth;
3113 struct spnego_context *spnego_ctx;
3116 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3117 if (!NT_STATUS_IS_OK(status)) {
3121 auth = talloc(result, struct pipe_auth_data);
3123 status = NT_STATUS_NO_MEMORY;
3126 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3127 auth->auth_level = auth_level;
3132 auth->user_name = talloc_strdup(auth, username);
3133 if (!auth->user_name) {
3134 status = NT_STATUS_NO_MEMORY;
3138 /* Fixme, should we fetch/set the Realm ? */
3139 auth->domain = talloc_strdup(auth, "");
3140 if (!auth->domain) {
3141 status = NT_STATUS_NO_MEMORY;
3145 status = spnego_gssapi_init_client(auth,
3146 (auth->auth_level ==
3147 DCERPC_AUTH_LEVEL_INTEGRITY),
3148 (auth->auth_level ==
3149 DCERPC_AUTH_LEVEL_PRIVACY),
3151 NULL, server, "cifs",
3154 if (!NT_STATUS_IS_OK(status)) {
3155 DEBUG(0, ("spnego_init_client returned %s\n",
3156 nt_errstr(status)));
3159 auth->auth_ctx = spnego_ctx;
3161 status = rpc_pipe_bind(result, auth);
3162 if (!NT_STATUS_IS_OK(status)) {
3163 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3164 nt_errstr(status)));
3169 return NT_STATUS_OK;
3172 TALLOC_FREE(result);
3176 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3177 const struct ndr_syntax_id *interface,
3178 enum dcerpc_transport_t transport,
3179 enum dcerpc_AuthLevel auth_level,
3181 const char *username,
3182 const char *password,
3183 struct rpc_pipe_client **presult)
3185 struct rpc_pipe_client *result;
3186 struct pipe_auth_data *auth;
3187 struct spnego_context *spnego_ctx;
3190 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3191 if (!NT_STATUS_IS_OK(status)) {
3195 auth = talloc(result, struct pipe_auth_data);
3197 status = NT_STATUS_NO_MEMORY;
3200 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3201 auth->auth_level = auth_level;
3206 auth->user_name = talloc_strdup(auth, username);
3207 if (!auth->user_name) {
3208 status = NT_STATUS_NO_MEMORY;
3215 auth->domain = talloc_strdup(auth, domain);
3216 if (!auth->domain) {
3217 status = NT_STATUS_NO_MEMORY;
3221 status = spnego_ntlmssp_init_client(auth,
3222 (auth->auth_level ==
3223 DCERPC_AUTH_LEVEL_INTEGRITY),
3224 (auth->auth_level ==
3225 DCERPC_AUTH_LEVEL_PRIVACY),
3227 domain, username, password,
3229 if (!NT_STATUS_IS_OK(status)) {
3230 DEBUG(0, ("spnego_init_client returned %s\n",
3231 nt_errstr(status)));
3234 auth->auth_ctx = spnego_ctx;
3236 status = rpc_pipe_bind(result, auth);
3237 if (!NT_STATUS_IS_OK(status)) {
3238 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3239 nt_errstr(status)));
3244 return NT_STATUS_OK;
3247 TALLOC_FREE(result);
3251 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3252 struct rpc_pipe_client *cli,
3253 DATA_BLOB *session_key)
3255 struct pipe_auth_data *a;
3256 struct schannel_state *schannel_auth;
3257 struct auth_ntlmssp_state *ntlmssp_ctx;
3258 struct spnego_context *spnego_ctx;
3259 struct gse_context *gse_ctx;
3260 DATA_BLOB sk = data_blob_null;
3261 bool make_dup = false;
3263 if (!session_key || !cli) {
3264 return NT_STATUS_INVALID_PARAMETER;
3270 return NT_STATUS_INVALID_PARAMETER;
3273 switch (cli->auth->auth_type) {
3274 case DCERPC_AUTH_TYPE_SCHANNEL:
3275 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3276 struct schannel_state);
3277 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3280 case DCERPC_AUTH_TYPE_SPNEGO:
3281 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
3282 struct spnego_context);
3283 sk = spnego_get_session_key(mem_ctx, spnego_ctx);
3286 case DCERPC_AUTH_TYPE_NTLMSSP:
3287 ntlmssp_ctx = talloc_get_type_abort(a->auth_ctx,
3288 struct auth_ntlmssp_state);
3289 sk = auth_ntlmssp_get_session_key(ntlmssp_ctx);
3292 case DCERPC_AUTH_TYPE_KRB5:
3293 gse_ctx = talloc_get_type_abort(a->auth_ctx,
3294 struct gse_context);
3295 sk = gse_get_session_key(mem_ctx, gse_ctx);
3298 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3299 case DCERPC_AUTH_TYPE_NONE:
3300 sk = data_blob_const(a->user_session_key.data,
3301 a->user_session_key.length);
3309 return NT_STATUS_NO_USER_SESSION_KEY;
3313 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3318 return NT_STATUS_OK;