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 "../libcli/auth/netlogon_creds_cli.h"
28 #include "auth_generic.h"
29 #include "librpc/gen_ndr/ndr_dcerpc.h"
30 #include "librpc/gen_ndr/ndr_netlogon_c.h"
31 #include "librpc/rpc/dcerpc.h"
34 #include "libsmb/libsmb.h"
35 #include "auth/gensec/gensec.h"
36 #include "auth/credentials/credentials.h"
37 #include "../libcli/smb/smbXcli_base.h"
38 #include "../libcli/smb/tstream_smbXcli_np.h"
39 #include "librpc/rpc/dcerpc_connection.h"
42 #define DBGC_CLASS DBGC_RPC_CLI
44 /********************************************************************
45 Pipe description for a DEBUG
46 ********************************************************************/
47 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
48 struct rpc_pipe_client *cli)
50 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
57 /********************************************************************
59 ********************************************************************/
61 static uint32 get_rpc_call_id(void)
63 static uint32 call_id = 0;
67 /*******************************************************************
68 Use SMBreadX to get rest of one fragment's worth of rpc data.
69 Reads the whole size or give an error message
70 ********************************************************************/
72 struct rpc_read_state {
73 struct tevent_context *ev;
74 struct rpc_cli_transport *transport;
80 static void rpc_read_done(struct tevent_req *subreq);
82 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
83 struct tevent_context *ev,
84 struct rpc_cli_transport *transport,
85 uint8_t *data, size_t size)
87 struct tevent_req *req, *subreq;
88 struct rpc_read_state *state;
90 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
95 state->transport = transport;
100 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
102 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
104 if (subreq == NULL) {
107 tevent_req_set_callback(subreq, rpc_read_done, req);
115 static void rpc_read_done(struct tevent_req *subreq)
117 struct tevent_req *req = tevent_req_callback_data(
118 subreq, struct tevent_req);
119 struct rpc_read_state *state = tevent_req_data(
120 req, struct rpc_read_state);
124 status = state->transport->read_recv(subreq, &received);
126 if (!NT_STATUS_IS_OK(status)) {
127 tevent_req_nterror(req, status);
131 state->num_read += received;
132 if (state->num_read == state->size) {
133 tevent_req_done(req);
137 subreq = state->transport->read_send(state, state->ev,
138 state->data + state->num_read,
139 state->size - state->num_read,
140 state->transport->priv);
141 if (tevent_req_nomem(subreq, req)) {
144 tevent_req_set_callback(subreq, rpc_read_done, req);
147 static NTSTATUS rpc_read_recv(struct tevent_req *req)
149 return tevent_req_simple_recv_ntstatus(req);
152 struct rpc_write_state {
153 struct tevent_context *ev;
154 struct rpc_cli_transport *transport;
160 static void rpc_write_done(struct tevent_req *subreq);
162 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
163 struct tevent_context *ev,
164 struct rpc_cli_transport *transport,
165 const uint8_t *data, size_t size)
167 struct tevent_req *req, *subreq;
168 struct rpc_write_state *state;
170 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
175 state->transport = transport;
178 state->num_written = 0;
180 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
182 subreq = transport->write_send(state, ev, data, size, transport->priv);
183 if (subreq == NULL) {
186 tevent_req_set_callback(subreq, rpc_write_done, req);
193 static void rpc_write_done(struct tevent_req *subreq)
195 struct tevent_req *req = tevent_req_callback_data(
196 subreq, struct tevent_req);
197 struct rpc_write_state *state = tevent_req_data(
198 req, struct rpc_write_state);
202 status = state->transport->write_recv(subreq, &written);
204 if (!NT_STATUS_IS_OK(status)) {
205 tevent_req_nterror(req, status);
209 state->num_written += written;
211 if (state->num_written == state->size) {
212 tevent_req_done(req);
216 subreq = state->transport->write_send(state, state->ev,
217 state->data + state->num_written,
218 state->size - state->num_written,
219 state->transport->priv);
220 if (tevent_req_nomem(subreq, req)) {
223 tevent_req_set_callback(subreq, rpc_write_done, req);
226 static NTSTATUS rpc_write_recv(struct tevent_req *req)
228 return tevent_req_simple_recv_ntstatus(req);
232 /****************************************************************************
233 Try and get a PDU's worth of data from current_pdu. If not, then read more
235 ****************************************************************************/
237 struct get_complete_frag_state {
238 struct tevent_context *ev;
239 struct rpc_pipe_client *cli;
244 static void get_complete_frag_got_header(struct tevent_req *subreq);
245 static void get_complete_frag_got_rest(struct tevent_req *subreq);
247 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
248 struct tevent_context *ev,
249 struct rpc_pipe_client *cli,
252 struct tevent_req *req, *subreq;
253 struct get_complete_frag_state *state;
257 req = tevent_req_create(mem_ctx, &state,
258 struct get_complete_frag_state);
264 state->frag_len = RPC_HEADER_LEN;
267 received = pdu->length;
268 if (received < RPC_HEADER_LEN) {
269 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
270 status = NT_STATUS_NO_MEMORY;
273 subreq = rpc_read_send(state, state->ev,
274 state->cli->transport,
275 pdu->data + received,
276 RPC_HEADER_LEN - received);
277 if (subreq == NULL) {
278 status = NT_STATUS_NO_MEMORY;
281 tevent_req_set_callback(subreq, get_complete_frag_got_header,
286 state->frag_len = dcerpc_get_frag_length(pdu);
287 if (state->frag_len < RPC_HEADER_LEN) {
288 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
289 return tevent_req_post(req, ev);
293 * Ensure we have frag_len bytes of data.
295 if (received < state->frag_len) {
296 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
297 status = NT_STATUS_NO_MEMORY;
300 subreq = rpc_read_send(state, state->ev,
301 state->cli->transport,
302 pdu->data + received,
303 state->frag_len - received);
304 if (subreq == NULL) {
305 status = NT_STATUS_NO_MEMORY;
308 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
313 status = NT_STATUS_OK;
315 if (NT_STATUS_IS_OK(status)) {
316 tevent_req_done(req);
318 tevent_req_nterror(req, status);
320 return tevent_req_post(req, ev);
323 static void get_complete_frag_got_header(struct tevent_req *subreq)
325 struct tevent_req *req = tevent_req_callback_data(
326 subreq, struct tevent_req);
327 struct get_complete_frag_state *state = tevent_req_data(
328 req, struct get_complete_frag_state);
331 status = rpc_read_recv(subreq);
333 if (!NT_STATUS_IS_OK(status)) {
334 tevent_req_nterror(req, status);
338 state->frag_len = dcerpc_get_frag_length(state->pdu);
339 if (state->frag_len < RPC_HEADER_LEN) {
340 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
344 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
345 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
350 * We're here in this piece of code because we've read exactly
351 * RPC_HEADER_LEN bytes into state->pdu.
354 subreq = rpc_read_send(state, state->ev, state->cli->transport,
355 state->pdu->data + RPC_HEADER_LEN,
356 state->frag_len - RPC_HEADER_LEN);
357 if (tevent_req_nomem(subreq, req)) {
360 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
363 static void get_complete_frag_got_rest(struct tevent_req *subreq)
365 struct tevent_req *req = tevent_req_callback_data(
366 subreq, struct tevent_req);
369 status = rpc_read_recv(subreq);
371 if (!NT_STATUS_IS_OK(status)) {
372 tevent_req_nterror(req, status);
375 tevent_req_done(req);
378 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
380 return tevent_req_simple_recv_ntstatus(req);
383 /****************************************************************************
384 Do basic authentication checks on an incoming pdu.
385 ****************************************************************************/
387 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
388 struct rpc_pipe_client *cli,
389 struct ncacn_packet *pkt,
391 uint8_t expected_pkt_type,
394 DATA_BLOB *reply_pdu)
396 struct dcerpc_response *r;
397 NTSTATUS ret = NT_STATUS_OK;
401 * Point the return values at the real data including the RPC
402 * header. Just in case the caller wants it.
406 /* Ensure we have the correct type. */
407 switch (pkt->ptype) {
408 case DCERPC_PKT_ALTER_RESP:
409 case DCERPC_PKT_BIND_ACK:
411 /* Client code never receives this kind of packets */
415 case DCERPC_PKT_RESPONSE:
417 r = &pkt->u.response;
419 /* Here's where we deal with incoming sign/seal. */
420 ret = dcerpc_check_auth(cli->auth, pkt,
421 &r->stub_and_verifier,
422 DCERPC_RESPONSE_LENGTH,
424 if (!NT_STATUS_IS_OK(ret)) {
428 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
429 return NT_STATUS_BUFFER_TOO_SMALL;
432 /* Point the return values at the NDR data. */
433 rdata->data = r->stub_and_verifier.data;
435 if (pkt->auth_length) {
436 /* We've already done integer wrap tests in
437 * dcerpc_check_auth(). */
438 rdata->length = r->stub_and_verifier.length
440 - DCERPC_AUTH_TRAILER_LENGTH
443 rdata->length = r->stub_and_verifier.length;
446 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
447 (long unsigned int)pdu->length,
448 (long unsigned int)rdata->length,
449 (unsigned int)pad_len));
452 * If this is the first reply, and the allocation hint is
453 * reasonable, try and set up the reply_pdu DATA_BLOB to the
457 if ((reply_pdu->length == 0) &&
458 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
459 if (!data_blob_realloc(mem_ctx, reply_pdu,
461 DEBUG(0, ("reply alloc hint %d too "
462 "large to allocate\n",
463 (int)r->alloc_hint));
464 return NT_STATUS_NO_MEMORY;
470 case DCERPC_PKT_BIND_NAK:
471 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
472 rpccli_pipe_txt(talloc_tos(), cli)));
473 /* Use this for now... */
474 return NT_STATUS_NETWORK_ACCESS_DENIED;
476 case DCERPC_PKT_FAULT:
478 DEBUG(1, (__location__ ": RPC fault code %s received "
480 dcerpc_errstr(talloc_tos(),
481 pkt->u.fault.status),
482 rpccli_pipe_txt(talloc_tos(), cli)));
484 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
487 DEBUG(0, (__location__ "Unknown packet type %u received "
489 (unsigned int)pkt->ptype,
490 rpccli_pipe_txt(talloc_tos(), cli)));
491 return NT_STATUS_RPC_PROTOCOL_ERROR;
494 if (pkt->ptype != expected_pkt_type) {
495 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
496 "RPC packet type - %u, not %u\n",
497 rpccli_pipe_txt(talloc_tos(), cli),
498 pkt->ptype, expected_pkt_type));
499 return NT_STATUS_RPC_PROTOCOL_ERROR;
502 if (pkt->call_id != call_id) {
503 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
504 "RPC call_id - %u, not %u\n",
505 rpccli_pipe_txt(talloc_tos(), cli),
506 pkt->call_id, call_id));
507 return NT_STATUS_RPC_PROTOCOL_ERROR;
510 /* Do this just before return - we don't want to modify any rpc header
511 data before now as we may have needed to do cryptographic actions on
514 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
515 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
516 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
517 "fragment first/last ON.\n"));
518 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
524 /****************************************************************************
525 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
526 ****************************************************************************/
528 struct cli_api_pipe_state {
529 struct tevent_context *ev;
530 struct rpc_cli_transport *transport;
535 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
536 static void cli_api_pipe_write_done(struct tevent_req *subreq);
537 static void cli_api_pipe_read_done(struct tevent_req *subreq);
539 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
540 struct tevent_context *ev,
541 struct rpc_cli_transport *transport,
542 uint8_t *data, size_t data_len,
543 uint32_t max_rdata_len)
545 struct tevent_req *req, *subreq;
546 struct cli_api_pipe_state *state;
549 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
554 state->transport = transport;
556 if (max_rdata_len < RPC_HEADER_LEN) {
558 * For a RPC reply we always need at least RPC_HEADER_LEN
559 * bytes. We check this here because we will receive
560 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
562 status = NT_STATUS_INVALID_PARAMETER;
566 if (transport->trans_send != NULL) {
567 subreq = transport->trans_send(state, ev, data, data_len,
568 max_rdata_len, transport->priv);
569 if (subreq == NULL) {
572 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
577 * If the transport does not provide a "trans" routine, i.e. for
578 * example the ncacn_ip_tcp transport, do the write/read step here.
581 subreq = rpc_write_send(state, ev, transport, data, data_len);
582 if (subreq == NULL) {
585 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
589 tevent_req_nterror(req, status);
590 return tevent_req_post(req, ev);
596 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
598 struct tevent_req *req = tevent_req_callback_data(
599 subreq, struct tevent_req);
600 struct cli_api_pipe_state *state = tevent_req_data(
601 req, struct cli_api_pipe_state);
604 status = state->transport->trans_recv(subreq, state, &state->rdata,
607 if (!NT_STATUS_IS_OK(status)) {
608 tevent_req_nterror(req, status);
611 tevent_req_done(req);
614 static void cli_api_pipe_write_done(struct tevent_req *subreq)
616 struct tevent_req *req = tevent_req_callback_data(
617 subreq, struct tevent_req);
618 struct cli_api_pipe_state *state = tevent_req_data(
619 req, struct cli_api_pipe_state);
622 status = rpc_write_recv(subreq);
624 if (!NT_STATUS_IS_OK(status)) {
625 tevent_req_nterror(req, status);
629 state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
630 if (tevent_req_nomem(state->rdata, req)) {
635 * We don't need to use rpc_read_send here, the upper layer will cope
636 * with a short read, transport->trans_send could also return less
637 * than state->max_rdata_len.
639 subreq = state->transport->read_send(state, state->ev, state->rdata,
641 state->transport->priv);
642 if (tevent_req_nomem(subreq, req)) {
645 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
648 static void cli_api_pipe_read_done(struct tevent_req *subreq)
650 struct tevent_req *req = tevent_req_callback_data(
651 subreq, struct tevent_req);
652 struct cli_api_pipe_state *state = tevent_req_data(
653 req, struct cli_api_pipe_state);
657 status = state->transport->read_recv(subreq, &received);
659 if (!NT_STATUS_IS_OK(status)) {
660 tevent_req_nterror(req, status);
663 state->rdata_len = received;
664 tevent_req_done(req);
667 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
668 uint8_t **prdata, uint32_t *prdata_len)
670 struct cli_api_pipe_state *state = tevent_req_data(
671 req, struct cli_api_pipe_state);
674 if (tevent_req_is_nterror(req, &status)) {
678 *prdata = talloc_move(mem_ctx, &state->rdata);
679 *prdata_len = state->rdata_len;
683 /****************************************************************************
684 Send data on an rpc pipe via trans. The data must be the last
685 pdu fragment of an NDR data stream.
687 Receive response data from an rpc pipe, which may be large...
689 Read the first fragment: unfortunately have to use SMBtrans for the first
690 bit, then SMBreadX for subsequent bits.
692 If first fragment received also wasn't the last fragment, continue
693 getting fragments until we _do_ receive the last fragment.
695 Request/Response PDU's look like the following...
697 |<------------------PDU len----------------------------------------------->|
698 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
700 +------------+-----------------+-------------+---------------+-------------+
701 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
702 +------------+-----------------+-------------+---------------+-------------+
704 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
705 signing & sealing being negotiated.
707 ****************************************************************************/
709 struct rpc_api_pipe_state {
710 struct tevent_context *ev;
711 struct rpc_pipe_client *cli;
712 uint8_t expected_pkt_type;
715 DATA_BLOB incoming_frag;
716 struct ncacn_packet *pkt;
720 size_t reply_pdu_offset;
724 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
725 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
726 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
728 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
729 struct tevent_context *ev,
730 struct rpc_pipe_client *cli,
731 DATA_BLOB *data, /* Outgoing PDU */
732 uint8_t expected_pkt_type,
735 struct tevent_req *req, *subreq;
736 struct rpc_api_pipe_state *state;
737 uint16_t max_recv_frag;
740 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
746 state->expected_pkt_type = expected_pkt_type;
747 state->call_id = call_id;
748 state->endianess = DCERPC_DREP_LE;
751 * Ensure we're not sending too much.
753 if (data->length > cli->max_xmit_frag) {
754 status = NT_STATUS_INVALID_PARAMETER;
758 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
760 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
761 subreq = rpc_write_send(state, ev, cli->transport,
762 data->data, data->length);
763 if (subreq == NULL) {
766 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
770 /* get the header first, then fetch the rest once we have
771 * the frag_length available */
772 max_recv_frag = RPC_HEADER_LEN;
774 subreq = cli_api_pipe_send(state, ev, cli->transport,
775 data->data, data->length, max_recv_frag);
776 if (subreq == NULL) {
779 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
783 tevent_req_nterror(req, status);
784 return tevent_req_post(req, ev);
790 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
792 struct tevent_req *req =
793 tevent_req_callback_data(subreq,
797 status = rpc_write_recv(subreq);
799 if (!NT_STATUS_IS_OK(status)) {
800 tevent_req_nterror(req, status);
804 tevent_req_done(req);
807 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
809 struct tevent_req *req = tevent_req_callback_data(
810 subreq, struct tevent_req);
811 struct rpc_api_pipe_state *state = tevent_req_data(
812 req, struct rpc_api_pipe_state);
814 uint8_t *rdata = NULL;
815 uint32_t rdata_len = 0;
817 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
819 if (!NT_STATUS_IS_OK(status)) {
820 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
821 tevent_req_nterror(req, status);
826 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
827 rpccli_pipe_txt(talloc_tos(), state->cli)));
828 tevent_req_done(req);
833 * Move data on state->incoming_frag.
835 state->incoming_frag.data = talloc_move(state, &rdata);
836 state->incoming_frag.length = rdata_len;
837 if (!state->incoming_frag.data) {
838 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
842 /* Ensure we have enough data for a pdu. */
843 subreq = get_complete_frag_send(state, state->ev, state->cli,
844 &state->incoming_frag);
845 if (tevent_req_nomem(subreq, req)) {
848 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
851 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
853 struct tevent_req *req = tevent_req_callback_data(
854 subreq, struct tevent_req);
855 struct rpc_api_pipe_state *state = tevent_req_data(
856 req, struct rpc_api_pipe_state);
858 DATA_BLOB rdata = data_blob_null;
860 status = get_complete_frag_recv(subreq);
862 if (!NT_STATUS_IS_OK(status)) {
863 DEBUG(5, ("get_complete_frag failed: %s\n",
865 tevent_req_nterror(req, status);
869 state->pkt = talloc(state, struct ncacn_packet);
871 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
875 status = dcerpc_pull_ncacn_packet(state->pkt,
876 &state->incoming_frag,
879 if (!NT_STATUS_IS_OK(status)) {
880 tevent_req_nterror(req, status);
884 if (state->incoming_frag.length != state->pkt->frag_length) {
885 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
886 (unsigned int)state->incoming_frag.length,
887 (unsigned int)state->pkt->frag_length));
888 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
892 status = cli_pipe_validate_current_pdu(state,
893 state->cli, state->pkt,
894 &state->incoming_frag,
895 state->expected_pkt_type,
900 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
901 (unsigned)state->incoming_frag.length,
902 (unsigned)state->reply_pdu_offset,
905 if (!NT_STATUS_IS_OK(status)) {
906 tevent_req_nterror(req, status);
910 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
911 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
913 * Set the data type correctly for big-endian data on the
916 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
918 rpccli_pipe_txt(talloc_tos(), state->cli)));
919 state->endianess = 0x00; /* BIG ENDIAN */
922 * Check endianness on subsequent packets.
924 if (state->endianess != state->pkt->drep[0]) {
925 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
927 state->endianess?"little":"big",
928 state->pkt->drep[0]?"little":"big"));
929 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
933 /* Now copy the data portion out of the pdu into rbuf. */
934 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
935 if (!data_blob_realloc(NULL, &state->reply_pdu,
936 state->reply_pdu_offset + rdata.length)) {
937 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
942 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
943 rdata.data, rdata.length);
944 state->reply_pdu_offset += rdata.length;
946 /* reset state->incoming_frag, there is no need to free it,
947 * it will be reallocated to the right size the next time
949 state->incoming_frag.length = 0;
951 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
952 /* make sure the pdu length is right now that we
953 * have all the data available (alloc hint may
954 * have allocated more than was actually used) */
955 state->reply_pdu.length = state->reply_pdu_offset;
956 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
957 rpccli_pipe_txt(talloc_tos(), state->cli),
958 (unsigned)state->reply_pdu.length));
959 tevent_req_done(req);
963 subreq = get_complete_frag_send(state, state->ev, state->cli,
964 &state->incoming_frag);
965 if (tevent_req_nomem(subreq, req)) {
968 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
971 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
972 struct ncacn_packet **pkt,
973 DATA_BLOB *reply_pdu)
975 struct rpc_api_pipe_state *state = tevent_req_data(
976 req, struct rpc_api_pipe_state);
979 if (tevent_req_is_nterror(req, &status)) {
983 /* return data to caller and assign it ownership of memory */
985 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
986 reply_pdu->length = state->reply_pdu.length;
987 state->reply_pdu.length = 0;
989 data_blob_free(&state->reply_pdu);
993 *pkt = talloc_steal(mem_ctx, state->pkt);
999 /*******************************************************************
1000 Creates NTLMSSP auth bind.
1001 ********************************************************************/
1003 static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1004 TALLOC_CTX *mem_ctx,
1005 DATA_BLOB *auth_token,
1006 bool *client_hdr_signing)
1008 struct gensec_security *gensec_security;
1009 DATA_BLOB null_blob = data_blob_null;
1012 gensec_security = talloc_get_type_abort(cli->auth->auth_ctx,
1013 struct gensec_security);
1015 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1016 status = gensec_update(gensec_security, mem_ctx, NULL, null_blob, auth_token);
1018 if (!NT_STATUS_IS_OK(status) &&
1019 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1024 if (client_hdr_signing == NULL) {
1028 if (cli->auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1029 *client_hdr_signing = false;
1033 *client_hdr_signing = gensec_have_feature(gensec_security,
1034 GENSEC_FEATURE_SIGN_PKT_HEADER);
1039 /*******************************************************************
1040 Creates the internals of a DCE/RPC bind request or alter context PDU.
1041 ********************************************************************/
1043 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1044 enum dcerpc_pkt_type ptype,
1046 const struct ndr_syntax_id *abstract,
1047 const struct ndr_syntax_id *transfer,
1048 const DATA_BLOB *auth_info,
1049 bool client_hdr_signing,
1052 uint16 auth_len = auth_info->length;
1054 union dcerpc_payload u;
1055 struct dcerpc_ctx_list ctx_list;
1056 uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1059 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1062 if (client_hdr_signing) {
1063 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
1066 ctx_list.context_id = 0;
1067 ctx_list.num_transfer_syntaxes = 1;
1068 ctx_list.abstract_syntax = *abstract;
1069 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1071 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1072 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1073 u.bind.assoc_group_id = 0x0;
1074 u.bind.num_contexts = 1;
1075 u.bind.ctx_list = &ctx_list;
1076 u.bind.auth_info = *auth_info;
1078 status = dcerpc_push_ncacn_packet(mem_ctx,
1084 if (!NT_STATUS_IS_OK(status)) {
1085 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1089 return NT_STATUS_OK;
1092 /*******************************************************************
1093 Creates a DCE/RPC bind request.
1094 ********************************************************************/
1096 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1097 struct rpc_pipe_client *cli,
1098 struct pipe_auth_data *auth,
1100 const struct ndr_syntax_id *abstract,
1101 const struct ndr_syntax_id *transfer,
1104 DATA_BLOB auth_token = data_blob_null;
1105 DATA_BLOB auth_info = data_blob_null;
1106 NTSTATUS ret = NT_STATUS_OK;
1108 switch (auth->auth_type) {
1109 case DCERPC_AUTH_TYPE_SCHANNEL:
1110 case DCERPC_AUTH_TYPE_NTLMSSP:
1111 case DCERPC_AUTH_TYPE_KRB5:
1112 case DCERPC_AUTH_TYPE_SPNEGO:
1113 ret = create_generic_auth_rpc_bind_req(cli, mem_ctx,
1115 &auth->client_hdr_signing);
1117 if (!NT_STATUS_IS_OK(ret) &&
1118 !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1123 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1124 auth_token = data_blob_talloc(mem_ctx,
1125 "NCALRPC_AUTH_TOKEN",
1129 case DCERPC_AUTH_TYPE_NONE:
1133 /* "Can't" happen. */
1134 return NT_STATUS_INVALID_INFO_CLASS;
1137 if (auth_token.length != 0) {
1138 ret = dcerpc_push_dcerpc_auth(cli,
1141 0, /* auth_pad_length */
1142 1, /* auth_context_id */
1145 if (!NT_STATUS_IS_OK(ret)) {
1148 data_blob_free(&auth_token);
1151 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1157 auth->client_hdr_signing,
1162 /*******************************************************************
1164 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1165 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1166 and deals with signing/sealing details.
1167 ********************************************************************/
1169 struct rpc_api_pipe_req_state {
1170 struct tevent_context *ev;
1171 struct rpc_pipe_client *cli;
1174 const DATA_BLOB *req_data;
1175 uint32_t req_data_sent;
1176 DATA_BLOB req_trailer;
1177 uint32_t req_trailer_sent;
1178 bool verify_bitmask1;
1179 bool verify_pcontext;
1181 DATA_BLOB reply_pdu;
1184 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1185 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1186 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
1187 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1188 bool *is_last_frag);
1190 static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1191 struct tevent_context *ev,
1192 struct rpc_pipe_client *cli,
1194 const DATA_BLOB *req_data)
1196 struct tevent_req *req, *subreq;
1197 struct rpc_api_pipe_req_state *state;
1201 req = tevent_req_create(mem_ctx, &state,
1202 struct rpc_api_pipe_req_state);
1208 state->op_num = op_num;
1209 state->req_data = req_data;
1210 state->req_data_sent = 0;
1211 state->call_id = get_rpc_call_id();
1212 state->reply_pdu = data_blob_null;
1213 state->rpc_out = data_blob_null;
1215 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1216 + RPC_MAX_SIGN_SIZE) {
1217 /* Server is screwed up ! */
1218 status = NT_STATUS_INVALID_PARAMETER;
1222 status = prepare_verification_trailer(state);
1223 if (!NT_STATUS_IS_OK(status)) {
1227 status = prepare_next_frag(state, &is_last_frag);
1228 if (!NT_STATUS_IS_OK(status)) {
1233 subreq = rpc_api_pipe_send(state, ev, state->cli,
1235 DCERPC_PKT_RESPONSE,
1237 if (subreq == NULL) {
1240 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1242 subreq = rpc_write_send(state, ev, cli->transport,
1243 state->rpc_out.data,
1244 state->rpc_out.length);
1245 if (subreq == NULL) {
1248 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1254 tevent_req_nterror(req, status);
1255 return tevent_req_post(req, ev);
1261 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
1263 struct pipe_auth_data *a = state->cli->auth;
1264 struct dcerpc_sec_verification_trailer *t;
1265 struct dcerpc_sec_vt *c = NULL;
1266 struct ndr_push *ndr = NULL;
1267 enum ndr_err_code ndr_err;
1272 return NT_STATUS_OK;
1275 if (a->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1276 return NT_STATUS_OK;
1279 t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
1281 return NT_STATUS_NO_MEMORY;
1284 if (!a->verified_bitmask1) {
1285 t->commands = talloc_realloc(t, t->commands,
1286 struct dcerpc_sec_vt,
1287 t->count.count + 1);
1288 if (t->commands == NULL) {
1289 return NT_STATUS_NO_MEMORY;
1291 c = &t->commands[t->count.count++];
1294 c->command = DCERPC_SEC_VT_COMMAND_BITMASK1;
1295 if (a->client_hdr_signing) {
1296 c->u.bitmask1 = DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING;
1298 state->verify_bitmask1 = true;
1301 if (!state->cli->verified_pcontext) {
1302 t->commands = talloc_realloc(t, t->commands,
1303 struct dcerpc_sec_vt,
1304 t->count.count + 1);
1305 if (t->commands == NULL) {
1306 return NT_STATUS_NO_MEMORY;
1308 c = &t->commands[t->count.count++];
1311 c->command = DCERPC_SEC_VT_COMMAND_PCONTEXT;
1312 c->u.pcontext.abstract_syntax = state->cli->abstract_syntax;
1313 c->u.pcontext.transfer_syntax = state->cli->transfer_syntax;
1315 state->verify_pcontext = true;
1318 if (1|| !a->hdr_signing) {
1319 t->commands = talloc_realloc(t, t->commands,
1320 struct dcerpc_sec_vt,
1321 t->count.count + 1);
1322 if (t->commands == NULL) {
1323 return NT_STATUS_NO_MEMORY;
1325 c = &t->commands[t->count.count++];
1328 c->command = DCERPC_SEC_VT_COMMAND_HEADER2;
1329 c->u.header2.ptype = DCERPC_PKT_REQUEST;
1330 c->u.header2.drep[0] = DCERPC_DREP_LE;
1331 c->u.header2.drep[1] = 0;
1332 c->u.header2.drep[2] = 0;
1333 c->u.header2.drep[3] = 0;
1335 static bool kaputtmachen = false;
1337 c->u.header2.drep[3] = 42;
1339 kaputtmachen = !kaputtmachen;
1341 c->u.header2.call_id = state->call_id;
1342 c->u.header2.context_id = 0;
1343 c->u.header2.opnum = state->op_num;
1346 if (t->count.count == 0) {
1348 return NT_STATUS_OK;
1351 c = &t->commands[t->count.count - 1];
1352 c->command |= DCERPC_SEC_VT_COMMAND_END;
1354 if (DEBUGLEVEL >= 10) {
1355 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
1358 ndr = ndr_push_init_ctx(state);
1360 return NT_STATUS_NO_MEMORY;
1363 ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
1364 NDR_SCALARS | NDR_BUFFERS,
1366 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1367 return ndr_map_error2ntstatus(ndr_err);
1369 state->req_trailer = ndr_push_blob(ndr);
1371 align = state->req_data->length & 0x3;
1378 const uint8_t zeros[4] = { 0, };
1380 ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
1382 return NT_STATUS_NO_MEMORY;
1385 /* move the padding to the start */
1386 p = state->req_trailer.data;
1387 memmove(p + pad, p, state->req_trailer.length - pad);
1391 return NT_STATUS_OK;
1394 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1402 size_t data_thistime;
1403 size_t trailer_left;
1404 size_t trailer_thistime = 0;
1406 size_t total_thistime;
1409 union dcerpc_payload u;
1411 data_left = state->req_data->length - state->req_data_sent;
1412 trailer_left = state->req_trailer.length - state->req_trailer_sent;
1413 total_left = data_left + trailer_left;
1414 if ((total_left < data_left) || (total_left < trailer_left)) {
1418 return NT_STATUS_INVALID_PARAMETER_MIX;
1421 status = dcerpc_guess_sizes(state->cli->auth,
1422 DCERPC_REQUEST_LENGTH, total_left,
1423 state->cli->max_xmit_frag,
1424 CLIENT_NDR_PADDING_SIZE,
1426 &frag_len, &auth_len, &pad_len);
1427 if (!NT_STATUS_IS_OK(status)) {
1431 if (state->req_data_sent == 0) {
1432 flags = DCERPC_PFC_FLAG_FIRST;
1435 if (total_thistime == total_left) {
1436 flags |= DCERPC_PFC_FLAG_LAST;
1439 data_thistime = MIN(total_thistime, data_left);
1440 if (data_thistime < total_thistime) {
1441 trailer_thistime = total_thistime - data_thistime;
1444 data_blob_free(&state->rpc_out);
1446 ZERO_STRUCT(u.request);
1448 u.request.alloc_hint = total_left;
1449 u.request.context_id = 0;
1450 u.request.opnum = state->op_num;
1452 if (!(flags & DCERPC_PFC_FLAG_FIRST)) {
1453 u.request.opnum= 0xdead;
1456 status = dcerpc_push_ncacn_packet(state,
1463 if (!NT_STATUS_IS_OK(status)) {
1467 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1468 * compute it right for requests because the auth trailer is missing
1470 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1472 if (data_thistime > 0) {
1473 /* Copy in the data. */
1474 ok = data_blob_append(NULL, &state->rpc_out,
1475 state->req_data->data + state->req_data_sent,
1478 return NT_STATUS_NO_MEMORY;
1480 state->req_data_sent += data_thistime;
1483 if (trailer_thistime > 0) {
1484 /* Copy in the verification trailer. */
1485 ok = data_blob_append(NULL, &state->rpc_out,
1486 state->req_trailer.data + state->req_trailer_sent,
1489 return NT_STATUS_NO_MEMORY;
1491 state->req_trailer_sent += trailer_thistime;
1494 switch (state->cli->auth->auth_level) {
1495 case DCERPC_AUTH_LEVEL_NONE:
1496 case DCERPC_AUTH_LEVEL_CONNECT:
1497 case DCERPC_AUTH_LEVEL_PACKET:
1499 case DCERPC_AUTH_LEVEL_INTEGRITY:
1500 case DCERPC_AUTH_LEVEL_PRIVACY:
1501 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1503 if (!NT_STATUS_IS_OK(status)) {
1508 return NT_STATUS_INVALID_PARAMETER;
1511 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1516 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1518 struct tevent_req *req = tevent_req_callback_data(
1519 subreq, struct tevent_req);
1520 struct rpc_api_pipe_req_state *state = tevent_req_data(
1521 req, struct rpc_api_pipe_req_state);
1525 status = rpc_write_recv(subreq);
1526 TALLOC_FREE(subreq);
1527 if (!NT_STATUS_IS_OK(status)) {
1528 tevent_req_nterror(req, status);
1532 status = prepare_next_frag(state, &is_last_frag);
1533 if (!NT_STATUS_IS_OK(status)) {
1534 tevent_req_nterror(req, status);
1539 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1541 DCERPC_PKT_RESPONSE,
1543 if (tevent_req_nomem(subreq, req)) {
1546 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1548 subreq = rpc_write_send(state, state->ev,
1549 state->cli->transport,
1550 state->rpc_out.data,
1551 state->rpc_out.length);
1552 if (tevent_req_nomem(subreq, req)) {
1555 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1560 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1562 struct tevent_req *req = tevent_req_callback_data(
1563 subreq, struct tevent_req);
1564 struct rpc_api_pipe_req_state *state = tevent_req_data(
1565 req, struct rpc_api_pipe_req_state);
1568 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1569 TALLOC_FREE(subreq);
1570 if (!NT_STATUS_IS_OK(status)) {
1571 tevent_req_nterror(req, status);
1575 if (state->cli->auth == NULL) {
1576 tevent_req_done(req);
1580 if (state->verify_bitmask1) {
1581 state->cli->auth->verified_bitmask1 = true;
1584 if (state->verify_pcontext) {
1585 state->cli->verified_pcontext = true;
1588 tevent_req_done(req);
1591 static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1592 DATA_BLOB *reply_pdu)
1594 struct rpc_api_pipe_req_state *state = tevent_req_data(
1595 req, struct rpc_api_pipe_req_state);
1598 if (tevent_req_is_nterror(req, &status)) {
1600 * We always have to initialize to reply pdu, even if there is
1601 * none. The rpccli_* caller routines expect this.
1603 *reply_pdu = data_blob_null;
1607 /* return data to caller and assign it ownership of memory */
1608 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1609 reply_pdu->length = state->reply_pdu.length;
1610 state->reply_pdu.length = 0;
1612 return NT_STATUS_OK;
1615 /****************************************************************************
1616 Check the rpc bind acknowledge response.
1617 ****************************************************************************/
1619 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1620 const struct ndr_syntax_id *transfer)
1622 struct dcerpc_ack_ctx ctx;
1624 if (r->secondary_address_size == 0) {
1625 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1628 if (r->num_results < 1 || !r->ctx_list) {
1632 ctx = r->ctx_list[0];
1634 /* check the transfer syntax */
1635 if ((ctx.syntax.if_version != transfer->if_version) ||
1636 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1637 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1641 if (r->num_results != 0x1 || ctx.result != 0) {
1642 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1643 r->num_results, ctx.reason.value));
1646 DEBUG(5,("check_bind_response: accepted!\n"));
1650 /*******************************************************************
1651 Creates a DCE/RPC bind authentication response.
1652 This is the packet that is sent back to the server once we
1653 have received a BIND-ACK, to finish the third leg of
1654 the authentication handshake.
1655 ********************************************************************/
1657 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1658 struct rpc_pipe_client *cli,
1660 enum dcerpc_AuthType auth_type,
1661 enum dcerpc_AuthLevel auth_level,
1662 DATA_BLOB *pauth_blob,
1666 union dcerpc_payload u;
1670 status = dcerpc_push_dcerpc_auth(mem_ctx,
1673 0, /* auth_pad_length */
1674 1, /* auth_context_id */
1676 &u.auth3.auth_info);
1677 if (!NT_STATUS_IS_OK(status)) {
1681 status = dcerpc_push_ncacn_packet(mem_ctx,
1683 DCERPC_PFC_FLAG_FIRST |
1684 DCERPC_PFC_FLAG_LAST,
1689 data_blob_free(&u.auth3.auth_info);
1690 if (!NT_STATUS_IS_OK(status)) {
1691 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1695 return NT_STATUS_OK;
1698 /*******************************************************************
1699 Creates a DCE/RPC bind alter context authentication request which
1700 may contain a spnego auth blobl
1701 ********************************************************************/
1703 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1704 enum dcerpc_AuthType auth_type,
1705 enum dcerpc_AuthLevel auth_level,
1707 const struct ndr_syntax_id *abstract,
1708 const struct ndr_syntax_id *transfer,
1709 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1712 DATA_BLOB auth_info;
1715 status = dcerpc_push_dcerpc_auth(mem_ctx,
1718 0, /* auth_pad_length */
1719 1, /* auth_context_id */
1722 if (!NT_STATUS_IS_OK(status)) {
1726 status = create_bind_or_alt_ctx_internal(mem_ctx,
1732 false, /* client_hdr_signing */
1734 data_blob_free(&auth_info);
1738 /****************************************************************************
1740 ****************************************************************************/
1742 struct rpc_pipe_bind_state {
1743 struct tevent_context *ev;
1744 struct rpc_pipe_client *cli;
1747 uint32_t rpc_call_id;
1750 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1751 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1752 struct rpc_pipe_bind_state *state,
1753 DATA_BLOB *credentials);
1754 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1755 struct rpc_pipe_bind_state *state,
1756 DATA_BLOB *credentials);
1758 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1759 struct tevent_context *ev,
1760 struct rpc_pipe_client *cli,
1761 struct pipe_auth_data *auth)
1763 struct tevent_req *req, *subreq;
1764 struct rpc_pipe_bind_state *state;
1767 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1772 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1773 rpccli_pipe_txt(talloc_tos(), cli),
1774 (unsigned int)auth->auth_type,
1775 (unsigned int)auth->auth_level ));
1779 state->rpc_call_id = get_rpc_call_id();
1781 cli->auth = talloc_move(cli, &auth);
1783 /* Marshall the outgoing data. */
1784 status = create_rpc_bind_req(state, cli,
1787 &cli->abstract_syntax,
1788 &cli->transfer_syntax,
1791 if (!NT_STATUS_IS_OK(status) &&
1792 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1796 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1797 DCERPC_PKT_BIND_ACK, state->rpc_call_id);
1798 if (subreq == NULL) {
1801 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1805 tevent_req_nterror(req, status);
1806 return tevent_req_post(req, ev);
1812 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1814 struct tevent_req *req = tevent_req_callback_data(
1815 subreq, struct tevent_req);
1816 struct rpc_pipe_bind_state *state = tevent_req_data(
1817 req, struct rpc_pipe_bind_state);
1818 struct pipe_auth_data *pauth = state->cli->auth;
1819 struct gensec_security *gensec_security;
1820 struct ncacn_packet *pkt = NULL;
1821 struct dcerpc_auth auth;
1822 DATA_BLOB auth_token = data_blob_null;
1825 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1826 TALLOC_FREE(subreq);
1827 if (!NT_STATUS_IS_OK(status)) {
1828 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1829 rpccli_pipe_txt(talloc_tos(), state->cli),
1830 nt_errstr(status)));
1831 tevent_req_nterror(req, status);
1836 tevent_req_done(req);
1840 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1841 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1842 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1846 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1847 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1849 switch(pauth->auth_type) {
1851 case DCERPC_AUTH_TYPE_NONE:
1852 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1853 /* Bind complete. */
1854 tevent_req_done(req);
1857 case DCERPC_AUTH_TYPE_SCHANNEL:
1858 case DCERPC_AUTH_TYPE_NTLMSSP:
1859 case DCERPC_AUTH_TYPE_SPNEGO:
1860 case DCERPC_AUTH_TYPE_KRB5:
1861 /* Paranoid lenght checks */
1862 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1863 + pkt->auth_length) {
1864 tevent_req_nterror(req,
1865 NT_STATUS_INFO_LENGTH_MISMATCH);
1868 /* get auth credentials */
1869 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1870 &pkt->u.bind_ack.auth_info,
1872 if (!NT_STATUS_IS_OK(status)) {
1873 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1874 nt_errstr(status)));
1875 tevent_req_nterror(req, status);
1885 * For authenticated binds we may need to do 3 or 4 leg binds.
1888 switch(pauth->auth_type) {
1890 case DCERPC_AUTH_TYPE_NONE:
1891 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1892 /* Bind complete. */
1893 tevent_req_done(req);
1896 case DCERPC_AUTH_TYPE_SCHANNEL:
1897 case DCERPC_AUTH_TYPE_NTLMSSP:
1898 case DCERPC_AUTH_TYPE_KRB5:
1899 case DCERPC_AUTH_TYPE_SPNEGO:
1900 gensec_security = talloc_get_type_abort(pauth->auth_ctx,
1901 struct gensec_security);
1903 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
1904 if (pauth->client_hdr_signing) {
1905 pauth->hdr_signing = true;
1906 gensec_want_feature(gensec_security,
1907 GENSEC_FEATURE_SIGN_PKT_HEADER);
1911 status = gensec_update(gensec_security, state, NULL,
1912 auth.credentials, &auth_token);
1913 if (NT_STATUS_EQUAL(status,
1914 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1915 status = rpc_bind_next_send(req, state,
1917 } else if (NT_STATUS_IS_OK(status)) {
1918 if (auth_token.length == 0) {
1919 /* Bind complete. */
1920 tevent_req_done(req);
1923 status = rpc_bind_finish_send(req, state,
1932 if (!NT_STATUS_IS_OK(status)) {
1933 tevent_req_nterror(req, status);
1938 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1939 (unsigned int)state->cli->auth->auth_type));
1940 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1943 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1944 struct rpc_pipe_bind_state *state,
1945 DATA_BLOB *auth_token)
1947 struct pipe_auth_data *auth = state->cli->auth;
1948 struct tevent_req *subreq;
1951 /* Now prepare the alter context pdu. */
1952 data_blob_free(&state->rpc_out);
1954 status = create_rpc_alter_context(state,
1958 &state->cli->abstract_syntax,
1959 &state->cli->transfer_syntax,
1962 if (!NT_STATUS_IS_OK(status)) {
1966 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1967 &state->rpc_out, DCERPC_PKT_ALTER_RESP,
1968 state->rpc_call_id);
1969 if (subreq == NULL) {
1970 return NT_STATUS_NO_MEMORY;
1972 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1973 return NT_STATUS_OK;
1976 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1977 struct rpc_pipe_bind_state *state,
1978 DATA_BLOB *auth_token)
1980 struct pipe_auth_data *auth = state->cli->auth;
1981 struct tevent_req *subreq;
1984 state->auth3 = true;
1986 /* Now prepare the auth3 context pdu. */
1987 data_blob_free(&state->rpc_out);
1989 status = create_rpc_bind_auth3(state, state->cli,
1995 if (!NT_STATUS_IS_OK(status)) {
1999 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2000 &state->rpc_out, DCERPC_PKT_AUTH3,
2001 state->rpc_call_id);
2002 if (subreq == NULL) {
2003 return NT_STATUS_NO_MEMORY;
2005 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2006 return NT_STATUS_OK;
2009 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2011 return tevent_req_simple_recv_ntstatus(req);
2014 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2015 struct pipe_auth_data *auth)
2017 TALLOC_CTX *frame = talloc_stackframe();
2018 struct tevent_context *ev;
2019 NTSTATUS status = NT_STATUS_OK;
2020 struct dcerpc_call *call;
2021 struct tevent_req *subreq;
2022 struct dcerpc_presentation *pres[1];
2024 ev = samba_tevent_context_init(frame);
2026 status = NT_STATUS_NO_MEMORY;
2030 cli->sec = dcerpc_security_allocate(cli, cli->conn,
2035 call = dcerpc_call_allocate(frame, cli->assoc, NULL, NULL);
2037 pres[0] = cli->pres;
2039 subreq = dcerpc_do_bind_send(frame, ev, cli->conn, call,
2040 cli->sec, ARRAY_SIZE(pres), pres);
2042 if (subreq == NULL) {
2043 status = NT_STATUS_NO_MEMORY;
2047 if (!tevent_req_poll(subreq, ev)) {
2048 status = map_nt_error_from_unix(errno);
2052 status = dcerpc_do_bind_recv(subreq);
2058 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2060 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2061 unsigned int timeout)
2065 if (rpc_cli->transport == NULL) {
2066 return RPCCLI_DEFAULT_TIMEOUT;
2069 if (rpc_cli->transport->set_timeout == NULL) {
2070 return RPCCLI_DEFAULT_TIMEOUT;
2073 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2075 return RPCCLI_DEFAULT_TIMEOUT;
2081 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2083 if (rpc_cli == NULL) {
2087 if (rpc_cli->transport == NULL) {
2091 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2094 struct rpccli_bh_state {
2095 struct rpc_pipe_client *rpc_cli;
2098 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2100 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2101 struct rpccli_bh_state);
2103 return rpccli_is_connected(hs->rpc_cli);
2106 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2109 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2110 struct rpccli_bh_state);
2112 return rpccli_set_timeout(hs->rpc_cli, timeout);
2115 static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
2116 enum dcerpc_AuthType *auth_type,
2117 enum dcerpc_AuthLevel *auth_level)
2119 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2120 struct rpccli_bh_state);
2122 if (hs->rpc_cli == NULL) {
2126 if (hs->rpc_cli->auth == NULL) {
2130 *auth_type = hs->rpc_cli->auth->auth_type;
2131 *auth_level = hs->rpc_cli->auth->auth_level;
2134 struct rpccli_bh_raw_call_state {
2135 struct dcerpc_call *call;
2141 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2143 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2144 struct tevent_context *ev,
2145 struct dcerpc_binding_handle *h,
2146 const struct GUID *object,
2149 const uint8_t *in_data,
2152 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2153 struct rpccli_bh_state);
2154 struct tevent_req *req;
2155 struct rpccli_bh_raw_call_state *state;
2157 struct tevent_req *subreq;
2158 bool bigendian = false;
2160 req = tevent_req_create(mem_ctx, &state,
2161 struct rpccli_bh_raw_call_state);
2165 state->in_data.data = discard_const_p(uint8_t, in_data);
2166 state->in_data.length = in_length;
2168 ok = rpccli_bh_is_connected(h);
2170 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2171 return tevent_req_post(req, ev);
2174 state->call = dcerpc_call_allocate(state,
2179 if (in_flags & LIBNDR_FLAG_BIGENDIAN) {
2183 subreq = dcerpc_do_request_send(state, ev, hs->rpc_cli->conn,
2184 state->call, NULL, opnum,
2185 &state->in_data, bigendian);
2186 // subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2187 // opnum, &state->in_data);
2188 if (tevent_req_nomem(subreq, req)) {
2189 return tevent_req_post(req, ev);
2191 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2196 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2198 struct tevent_req *req =
2199 tevent_req_callback_data(subreq,
2201 struct rpccli_bh_raw_call_state *state =
2202 tevent_req_data(req,
2203 struct rpccli_bh_raw_call_state);
2205 bool bigendian = false;
2207 state->out_flags = 0;
2209 /* TODO: support bigendian responses */
2211 status = dcerpc_do_request_recv(subreq, state, &state->out_data,
2213 //status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2214 TALLOC_FREE(subreq);
2215 if (!NT_STATUS_IS_OK(status)) {
2216 tevent_req_nterror(req, status);
2221 state->out_flags |= LIBNDR_FLAG_BIGENDIAN;
2224 tevent_req_done(req);
2227 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2228 TALLOC_CTX *mem_ctx,
2231 uint32_t *out_flags)
2233 struct rpccli_bh_raw_call_state *state =
2234 tevent_req_data(req,
2235 struct rpccli_bh_raw_call_state);
2238 if (tevent_req_is_nterror(req, &status)) {
2239 tevent_req_received(req);
2243 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2244 *out_length = state->out_data.length;
2245 *out_flags = state->out_flags;
2246 tevent_req_received(req);
2247 return NT_STATUS_OK;
2250 struct rpccli_bh_disconnect_state {
2254 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2255 struct tevent_context *ev,
2256 struct dcerpc_binding_handle *h)
2258 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2259 struct rpccli_bh_state);
2260 struct tevent_req *req;
2261 struct rpccli_bh_disconnect_state *state;
2264 req = tevent_req_create(mem_ctx, &state,
2265 struct rpccli_bh_disconnect_state);
2270 ok = rpccli_bh_is_connected(h);
2272 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2273 return tevent_req_post(req, ev);
2277 * TODO: do a real async disconnect ...
2279 * For now the caller needs to free rpc_cli
2283 tevent_req_done(req);
2284 return tevent_req_post(req, ev);
2287 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2291 if (tevent_req_is_nterror(req, &status)) {
2292 tevent_req_received(req);
2296 tevent_req_received(req);
2297 return NT_STATUS_OK;
2300 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2305 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2307 const void *_struct_ptr,
2308 const struct ndr_interface_call *call)
2310 void *struct_ptr = discard_const(_struct_ptr);
2312 if (DEBUGLEVEL < 10) {
2316 if (ndr_flags & NDR_IN) {
2317 ndr_print_function_debug(call->ndr_print,
2322 if (ndr_flags & NDR_OUT) {
2323 ndr_print_function_debug(call->ndr_print,
2330 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2332 .is_connected = rpccli_bh_is_connected,
2333 .set_timeout = rpccli_bh_set_timeout,
2334 .auth_info = rpccli_bh_auth_info,
2335 .raw_call_send = rpccli_bh_raw_call_send,
2336 .raw_call_recv = rpccli_bh_raw_call_recv,
2337 .disconnect_send = rpccli_bh_disconnect_send,
2338 .disconnect_recv = rpccli_bh_disconnect_recv,
2340 .ref_alloc = rpccli_bh_ref_alloc,
2341 .do_ndr_print = rpccli_bh_do_ndr_print,
2344 /* initialise a rpc_pipe_client binding handle */
2345 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
2346 const struct GUID *object,
2347 const struct ndr_interface_table *table)
2349 struct dcerpc_binding_handle *h;
2350 struct rpccli_bh_state *hs;
2352 h = dcerpc_binding_handle_create(c,
2357 struct rpccli_bh_state,
2367 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2368 struct pipe_auth_data **presult)
2370 struct pipe_auth_data *result;
2372 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2373 if (result == NULL) {
2374 return NT_STATUS_NO_MEMORY;
2377 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2378 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2380 result->user_name = talloc_strdup(result, "");
2381 result->domain = talloc_strdup(result, "");
2382 if ((result->user_name == NULL) || (result->domain == NULL)) {
2383 TALLOC_FREE(result);
2384 return NT_STATUS_NO_MEMORY;
2388 return NT_STATUS_OK;
2391 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2392 struct pipe_auth_data **presult)
2394 struct pipe_auth_data *result;
2396 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2397 if (result == NULL) {
2398 return NT_STATUS_NO_MEMORY;
2401 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2402 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2404 result->user_name = talloc_strdup(result, "");
2405 result->domain = talloc_strdup(result, "");
2406 if ((result->user_name == NULL) || (result->domain == NULL)) {
2407 TALLOC_FREE(result);
2408 return NT_STATUS_NO_MEMORY;
2412 return NT_STATUS_OK;
2415 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2416 enum dcerpc_AuthType auth_type,
2417 enum dcerpc_AuthLevel auth_level,
2419 const char *target_service,
2421 const char *username,
2422 const char *password,
2423 enum credentials_use_kerberos use_kerberos,
2424 struct netlogon_creds_CredentialState *creds,
2425 struct pipe_auth_data **presult)
2427 struct auth_generic_state *auth_generic_ctx;
2428 struct pipe_auth_data *result;
2431 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2432 if (result == NULL) {
2433 return NT_STATUS_NO_MEMORY;
2436 result->auth_type = auth_type;
2437 result->auth_level = auth_level;
2439 result->user_name = talloc_strdup(result, username);
2440 result->domain = talloc_strdup(result, domain);
2441 if ((result->user_name == NULL) || (result->domain == NULL)) {
2442 status = NT_STATUS_NO_MEMORY;
2446 status = auth_generic_client_prepare(result,
2448 if (!NT_STATUS_IS_OK(status)) {
2452 status = auth_generic_set_username(auth_generic_ctx, username);
2453 if (!NT_STATUS_IS_OK(status)) {
2457 status = auth_generic_set_domain(auth_generic_ctx, domain);
2458 if (!NT_STATUS_IS_OK(status)) {
2462 status = auth_generic_set_password(auth_generic_ctx, password);
2463 if (!NT_STATUS_IS_OK(status)) {
2467 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2468 if (!NT_STATUS_IS_OK(status)) {
2472 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2473 if (!NT_STATUS_IS_OK(status)) {
2477 cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
2478 cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2480 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2481 if (!NT_STATUS_IS_OK(status)) {
2485 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2486 talloc_free(auth_generic_ctx);
2488 return NT_STATUS_OK;
2491 TALLOC_FREE(result);
2496 * Create an rpc pipe client struct, connecting to a tcp port.
2498 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2499 const struct sockaddr_storage *ss_addr,
2501 const struct ndr_interface_table *table,
2502 struct rpc_pipe_client **presult)
2504 struct rpc_pipe_client *result;
2505 struct sockaddr_storage addr;
2509 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2510 if (result == NULL) {
2511 return NT_STATUS_NO_MEMORY;
2514 result->abstract_syntax = table->syntax_id;
2515 result->transfer_syntax = ndr_transfer_syntax_ndr;
2517 result->desthost = talloc_strdup(result, host);
2518 result->srv_name_slash = talloc_asprintf_strupper_m(
2519 result, "\\\\%s", result->desthost);
2520 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2521 status = NT_STATUS_NO_MEMORY;
2525 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2526 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2528 if (ss_addr == NULL) {
2529 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2530 status = NT_STATUS_NOT_FOUND;
2537 status = open_socket_out(&addr, port, 60*1000, &fd);
2538 if (!NT_STATUS_IS_OK(status)) {
2541 set_socket_options(fd, lp_socket_options());
2543 status = rpc_transport_sock_init(result, fd, &result->transport);
2544 if (!NT_STATUS_IS_OK(status)) {
2549 result->transport->transport = NCACN_IP_TCP;
2551 result->assoc = dcerpc_association_create(result, 0);
2552 result->conn = dcerpc_connection_create(result, result->assoc,
2553 &result->transport->stream);
2554 result->pres = dcerpc_presentation_allocate(result, result->conn, table,
2555 &ndr_transfer_syntax_ndr);
2556 result->sec = dcerpc_security_allocate(result, result->conn,
2557 DCERPC_AUTH_TYPE_NONE,
2558 DCERPC_AUTH_LEVEL_NONE,
2561 result->binding_handle = rpccli_bh_create(result, NULL, table);
2562 if (result->binding_handle == NULL) {
2563 TALLOC_FREE(result);
2564 return NT_STATUS_NO_MEMORY;
2568 return NT_STATUS_OK;
2571 TALLOC_FREE(result);
2576 * Determine the tcp port on which a dcerpc interface is listening
2577 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2580 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2581 const struct sockaddr_storage *addr,
2582 const struct ndr_interface_table *table,
2586 struct rpc_pipe_client *epm_pipe = NULL;
2587 struct dcerpc_binding_handle *epm_handle = NULL;
2588 struct pipe_auth_data *auth = NULL;
2589 struct dcerpc_binding *map_binding = NULL;
2590 struct dcerpc_binding *res_binding = NULL;
2591 struct epm_twr_t *map_tower = NULL;
2592 struct epm_twr_t *res_towers = NULL;
2593 struct policy_handle *entry_handle = NULL;
2594 uint32_t num_towers = 0;
2595 uint32_t max_towers = 1;
2596 struct epm_twr_p_t towers;
2597 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2598 uint32_t result = 0;
2600 if (pport == NULL) {
2601 status = NT_STATUS_INVALID_PARAMETER;
2605 if (ndr_syntax_id_equal(&table->syntax_id,
2606 &ndr_table_epmapper.syntax_id)) {
2608 status = NT_STATUS_OK;
2612 /* open the connection to the endpoint mapper */
2613 status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2614 &ndr_table_epmapper,
2617 if (!NT_STATUS_IS_OK(status)) {
2620 epm_handle = epm_pipe->binding_handle;
2622 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2623 if (!NT_STATUS_IS_OK(status)) {
2627 status = rpc_pipe_bind(epm_pipe, auth);
2628 if (!NT_STATUS_IS_OK(status)) {
2632 /* create tower for asking the epmapper */
2634 map_binding = talloc_zero(tmp_ctx, struct dcerpc_binding);
2635 if (map_binding == NULL) {
2636 status = NT_STATUS_NO_MEMORY;
2640 map_binding->transport = NCACN_IP_TCP;
2641 map_binding->object = table->syntax_id;
2642 map_binding->host = host; /* needed? */
2643 map_binding->endpoint = "0"; /* correct? needed? */
2645 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2646 if (map_tower == NULL) {
2647 status = NT_STATUS_NO_MEMORY;
2651 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2652 &(map_tower->tower));
2653 if (!NT_STATUS_IS_OK(status)) {
2657 /* allocate further parameters for the epm_Map call */
2659 res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2660 if (res_towers == NULL) {
2661 status = NT_STATUS_NO_MEMORY;
2664 towers.twr = res_towers;
2666 entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2667 if (entry_handle == NULL) {
2668 status = NT_STATUS_NO_MEMORY;
2672 /* ask the endpoint mapper for the port */
2674 status = dcerpc_epm_Map(epm_handle,
2676 discard_const_p(struct GUID,
2677 &(table->syntax_id.uuid)),
2685 if (!NT_STATUS_IS_OK(status)) {
2689 if (result != EPMAPPER_STATUS_OK) {
2690 status = NT_STATUS_UNSUCCESSFUL;
2694 if (num_towers != 1) {
2695 status = NT_STATUS_UNSUCCESSFUL;
2699 /* extract the port from the answer */
2701 status = dcerpc_binding_from_tower(tmp_ctx,
2702 &(towers.twr->tower),
2704 if (!NT_STATUS_IS_OK(status)) {
2708 /* are further checks here necessary? */
2709 if (res_binding->transport != NCACN_IP_TCP) {
2710 status = NT_STATUS_UNSUCCESSFUL;
2714 *pport = (uint16_t)atoi(res_binding->endpoint);
2717 TALLOC_FREE(tmp_ctx);
2722 * Create a rpc pipe client struct, connecting to a host via tcp.
2723 * The port is determined by asking the endpoint mapper on the given
2726 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2727 const struct sockaddr_storage *addr,
2728 const struct ndr_interface_table *table,
2729 struct rpc_pipe_client **presult)
2734 status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2735 if (!NT_STATUS_IS_OK(status)) {
2739 return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2743 /********************************************************************
2744 Create a rpc pipe client struct, connecting to a unix domain socket
2745 ********************************************************************/
2746 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2747 const struct ndr_interface_table *table,
2748 struct rpc_pipe_client **presult)
2750 struct rpc_pipe_client *result;
2751 struct sockaddr_un addr;
2756 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2757 if (result == NULL) {
2758 return NT_STATUS_NO_MEMORY;
2761 result->abstract_syntax = table->syntax_id;
2762 result->transfer_syntax = ndr_transfer_syntax_ndr;
2764 result->desthost = get_myname(result);
2765 result->srv_name_slash = talloc_asprintf_strupper_m(
2766 result, "\\\\%s", result->desthost);
2767 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2768 status = NT_STATUS_NO_MEMORY;
2772 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2773 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2775 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2777 status = map_nt_error_from_unix(errno);
2782 addr.sun_family = AF_UNIX;
2783 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2784 salen = sizeof(struct sockaddr_un);
2786 if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
2787 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2790 return map_nt_error_from_unix(errno);
2793 status = rpc_transport_sock_init(result, fd, &result->transport);
2794 if (!NT_STATUS_IS_OK(status)) {
2799 result->transport->transport = NCALRPC;
2801 result->assoc = dcerpc_association_create(result, 0);
2802 result->conn = dcerpc_connection_create(result, result->assoc,
2803 &result->transport->stream);
2804 result->pres = dcerpc_presentation_allocate(result, result->conn, table,
2805 &ndr_transfer_syntax_ndr);
2806 result->sec = dcerpc_security_allocate(result, result->conn,
2807 DCERPC_AUTH_TYPE_NONE,
2808 DCERPC_AUTH_LEVEL_NONE,
2811 result->binding_handle = rpccli_bh_create(result, NULL, table);
2812 if (result->binding_handle == NULL) {
2813 TALLOC_FREE(result);
2814 return NT_STATUS_NO_MEMORY;
2818 return NT_STATUS_OK;
2821 TALLOC_FREE(result);
2825 struct rpc_pipe_client_np_ref {
2826 struct cli_state *cli;
2827 struct rpc_pipe_client *pipe;
2830 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2832 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2836 /****************************************************************************
2837 Open a named pipe over SMB to a remote server.
2839 * CAVEAT CALLER OF THIS FUNCTION:
2840 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2841 * so be sure that this function is called AFTER any structure (vs pointer)
2842 * assignment of the cli. In particular, libsmbclient does structure
2843 * assignments of cli, which invalidates the data in the returned
2844 * rpc_pipe_client if this function is called before the structure assignment
2847 ****************************************************************************/
2849 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2850 const struct ndr_interface_table *table,
2851 struct rpc_pipe_client **presult)
2853 struct rpc_pipe_client *result;
2855 struct rpc_pipe_client_np_ref *np_ref;
2857 /* sanity check to protect against crashes */
2860 return NT_STATUS_INVALID_HANDLE;
2863 result = talloc_zero(NULL, struct rpc_pipe_client);
2864 if (result == NULL) {
2865 return NT_STATUS_NO_MEMORY;
2868 result->abstract_syntax = table->syntax_id;
2869 result->transfer_syntax = ndr_transfer_syntax_ndr;
2870 result->desthost = talloc_strdup(result, smbXcli_conn_remote_name(cli->conn));
2871 result->srv_name_slash = talloc_asprintf_strupper_m(
2872 result, "\\\\%s", result->desthost);
2874 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2875 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2877 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2878 TALLOC_FREE(result);
2879 return NT_STATUS_NO_MEMORY;
2882 status = rpc_transport_np_init(result, cli, table,
2883 &result->transport);
2884 if (!NT_STATUS_IS_OK(status)) {
2885 TALLOC_FREE(result);
2889 result->transport->transport = NCACN_NP;
2891 result->assoc = dcerpc_association_create(result, 0);
2892 result->conn = dcerpc_connection_create(result, result->assoc,
2893 &result->transport->stream);
2894 dcerpc_connection_set_use_trans_fn(result->conn,
2895 tstream_smbXcli_np_use_trans);
2896 result->pres = dcerpc_presentation_allocate(result, result->conn, table,
2897 &ndr_transfer_syntax_ndr);
2898 result->sec = dcerpc_security_allocate(result, result->conn,
2899 DCERPC_AUTH_TYPE_NONE,
2900 DCERPC_AUTH_LEVEL_NONE,
2903 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2904 if (np_ref == NULL) {
2905 TALLOC_FREE(result);
2906 return NT_STATUS_NO_MEMORY;
2909 np_ref->pipe = result;
2911 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2912 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2914 result->binding_handle = rpccli_bh_create(result, NULL, table);
2915 if (result->binding_handle == NULL) {
2916 TALLOC_FREE(result);
2917 return NT_STATUS_NO_MEMORY;
2921 return NT_STATUS_OK;
2924 /****************************************************************************
2925 Open a pipe to a remote server.
2926 ****************************************************************************/
2928 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2929 enum dcerpc_transport_t transport,
2930 const struct ndr_interface_table *table,
2931 struct rpc_pipe_client **presult)
2933 switch (transport) {
2935 return rpc_pipe_open_tcp(NULL,
2936 smbXcli_conn_remote_name(cli->conn),
2937 smbXcli_conn_remote_sockaddr(cli->conn),
2940 return rpc_pipe_open_np(cli, table, presult);
2942 return NT_STATUS_NOT_IMPLEMENTED;
2946 /****************************************************************************
2947 Open a named pipe to an SMB server and bind anonymously.
2948 ****************************************************************************/
2950 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2951 enum dcerpc_transport_t transport,
2952 const struct ndr_interface_table *table,
2953 struct rpc_pipe_client **presult)
2955 struct rpc_pipe_client *result;
2956 struct pipe_auth_data *auth;
2959 status = cli_rpc_pipe_open(cli, transport, table, &result);
2960 if (!NT_STATUS_IS_OK(status)) {
2964 status = rpccli_anon_bind_data(result, &auth);
2965 if (!NT_STATUS_IS_OK(status)) {
2966 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2967 nt_errstr(status)));
2968 TALLOC_FREE(result);
2973 * This is a bit of an abstraction violation due to the fact that an
2974 * anonymous bind on an authenticated SMB inherits the user/domain
2975 * from the enclosing SMB creds
2978 TALLOC_FREE(auth->user_name);
2979 TALLOC_FREE(auth->domain);
2981 auth->user_name = talloc_strdup(auth, cli->user_name);
2982 auth->domain = talloc_strdup(auth, cli->domain);
2984 if (transport == NCACN_NP) {
2985 struct smbXcli_session *session;
2987 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2988 session = cli->smb2.session;
2990 session = cli->smb1.session;
2993 status = smbXcli_session_application_key(session, auth,
2994 &auth->transport_session_key);
2995 if (!NT_STATUS_IS_OK(status)) {
2996 auth->transport_session_key = data_blob_null;
3000 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3001 TALLOC_FREE(result);
3002 return NT_STATUS_NO_MEMORY;
3005 status = rpc_pipe_bind(result, auth);
3006 if (!NT_STATUS_IS_OK(status)) {
3008 if (ndr_syntax_id_equal(&table->syntax_id,
3009 &ndr_table_dssetup.syntax_id)) {
3010 /* non AD domains just don't have this pipe, avoid
3011 * level 0 statement in that case - gd */
3014 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3015 "%s failed with error %s\n",
3017 nt_errstr(status) ));
3018 TALLOC_FREE(result);
3022 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3023 "%s and bound anonymously.\n",
3028 return NT_STATUS_OK;
3031 /****************************************************************************
3032 ****************************************************************************/
3034 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3035 const struct ndr_interface_table *table,
3036 struct rpc_pipe_client **presult)
3038 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3042 /****************************************************************************
3043 Open a named pipe to an SMB server and bind using the mech specified
3044 ****************************************************************************/
3046 NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
3047 const struct ndr_interface_table *table,
3048 enum dcerpc_transport_t transport,
3049 enum dcerpc_AuthType auth_type,
3050 enum dcerpc_AuthLevel auth_level,
3053 const char *username,
3054 const char *password,
3055 struct rpc_pipe_client **presult)
3057 struct rpc_pipe_client *result;
3058 struct pipe_auth_data *auth = NULL;
3059 const char *target_service = table->authservices->names[0];
3063 status = cli_rpc_pipe_open(cli, transport, table, &result);
3064 if (!NT_STATUS_IS_OK(status)) {
3068 status = rpccli_generic_bind_data(result,
3069 auth_type, auth_level,
3070 server, target_service,
3071 domain, username, password,
3072 CRED_AUTO_USE_KERBEROS,
3075 if (!NT_STATUS_IS_OK(status)) {
3076 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3077 nt_errstr(status)));
3081 status = rpc_pipe_bind(result, auth);
3082 if (!NT_STATUS_IS_OK(status)) {
3083 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3084 nt_errstr(status) ));
3088 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3089 "machine %s and bound as user %s\\%s.\n", table->name,
3090 result->desthost, domain, username));
3093 return NT_STATUS_OK;
3097 TALLOC_FREE(result);
3101 /****************************************************************************
3103 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3104 using session_key. sign and seal.
3106 The *pdc will be stolen onto this new pipe
3107 ****************************************************************************/
3109 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3110 const struct ndr_interface_table *table,
3111 enum dcerpc_transport_t transport,
3113 struct netlogon_creds_cli_context *netlogon_creds,
3114 struct rpc_pipe_client **_rpccli)
3116 struct rpc_pipe_client *rpccli;
3117 struct pipe_auth_data *rpcauth;
3118 struct netlogon_creds_CredentialState *creds = NULL;
3119 enum dcerpc_AuthLevel auth_level;
3121 const char *target_service = table->authservices->names[0];
3122 int rpc_pipe_bind_dbglvl = 0;
3124 status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
3125 if (!NT_STATUS_IS_OK(status)) {
3129 status = netlogon_creds_cli_lock(netlogon_creds, rpccli, &creds);
3130 if (!NT_STATUS_IS_OK(status)) {
3131 DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
3132 nt_errstr(status)));
3133 TALLOC_FREE(rpccli);
3137 auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
3139 status = rpccli_generic_bind_data(rpccli,
3140 DCERPC_AUTH_TYPE_SCHANNEL,
3145 creds->computer_name,
3147 CRED_AUTO_USE_KERBEROS,
3150 if (!NT_STATUS_IS_OK(status)) {
3151 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3152 nt_errstr(status)));
3153 TALLOC_FREE(rpccli);
3157 status = rpc_pipe_bind(rpccli, rpcauth);
3158 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3159 rpc_pipe_bind_dbglvl = 1;
3160 netlogon_creds_cli_delete(netlogon_creds, &creds);
3162 if (!NT_STATUS_IS_OK(status)) {
3163 DEBUG(rpc_pipe_bind_dbglvl,
3164 ("cli_rpc_pipe_open_schannel_with_key: "
3165 "rpc_pipe_bind failed with error %s\n",
3166 nt_errstr(status)));
3167 TALLOC_FREE(rpccli);
3173 if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
3177 status = netlogon_creds_cli_check(netlogon_creds,
3178 rpccli->binding_handle);
3179 if (!NT_STATUS_IS_OK(status)) {
3180 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3181 nt_errstr(status)));
3182 TALLOC_FREE(rpccli);
3188 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3189 "for domain %s and bound using schannel.\n",
3191 rpccli->desthost, domain));
3194 return NT_STATUS_OK;
3197 NTSTATUS cli_rpc_pipe_open_spnego(struct cli_state *cli,
3198 const struct ndr_interface_table *table,
3199 enum dcerpc_transport_t transport,
3201 enum dcerpc_AuthLevel auth_level,
3204 const char *username,
3205 const char *password,
3206 struct rpc_pipe_client **presult)
3208 struct rpc_pipe_client *result;
3209 struct pipe_auth_data *auth = NULL;
3210 const char *target_service = table->authservices->names[0];
3213 enum credentials_use_kerberos use_kerberos;
3215 if (strcmp(oid, GENSEC_OID_KERBEROS5) == 0) {
3216 use_kerberos = CRED_MUST_USE_KERBEROS;
3217 } else if (strcmp(oid, GENSEC_OID_NTLMSSP) == 0) {
3218 use_kerberos = CRED_DONT_USE_KERBEROS;
3220 return NT_STATUS_INVALID_PARAMETER;
3223 status = cli_rpc_pipe_open(cli, transport, table, &result);
3224 if (!NT_STATUS_IS_OK(status)) {
3228 status = rpccli_generic_bind_data(result,
3229 DCERPC_AUTH_TYPE_SPNEGO, auth_level,
3230 server, target_service,
3231 domain, username, password,
3234 if (!NT_STATUS_IS_OK(status)) {
3235 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3236 nt_errstr(status)));
3240 status = rpc_pipe_bind(result, auth);
3241 if (!NT_STATUS_IS_OK(status)) {
3242 DEBUG(0, ("cli_rpc_pipe_open_spnego: cli_rpc_pipe_bind failed with error %s\n",
3243 nt_errstr(status) ));
3247 DEBUG(10,("cli_rpc_pipe_open_spnego: opened pipe %s to "
3248 "machine %s.\n", table->name,
3252 return NT_STATUS_OK;
3256 TALLOC_FREE(result);
3260 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3261 struct rpc_pipe_client *cli,
3262 DATA_BLOB *session_key)
3265 struct pipe_auth_data *a;
3266 struct gensec_security *gensec_security;
3267 DATA_BLOB sk = data_blob_null;
3268 bool make_dup = false;
3270 if (!session_key || !cli) {
3271 return NT_STATUS_INVALID_PARAMETER;
3277 return NT_STATUS_INVALID_PARAMETER;
3280 switch (cli->auth->auth_type) {
3281 case DCERPC_AUTH_TYPE_SPNEGO:
3282 case DCERPC_AUTH_TYPE_NTLMSSP:
3283 case DCERPC_AUTH_TYPE_KRB5:
3284 gensec_security = talloc_get_type_abort(a->auth_ctx,
3285 struct gensec_security);
3286 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3287 if (!NT_STATUS_IS_OK(status)) {
3292 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3293 case DCERPC_AUTH_TYPE_NONE:
3294 sk = data_blob_const(a->transport_session_key.data,
3295 a->transport_session_key.length);
3303 return NT_STATUS_NO_USER_SESSION_KEY;
3307 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3312 return NT_STATUS_OK;