2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client routines
4 * Largely rewritten by Jeremy Allison 2005.
5 * Heavily modified by Simo Sorce 2010.
6 * Copyright Andrew Bartlett 2011.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "../lib/util/tevent_ntstatus.h"
24 #include "librpc/gen_ndr/ndr_epmapper_c.h"
25 #include "../librpc/gen_ndr/ndr_dssetup.h"
26 #include "../libcli/auth/schannel.h"
27 #include "auth_generic.h"
28 #include "librpc/gen_ndr/ndr_dcerpc.h"
29 #include "librpc/gen_ndr/ndr_netlogon_c.h"
30 #include "librpc/rpc/dcerpc.h"
33 #include "libsmb/libsmb.h"
34 #include "auth/gensec/gensec.h"
35 #include "auth/credentials/credentials.h"
36 #include "../libcli/smb/smbXcli_base.h"
39 #define DBGC_CLASS DBGC_RPC_CLI
41 /********************************************************************
42 Pipe description for a DEBUG
43 ********************************************************************/
44 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
45 struct rpc_pipe_client *cli)
47 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
54 /********************************************************************
56 ********************************************************************/
58 static uint32 get_rpc_call_id(void)
60 static uint32 call_id = 0;
64 /*******************************************************************
65 Use SMBreadX to get rest of one fragment's worth of rpc data.
66 Reads the whole size or give an error message
67 ********************************************************************/
69 struct rpc_read_state {
70 struct tevent_context *ev;
71 struct rpc_cli_transport *transport;
77 static void rpc_read_done(struct tevent_req *subreq);
79 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
80 struct tevent_context *ev,
81 struct rpc_cli_transport *transport,
82 uint8_t *data, size_t size)
84 struct tevent_req *req, *subreq;
85 struct rpc_read_state *state;
87 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
92 state->transport = transport;
97 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
99 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
101 if (subreq == NULL) {
104 tevent_req_set_callback(subreq, rpc_read_done, req);
112 static void rpc_read_done(struct tevent_req *subreq)
114 struct tevent_req *req = tevent_req_callback_data(
115 subreq, struct tevent_req);
116 struct rpc_read_state *state = tevent_req_data(
117 req, struct rpc_read_state);
121 status = state->transport->read_recv(subreq, &received);
123 if (!NT_STATUS_IS_OK(status)) {
124 tevent_req_nterror(req, status);
128 state->num_read += received;
129 if (state->num_read == state->size) {
130 tevent_req_done(req);
134 subreq = state->transport->read_send(state, state->ev,
135 state->data + state->num_read,
136 state->size - state->num_read,
137 state->transport->priv);
138 if (tevent_req_nomem(subreq, req)) {
141 tevent_req_set_callback(subreq, rpc_read_done, req);
144 static NTSTATUS rpc_read_recv(struct tevent_req *req)
146 return tevent_req_simple_recv_ntstatus(req);
149 struct rpc_write_state {
150 struct tevent_context *ev;
151 struct rpc_cli_transport *transport;
157 static void rpc_write_done(struct tevent_req *subreq);
159 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
160 struct tevent_context *ev,
161 struct rpc_cli_transport *transport,
162 const uint8_t *data, size_t size)
164 struct tevent_req *req, *subreq;
165 struct rpc_write_state *state;
167 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
172 state->transport = transport;
175 state->num_written = 0;
177 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
179 subreq = transport->write_send(state, ev, data, size, transport->priv);
180 if (subreq == NULL) {
183 tevent_req_set_callback(subreq, rpc_write_done, req);
190 static void rpc_write_done(struct tevent_req *subreq)
192 struct tevent_req *req = tevent_req_callback_data(
193 subreq, struct tevent_req);
194 struct rpc_write_state *state = tevent_req_data(
195 req, struct rpc_write_state);
199 status = state->transport->write_recv(subreq, &written);
201 if (!NT_STATUS_IS_OK(status)) {
202 tevent_req_nterror(req, status);
206 state->num_written += written;
208 if (state->num_written == state->size) {
209 tevent_req_done(req);
213 subreq = state->transport->write_send(state, state->ev,
214 state->data + state->num_written,
215 state->size - state->num_written,
216 state->transport->priv);
217 if (tevent_req_nomem(subreq, req)) {
220 tevent_req_set_callback(subreq, rpc_write_done, req);
223 static NTSTATUS rpc_write_recv(struct tevent_req *req)
225 return tevent_req_simple_recv_ntstatus(req);
229 /****************************************************************************
230 Try and get a PDU's worth of data from current_pdu. If not, then read more
232 ****************************************************************************/
234 struct get_complete_frag_state {
235 struct tevent_context *ev;
236 struct rpc_pipe_client *cli;
241 static void get_complete_frag_got_header(struct tevent_req *subreq);
242 static void get_complete_frag_got_rest(struct tevent_req *subreq);
244 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
245 struct tevent_context *ev,
246 struct rpc_pipe_client *cli,
249 struct tevent_req *req, *subreq;
250 struct get_complete_frag_state *state;
254 req = tevent_req_create(mem_ctx, &state,
255 struct get_complete_frag_state);
261 state->frag_len = RPC_HEADER_LEN;
264 received = pdu->length;
265 if (received < RPC_HEADER_LEN) {
266 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
267 status = NT_STATUS_NO_MEMORY;
270 subreq = rpc_read_send(state, state->ev,
271 state->cli->transport,
272 pdu->data + received,
273 RPC_HEADER_LEN - received);
274 if (subreq == NULL) {
275 status = NT_STATUS_NO_MEMORY;
278 tevent_req_set_callback(subreq, get_complete_frag_got_header,
283 state->frag_len = dcerpc_get_frag_length(pdu);
286 * Ensure we have frag_len bytes of data.
288 if (received < state->frag_len) {
289 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
290 status = NT_STATUS_NO_MEMORY;
293 subreq = rpc_read_send(state, state->ev,
294 state->cli->transport,
295 pdu->data + received,
296 state->frag_len - received);
297 if (subreq == NULL) {
298 status = NT_STATUS_NO_MEMORY;
301 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
306 status = NT_STATUS_OK;
308 if (NT_STATUS_IS_OK(status)) {
309 tevent_req_done(req);
311 tevent_req_nterror(req, status);
313 return tevent_req_post(req, ev);
316 static void get_complete_frag_got_header(struct tevent_req *subreq)
318 struct tevent_req *req = tevent_req_callback_data(
319 subreq, struct tevent_req);
320 struct get_complete_frag_state *state = tevent_req_data(
321 req, struct get_complete_frag_state);
324 status = rpc_read_recv(subreq);
326 if (!NT_STATUS_IS_OK(status)) {
327 tevent_req_nterror(req, status);
331 state->frag_len = dcerpc_get_frag_length(state->pdu);
333 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
334 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
339 * We're here in this piece of code because we've read exactly
340 * RPC_HEADER_LEN bytes into state->pdu.
343 subreq = rpc_read_send(state, state->ev, state->cli->transport,
344 state->pdu->data + RPC_HEADER_LEN,
345 state->frag_len - RPC_HEADER_LEN);
346 if (tevent_req_nomem(subreq, req)) {
349 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
352 static void get_complete_frag_got_rest(struct tevent_req *subreq)
354 struct tevent_req *req = tevent_req_callback_data(
355 subreq, struct tevent_req);
358 status = rpc_read_recv(subreq);
360 if (!NT_STATUS_IS_OK(status)) {
361 tevent_req_nterror(req, status);
364 tevent_req_done(req);
367 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
369 return tevent_req_simple_recv_ntstatus(req);
372 /****************************************************************************
373 Do basic authentication checks on an incoming pdu.
374 ****************************************************************************/
376 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
377 struct rpc_pipe_client *cli,
378 struct ncacn_packet *pkt,
380 uint8_t expected_pkt_type,
382 DATA_BLOB *reply_pdu)
384 struct dcerpc_response *r;
385 NTSTATUS ret = NT_STATUS_OK;
389 * Point the return values at the real data including the RPC
390 * header. Just in case the caller wants it.
394 /* Ensure we have the correct type. */
395 switch (pkt->ptype) {
396 case DCERPC_PKT_ALTER_RESP:
397 case DCERPC_PKT_BIND_ACK:
399 /* Client code never receives this kind of packets */
403 case DCERPC_PKT_RESPONSE:
405 r = &pkt->u.response;
407 /* Here's where we deal with incoming sign/seal. */
408 ret = dcerpc_check_auth(cli->auth, pkt,
409 &r->stub_and_verifier,
410 DCERPC_RESPONSE_LENGTH,
412 if (!NT_STATUS_IS_OK(ret)) {
416 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
417 return NT_STATUS_BUFFER_TOO_SMALL;
420 /* Point the return values at the NDR data. */
421 rdata->data = r->stub_and_verifier.data;
423 if (pkt->auth_length) {
424 /* We've already done integer wrap tests in
425 * dcerpc_check_auth(). */
426 rdata->length = r->stub_and_verifier.length
428 - DCERPC_AUTH_TRAILER_LENGTH
431 rdata->length = r->stub_and_verifier.length;
434 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
435 (long unsigned int)pdu->length,
436 (long unsigned int)rdata->length,
437 (unsigned int)pad_len));
440 * If this is the first reply, and the allocation hint is
441 * reasonable, try and set up the reply_pdu DATA_BLOB to the
445 if ((reply_pdu->length == 0) &&
446 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
447 if (!data_blob_realloc(mem_ctx, reply_pdu,
449 DEBUG(0, ("reply alloc hint %d too "
450 "large to allocate\n",
451 (int)r->alloc_hint));
452 return NT_STATUS_NO_MEMORY;
458 case DCERPC_PKT_BIND_NAK:
459 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
460 rpccli_pipe_txt(talloc_tos(), cli)));
461 /* Use this for now... */
462 return NT_STATUS_NETWORK_ACCESS_DENIED;
464 case DCERPC_PKT_FAULT:
466 DEBUG(1, (__location__ ": RPC fault code %s received "
468 dcerpc_errstr(talloc_tos(),
469 pkt->u.fault.status),
470 rpccli_pipe_txt(talloc_tos(), cli)));
472 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
475 DEBUG(0, (__location__ "Unknown packet type %u received "
477 (unsigned int)pkt->ptype,
478 rpccli_pipe_txt(talloc_tos(), cli)));
479 return NT_STATUS_INVALID_INFO_CLASS;
482 if (pkt->ptype != expected_pkt_type) {
483 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
484 "RPC packet type - %u, not %u\n",
485 rpccli_pipe_txt(talloc_tos(), cli),
486 pkt->ptype, expected_pkt_type));
487 return NT_STATUS_INVALID_INFO_CLASS;
490 /* Do this just before return - we don't want to modify any rpc header
491 data before now as we may have needed to do cryptographic actions on
494 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
495 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
496 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
497 "fragment first/last ON.\n"));
498 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
504 /****************************************************************************
505 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
506 ****************************************************************************/
508 struct cli_api_pipe_state {
509 struct tevent_context *ev;
510 struct rpc_cli_transport *transport;
515 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
516 static void cli_api_pipe_write_done(struct tevent_req *subreq);
517 static void cli_api_pipe_read_done(struct tevent_req *subreq);
519 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
520 struct tevent_context *ev,
521 struct rpc_cli_transport *transport,
522 uint8_t *data, size_t data_len,
523 uint32_t max_rdata_len)
525 struct tevent_req *req, *subreq;
526 struct cli_api_pipe_state *state;
529 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
534 state->transport = transport;
536 if (max_rdata_len < RPC_HEADER_LEN) {
538 * For a RPC reply we always need at least RPC_HEADER_LEN
539 * bytes. We check this here because we will receive
540 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
542 status = NT_STATUS_INVALID_PARAMETER;
546 if (transport->trans_send != NULL) {
547 subreq = transport->trans_send(state, ev, data, data_len,
548 max_rdata_len, transport->priv);
549 if (subreq == NULL) {
552 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
557 * If the transport does not provide a "trans" routine, i.e. for
558 * example the ncacn_ip_tcp transport, do the write/read step here.
561 subreq = rpc_write_send(state, ev, transport, data, data_len);
562 if (subreq == NULL) {
565 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
569 tevent_req_nterror(req, status);
570 return tevent_req_post(req, ev);
576 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
578 struct tevent_req *req = tevent_req_callback_data(
579 subreq, struct tevent_req);
580 struct cli_api_pipe_state *state = tevent_req_data(
581 req, struct cli_api_pipe_state);
584 status = state->transport->trans_recv(subreq, state, &state->rdata,
587 if (!NT_STATUS_IS_OK(status)) {
588 tevent_req_nterror(req, status);
591 tevent_req_done(req);
594 static void cli_api_pipe_write_done(struct tevent_req *subreq)
596 struct tevent_req *req = tevent_req_callback_data(
597 subreq, struct tevent_req);
598 struct cli_api_pipe_state *state = tevent_req_data(
599 req, struct cli_api_pipe_state);
602 status = rpc_write_recv(subreq);
604 if (!NT_STATUS_IS_OK(status)) {
605 tevent_req_nterror(req, status);
609 state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
610 if (tevent_req_nomem(state->rdata, req)) {
615 * We don't need to use rpc_read_send here, the upper layer will cope
616 * with a short read, transport->trans_send could also return less
617 * than state->max_rdata_len.
619 subreq = state->transport->read_send(state, state->ev, state->rdata,
621 state->transport->priv);
622 if (tevent_req_nomem(subreq, req)) {
625 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
628 static void cli_api_pipe_read_done(struct tevent_req *subreq)
630 struct tevent_req *req = tevent_req_callback_data(
631 subreq, struct tevent_req);
632 struct cli_api_pipe_state *state = tevent_req_data(
633 req, struct cli_api_pipe_state);
637 status = state->transport->read_recv(subreq, &received);
639 if (!NT_STATUS_IS_OK(status)) {
640 tevent_req_nterror(req, status);
643 state->rdata_len = received;
644 tevent_req_done(req);
647 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
648 uint8_t **prdata, uint32_t *prdata_len)
650 struct cli_api_pipe_state *state = tevent_req_data(
651 req, struct cli_api_pipe_state);
654 if (tevent_req_is_nterror(req, &status)) {
658 *prdata = talloc_move(mem_ctx, &state->rdata);
659 *prdata_len = state->rdata_len;
663 /****************************************************************************
664 Send data on an rpc pipe via trans. The data must be the last
665 pdu fragment of an NDR data stream.
667 Receive response data from an rpc pipe, which may be large...
669 Read the first fragment: unfortunately have to use SMBtrans for the first
670 bit, then SMBreadX for subsequent bits.
672 If first fragment received also wasn't the last fragment, continue
673 getting fragments until we _do_ receive the last fragment.
675 Request/Response PDU's look like the following...
677 |<------------------PDU len----------------------------------------------->|
678 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
680 +------------+-----------------+-------------+---------------+-------------+
681 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
682 +------------+-----------------+-------------+---------------+-------------+
684 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
685 signing & sealing being negotiated.
687 ****************************************************************************/
689 struct rpc_api_pipe_state {
690 struct tevent_context *ev;
691 struct rpc_pipe_client *cli;
692 uint8_t expected_pkt_type;
694 DATA_BLOB incoming_frag;
695 struct ncacn_packet *pkt;
699 size_t reply_pdu_offset;
703 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
704 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
705 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
707 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
708 struct tevent_context *ev,
709 struct rpc_pipe_client *cli,
710 DATA_BLOB *data, /* Outgoing PDU */
711 uint8_t expected_pkt_type)
713 struct tevent_req *req, *subreq;
714 struct rpc_api_pipe_state *state;
715 uint16_t max_recv_frag;
718 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
724 state->expected_pkt_type = expected_pkt_type;
725 state->endianess = DCERPC_DREP_LE;
728 * Ensure we're not sending too much.
730 if (data->length > cli->max_xmit_frag) {
731 status = NT_STATUS_INVALID_PARAMETER;
735 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
737 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
738 subreq = rpc_write_send(state, ev, cli->transport,
739 data->data, data->length);
740 if (subreq == NULL) {
743 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
747 /* get the header first, then fetch the rest once we have
748 * the frag_length available */
749 max_recv_frag = RPC_HEADER_LEN;
751 subreq = cli_api_pipe_send(state, ev, cli->transport,
752 data->data, data->length, max_recv_frag);
753 if (subreq == NULL) {
756 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
760 tevent_req_nterror(req, status);
761 return tevent_req_post(req, ev);
767 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
769 struct tevent_req *req =
770 tevent_req_callback_data(subreq,
774 status = rpc_write_recv(subreq);
776 if (!NT_STATUS_IS_OK(status)) {
777 tevent_req_nterror(req, status);
781 tevent_req_done(req);
784 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
786 struct tevent_req *req = tevent_req_callback_data(
787 subreq, struct tevent_req);
788 struct rpc_api_pipe_state *state = tevent_req_data(
789 req, struct rpc_api_pipe_state);
791 uint8_t *rdata = NULL;
792 uint32_t rdata_len = 0;
794 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
796 if (!NT_STATUS_IS_OK(status)) {
797 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
798 tevent_req_nterror(req, status);
803 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
804 rpccli_pipe_txt(talloc_tos(), state->cli)));
805 tevent_req_done(req);
810 * Move data on state->incoming_frag.
812 state->incoming_frag.data = talloc_move(state, &rdata);
813 state->incoming_frag.length = rdata_len;
814 if (!state->incoming_frag.data) {
815 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
819 /* Ensure we have enough data for a pdu. */
820 subreq = get_complete_frag_send(state, state->ev, state->cli,
821 &state->incoming_frag);
822 if (tevent_req_nomem(subreq, req)) {
825 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
828 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
830 struct tevent_req *req = tevent_req_callback_data(
831 subreq, struct tevent_req);
832 struct rpc_api_pipe_state *state = tevent_req_data(
833 req, struct rpc_api_pipe_state);
835 DATA_BLOB rdata = data_blob_null;
837 status = get_complete_frag_recv(subreq);
839 if (!NT_STATUS_IS_OK(status)) {
840 DEBUG(5, ("get_complete_frag failed: %s\n",
842 tevent_req_nterror(req, status);
846 state->pkt = talloc(state, struct ncacn_packet);
848 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
852 status = dcerpc_pull_ncacn_packet(state->pkt,
853 &state->incoming_frag,
856 if (!NT_STATUS_IS_OK(status)) {
857 tevent_req_nterror(req, status);
861 if (state->incoming_frag.length != state->pkt->frag_length) {
862 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
863 (unsigned int)state->incoming_frag.length,
864 (unsigned int)state->pkt->frag_length));
865 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
869 status = cli_pipe_validate_current_pdu(state,
870 state->cli, state->pkt,
871 &state->incoming_frag,
872 state->expected_pkt_type,
876 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
877 (unsigned)state->incoming_frag.length,
878 (unsigned)state->reply_pdu_offset,
881 if (!NT_STATUS_IS_OK(status)) {
882 tevent_req_nterror(req, status);
886 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
887 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
889 * Set the data type correctly for big-endian data on the
892 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
894 rpccli_pipe_txt(talloc_tos(), state->cli)));
895 state->endianess = 0x00; /* BIG ENDIAN */
898 * Check endianness on subsequent packets.
900 if (state->endianess != state->pkt->drep[0]) {
901 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
903 state->endianess?"little":"big",
904 state->pkt->drep[0]?"little":"big"));
905 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
909 /* Now copy the data portion out of the pdu into rbuf. */
910 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
911 if (!data_blob_realloc(NULL, &state->reply_pdu,
912 state->reply_pdu_offset + rdata.length)) {
913 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
918 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
919 rdata.data, rdata.length);
920 state->reply_pdu_offset += rdata.length;
922 /* reset state->incoming_frag, there is no need to free it,
923 * it will be reallocated to the right size the next time
925 state->incoming_frag.length = 0;
927 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
928 /* make sure the pdu length is right now that we
929 * have all the data available (alloc hint may
930 * have allocated more than was actually used) */
931 state->reply_pdu.length = state->reply_pdu_offset;
932 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
933 rpccli_pipe_txt(talloc_tos(), state->cli),
934 (unsigned)state->reply_pdu.length));
935 tevent_req_done(req);
939 subreq = get_complete_frag_send(state, state->ev, state->cli,
940 &state->incoming_frag);
941 if (tevent_req_nomem(subreq, req)) {
944 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
947 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
948 struct ncacn_packet **pkt,
949 DATA_BLOB *reply_pdu)
951 struct rpc_api_pipe_state *state = tevent_req_data(
952 req, struct rpc_api_pipe_state);
955 if (tevent_req_is_nterror(req, &status)) {
959 /* return data to caller and assign it ownership of memory */
961 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
962 reply_pdu->length = state->reply_pdu.length;
963 state->reply_pdu.length = 0;
965 data_blob_free(&state->reply_pdu);
969 *pkt = talloc_steal(mem_ctx, state->pkt);
975 /*******************************************************************
976 Creates NTLMSSP auth bind.
977 ********************************************************************/
979 static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
981 DATA_BLOB *auth_token)
983 struct gensec_security *gensec_security;
984 DATA_BLOB null_blob = data_blob_null;
986 gensec_security = talloc_get_type_abort(cli->auth->auth_ctx,
987 struct gensec_security);
989 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
990 return gensec_update(gensec_security, mem_ctx, NULL, null_blob, auth_token);
993 /*******************************************************************
994 Creates the internals of a DCE/RPC bind request or alter context PDU.
995 ********************************************************************/
997 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
998 enum dcerpc_pkt_type ptype,
1000 const struct ndr_syntax_id *abstract,
1001 const struct ndr_syntax_id *transfer,
1002 const DATA_BLOB *auth_info,
1005 uint16 auth_len = auth_info->length;
1007 union dcerpc_payload u;
1008 struct dcerpc_ctx_list ctx_list;
1011 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1014 ctx_list.context_id = 0;
1015 ctx_list.num_transfer_syntaxes = 1;
1016 ctx_list.abstract_syntax = *abstract;
1017 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1019 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1020 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1021 u.bind.assoc_group_id = 0x0;
1022 u.bind.num_contexts = 1;
1023 u.bind.ctx_list = &ctx_list;
1024 u.bind.auth_info = *auth_info;
1026 status = dcerpc_push_ncacn_packet(mem_ctx,
1028 DCERPC_PFC_FLAG_FIRST |
1029 DCERPC_PFC_FLAG_LAST,
1034 if (!NT_STATUS_IS_OK(status)) {
1035 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1039 return NT_STATUS_OK;
1042 /*******************************************************************
1043 Creates a DCE/RPC bind request.
1044 ********************************************************************/
1046 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1047 struct rpc_pipe_client *cli,
1048 struct pipe_auth_data *auth,
1050 const struct ndr_syntax_id *abstract,
1051 const struct ndr_syntax_id *transfer,
1054 DATA_BLOB auth_token = data_blob_null;
1055 DATA_BLOB auth_info = data_blob_null;
1056 NTSTATUS ret = NT_STATUS_OK;
1058 switch (auth->auth_type) {
1059 case DCERPC_AUTH_TYPE_SCHANNEL:
1060 case DCERPC_AUTH_TYPE_NTLMSSP:
1061 case DCERPC_AUTH_TYPE_KRB5:
1062 case DCERPC_AUTH_TYPE_SPNEGO:
1063 ret = create_generic_auth_rpc_bind_req(cli, mem_ctx, &auth_token);
1065 if (!NT_STATUS_IS_OK(ret) &&
1066 !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1071 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1072 auth_token = data_blob_talloc(mem_ctx,
1073 "NCALRPC_AUTH_TOKEN",
1077 case DCERPC_AUTH_TYPE_NONE:
1081 /* "Can't" happen. */
1082 return NT_STATUS_INVALID_INFO_CLASS;
1085 if (auth_token.length != 0) {
1086 ret = dcerpc_push_dcerpc_auth(cli,
1089 0, /* auth_pad_length */
1090 1, /* auth_context_id */
1093 if (!NT_STATUS_IS_OK(ret)) {
1096 data_blob_free(&auth_token);
1099 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1109 /*******************************************************************
1111 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1112 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1113 and deals with signing/sealing details.
1114 ********************************************************************/
1116 struct rpc_api_pipe_req_state {
1117 struct tevent_context *ev;
1118 struct rpc_pipe_client *cli;
1121 DATA_BLOB *req_data;
1122 uint32_t req_data_sent;
1124 DATA_BLOB reply_pdu;
1127 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1128 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1129 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1130 bool *is_last_frag);
1132 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1133 struct tevent_context *ev,
1134 struct rpc_pipe_client *cli,
1136 DATA_BLOB *req_data)
1138 struct tevent_req *req, *subreq;
1139 struct rpc_api_pipe_req_state *state;
1143 req = tevent_req_create(mem_ctx, &state,
1144 struct rpc_api_pipe_req_state);
1150 state->op_num = op_num;
1151 state->req_data = req_data;
1152 state->req_data_sent = 0;
1153 state->call_id = get_rpc_call_id();
1154 state->reply_pdu = data_blob_null;
1155 state->rpc_out = data_blob_null;
1157 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1158 + RPC_MAX_SIGN_SIZE) {
1159 /* Server is screwed up ! */
1160 status = NT_STATUS_INVALID_PARAMETER;
1164 status = prepare_next_frag(state, &is_last_frag);
1165 if (!NT_STATUS_IS_OK(status)) {
1170 subreq = rpc_api_pipe_send(state, ev, state->cli,
1172 DCERPC_PKT_RESPONSE);
1173 if (subreq == NULL) {
1176 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1178 subreq = rpc_write_send(state, ev, cli->transport,
1179 state->rpc_out.data,
1180 state->rpc_out.length);
1181 if (subreq == NULL) {
1184 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1190 tevent_req_nterror(req, status);
1191 return tevent_req_post(req, ev);
1197 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1200 size_t data_sent_thistime;
1207 union dcerpc_payload u;
1209 data_left = state->req_data->length - state->req_data_sent;
1211 status = dcerpc_guess_sizes(state->cli->auth,
1212 DCERPC_REQUEST_LENGTH, data_left,
1213 state->cli->max_xmit_frag,
1214 CLIENT_NDR_PADDING_SIZE,
1215 &data_sent_thistime,
1216 &frag_len, &auth_len, &pad_len);
1217 if (!NT_STATUS_IS_OK(status)) {
1221 if (state->req_data_sent == 0) {
1222 flags = DCERPC_PFC_FLAG_FIRST;
1225 if (data_sent_thistime == data_left) {
1226 flags |= DCERPC_PFC_FLAG_LAST;
1229 data_blob_free(&state->rpc_out);
1231 ZERO_STRUCT(u.request);
1233 u.request.alloc_hint = state->req_data->length;
1234 u.request.context_id = 0;
1235 u.request.opnum = state->op_num;
1237 status = dcerpc_push_ncacn_packet(state,
1244 if (!NT_STATUS_IS_OK(status)) {
1248 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1249 * compute it right for requests because the auth trailer is missing
1251 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1253 /* Copy in the data. */
1254 if (!data_blob_append(NULL, &state->rpc_out,
1255 state->req_data->data + state->req_data_sent,
1256 data_sent_thistime)) {
1257 return NT_STATUS_NO_MEMORY;
1260 switch (state->cli->auth->auth_level) {
1261 case DCERPC_AUTH_LEVEL_NONE:
1262 case DCERPC_AUTH_LEVEL_CONNECT:
1263 case DCERPC_AUTH_LEVEL_PACKET:
1265 case DCERPC_AUTH_LEVEL_INTEGRITY:
1266 case DCERPC_AUTH_LEVEL_PRIVACY:
1267 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1269 if (!NT_STATUS_IS_OK(status)) {
1274 return NT_STATUS_INVALID_PARAMETER;
1277 state->req_data_sent += data_sent_thistime;
1278 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1283 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1285 struct tevent_req *req = tevent_req_callback_data(
1286 subreq, struct tevent_req);
1287 struct rpc_api_pipe_req_state *state = tevent_req_data(
1288 req, struct rpc_api_pipe_req_state);
1292 status = rpc_write_recv(subreq);
1293 TALLOC_FREE(subreq);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 tevent_req_nterror(req, status);
1299 status = prepare_next_frag(state, &is_last_frag);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 tevent_req_nterror(req, status);
1306 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1308 DCERPC_PKT_RESPONSE);
1309 if (tevent_req_nomem(subreq, req)) {
1312 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1314 subreq = rpc_write_send(state, state->ev,
1315 state->cli->transport,
1316 state->rpc_out.data,
1317 state->rpc_out.length);
1318 if (tevent_req_nomem(subreq, req)) {
1321 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1326 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1328 struct tevent_req *req = tevent_req_callback_data(
1329 subreq, struct tevent_req);
1330 struct rpc_api_pipe_req_state *state = tevent_req_data(
1331 req, struct rpc_api_pipe_req_state);
1334 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1335 TALLOC_FREE(subreq);
1336 if (!NT_STATUS_IS_OK(status)) {
1337 tevent_req_nterror(req, status);
1340 tevent_req_done(req);
1343 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1344 DATA_BLOB *reply_pdu)
1346 struct rpc_api_pipe_req_state *state = tevent_req_data(
1347 req, struct rpc_api_pipe_req_state);
1350 if (tevent_req_is_nterror(req, &status)) {
1352 * We always have to initialize to reply pdu, even if there is
1353 * none. The rpccli_* caller routines expect this.
1355 *reply_pdu = data_blob_null;
1359 /* return data to caller and assign it ownership of memory */
1360 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1361 reply_pdu->length = state->reply_pdu.length;
1362 state->reply_pdu.length = 0;
1364 return NT_STATUS_OK;
1367 /****************************************************************************
1368 Check the rpc bind acknowledge response.
1369 ****************************************************************************/
1371 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1372 const struct ndr_syntax_id *transfer)
1374 struct dcerpc_ack_ctx ctx;
1376 if (r->secondary_address_size == 0) {
1377 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1380 if (r->num_results < 1 || !r->ctx_list) {
1384 ctx = r->ctx_list[0];
1386 /* check the transfer syntax */
1387 if ((ctx.syntax.if_version != transfer->if_version) ||
1388 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1389 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1393 if (r->num_results != 0x1 || ctx.result != 0) {
1394 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1395 r->num_results, ctx.reason));
1398 DEBUG(5,("check_bind_response: accepted!\n"));
1402 /*******************************************************************
1403 Creates a DCE/RPC bind authentication response.
1404 This is the packet that is sent back to the server once we
1405 have received a BIND-ACK, to finish the third leg of
1406 the authentication handshake.
1407 ********************************************************************/
1409 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1410 struct rpc_pipe_client *cli,
1412 enum dcerpc_AuthType auth_type,
1413 enum dcerpc_AuthLevel auth_level,
1414 DATA_BLOB *pauth_blob,
1418 union dcerpc_payload u;
1422 status = dcerpc_push_dcerpc_auth(mem_ctx,
1425 0, /* auth_pad_length */
1426 1, /* auth_context_id */
1428 &u.auth3.auth_info);
1429 if (!NT_STATUS_IS_OK(status)) {
1433 status = dcerpc_push_ncacn_packet(mem_ctx,
1435 DCERPC_PFC_FLAG_FIRST |
1436 DCERPC_PFC_FLAG_LAST,
1441 data_blob_free(&u.auth3.auth_info);
1442 if (!NT_STATUS_IS_OK(status)) {
1443 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1447 return NT_STATUS_OK;
1450 /*******************************************************************
1451 Creates a DCE/RPC bind alter context authentication request which
1452 may contain a spnego auth blobl
1453 ********************************************************************/
1455 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1456 enum dcerpc_AuthType auth_type,
1457 enum dcerpc_AuthLevel auth_level,
1459 const struct ndr_syntax_id *abstract,
1460 const struct ndr_syntax_id *transfer,
1461 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1464 DATA_BLOB auth_info;
1467 status = dcerpc_push_dcerpc_auth(mem_ctx,
1470 0, /* auth_pad_length */
1471 1, /* auth_context_id */
1474 if (!NT_STATUS_IS_OK(status)) {
1478 status = create_bind_or_alt_ctx_internal(mem_ctx,
1485 data_blob_free(&auth_info);
1489 /****************************************************************************
1491 ****************************************************************************/
1493 struct rpc_pipe_bind_state {
1494 struct tevent_context *ev;
1495 struct rpc_pipe_client *cli;
1498 uint32_t rpc_call_id;
1501 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1502 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1503 struct rpc_pipe_bind_state *state,
1504 DATA_BLOB *credentials);
1505 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1506 struct rpc_pipe_bind_state *state,
1507 DATA_BLOB *credentials);
1509 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1510 struct tevent_context *ev,
1511 struct rpc_pipe_client *cli,
1512 struct pipe_auth_data *auth)
1514 struct tevent_req *req, *subreq;
1515 struct rpc_pipe_bind_state *state;
1518 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1523 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1524 rpccli_pipe_txt(talloc_tos(), cli),
1525 (unsigned int)auth->auth_type,
1526 (unsigned int)auth->auth_level ));
1530 state->rpc_call_id = get_rpc_call_id();
1532 cli->auth = talloc_move(cli, &auth);
1534 /* Marshall the outgoing data. */
1535 status = create_rpc_bind_req(state, cli,
1538 &cli->abstract_syntax,
1539 &cli->transfer_syntax,
1542 if (!NT_STATUS_IS_OK(status) &&
1543 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1547 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1548 DCERPC_PKT_BIND_ACK);
1549 if (subreq == NULL) {
1552 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1556 tevent_req_nterror(req, status);
1557 return tevent_req_post(req, ev);
1563 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1565 struct tevent_req *req = tevent_req_callback_data(
1566 subreq, struct tevent_req);
1567 struct rpc_pipe_bind_state *state = tevent_req_data(
1568 req, struct rpc_pipe_bind_state);
1569 struct pipe_auth_data *pauth = state->cli->auth;
1570 struct gensec_security *gensec_security;
1571 struct ncacn_packet *pkt = NULL;
1572 struct dcerpc_auth auth;
1573 DATA_BLOB auth_token = data_blob_null;
1576 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1577 TALLOC_FREE(subreq);
1578 if (!NT_STATUS_IS_OK(status)) {
1579 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1580 rpccli_pipe_txt(talloc_tos(), state->cli),
1581 nt_errstr(status)));
1582 tevent_req_nterror(req, status);
1587 tevent_req_done(req);
1591 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1592 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1593 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1597 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1598 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1600 switch(pauth->auth_type) {
1602 case DCERPC_AUTH_TYPE_NONE:
1603 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1604 case DCERPC_AUTH_TYPE_SCHANNEL:
1605 /* Bind complete. */
1606 tevent_req_done(req);
1609 case DCERPC_AUTH_TYPE_NTLMSSP:
1610 case DCERPC_AUTH_TYPE_SPNEGO:
1611 case DCERPC_AUTH_TYPE_KRB5:
1612 /* Paranoid lenght checks */
1613 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1614 + pkt->auth_length) {
1615 tevent_req_nterror(req,
1616 NT_STATUS_INFO_LENGTH_MISMATCH);
1619 /* get auth credentials */
1620 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1621 &pkt->u.bind_ack.auth_info,
1623 if (!NT_STATUS_IS_OK(status)) {
1624 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1625 nt_errstr(status)));
1626 tevent_req_nterror(req, status);
1636 * For authenticated binds we may need to do 3 or 4 leg binds.
1639 switch(pauth->auth_type) {
1641 case DCERPC_AUTH_TYPE_NONE:
1642 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1643 case DCERPC_AUTH_TYPE_SCHANNEL:
1644 /* Bind complete. */
1645 tevent_req_done(req);
1648 case DCERPC_AUTH_TYPE_NTLMSSP:
1649 case DCERPC_AUTH_TYPE_KRB5:
1650 case DCERPC_AUTH_TYPE_SPNEGO:
1651 gensec_security = talloc_get_type_abort(pauth->auth_ctx,
1652 struct gensec_security);
1653 status = gensec_update(gensec_security, state, NULL,
1654 auth.credentials, &auth_token);
1655 if (NT_STATUS_EQUAL(status,
1656 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1657 status = rpc_bind_next_send(req, state,
1659 } else if (NT_STATUS_IS_OK(status)) {
1660 if (auth_token.length == 0) {
1661 /* Bind complete. */
1662 tevent_req_done(req);
1665 status = rpc_bind_finish_send(req, state,
1674 if (!NT_STATUS_IS_OK(status)) {
1675 tevent_req_nterror(req, status);
1680 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1681 (unsigned int)state->cli->auth->auth_type));
1682 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1685 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1686 struct rpc_pipe_bind_state *state,
1687 DATA_BLOB *auth_token)
1689 struct pipe_auth_data *auth = state->cli->auth;
1690 struct tevent_req *subreq;
1693 /* Now prepare the alter context pdu. */
1694 data_blob_free(&state->rpc_out);
1696 status = create_rpc_alter_context(state,
1700 &state->cli->abstract_syntax,
1701 &state->cli->transfer_syntax,
1704 if (!NT_STATUS_IS_OK(status)) {
1708 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1709 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1710 if (subreq == NULL) {
1711 return NT_STATUS_NO_MEMORY;
1713 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1714 return NT_STATUS_OK;
1717 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1718 struct rpc_pipe_bind_state *state,
1719 DATA_BLOB *auth_token)
1721 struct pipe_auth_data *auth = state->cli->auth;
1722 struct tevent_req *subreq;
1725 state->auth3 = true;
1727 /* Now prepare the auth3 context pdu. */
1728 data_blob_free(&state->rpc_out);
1730 status = create_rpc_bind_auth3(state, state->cli,
1736 if (!NT_STATUS_IS_OK(status)) {
1740 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1741 &state->rpc_out, DCERPC_PKT_AUTH3);
1742 if (subreq == NULL) {
1743 return NT_STATUS_NO_MEMORY;
1745 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1746 return NT_STATUS_OK;
1749 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1751 return tevent_req_simple_recv_ntstatus(req);
1754 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1755 struct pipe_auth_data *auth)
1757 TALLOC_CTX *frame = talloc_stackframe();
1758 struct tevent_context *ev;
1759 struct tevent_req *req;
1760 NTSTATUS status = NT_STATUS_OK;
1762 ev = samba_tevent_context_init(frame);
1764 status = NT_STATUS_NO_MEMORY;
1768 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1770 status = NT_STATUS_NO_MEMORY;
1774 if (!tevent_req_poll(req, ev)) {
1775 status = map_nt_error_from_unix(errno);
1779 status = rpc_pipe_bind_recv(req);
1785 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1787 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1788 unsigned int timeout)
1792 if (rpc_cli->transport == NULL) {
1793 return RPCCLI_DEFAULT_TIMEOUT;
1796 if (rpc_cli->transport->set_timeout == NULL) {
1797 return RPCCLI_DEFAULT_TIMEOUT;
1800 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1802 return RPCCLI_DEFAULT_TIMEOUT;
1808 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1810 if (rpc_cli == NULL) {
1814 if (rpc_cli->transport == NULL) {
1818 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1821 struct rpccli_bh_state {
1822 struct rpc_pipe_client *rpc_cli;
1825 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1827 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1828 struct rpccli_bh_state);
1830 return rpccli_is_connected(hs->rpc_cli);
1833 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1836 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1837 struct rpccli_bh_state);
1839 return rpccli_set_timeout(hs->rpc_cli, timeout);
1842 struct rpccli_bh_raw_call_state {
1848 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
1850 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
1851 struct tevent_context *ev,
1852 struct dcerpc_binding_handle *h,
1853 const struct GUID *object,
1856 const uint8_t *in_data,
1859 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1860 struct rpccli_bh_state);
1861 struct tevent_req *req;
1862 struct rpccli_bh_raw_call_state *state;
1864 struct tevent_req *subreq;
1866 req = tevent_req_create(mem_ctx, &state,
1867 struct rpccli_bh_raw_call_state);
1871 state->in_data.data = discard_const_p(uint8_t, in_data);
1872 state->in_data.length = in_length;
1874 ok = rpccli_bh_is_connected(h);
1876 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
1877 return tevent_req_post(req, ev);
1880 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
1881 opnum, &state->in_data);
1882 if (tevent_req_nomem(subreq, req)) {
1883 return tevent_req_post(req, ev);
1885 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
1890 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
1892 struct tevent_req *req =
1893 tevent_req_callback_data(subreq,
1895 struct rpccli_bh_raw_call_state *state =
1896 tevent_req_data(req,
1897 struct rpccli_bh_raw_call_state);
1900 state->out_flags = 0;
1902 /* TODO: support bigendian responses */
1904 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
1905 TALLOC_FREE(subreq);
1906 if (!NT_STATUS_IS_OK(status)) {
1907 tevent_req_nterror(req, status);
1911 tevent_req_done(req);
1914 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
1915 TALLOC_CTX *mem_ctx,
1918 uint32_t *out_flags)
1920 struct rpccli_bh_raw_call_state *state =
1921 tevent_req_data(req,
1922 struct rpccli_bh_raw_call_state);
1925 if (tevent_req_is_nterror(req, &status)) {
1926 tevent_req_received(req);
1930 *out_data = talloc_move(mem_ctx, &state->out_data.data);
1931 *out_length = state->out_data.length;
1932 *out_flags = state->out_flags;
1933 tevent_req_received(req);
1934 return NT_STATUS_OK;
1937 struct rpccli_bh_disconnect_state {
1941 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
1942 struct tevent_context *ev,
1943 struct dcerpc_binding_handle *h)
1945 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1946 struct rpccli_bh_state);
1947 struct tevent_req *req;
1948 struct rpccli_bh_disconnect_state *state;
1951 req = tevent_req_create(mem_ctx, &state,
1952 struct rpccli_bh_disconnect_state);
1957 ok = rpccli_bh_is_connected(h);
1959 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
1960 return tevent_req_post(req, ev);
1964 * TODO: do a real async disconnect ...
1966 * For now the caller needs to free rpc_cli
1970 tevent_req_done(req);
1971 return tevent_req_post(req, ev);
1974 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
1978 if (tevent_req_is_nterror(req, &status)) {
1979 tevent_req_received(req);
1983 tevent_req_received(req);
1984 return NT_STATUS_OK;
1987 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
1992 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
1994 const void *_struct_ptr,
1995 const struct ndr_interface_call *call)
1997 void *struct_ptr = discard_const(_struct_ptr);
1999 if (DEBUGLEVEL < 10) {
2003 if (ndr_flags & NDR_IN) {
2004 ndr_print_function_debug(call->ndr_print,
2009 if (ndr_flags & NDR_OUT) {
2010 ndr_print_function_debug(call->ndr_print,
2017 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2019 .is_connected = rpccli_bh_is_connected,
2020 .set_timeout = rpccli_bh_set_timeout,
2021 .raw_call_send = rpccli_bh_raw_call_send,
2022 .raw_call_recv = rpccli_bh_raw_call_recv,
2023 .disconnect_send = rpccli_bh_disconnect_send,
2024 .disconnect_recv = rpccli_bh_disconnect_recv,
2026 .ref_alloc = rpccli_bh_ref_alloc,
2027 .do_ndr_print = rpccli_bh_do_ndr_print,
2030 /* initialise a rpc_pipe_client binding handle */
2031 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2033 struct dcerpc_binding_handle *h;
2034 struct rpccli_bh_state *hs;
2036 h = dcerpc_binding_handle_create(c,
2041 struct rpccli_bh_state,
2051 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2052 struct pipe_auth_data **presult)
2054 struct pipe_auth_data *result;
2056 result = talloc(mem_ctx, struct pipe_auth_data);
2057 if (result == NULL) {
2058 return NT_STATUS_NO_MEMORY;
2061 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2062 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2064 result->user_name = talloc_strdup(result, "");
2065 result->domain = talloc_strdup(result, "");
2066 if ((result->user_name == NULL) || (result->domain == NULL)) {
2067 TALLOC_FREE(result);
2068 return NT_STATUS_NO_MEMORY;
2072 return NT_STATUS_OK;
2075 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2076 struct pipe_auth_data **presult)
2078 struct pipe_auth_data *result;
2080 result = talloc(mem_ctx, struct pipe_auth_data);
2081 if (result == NULL) {
2082 return NT_STATUS_NO_MEMORY;
2085 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2086 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2088 result->user_name = talloc_strdup(result, "");
2089 result->domain = talloc_strdup(result, "");
2090 if ((result->user_name == NULL) || (result->domain == NULL)) {
2091 TALLOC_FREE(result);
2092 return NT_STATUS_NO_MEMORY;
2096 return NT_STATUS_OK;
2099 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2100 enum dcerpc_AuthType auth_type,
2101 enum dcerpc_AuthLevel auth_level,
2103 const char *target_service,
2105 const char *username,
2106 const char *password,
2107 enum credentials_use_kerberos use_kerberos,
2108 struct netlogon_creds_CredentialState *creds,
2109 struct pipe_auth_data **presult)
2111 struct auth_generic_state *auth_generic_ctx;
2112 struct pipe_auth_data *result;
2115 result = talloc(mem_ctx, struct pipe_auth_data);
2116 if (result == NULL) {
2117 return NT_STATUS_NO_MEMORY;
2120 result->auth_type = auth_type;
2121 result->auth_level = auth_level;
2123 result->user_name = talloc_strdup(result, username);
2124 result->domain = talloc_strdup(result, domain);
2125 if ((result->user_name == NULL) || (result->domain == NULL)) {
2126 status = NT_STATUS_NO_MEMORY;
2130 status = auth_generic_client_prepare(result,
2132 if (!NT_STATUS_IS_OK(status)) {
2136 status = auth_generic_set_username(auth_generic_ctx, username);
2137 if (!NT_STATUS_IS_OK(status)) {
2141 status = auth_generic_set_domain(auth_generic_ctx, domain);
2142 if (!NT_STATUS_IS_OK(status)) {
2146 status = auth_generic_set_password(auth_generic_ctx, password);
2147 if (!NT_STATUS_IS_OK(status)) {
2151 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2152 if (!NT_STATUS_IS_OK(status)) {
2156 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2157 if (!NT_STATUS_IS_OK(status)) {
2161 cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
2162 cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2164 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2165 if (!NT_STATUS_IS_OK(status)) {
2169 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2170 talloc_free(auth_generic_ctx);
2172 return NT_STATUS_OK;
2175 TALLOC_FREE(result);
2180 * Create an rpc pipe client struct, connecting to a tcp port.
2182 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2183 const struct sockaddr_storage *ss_addr,
2185 const struct ndr_interface_table *table,
2186 struct rpc_pipe_client **presult)
2188 struct rpc_pipe_client *result;
2189 struct sockaddr_storage addr;
2193 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2194 if (result == NULL) {
2195 return NT_STATUS_NO_MEMORY;
2198 result->abstract_syntax = table->syntax_id;
2199 result->transfer_syntax = ndr_transfer_syntax_ndr;
2201 result->desthost = talloc_strdup(result, host);
2202 result->srv_name_slash = talloc_asprintf_strupper_m(
2203 result, "\\\\%s", result->desthost);
2204 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2205 status = NT_STATUS_NO_MEMORY;
2209 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2210 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2212 if (ss_addr == NULL) {
2213 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2214 status = NT_STATUS_NOT_FOUND;
2221 status = open_socket_out(&addr, port, 60*1000, &fd);
2222 if (!NT_STATUS_IS_OK(status)) {
2225 set_socket_options(fd, lp_socket_options());
2227 status = rpc_transport_sock_init(result, fd, &result->transport);
2228 if (!NT_STATUS_IS_OK(status)) {
2233 result->transport->transport = NCACN_IP_TCP;
2235 result->binding_handle = rpccli_bh_create(result);
2236 if (result->binding_handle == NULL) {
2237 TALLOC_FREE(result);
2238 return NT_STATUS_NO_MEMORY;
2242 return NT_STATUS_OK;
2245 TALLOC_FREE(result);
2250 * Determine the tcp port on which a dcerpc interface is listening
2251 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2254 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2255 const struct sockaddr_storage *addr,
2256 const struct ndr_interface_table *table,
2260 struct rpc_pipe_client *epm_pipe = NULL;
2261 struct dcerpc_binding_handle *epm_handle = NULL;
2262 struct pipe_auth_data *auth = NULL;
2263 struct dcerpc_binding *map_binding = NULL;
2264 struct dcerpc_binding *res_binding = NULL;
2265 struct epm_twr_t *map_tower = NULL;
2266 struct epm_twr_t *res_towers = NULL;
2267 struct policy_handle *entry_handle = NULL;
2268 uint32_t num_towers = 0;
2269 uint32_t max_towers = 1;
2270 struct epm_twr_p_t towers;
2271 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2272 uint32_t result = 0;
2274 if (pport == NULL) {
2275 status = NT_STATUS_INVALID_PARAMETER;
2279 if (ndr_syntax_id_equal(&table->syntax_id,
2280 &ndr_table_epmapper.syntax_id)) {
2282 return NT_STATUS_OK;
2285 /* open the connection to the endpoint mapper */
2286 status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2287 &ndr_table_epmapper,
2290 if (!NT_STATUS_IS_OK(status)) {
2293 epm_handle = epm_pipe->binding_handle;
2295 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2296 if (!NT_STATUS_IS_OK(status)) {
2300 status = rpc_pipe_bind(epm_pipe, auth);
2301 if (!NT_STATUS_IS_OK(status)) {
2305 /* create tower for asking the epmapper */
2307 map_binding = talloc_zero(tmp_ctx, struct dcerpc_binding);
2308 if (map_binding == NULL) {
2309 status = NT_STATUS_NO_MEMORY;
2313 map_binding->transport = NCACN_IP_TCP;
2314 map_binding->object = table->syntax_id;
2315 map_binding->host = host; /* needed? */
2316 map_binding->endpoint = "0"; /* correct? needed? */
2318 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2319 if (map_tower == NULL) {
2320 status = NT_STATUS_NO_MEMORY;
2324 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2325 &(map_tower->tower));
2326 if (!NT_STATUS_IS_OK(status)) {
2330 /* allocate further parameters for the epm_Map call */
2332 res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2333 if (res_towers == NULL) {
2334 status = NT_STATUS_NO_MEMORY;
2337 towers.twr = res_towers;
2339 entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2340 if (entry_handle == NULL) {
2341 status = NT_STATUS_NO_MEMORY;
2345 /* ask the endpoint mapper for the port */
2347 status = dcerpc_epm_Map(epm_handle,
2349 discard_const_p(struct GUID,
2350 &(table->syntax_id.uuid)),
2358 if (!NT_STATUS_IS_OK(status)) {
2362 if (result != EPMAPPER_STATUS_OK) {
2363 status = NT_STATUS_UNSUCCESSFUL;
2367 if (num_towers != 1) {
2368 status = NT_STATUS_UNSUCCESSFUL;
2372 /* extract the port from the answer */
2374 status = dcerpc_binding_from_tower(tmp_ctx,
2375 &(towers.twr->tower),
2377 if (!NT_STATUS_IS_OK(status)) {
2381 /* are further checks here necessary? */
2382 if (res_binding->transport != NCACN_IP_TCP) {
2383 status = NT_STATUS_UNSUCCESSFUL;
2387 *pport = (uint16_t)atoi(res_binding->endpoint);
2390 TALLOC_FREE(tmp_ctx);
2395 * Create a rpc pipe client struct, connecting to a host via tcp.
2396 * The port is determined by asking the endpoint mapper on the given
2399 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2400 const struct sockaddr_storage *addr,
2401 const struct ndr_interface_table *table,
2402 struct rpc_pipe_client **presult)
2407 status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2408 if (!NT_STATUS_IS_OK(status)) {
2412 return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2416 /********************************************************************
2417 Create a rpc pipe client struct, connecting to a unix domain socket
2418 ********************************************************************/
2419 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2420 const struct ndr_interface_table *table,
2421 struct rpc_pipe_client **presult)
2423 struct rpc_pipe_client *result;
2424 struct sockaddr_un addr;
2429 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2430 if (result == NULL) {
2431 return NT_STATUS_NO_MEMORY;
2434 result->abstract_syntax = table->syntax_id;
2435 result->transfer_syntax = ndr_transfer_syntax_ndr;
2437 result->desthost = get_myname(result);
2438 result->srv_name_slash = talloc_asprintf_strupper_m(
2439 result, "\\\\%s", result->desthost);
2440 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2441 status = NT_STATUS_NO_MEMORY;
2445 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2446 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2448 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2450 status = map_nt_error_from_unix(errno);
2455 addr.sun_family = AF_UNIX;
2456 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2457 salen = sizeof(struct sockaddr_un);
2459 if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
2460 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2463 return map_nt_error_from_unix(errno);
2466 status = rpc_transport_sock_init(result, fd, &result->transport);
2467 if (!NT_STATUS_IS_OK(status)) {
2472 result->transport->transport = NCALRPC;
2474 result->binding_handle = rpccli_bh_create(result);
2475 if (result->binding_handle == NULL) {
2476 TALLOC_FREE(result);
2477 return NT_STATUS_NO_MEMORY;
2481 return NT_STATUS_OK;
2484 TALLOC_FREE(result);
2488 struct rpc_pipe_client_np_ref {
2489 struct cli_state *cli;
2490 struct rpc_pipe_client *pipe;
2493 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2495 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2499 /****************************************************************************
2500 Open a named pipe over SMB to a remote server.
2502 * CAVEAT CALLER OF THIS FUNCTION:
2503 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2504 * so be sure that this function is called AFTER any structure (vs pointer)
2505 * assignment of the cli. In particular, libsmbclient does structure
2506 * assignments of cli, which invalidates the data in the returned
2507 * rpc_pipe_client if this function is called before the structure assignment
2510 ****************************************************************************/
2512 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2513 const struct ndr_interface_table *table,
2514 struct rpc_pipe_client **presult)
2516 struct rpc_pipe_client *result;
2518 struct rpc_pipe_client_np_ref *np_ref;
2520 /* sanity check to protect against crashes */
2523 return NT_STATUS_INVALID_HANDLE;
2526 result = talloc_zero(NULL, struct rpc_pipe_client);
2527 if (result == NULL) {
2528 return NT_STATUS_NO_MEMORY;
2531 result->abstract_syntax = table->syntax_id;
2532 result->transfer_syntax = ndr_transfer_syntax_ndr;
2533 result->desthost = talloc_strdup(result, smbXcli_conn_remote_name(cli->conn));
2534 result->srv_name_slash = talloc_asprintf_strupper_m(
2535 result, "\\\\%s", result->desthost);
2537 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2538 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2540 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2541 TALLOC_FREE(result);
2542 return NT_STATUS_NO_MEMORY;
2545 status = rpc_transport_np_init(result, cli, table,
2546 &result->transport);
2547 if (!NT_STATUS_IS_OK(status)) {
2548 TALLOC_FREE(result);
2552 result->transport->transport = NCACN_NP;
2554 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2555 if (np_ref == NULL) {
2556 TALLOC_FREE(result);
2557 return NT_STATUS_NO_MEMORY;
2560 np_ref->pipe = result;
2562 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2563 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2565 result->binding_handle = rpccli_bh_create(result);
2566 if (result->binding_handle == NULL) {
2567 TALLOC_FREE(result);
2568 return NT_STATUS_NO_MEMORY;
2572 return NT_STATUS_OK;
2575 /****************************************************************************
2576 Open a pipe to a remote server.
2577 ****************************************************************************/
2579 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2580 enum dcerpc_transport_t transport,
2581 const struct ndr_interface_table *table,
2582 struct rpc_pipe_client **presult)
2584 switch (transport) {
2586 return rpc_pipe_open_tcp(NULL,
2587 smbXcli_conn_remote_name(cli->conn),
2588 smbXcli_conn_remote_sockaddr(cli->conn),
2591 return rpc_pipe_open_np(cli, table, presult);
2593 return NT_STATUS_NOT_IMPLEMENTED;
2597 /****************************************************************************
2598 Open a named pipe to an SMB server and bind anonymously.
2599 ****************************************************************************/
2601 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2602 enum dcerpc_transport_t transport,
2603 const struct ndr_interface_table *table,
2604 struct rpc_pipe_client **presult)
2606 struct rpc_pipe_client *result;
2607 struct pipe_auth_data *auth;
2610 status = cli_rpc_pipe_open(cli, transport, table, &result);
2611 if (!NT_STATUS_IS_OK(status)) {
2615 status = rpccli_anon_bind_data(result, &auth);
2616 if (!NT_STATUS_IS_OK(status)) {
2617 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2618 nt_errstr(status)));
2619 TALLOC_FREE(result);
2624 * This is a bit of an abstraction violation due to the fact that an
2625 * anonymous bind on an authenticated SMB inherits the user/domain
2626 * from the enclosing SMB creds
2629 TALLOC_FREE(auth->user_name);
2630 TALLOC_FREE(auth->domain);
2632 auth->user_name = talloc_strdup(auth, cli->user_name);
2633 auth->domain = talloc_strdup(auth, cli->domain);
2635 if (transport == NCACN_NP) {
2636 struct smbXcli_session *session;
2638 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2639 session = cli->smb2.session;
2641 session = cli->smb1.session;
2644 status = smbXcli_session_application_key(session, auth,
2645 &auth->transport_session_key);
2646 if (!NT_STATUS_IS_OK(status)) {
2647 auth->transport_session_key = data_blob_null;
2651 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2652 TALLOC_FREE(result);
2653 return NT_STATUS_NO_MEMORY;
2656 status = rpc_pipe_bind(result, auth);
2657 if (!NT_STATUS_IS_OK(status)) {
2659 if (ndr_syntax_id_equal(&table->syntax_id,
2660 &ndr_table_dssetup.syntax_id)) {
2661 /* non AD domains just don't have this pipe, avoid
2662 * level 0 statement in that case - gd */
2665 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2666 "%s failed with error %s\n",
2668 nt_errstr(status) ));
2669 TALLOC_FREE(result);
2673 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2674 "%s and bound anonymously.\n",
2679 return NT_STATUS_OK;
2682 /****************************************************************************
2683 ****************************************************************************/
2685 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2686 const struct ndr_interface_table *table,
2687 struct rpc_pipe_client **presult)
2689 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2693 /****************************************************************************
2694 Open a named pipe to an SMB server and bind using the mech specified
2695 ****************************************************************************/
2697 NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
2698 const struct ndr_interface_table *table,
2699 enum dcerpc_transport_t transport,
2700 enum dcerpc_AuthType auth_type,
2701 enum dcerpc_AuthLevel auth_level,
2704 const char *username,
2705 const char *password,
2706 struct rpc_pipe_client **presult)
2708 struct rpc_pipe_client *result;
2709 struct pipe_auth_data *auth = NULL;
2710 const char *target_service = table->authservices->names[0];
2714 status = cli_rpc_pipe_open(cli, transport, table, &result);
2715 if (!NT_STATUS_IS_OK(status)) {
2719 status = rpccli_generic_bind_data(result,
2720 auth_type, auth_level,
2721 server, target_service,
2722 domain, username, password,
2723 CRED_AUTO_USE_KERBEROS,
2726 if (!NT_STATUS_IS_OK(status)) {
2727 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
2728 nt_errstr(status)));
2732 status = rpc_pipe_bind(result, auth);
2733 if (!NT_STATUS_IS_OK(status)) {
2734 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
2735 nt_errstr(status) ));
2739 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
2740 "machine %s and bound as user %s\\%s.\n", table->name,
2741 result->desthost, domain, username));
2744 return NT_STATUS_OK;
2748 TALLOC_FREE(result);
2752 /****************************************************************************
2754 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2755 using session_key. sign and seal.
2757 The *pdc will be stolen onto this new pipe
2758 ****************************************************************************/
2760 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2761 const struct ndr_interface_table *table,
2762 enum dcerpc_transport_t transport,
2763 enum dcerpc_AuthLevel auth_level,
2765 struct netlogon_creds_CredentialState **pdc,
2766 struct rpc_pipe_client **_rpccli)
2768 struct rpc_pipe_client *rpccli;
2769 struct pipe_auth_data *rpcauth;
2772 struct netlogon_creds_CredentialState save_creds;
2773 struct netr_Authenticator auth;
2774 struct netr_Authenticator return_auth;
2775 union netr_Capabilities capabilities;
2776 const char *target_service = table->authservices->names[0];
2778 status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
2779 if (!NT_STATUS_IS_OK(status)) {
2783 status = rpccli_generic_bind_data(rpccli,
2784 DCERPC_AUTH_TYPE_SCHANNEL,
2789 (*pdc)->computer_name,
2791 CRED_AUTO_USE_KERBEROS,
2794 if (!NT_STATUS_IS_OK(status)) {
2795 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
2796 nt_errstr(status)));
2797 TALLOC_FREE(rpccli);
2802 * The credentials on a new netlogon pipe are the ones we are passed
2803 * in - copy them over
2805 * This may get overwritten... in rpc_pipe_bind()...
2807 rpccli->dc = netlogon_creds_copy(rpccli, *pdc);
2808 if (rpccli->dc == NULL) {
2809 TALLOC_FREE(rpccli);
2810 return NT_STATUS_NO_MEMORY;
2813 status = rpc_pipe_bind(rpccli, rpcauth);
2814 if (!NT_STATUS_IS_OK(status)) {
2815 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
2816 "cli_rpc_pipe_bind failed with error %s\n",
2817 nt_errstr(status) ));
2818 TALLOC_FREE(rpccli);
2822 if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
2826 save_creds = *rpccli->dc;
2827 ZERO_STRUCT(return_auth);
2828 ZERO_STRUCT(capabilities);
2830 netlogon_creds_client_authenticator(&save_creds, &auth);
2832 status = dcerpc_netr_LogonGetCapabilities(rpccli->binding_handle,
2834 rpccli->srv_name_slash,
2835 save_creds.computer_name,
2836 &auth, &return_auth,
2839 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
2840 if (save_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
2841 DEBUG(5, ("AES was negotiated and the error was %s - "
2842 "downgrade detected\n",
2843 nt_errstr(status)));
2844 TALLOC_FREE(rpccli);
2845 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2848 /* This is probably an old Samba Version */
2849 DEBUG(5, ("We are checking against an NT or old Samba - %s\n",
2850 nt_errstr(status)));
2854 if (!NT_STATUS_IS_OK(status)) {
2855 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities failed with %s\n",
2856 nt_errstr(status)));
2857 TALLOC_FREE(rpccli);
2861 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
2862 if (save_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
2863 /* This means AES isn't supported. */
2864 DEBUG(5, ("AES was negotiated and the result was %s - "
2865 "downgrade detected\n",
2866 nt_errstr(result)));
2867 TALLOC_FREE(rpccli);
2868 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2871 /* This is probably an old Windows version */
2872 DEBUG(5, ("We are checking against an win2k3 or Samba - %s\n",
2873 nt_errstr(result)));
2878 * We need to check the credential state here, cause win2k3 and earlier
2879 * returns NT_STATUS_NOT_IMPLEMENTED
2881 if (!netlogon_creds_client_check(&save_creds, &return_auth.cred)) {
2883 * Server replied with bad credential. Fail.
2885 DEBUG(0,("cli_rpc_pipe_open_schannel_with_key: server %s "
2886 "replied with bad credential\n",
2888 TALLOC_FREE(rpccli);
2889 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2891 *rpccli->dc = save_creds;
2893 if (!NT_STATUS_IS_OK(result)) {
2894 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities failed with %s\n",
2895 nt_errstr(result)));
2896 TALLOC_FREE(rpccli);
2900 if (!(save_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
2901 /* This means AES isn't supported. */
2902 DEBUG(5, ("AES is not negotiated, but netr_LogonGetCapabilities "
2903 "was OK - downgrade detected\n"));
2904 TALLOC_FREE(rpccli);
2905 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2908 if (save_creds.negotiate_flags != capabilities.server_capabilities) {
2909 DEBUG(0, ("The client capabilities don't match the server "
2910 "capabilities: local[0x%08X] remote[0x%08X]\n",
2911 save_creds.negotiate_flags,
2912 capabilities.server_capabilities));
2913 TALLOC_FREE(rpccli);
2914 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2918 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2919 "for domain %s and bound using schannel.\n",
2921 rpccli->desthost, domain));
2924 return NT_STATUS_OK;
2927 NTSTATUS cli_rpc_pipe_open_spnego(struct cli_state *cli,
2928 const struct ndr_interface_table *table,
2929 enum dcerpc_transport_t transport,
2931 enum dcerpc_AuthLevel auth_level,
2934 const char *username,
2935 const char *password,
2936 struct rpc_pipe_client **presult)
2938 struct rpc_pipe_client *result;
2939 struct pipe_auth_data *auth = NULL;
2940 const char *target_service = table->authservices->names[0];
2943 enum credentials_use_kerberos use_kerberos;
2945 if (strcmp(oid, GENSEC_OID_KERBEROS5) == 0) {
2946 use_kerberos = CRED_MUST_USE_KERBEROS;
2947 } else if (strcmp(oid, GENSEC_OID_NTLMSSP) == 0) {
2948 use_kerberos = CRED_DONT_USE_KERBEROS;
2950 return NT_STATUS_INVALID_PARAMETER;
2953 status = cli_rpc_pipe_open(cli, transport, table, &result);
2954 if (!NT_STATUS_IS_OK(status)) {
2958 status = rpccli_generic_bind_data(result,
2959 DCERPC_AUTH_TYPE_SPNEGO, auth_level,
2960 server, target_service,
2961 domain, username, password,
2964 if (!NT_STATUS_IS_OK(status)) {
2965 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
2966 nt_errstr(status)));
2970 status = rpc_pipe_bind(result, auth);
2971 if (!NT_STATUS_IS_OK(status)) {
2972 DEBUG(0, ("cli_rpc_pipe_open_spnego: cli_rpc_pipe_bind failed with error %s\n",
2973 nt_errstr(status) ));
2977 DEBUG(10,("cli_rpc_pipe_open_spnego: opened pipe %s to "
2978 "machine %s.\n", table->name,
2982 return NT_STATUS_OK;
2986 TALLOC_FREE(result);
2990 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
2991 struct rpc_pipe_client *cli,
2992 DATA_BLOB *session_key)
2995 struct pipe_auth_data *a;
2996 struct gensec_security *gensec_security;
2997 DATA_BLOB sk = data_blob_null;
2998 bool make_dup = false;
3000 if (!session_key || !cli) {
3001 return NT_STATUS_INVALID_PARAMETER;
3007 return NT_STATUS_INVALID_PARAMETER;
3010 switch (cli->auth->auth_type) {
3011 case DCERPC_AUTH_TYPE_SPNEGO:
3012 case DCERPC_AUTH_TYPE_NTLMSSP:
3013 case DCERPC_AUTH_TYPE_KRB5:
3014 gensec_security = talloc_get_type_abort(a->auth_ctx,
3015 struct gensec_security);
3016 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3017 if (!NT_STATUS_IS_OK(status)) {
3022 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3023 case DCERPC_AUTH_TYPE_NONE:
3024 sk = data_blob_const(a->transport_session_key.data,
3025 a->transport_session_key.length);
3033 return NT_STATUS_NO_USER_SESSION_KEY;
3037 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3042 return NT_STATUS_OK;