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 "libsmb/namequery.h"
24 #include "../lib/util/tevent_ntstatus.h"
25 #include "librpc/gen_ndr/ndr_epmapper_c.h"
26 #include "../librpc/gen_ndr/ndr_dssetup.h"
27 #include "../libcli/auth/schannel.h"
28 #include "../libcli/auth/netlogon_creds_cli.h"
29 #include "auth_generic.h"
30 #include "librpc/gen_ndr/ndr_dcerpc.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/auth.h"
33 #include "librpc/rpc/dcerpc.h"
34 #include "librpc/rpc/dcerpc_util.h"
37 #include "libsmb/libsmb.h"
38 #include "auth/gensec/gensec.h"
39 #include "auth/credentials/credentials.h"
40 #include "auth/auth_util.h"
41 #include "../libcli/smb/smbXcli_base.h"
42 #include "lib/tsocket/tsocket.h"
43 #include "libcli/named_pipe_auth/npa_tstream.h"
44 #include "librpc/gen_ndr/ndr_winreg.h"
48 #define DBGC_CLASS DBGC_RPC_CLI
50 /********************************************************************
51 Pipe description for a DEBUG
52 ********************************************************************/
53 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
54 struct rpc_pipe_client *cli)
56 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
63 /********************************************************************
65 ********************************************************************/
67 static uint32_t get_rpc_call_id(void)
69 static uint32_t call_id = 0;
73 /*******************************************************************
74 Use SMBreadX to get rest of one fragment's worth of rpc data.
75 Reads the whole size or give an error message
76 ********************************************************************/
78 struct rpc_read_state {
79 struct tevent_context *ev;
80 struct rpc_cli_transport *transport;
86 static void rpc_read_done(struct tevent_req *subreq);
88 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
89 struct tevent_context *ev,
90 struct rpc_cli_transport *transport,
91 uint8_t *data, size_t size)
93 struct tevent_req *req, *subreq;
94 struct rpc_read_state *state;
96 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
101 state->transport = transport;
106 DBG_INFO("data_to_read: %zu\n", size);
108 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
110 if (subreq == NULL) {
113 tevent_req_set_callback(subreq, rpc_read_done, req);
121 static void rpc_read_done(struct tevent_req *subreq)
123 struct tevent_req *req = tevent_req_callback_data(
124 subreq, struct tevent_req);
125 struct rpc_read_state *state = tevent_req_data(
126 req, struct rpc_read_state);
130 status = state->transport->read_recv(subreq, &received);
132 if (tevent_req_nterror(req, status)) {
136 state->num_read += received;
137 if (state->num_read == state->size) {
138 tevent_req_done(req);
142 subreq = state->transport->read_send(state, state->ev,
143 state->data + state->num_read,
144 state->size - state->num_read,
145 state->transport->priv);
146 if (tevent_req_nomem(subreq, req)) {
149 tevent_req_set_callback(subreq, rpc_read_done, req);
152 static NTSTATUS rpc_read_recv(struct tevent_req *req)
154 return tevent_req_simple_recv_ntstatus(req);
157 struct rpc_write_state {
158 struct tevent_context *ev;
159 struct rpc_cli_transport *transport;
165 static void rpc_write_done(struct tevent_req *subreq);
167 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
168 struct tevent_context *ev,
169 struct rpc_cli_transport *transport,
170 const uint8_t *data, size_t size)
172 struct tevent_req *req, *subreq;
173 struct rpc_write_state *state;
175 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
180 state->transport = transport;
183 state->num_written = 0;
185 DBG_INFO("data_to_write: %zu\n", size);
187 subreq = transport->write_send(state, ev, data, size, transport->priv);
188 if (tevent_req_nomem(subreq, req)) {
189 return tevent_req_post(req, ev);
191 tevent_req_set_callback(subreq, rpc_write_done, req);
195 static void rpc_write_done(struct tevent_req *subreq)
197 struct tevent_req *req = tevent_req_callback_data(
198 subreq, struct tevent_req);
199 struct rpc_write_state *state = tevent_req_data(
200 req, struct rpc_write_state);
204 status = state->transport->write_recv(subreq, &written);
206 if (tevent_req_nterror(req, status)) {
210 state->num_written += written;
212 if (state->num_written == state->size) {
213 tevent_req_done(req);
217 subreq = state->transport->write_send(state, state->ev,
218 state->data + state->num_written,
219 state->size - state->num_written,
220 state->transport->priv);
221 if (tevent_req_nomem(subreq, req)) {
224 tevent_req_set_callback(subreq, rpc_write_done, req);
227 static NTSTATUS rpc_write_recv(struct tevent_req *req)
229 return tevent_req_simple_recv_ntstatus(req);
233 /****************************************************************************
234 Try and get a PDU's worth of data from current_pdu. If not, then read more
236 ****************************************************************************/
238 struct get_complete_frag_state {
239 struct tevent_context *ev;
240 struct rpc_pipe_client *cli;
245 static void get_complete_frag_got_header(struct tevent_req *subreq);
246 static void get_complete_frag_got_rest(struct tevent_req *subreq);
248 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
249 struct tevent_context *ev,
250 struct rpc_pipe_client *cli,
253 struct tevent_req *req, *subreq;
254 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)) {
271 return tevent_req_post(req, ev);
273 subreq = rpc_read_send(state, state->ev,
274 state->cli->transport,
275 pdu->data + received,
276 RPC_HEADER_LEN - received);
277 if (tevent_req_nomem(subreq, req)) {
278 return tevent_req_post(req, ev);
280 tevent_req_set_callback(subreq, get_complete_frag_got_header,
285 state->frag_len = dcerpc_get_frag_length(pdu);
286 if (state->frag_len < RPC_HEADER_LEN) {
287 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
288 return tevent_req_post(req, ev);
291 if (received >= state->frag_len) {
293 * Got the whole fragment
295 tevent_req_done(req);
296 return tevent_req_post(req, ev);
299 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
301 return tevent_req_post(req, ev);
304 subreq = rpc_read_send(
307 state->cli->transport,
308 pdu->data + received,
309 state->frag_len - received);
310 if (tevent_req_nomem(subreq, req)) {
311 return tevent_req_post(req, ev);
313 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
317 static void get_complete_frag_got_header(struct tevent_req *subreq)
319 struct tevent_req *req = tevent_req_callback_data(
320 subreq, struct tevent_req);
321 struct get_complete_frag_state *state = tevent_req_data(
322 req, struct get_complete_frag_state);
325 status = rpc_read_recv(subreq);
327 if (tevent_req_nterror(req, status)) {
331 state->frag_len = dcerpc_get_frag_length(state->pdu);
332 if (state->frag_len < RPC_HEADER_LEN) {
333 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
337 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
343 * We're here in this piece of code because we've read exactly
344 * RPC_HEADER_LEN bytes into state->pdu.
347 subreq = rpc_read_send(state, state->ev, state->cli->transport,
348 state->pdu->data + RPC_HEADER_LEN,
349 state->frag_len - RPC_HEADER_LEN);
350 if (tevent_req_nomem(subreq, req)) {
353 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
356 static void get_complete_frag_got_rest(struct tevent_req *subreq)
358 NTSTATUS status = rpc_read_recv(subreq);
359 return tevent_req_simple_finish_ntstatus(subreq, status);
362 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
364 return tevent_req_simple_recv_ntstatus(req);
367 /****************************************************************************
368 Do basic authentication checks on an incoming pdu.
369 ****************************************************************************/
371 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
372 struct rpc_pipe_client *cli,
373 struct ncacn_packet *pkt,
375 uint8_t expected_pkt_type,
378 DATA_BLOB *reply_pdu)
380 const struct dcerpc_response *r = NULL;
381 DATA_BLOB tmp_stub = { .data = NULL };
385 * Point the return values at the real data including the RPC
386 * header. Just in case the caller wants it.
390 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
391 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
393 * TODO: do we still need this hack which was introduced
394 * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
396 * I don't even know what AS/U might be...
398 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
399 "fragment first/last ON.\n"));
400 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
403 /* Ensure we have the correct type. */
404 switch (pkt->ptype) {
405 case DCERPC_PKT_BIND_NAK:
406 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
407 rpccli_pipe_txt(talloc_tos(), cli)));
409 ret = dcerpc_verify_ncacn_packet_header(pkt,
411 0, /* max_auth_info */
412 DCERPC_PFC_FLAG_FIRST |
413 DCERPC_PFC_FLAG_LAST,
414 0); /* optional flags */
415 if (!NT_STATUS_IS_OK(ret)) {
416 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
417 "RPC packet type - %u, expected %u: %s\n",
418 rpccli_pipe_txt(talloc_tos(), cli),
419 pkt->ptype, expected_pkt_type,
421 NDR_PRINT_DEBUG(ncacn_packet, pkt);
425 /* Use this for now... */
426 return NT_STATUS_NETWORK_ACCESS_DENIED;
428 case DCERPC_PKT_BIND_ACK:
429 ret = dcerpc_verify_ncacn_packet_header(pkt,
431 pkt->u.bind_ack.auth_info.length,
432 DCERPC_PFC_FLAG_FIRST |
433 DCERPC_PFC_FLAG_LAST,
434 DCERPC_PFC_FLAG_CONC_MPX |
435 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
436 if (!NT_STATUS_IS_OK(ret)) {
437 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
438 "RPC packet type - %u, expected %u: %s\n",
439 rpccli_pipe_txt(talloc_tos(), cli),
440 pkt->ptype, expected_pkt_type,
442 NDR_PRINT_DEBUG(ncacn_packet, pkt);
448 case DCERPC_PKT_ALTER_RESP:
449 ret = dcerpc_verify_ncacn_packet_header(pkt,
451 pkt->u.alter_resp.auth_info.length,
452 DCERPC_PFC_FLAG_FIRST |
453 DCERPC_PFC_FLAG_LAST,
454 DCERPC_PFC_FLAG_CONC_MPX |
455 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
456 if (!NT_STATUS_IS_OK(ret)) {
457 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
458 "RPC packet type - %u, expected %u: %s\n",
459 rpccli_pipe_txt(talloc_tos(), cli),
460 pkt->ptype, expected_pkt_type,
462 NDR_PRINT_DEBUG(ncacn_packet, pkt);
468 case DCERPC_PKT_RESPONSE:
470 r = &pkt->u.response;
472 ret = dcerpc_verify_ncacn_packet_header(pkt,
474 r->stub_and_verifier.length,
475 0, /* required_flags */
476 DCERPC_PFC_FLAG_FIRST |
477 DCERPC_PFC_FLAG_LAST);
478 if (!NT_STATUS_IS_OK(ret)) {
479 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
480 "RPC packet type - %u, expected %u: %s\n",
481 rpccli_pipe_txt(talloc_tos(), cli),
482 pkt->ptype, expected_pkt_type,
484 NDR_PRINT_DEBUG(ncacn_packet, pkt);
488 tmp_stub.data = r->stub_and_verifier.data;
489 tmp_stub.length = r->stub_and_verifier.length;
491 /* Here's where we deal with incoming sign/seal. */
492 ret = dcerpc_check_auth(cli->auth, pkt,
494 DCERPC_RESPONSE_LENGTH,
496 if (!NT_STATUS_IS_OK(ret)) {
497 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
498 "RPC packet type - %u, expected %u: %s\n",
499 rpccli_pipe_txt(talloc_tos(), cli),
500 pkt->ptype, expected_pkt_type,
502 NDR_PRINT_DEBUG(ncacn_packet, pkt);
506 /* Point the return values at the NDR data. */
509 DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
510 (long unsigned int)pdu->length,
511 (long unsigned int)rdata->length));
514 * If this is the first reply, and the allocation hint is
515 * reasonable, try and set up the reply_pdu DATA_BLOB to the
519 if ((reply_pdu->length == 0) &&
520 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
521 if (!data_blob_realloc(mem_ctx, reply_pdu,
523 DEBUG(0, ("reply alloc hint %d too "
524 "large to allocate\n",
525 (int)r->alloc_hint));
526 return NT_STATUS_NO_MEMORY;
532 case DCERPC_PKT_FAULT:
534 ret = dcerpc_verify_ncacn_packet_header(pkt,
536 0, /* max_auth_info */
537 DCERPC_PFC_FLAG_FIRST |
538 DCERPC_PFC_FLAG_LAST,
539 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
540 if (!NT_STATUS_IS_OK(ret)) {
541 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
542 "RPC packet type - %u, expected %u: %s\n",
543 rpccli_pipe_txt(talloc_tos(), cli),
544 pkt->ptype, expected_pkt_type,
546 NDR_PRINT_DEBUG(ncacn_packet, pkt);
550 DEBUG(1, (__location__ ": RPC fault code %s received "
552 dcerpc_errstr(talloc_tos(),
553 pkt->u.fault.status),
554 rpccli_pipe_txt(talloc_tos(), cli)));
556 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
559 DEBUG(0, (__location__ "Unknown packet type %u received "
561 (unsigned int)pkt->ptype,
562 rpccli_pipe_txt(talloc_tos(), cli)));
563 return NT_STATUS_RPC_PROTOCOL_ERROR;
567 if (pkt->call_id != call_id) {
568 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
569 "RPC call_id - %u, not %u\n",
570 rpccli_pipe_txt(talloc_tos(), cli),
571 pkt->call_id, call_id));
572 return NT_STATUS_RPC_PROTOCOL_ERROR;
578 /****************************************************************************
579 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
580 ****************************************************************************/
582 struct cli_api_pipe_state {
583 struct tevent_context *ev;
584 struct rpc_cli_transport *transport;
589 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
590 static void cli_api_pipe_write_done(struct tevent_req *subreq);
591 static void cli_api_pipe_read_done(struct tevent_req *subreq);
593 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
594 struct tevent_context *ev,
595 struct rpc_cli_transport *transport,
596 uint8_t *data, size_t data_len,
597 uint32_t max_rdata_len)
599 struct tevent_req *req, *subreq;
600 struct cli_api_pipe_state *state;
602 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
607 state->transport = transport;
609 if (max_rdata_len < RPC_HEADER_LEN) {
611 * For a RPC reply we always need at least RPC_HEADER_LEN
612 * bytes. We check this here because we will receive
613 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
615 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
616 return tevent_req_post(req, ev);
619 if (transport->trans_send != NULL) {
620 subreq = transport->trans_send(state, ev, data, data_len,
621 max_rdata_len, transport->priv);
622 if (tevent_req_nomem(subreq, req)) {
623 return tevent_req_post(req, ev);
625 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
630 * If the transport does not provide a "trans" routine, i.e. for
631 * example the ncacn_ip_tcp transport, do the write/read step here.
634 subreq = rpc_write_send(state, ev, transport, data, data_len);
635 if (tevent_req_nomem(subreq, req)) {
636 return tevent_req_post(req, ev);
638 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
642 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
644 struct tevent_req *req = tevent_req_callback_data(
645 subreq, struct tevent_req);
646 struct cli_api_pipe_state *state = tevent_req_data(
647 req, struct cli_api_pipe_state);
650 status = state->transport->trans_recv(subreq, state, &state->rdata,
653 if (tevent_req_nterror(req, status)) {
656 tevent_req_done(req);
659 static void cli_api_pipe_write_done(struct tevent_req *subreq)
661 struct tevent_req *req = tevent_req_callback_data(
662 subreq, struct tevent_req);
663 struct cli_api_pipe_state *state = tevent_req_data(
664 req, struct cli_api_pipe_state);
667 status = rpc_write_recv(subreq);
669 if (tevent_req_nterror(req, status)) {
673 state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
674 if (tevent_req_nomem(state->rdata, req)) {
679 * We don't need to use rpc_read_send here, the upper layer will cope
680 * with a short read, transport->trans_send could also return less
681 * than state->max_rdata_len.
683 subreq = state->transport->read_send(state, state->ev, state->rdata,
685 state->transport->priv);
686 if (tevent_req_nomem(subreq, req)) {
689 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
692 static void cli_api_pipe_read_done(struct tevent_req *subreq)
694 struct tevent_req *req = tevent_req_callback_data(
695 subreq, struct tevent_req);
696 struct cli_api_pipe_state *state = tevent_req_data(
697 req, struct cli_api_pipe_state);
701 status = state->transport->read_recv(subreq, &received);
703 if (tevent_req_nterror(req, status)) {
706 state->rdata_len = received;
707 tevent_req_done(req);
710 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
711 uint8_t **prdata, uint32_t *prdata_len)
713 struct cli_api_pipe_state *state = tevent_req_data(
714 req, struct cli_api_pipe_state);
717 if (tevent_req_is_nterror(req, &status)) {
721 *prdata = talloc_move(mem_ctx, &state->rdata);
722 *prdata_len = state->rdata_len;
726 /****************************************************************************
727 Send data on an rpc pipe via trans. The data must be the last
728 pdu fragment of an NDR data stream.
730 Receive response data from an rpc pipe, which may be large...
732 Read the first fragment: unfortunately have to use SMBtrans for the first
733 bit, then SMBreadX for subsequent bits.
735 If first fragment received also wasn't the last fragment, continue
736 getting fragments until we _do_ receive the last fragment.
738 Request/Response PDU's look like the following...
740 |<------------------PDU len----------------------------------------------->|
741 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
743 +------------+-----------------+-------------+---------------+-------------+
744 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
745 +------------+-----------------+-------------+---------------+-------------+
747 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
748 signing & sealing being negotiated.
750 ****************************************************************************/
752 struct rpc_api_pipe_state {
753 struct tevent_context *ev;
754 struct rpc_pipe_client *cli;
755 uint8_t expected_pkt_type;
758 DATA_BLOB incoming_frag;
759 struct ncacn_packet *pkt;
763 size_t reply_pdu_offset;
767 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
768 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
769 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
771 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
772 struct tevent_context *ev,
773 struct rpc_pipe_client *cli,
774 DATA_BLOB *data, /* Outgoing PDU */
775 uint8_t expected_pkt_type,
778 struct tevent_req *req, *subreq;
779 struct rpc_api_pipe_state *state;
780 uint16_t max_recv_frag;
782 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
788 state->expected_pkt_type = expected_pkt_type;
789 state->call_id = call_id;
790 state->endianness = DCERPC_DREP_LE;
793 * Ensure we're not sending too much.
795 if (data->length > cli->max_xmit_frag) {
796 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
797 return tevent_req_post(req, ev);
800 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
802 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
803 subreq = rpc_write_send(state, ev, cli->transport,
804 data->data, data->length);
805 if (tevent_req_nomem(subreq, req)) {
806 return tevent_req_post(req, ev);
808 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
812 /* get the header first, then fetch the rest once we have
813 * the frag_length available */
814 max_recv_frag = RPC_HEADER_LEN;
816 subreq = cli_api_pipe_send(state, ev, cli->transport,
817 data->data, data->length, max_recv_frag);
818 if (tevent_req_nomem(subreq, req)) {
819 return tevent_req_post(req, ev);
821 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
825 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
827 NTSTATUS status = rpc_write_recv(subreq);
828 return tevent_req_simple_finish_ntstatus(subreq, status);
831 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
833 struct tevent_req *req = tevent_req_callback_data(
834 subreq, struct tevent_req);
835 struct rpc_api_pipe_state *state = tevent_req_data(
836 req, struct rpc_api_pipe_state);
838 uint8_t *rdata = NULL;
839 uint32_t rdata_len = 0;
841 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
843 if (tevent_req_nterror(req, status)) {;
844 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
849 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
850 rpccli_pipe_txt(talloc_tos(), state->cli)));
851 tevent_req_done(req);
856 * Move data on state->incoming_frag.
858 state->incoming_frag.data = talloc_move(state, &rdata);
859 state->incoming_frag.length = rdata_len;
860 if (!state->incoming_frag.data) {
861 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
865 /* Ensure we have enough data for a pdu. */
866 subreq = get_complete_frag_send(state, state->ev, state->cli,
867 &state->incoming_frag);
868 if (tevent_req_nomem(subreq, req)) {
871 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
874 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
876 struct tevent_req *req = tevent_req_callback_data(
877 subreq, struct tevent_req);
878 struct rpc_api_pipe_state *state = tevent_req_data(
879 req, struct rpc_api_pipe_state);
881 DATA_BLOB rdata = { .data = NULL };
883 status = get_complete_frag_recv(subreq);
885 if (tevent_req_nterror(req, status)) {
886 DEBUG(5, ("get_complete_frag failed: %s\n",
891 state->pkt = talloc(state, struct ncacn_packet);
894 * TODO: do a real async disconnect ...
896 * For now do it sync...
898 TALLOC_FREE(state->cli->transport);
903 status = dcerpc_pull_ncacn_packet(state->pkt,
904 &state->incoming_frag,
906 if (tevent_req_nterror(req, status)) {
908 * TODO: do a real async disconnect ...
910 * For now do it sync...
912 TALLOC_FREE(state->cli->transport);
916 if (DEBUGLEVEL >= 10) {
917 NDR_PRINT_DEBUG(ncacn_packet, state->pkt);
920 status = cli_pipe_validate_current_pdu(state,
921 state->cli, state->pkt,
922 &state->incoming_frag,
923 state->expected_pkt_type,
928 DBG_DEBUG("got frag len of %zu at offset %zu: %s\n",
929 state->incoming_frag.length,
930 state->reply_pdu_offset,
933 if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) {
935 * TODO: do a real async disconnect ...
937 * For now do it sync...
939 TALLOC_FREE(state->cli->transport);
940 } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
942 * TODO: do a real async disconnect ...
944 * For now do it sync...
946 TALLOC_FREE(state->cli->transport);
947 } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
949 * TODO: do a real async disconnect ...
951 * For now do it sync...
953 TALLOC_FREE(state->cli->transport);
955 if (tevent_req_nterror(req, status)) {
959 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
960 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
962 * Set the data type correctly for big-endian data on the
965 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
967 rpccli_pipe_txt(talloc_tos(), state->cli)));
968 state->endianness = 0x00; /* BIG ENDIAN */
971 * Check endianness on subsequent packets.
973 if (state->endianness != state->pkt->drep[0]) {
974 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
976 state->endianness?"little":"big",
977 state->pkt->drep[0]?"little":"big"));
979 * TODO: do a real async disconnect ...
981 * For now do it sync...
983 TALLOC_FREE(state->cli->transport);
984 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
988 if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) {
990 * TODO: do a real async disconnect ...
992 * For now do it sync...
994 TALLOC_FREE(state->cli->transport);
995 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
999 /* Now copy the data portion out of the pdu into rbuf. */
1000 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
1001 if (!data_blob_realloc(NULL, &state->reply_pdu,
1002 state->reply_pdu_offset + rdata.length)) {
1004 * TODO: do a real async disconnect ...
1006 * For now do it sync...
1008 TALLOC_FREE(state->cli->transport);
1009 tevent_req_oom(req);
1014 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
1015 rdata.data, rdata.length);
1016 state->reply_pdu_offset += rdata.length;
1018 /* reset state->incoming_frag, there is no need to free it,
1019 * it will be reallocated to the right size the next time
1021 state->incoming_frag.length = 0;
1023 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1024 /* make sure the pdu length is right now that we
1025 * have all the data available (alloc hint may
1026 * have allocated more than was actually used) */
1027 state->reply_pdu.length = state->reply_pdu_offset;
1028 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1029 rpccli_pipe_txt(talloc_tos(), state->cli),
1030 (unsigned)state->reply_pdu.length));
1031 tevent_req_done(req);
1035 subreq = get_complete_frag_send(state, state->ev, state->cli,
1036 &state->incoming_frag);
1037 if (subreq == NULL) {
1039 * TODO: do a real async disconnect ...
1041 * For now do it sync...
1043 TALLOC_FREE(state->cli->transport);
1045 if (tevent_req_nomem(subreq, req)) {
1048 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1051 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1052 struct ncacn_packet **pkt,
1053 DATA_BLOB *reply_pdu)
1055 struct rpc_api_pipe_state *state = tevent_req_data(
1056 req, struct rpc_api_pipe_state);
1059 if (tevent_req_is_nterror(req, &status)) {
1063 /* return data to caller and assign it ownership of memory */
1065 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1066 reply_pdu->length = state->reply_pdu.length;
1067 state->reply_pdu.length = 0;
1069 data_blob_free(&state->reply_pdu);
1073 *pkt = talloc_steal(mem_ctx, state->pkt);
1076 return NT_STATUS_OK;
1079 /*******************************************************************
1080 Creates NTLMSSP auth bind.
1081 ********************************************************************/
1083 static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1084 TALLOC_CTX *mem_ctx,
1085 DATA_BLOB *auth_token,
1086 bool *client_hdr_signing)
1088 struct gensec_security *gensec_security;
1089 DATA_BLOB null_blob = { .data = NULL };
1092 gensec_security = cli->auth->auth_ctx;
1094 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1095 status = gensec_update(gensec_security, mem_ctx, null_blob, auth_token);
1097 if (!NT_STATUS_IS_OK(status) &&
1098 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1103 if (client_hdr_signing == NULL) {
1107 if (cli->auth->auth_level < DCERPC_AUTH_LEVEL_PACKET) {
1108 *client_hdr_signing = false;
1112 *client_hdr_signing = gensec_have_feature(gensec_security,
1113 GENSEC_FEATURE_SIGN_PKT_HEADER);
1118 /*******************************************************************
1119 Creates the internals of a DCE/RPC bind request or alter context PDU.
1120 ********************************************************************/
1122 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1123 enum dcerpc_pkt_type ptype,
1124 uint32_t rpc_call_id,
1125 const struct ndr_syntax_id *abstract,
1126 const struct ndr_syntax_id *transfer,
1127 const DATA_BLOB *auth_info,
1128 bool client_hdr_signing,
1131 uint16_t auth_len = auth_info->length;
1133 struct ndr_syntax_id bind_time_features = dcerpc_construct_bind_time_features(
1134 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING |
1135 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN);
1136 struct dcerpc_ctx_list ctx_list[2] = {
1139 .num_transfer_syntaxes = 1,
1140 .abstract_syntax = *abstract,
1141 .transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer),
1145 .num_transfer_syntaxes = 1,
1146 .abstract_syntax = *abstract,
1147 .transfer_syntaxes = &bind_time_features,
1150 union dcerpc_payload u = {
1151 .bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN,
1152 .bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN,
1153 .bind.num_contexts = ptype == DCERPC_PKT_BIND ? 2 : 1,
1154 .bind.ctx_list = ctx_list,
1155 .bind.auth_info = *auth_info,
1157 uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1160 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1163 if (client_hdr_signing) {
1164 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
1167 status = dcerpc_push_ncacn_packet(mem_ctx,
1173 if (!NT_STATUS_IS_OK(status)) {
1174 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1178 return NT_STATUS_OK;
1181 /*******************************************************************
1182 Creates a DCE/RPC bind request.
1183 ********************************************************************/
1185 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1186 struct rpc_pipe_client *cli,
1187 struct pipe_auth_data *auth,
1188 uint32_t rpc_call_id,
1189 const struct ndr_syntax_id *abstract,
1190 const struct ndr_syntax_id *transfer,
1193 DATA_BLOB auth_token = { .data = NULL };
1194 DATA_BLOB auth_info = { .data = NULL };
1197 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
1198 ret = create_generic_auth_rpc_bind_req(
1199 cli, mem_ctx, &auth_token, &auth->client_hdr_signing);
1201 if (!NT_STATUS_IS_OK(ret) &&
1202 !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1207 if (auth_token.length != 0) {
1208 ret = dcerpc_push_dcerpc_auth(cli,
1211 0, /* auth_pad_length */
1212 auth->auth_context_id,
1215 if (!NT_STATUS_IS_OK(ret)) {
1218 data_blob_free(&auth_token);
1221 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1227 auth->client_hdr_signing,
1229 data_blob_free(&auth_info);
1234 /*******************************************************************
1236 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1237 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1238 and deals with signing/sealing details.
1239 ********************************************************************/
1241 struct rpc_api_pipe_req_state {
1242 struct tevent_context *ev;
1243 struct rpc_pipe_client *cli;
1246 const DATA_BLOB *req_data;
1247 const struct GUID *object_uuid;
1248 uint32_t req_data_sent;
1249 DATA_BLOB req_trailer;
1250 uint32_t req_trailer_sent;
1251 bool verify_bitmask1;
1252 bool verify_pcontext;
1254 DATA_BLOB reply_pdu;
1257 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1258 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1259 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
1260 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1261 bool *is_last_frag);
1263 static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1264 struct tevent_context *ev,
1265 struct rpc_pipe_client *cli,
1267 const struct GUID *object_uuid,
1268 const DATA_BLOB *req_data)
1270 struct tevent_req *req, *subreq;
1271 struct rpc_api_pipe_req_state *state;
1275 req = tevent_req_create(mem_ctx, &state,
1276 struct rpc_api_pipe_req_state);
1282 state->op_num = op_num;
1283 state->object_uuid = object_uuid;
1284 state->req_data = req_data;
1285 state->call_id = get_rpc_call_id();
1287 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1288 + RPC_MAX_SIGN_SIZE) {
1289 /* Server is screwed up ! */
1290 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1291 return tevent_req_post(req, ev);
1294 status = prepare_verification_trailer(state);
1295 if (tevent_req_nterror(req, status)) {
1296 return tevent_req_post(req, ev);
1299 status = prepare_next_frag(state, &is_last_frag);
1300 if (tevent_req_nterror(req, status)) {
1301 return tevent_req_post(req, ev);
1305 subreq = rpc_api_pipe_send(state, ev, state->cli,
1307 DCERPC_PKT_RESPONSE,
1309 if (tevent_req_nomem(subreq, req)) {
1310 return tevent_req_post(req, ev);
1312 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1314 subreq = rpc_write_send(state, ev, cli->transport,
1315 state->rpc_out.data,
1316 state->rpc_out.length);
1317 if (tevent_req_nomem(subreq, req)) {
1318 return tevent_req_post(req, ev);
1320 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1326 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
1328 struct pipe_auth_data *a = state->cli->auth;
1329 struct dcerpc_sec_verification_trailer *t;
1330 struct ndr_push *ndr = NULL;
1331 enum ndr_err_code ndr_err;
1336 return NT_STATUS_OK;
1339 if (a->auth_level < DCERPC_AUTH_LEVEL_PACKET) {
1340 return NT_STATUS_OK;
1343 t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
1345 return NT_STATUS_NO_MEMORY;
1348 if (!a->verified_bitmask1) {
1349 t->commands = talloc_realloc(t, t->commands,
1350 struct dcerpc_sec_vt,
1351 t->count.count + 1);
1352 if (t->commands == NULL) {
1353 return NT_STATUS_NO_MEMORY;
1355 t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1356 .command = DCERPC_SEC_VT_COMMAND_BITMASK1,
1357 .u.bitmask1 = (a->client_hdr_signing) ?
1358 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING :
1361 state->verify_bitmask1 = true;
1364 if (!state->cli->verified_pcontext) {
1365 t->commands = talloc_realloc(t, t->commands,
1366 struct dcerpc_sec_vt,
1367 t->count.count + 1);
1368 if (t->commands == NULL) {
1369 return NT_STATUS_NO_MEMORY;
1371 t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1372 .command = DCERPC_SEC_VT_COMMAND_PCONTEXT,
1373 .u.pcontext.abstract_syntax =
1374 state->cli->abstract_syntax,
1375 .u.pcontext.transfer_syntax =
1376 state->cli->transfer_syntax,
1378 state->verify_pcontext = true;
1381 if (!a->hdr_signing) {
1382 t->commands = talloc_realloc(t, t->commands,
1383 struct dcerpc_sec_vt,
1384 t->count.count + 1);
1385 if (t->commands == NULL) {
1386 return NT_STATUS_NO_MEMORY;
1388 t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1389 .command = DCERPC_SEC_VT_COMMAND_HEADER2,
1390 .u.header2.ptype = DCERPC_PKT_REQUEST,
1391 .u.header2.drep[0] = DCERPC_DREP_LE,
1392 .u.header2.call_id = state->call_id,
1393 .u.header2.context_id = 0,
1394 .u.header2.opnum = state->op_num,
1398 if (t->count.count == 0) {
1400 return NT_STATUS_OK;
1403 t->commands[t->count.count - 1].command |= DCERPC_SEC_VT_COMMAND_END;
1405 if (DEBUGLEVEL >= 10) {
1406 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
1409 ndr = ndr_push_init_ctx(state);
1411 return NT_STATUS_NO_MEMORY;
1414 ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
1415 NDR_SCALARS | NDR_BUFFERS,
1418 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1419 return ndr_map_error2ntstatus(ndr_err);
1421 state->req_trailer = ndr_push_blob(ndr);
1423 align = state->req_data->length & 0x3;
1430 const uint8_t zeros[4] = { 0, };
1432 ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
1434 return NT_STATUS_NO_MEMORY;
1437 /* move the padding to the start */
1438 p = state->req_trailer.data;
1439 memmove(p + pad, p, state->req_trailer.length - pad);
1443 return NT_STATUS_OK;
1446 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1454 size_t data_thistime;
1455 size_t trailer_left;
1456 size_t trailer_thistime = 0;
1458 size_t total_thistime;
1461 union dcerpc_payload u;
1463 data_left = state->req_data->length - state->req_data_sent;
1464 trailer_left = state->req_trailer.length - state->req_trailer_sent;
1465 total_left = data_left + trailer_left;
1466 if ((total_left < data_left) || (total_left < trailer_left)) {
1470 return NT_STATUS_INVALID_PARAMETER_MIX;
1473 status = dcerpc_guess_sizes(state->cli->auth,
1474 DCERPC_REQUEST_LENGTH, total_left,
1475 state->cli->max_xmit_frag,
1477 &frag_len, &auth_len, &pad_len);
1478 if (!NT_STATUS_IS_OK(status)) {
1482 if (state->req_data_sent == 0) {
1483 flags = DCERPC_PFC_FLAG_FIRST;
1486 if (total_thistime == total_left) {
1487 flags |= DCERPC_PFC_FLAG_LAST;
1490 data_thistime = MIN(total_thistime, data_left);
1491 if (data_thistime < total_thistime) {
1492 trailer_thistime = total_thistime - data_thistime;
1495 data_blob_free(&state->rpc_out);
1497 u = (union dcerpc_payload) {
1498 .request.alloc_hint = total_left,
1499 .request.context_id = 0,
1500 .request.opnum = state->op_num,
1503 if (state->object_uuid) {
1504 flags |= DCERPC_PFC_FLAG_OBJECT_UUID;
1505 u.request.object.object = *state->object_uuid;
1506 frag_len += ndr_size_GUID(state->object_uuid, 0);
1509 status = dcerpc_push_ncacn_packet(state,
1516 if (!NT_STATUS_IS_OK(status)) {
1520 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1521 * compute it right for requests because the auth trailer is missing
1523 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1525 if (data_thistime > 0) {
1526 /* Copy in the data. */
1527 ok = data_blob_append(NULL, &state->rpc_out,
1528 state->req_data->data + state->req_data_sent,
1531 return NT_STATUS_NO_MEMORY;
1533 state->req_data_sent += data_thistime;
1536 if (trailer_thistime > 0) {
1537 /* Copy in the verification trailer. */
1538 ok = data_blob_append(NULL, &state->rpc_out,
1539 state->req_trailer.data + state->req_trailer_sent,
1542 return NT_STATUS_NO_MEMORY;
1544 state->req_trailer_sent += trailer_thistime;
1547 switch (state->cli->auth->auth_level) {
1548 case DCERPC_AUTH_LEVEL_NONE:
1549 case DCERPC_AUTH_LEVEL_CONNECT:
1551 case DCERPC_AUTH_LEVEL_PACKET:
1552 case DCERPC_AUTH_LEVEL_INTEGRITY:
1553 case DCERPC_AUTH_LEVEL_PRIVACY:
1554 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1556 if (!NT_STATUS_IS_OK(status)) {
1561 return NT_STATUS_INVALID_PARAMETER;
1564 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1569 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1571 struct tevent_req *req = tevent_req_callback_data(
1572 subreq, struct tevent_req);
1573 struct rpc_api_pipe_req_state *state = tevent_req_data(
1574 req, struct rpc_api_pipe_req_state);
1578 status = rpc_write_recv(subreq);
1579 TALLOC_FREE(subreq);
1580 if (tevent_req_nterror(req, status)) {
1584 status = prepare_next_frag(state, &is_last_frag);
1585 if (tevent_req_nterror(req, status)) {
1590 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1592 DCERPC_PKT_RESPONSE,
1594 if (tevent_req_nomem(subreq, req)) {
1597 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1599 subreq = rpc_write_send(state, state->ev,
1600 state->cli->transport,
1601 state->rpc_out.data,
1602 state->rpc_out.length);
1603 if (tevent_req_nomem(subreq, req)) {
1606 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1611 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1613 struct tevent_req *req = tevent_req_callback_data(
1614 subreq, struct tevent_req);
1615 struct rpc_api_pipe_req_state *state = tevent_req_data(
1616 req, struct rpc_api_pipe_req_state);
1619 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1620 TALLOC_FREE(subreq);
1621 if (tevent_req_nterror(req, status)) {
1625 if (state->cli->auth == NULL) {
1626 tevent_req_done(req);
1630 if (state->verify_bitmask1) {
1631 state->cli->auth->verified_bitmask1 = true;
1634 if (state->verify_pcontext) {
1635 state->cli->verified_pcontext = true;
1638 tevent_req_done(req);
1641 static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1642 DATA_BLOB *reply_pdu)
1644 struct rpc_api_pipe_req_state *state = tevent_req_data(
1645 req, struct rpc_api_pipe_req_state);
1648 if (tevent_req_is_nterror(req, &status)) {
1650 * We always have to initialize to reply pdu, even if there is
1651 * none. The rpccli_* caller routines expect this.
1653 *reply_pdu = data_blob_null;
1657 /* return data to caller and assign it ownership of memory */
1658 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1659 reply_pdu->length = state->reply_pdu.length;
1660 state->reply_pdu.length = 0;
1662 return NT_STATUS_OK;
1665 /****************************************************************************
1666 Check the rpc bind acknowledge response.
1667 ****************************************************************************/
1669 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1670 struct rpc_pipe_client *cli)
1672 const struct ndr_syntax_id *transfer = &cli->transfer_syntax;
1673 struct dcerpc_ack_ctx ctx;
1676 if (r->secondary_address_size == 0) {
1677 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)\n"));
1680 if (r->num_results < 1 || !r->ctx_list) {
1684 ctx = r->ctx_list[0];
1686 /* check the transfer syntax */
1687 equal = ndr_syntax_id_equal(&ctx.syntax, transfer);
1689 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1693 if (ctx.result != DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1694 DBG_NOTICE("bind denied result: %d reason: %x\n",
1695 ctx.result, ctx.reason.value);
1699 if (r->num_results >= 2) {
1700 const struct dcerpc_ack_ctx *neg = &r->ctx_list[1];
1702 if (neg->result == DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) {
1703 cli->bind_time_features = neg->reason.negotiate;
1705 DBG_DEBUG("bind_time_feature failed - "
1706 "result: %d reason %x\n",
1707 neg->result, neg->reason.value);
1711 DEBUG(5,("check_bind_response: accepted!\n"));
1715 /*******************************************************************
1716 Creates a DCE/RPC bind authentication response.
1717 This is the packet that is sent back to the server once we
1718 have received a BIND-ACK, to finish the third leg of
1719 the authentication handshake.
1720 ********************************************************************/
1722 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1723 struct rpc_pipe_client *cli,
1724 struct pipe_auth_data *auth,
1725 uint32_t rpc_call_id,
1726 DATA_BLOB *pauth_blob,
1730 union dcerpc_payload u = { .auth3._pad = 0, };
1732 status = dcerpc_push_dcerpc_auth(mem_ctx,
1735 0, /* auth_pad_length */
1736 auth->auth_context_id,
1738 &u.auth3.auth_info);
1739 if (!NT_STATUS_IS_OK(status)) {
1743 status = dcerpc_push_ncacn_packet(mem_ctx,
1745 DCERPC_PFC_FLAG_FIRST |
1746 DCERPC_PFC_FLAG_LAST,
1751 data_blob_free(&u.auth3.auth_info);
1752 if (!NT_STATUS_IS_OK(status)) {
1753 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1757 return NT_STATUS_OK;
1760 /*******************************************************************
1761 Creates a DCE/RPC bind alter context authentication request which
1762 may contain a spnego auth blob
1763 ********************************************************************/
1765 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1766 struct pipe_auth_data *auth,
1767 uint32_t rpc_call_id,
1768 const struct ndr_syntax_id *abstract,
1769 const struct ndr_syntax_id *transfer,
1770 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1773 DATA_BLOB auth_info;
1776 status = dcerpc_push_dcerpc_auth(mem_ctx,
1779 0, /* auth_pad_length */
1780 auth->auth_context_id,
1783 if (!NT_STATUS_IS_OK(status)) {
1787 status = create_bind_or_alt_ctx_internal(mem_ctx,
1793 false, /* client_hdr_signing */
1795 data_blob_free(&auth_info);
1799 /****************************************************************************
1801 ****************************************************************************/
1803 struct rpc_pipe_bind_state {
1804 struct tevent_context *ev;
1805 struct rpc_pipe_client *cli;
1808 uint32_t rpc_call_id;
1811 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1812 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1813 struct rpc_pipe_bind_state *state,
1814 DATA_BLOB *credentials);
1815 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1816 struct rpc_pipe_bind_state *state,
1817 DATA_BLOB *credentials);
1819 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1820 struct tevent_context *ev,
1821 struct rpc_pipe_client *cli,
1822 struct pipe_auth_data *auth)
1824 struct tevent_req *req, *subreq;
1825 struct rpc_pipe_bind_state *state;
1828 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1833 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1834 rpccli_pipe_txt(talloc_tos(), cli),
1835 (unsigned int)auth->auth_type,
1836 (unsigned int)auth->auth_level ));
1840 state->rpc_call_id = get_rpc_call_id();
1842 cli->auth = talloc_move(cli, &auth);
1844 /* Marshall the outgoing data. */
1845 status = create_rpc_bind_req(state, cli,
1848 &cli->abstract_syntax,
1849 &cli->transfer_syntax,
1852 if (!NT_STATUS_IS_OK(status) &&
1853 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1854 tevent_req_nterror(req, status);
1855 return tevent_req_post(req, ev);
1858 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1859 DCERPC_PKT_BIND_ACK, state->rpc_call_id);
1860 if (tevent_req_nomem(subreq, req)) {
1861 return tevent_req_post(req, ev);
1863 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1867 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1869 struct tevent_req *req = tevent_req_callback_data(
1870 subreq, struct tevent_req);
1871 struct rpc_pipe_bind_state *state = tevent_req_data(
1872 req, struct rpc_pipe_bind_state);
1873 struct pipe_auth_data *pauth = state->cli->auth;
1874 struct gensec_security *gensec_security;
1875 struct ncacn_packet *pkt = NULL;
1876 struct dcerpc_auth auth;
1877 DATA_BLOB auth_token = { .data = NULL };
1880 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1881 TALLOC_FREE(subreq);
1882 if (tevent_req_nterror(req, status)) {
1883 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1884 rpccli_pipe_txt(talloc_tos(), state->cli),
1885 nt_errstr(status)));
1890 tevent_req_done(req);
1894 if (!check_bind_response(&pkt->u.bind_ack, state->cli)) {
1895 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1896 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1900 if (pkt->ptype == DCERPC_PKT_BIND_ACK) {
1901 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
1902 if (pauth->client_hdr_signing) {
1903 pauth->hdr_signing = true;
1908 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1910 if (pauth->auth_type == DCERPC_AUTH_TYPE_NONE) {
1911 /* Bind complete. */
1912 tevent_req_done(req);
1916 if (pkt->auth_length == 0) {
1917 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1921 /* get auth credentials */
1922 status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
1923 &pkt->u.bind_ack.auth_info,
1925 if (tevent_req_nterror(req, status)) {
1926 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1927 nt_errstr(status)));
1931 if (auth.auth_type != pauth->auth_type) {
1932 DBG_ERR("Auth type %u mismatch expected %u.\n",
1933 auth.auth_type, pauth->auth_type);
1934 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1938 if (auth.auth_level != pauth->auth_level) {
1939 DBG_ERR("Auth level %u mismatch expected %u.\n",
1940 auth.auth_level, pauth->auth_level);
1941 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1945 if (auth.auth_context_id != pauth->auth_context_id) {
1946 DBG_ERR("Auth context id %"PRIu32" mismatch "
1947 "expected %"PRIu32".\n",
1948 auth.auth_context_id,
1949 pauth->auth_context_id);
1950 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1955 * For authenticated binds we may need to do 3 or 4 leg binds.
1958 if (pauth->auth_type == DCERPC_AUTH_TYPE_NONE) {
1959 /* Bind complete. */
1960 tevent_req_done(req);
1964 gensec_security = pauth->auth_ctx;
1966 status = gensec_update(gensec_security, state,
1967 auth.credentials, &auth_token);
1968 if (NT_STATUS_EQUAL(status,
1969 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1970 status = rpc_bind_next_send(req, state,
1972 } else if (NT_STATUS_IS_OK(status)) {
1973 if (pauth->hdr_signing) {
1974 gensec_want_feature(gensec_security,
1975 GENSEC_FEATURE_SIGN_PKT_HEADER);
1978 if (auth_token.length == 0) {
1979 /* Bind complete. */
1980 tevent_req_done(req);
1983 status = rpc_bind_finish_send(req, state,
1987 if (!NT_STATUS_IS_OK(status)) {
1988 tevent_req_nterror(req, status);
1993 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1994 struct rpc_pipe_bind_state *state,
1995 DATA_BLOB *auth_token)
1997 struct pipe_auth_data *auth = state->cli->auth;
1998 struct tevent_req *subreq;
2001 /* Now prepare the alter context pdu. */
2002 data_blob_free(&state->rpc_out);
2004 status = create_rpc_alter_context(state, auth,
2006 &state->cli->abstract_syntax,
2007 &state->cli->transfer_syntax,
2010 if (!NT_STATUS_IS_OK(status)) {
2014 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2015 &state->rpc_out, DCERPC_PKT_ALTER_RESP,
2016 state->rpc_call_id);
2017 if (subreq == NULL) {
2018 return NT_STATUS_NO_MEMORY;
2020 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2021 return NT_STATUS_OK;
2024 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2025 struct rpc_pipe_bind_state *state,
2026 DATA_BLOB *auth_token)
2028 struct pipe_auth_data *auth = state->cli->auth;
2029 struct tevent_req *subreq;
2032 state->auth3 = true;
2034 /* Now prepare the auth3 context pdu. */
2035 data_blob_free(&state->rpc_out);
2037 status = create_rpc_bind_auth3(state, state->cli, auth,
2041 if (!NT_STATUS_IS_OK(status)) {
2045 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2046 &state->rpc_out, DCERPC_PKT_AUTH3,
2047 state->rpc_call_id);
2048 if (subreq == NULL) {
2049 return NT_STATUS_NO_MEMORY;
2051 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2052 return NT_STATUS_OK;
2055 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2057 return tevent_req_simple_recv_ntstatus(req);
2060 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2061 struct pipe_auth_data *auth)
2063 TALLOC_CTX *frame = talloc_stackframe();
2064 struct tevent_context *ev;
2065 struct tevent_req *req;
2066 NTSTATUS status = NT_STATUS_OK;
2068 ev = samba_tevent_context_init(frame);
2070 status = NT_STATUS_NO_MEMORY;
2074 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2076 status = NT_STATUS_NO_MEMORY;
2080 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2084 status = rpc_pipe_bind_recv(req);
2090 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2092 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2093 unsigned int timeout)
2095 if (rpc_cli == NULL) {
2096 return RPCCLI_DEFAULT_TIMEOUT;
2099 if (rpc_cli->binding_handle == NULL) {
2100 return RPCCLI_DEFAULT_TIMEOUT;
2103 return dcerpc_binding_handle_set_timeout(rpc_cli->binding_handle,
2107 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2109 if (rpc_cli == NULL) {
2113 if (rpc_cli->binding_handle == NULL) {
2117 return dcerpc_binding_handle_is_connected(rpc_cli->binding_handle);
2120 struct rpccli_bh_state {
2121 struct rpc_pipe_client *rpc_cli;
2124 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2126 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2127 struct rpccli_bh_state);
2128 struct rpc_cli_transport *transport = hs->rpc_cli->transport;
2130 if (transport == NULL) {
2134 if (transport->is_connected == NULL) {
2138 return transport->is_connected(transport->priv);
2141 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2144 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2145 struct rpccli_bh_state);
2146 struct rpc_cli_transport *transport = hs->rpc_cli->transport;
2149 if (transport == NULL) {
2150 return RPCCLI_DEFAULT_TIMEOUT;
2153 if (transport->set_timeout == NULL) {
2154 return RPCCLI_DEFAULT_TIMEOUT;
2157 old = transport->set_timeout(transport->priv, timeout);
2159 return RPCCLI_DEFAULT_TIMEOUT;
2165 static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
2166 enum dcerpc_AuthType *auth_type,
2167 enum dcerpc_AuthLevel *auth_level)
2169 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2170 struct rpccli_bh_state);
2172 if (hs->rpc_cli == NULL) {
2176 if (hs->rpc_cli->auth == NULL) {
2180 *auth_type = hs->rpc_cli->auth->auth_type;
2181 *auth_level = hs->rpc_cli->auth->auth_level;
2184 struct rpccli_bh_raw_call_state {
2190 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2192 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2193 struct tevent_context *ev,
2194 struct dcerpc_binding_handle *h,
2195 const struct GUID *object,
2198 const uint8_t *in_data,
2201 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2202 struct rpccli_bh_state);
2203 struct tevent_req *req;
2204 struct rpccli_bh_raw_call_state *state;
2206 struct tevent_req *subreq;
2208 req = tevent_req_create(mem_ctx, &state,
2209 struct rpccli_bh_raw_call_state);
2213 state->in_data.data = discard_const_p(uint8_t, in_data);
2214 state->in_data.length = in_length;
2216 ok = rpccli_bh_is_connected(h);
2218 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2219 return tevent_req_post(req, ev);
2222 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2223 opnum, object, &state->in_data);
2224 if (tevent_req_nomem(subreq, req)) {
2225 return tevent_req_post(req, ev);
2227 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2232 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2234 struct tevent_req *req =
2235 tevent_req_callback_data(subreq,
2237 struct rpccli_bh_raw_call_state *state =
2238 tevent_req_data(req,
2239 struct rpccli_bh_raw_call_state);
2242 state->out_flags = 0;
2244 /* TODO: support bigendian responses */
2246 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2247 TALLOC_FREE(subreq);
2248 if (tevent_req_nterror(req, status)) {
2252 tevent_req_done(req);
2255 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2256 TALLOC_CTX *mem_ctx,
2259 uint32_t *out_flags)
2261 struct rpccli_bh_raw_call_state *state =
2262 tevent_req_data(req,
2263 struct rpccli_bh_raw_call_state);
2266 if (tevent_req_is_nterror(req, &status)) {
2267 tevent_req_received(req);
2271 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2272 *out_length = state->out_data.length;
2273 *out_flags = state->out_flags;
2274 tevent_req_received(req);
2275 return NT_STATUS_OK;
2278 struct rpccli_bh_disconnect_state {
2282 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2283 struct tevent_context *ev,
2284 struct dcerpc_binding_handle *h)
2286 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2287 struct rpccli_bh_state);
2288 struct tevent_req *req;
2289 struct rpccli_bh_disconnect_state *state;
2292 req = tevent_req_create(mem_ctx, &state,
2293 struct rpccli_bh_disconnect_state);
2298 ok = rpccli_bh_is_connected(h);
2300 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2301 return tevent_req_post(req, ev);
2305 * TODO: do a real async disconnect ...
2307 * For now we do it sync...
2309 TALLOC_FREE(hs->rpc_cli->transport);
2312 tevent_req_done(req);
2313 return tevent_req_post(req, ev);
2316 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2318 return tevent_req_simple_recv_ntstatus(req);
2321 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2326 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2327 ndr_flags_type ndr_flags,
2328 const void *_struct_ptr,
2329 const struct ndr_interface_call *call)
2331 void *struct_ptr = discard_const(_struct_ptr);
2333 if (DEBUGLEVEL < 10) {
2337 if (ndr_flags & NDR_IN) {
2338 ndr_print_function_debug(call->ndr_print,
2343 if (ndr_flags & NDR_OUT) {
2344 ndr_print_function_debug(call->ndr_print,
2351 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2353 .is_connected = rpccli_bh_is_connected,
2354 .set_timeout = rpccli_bh_set_timeout,
2355 .auth_info = rpccli_bh_auth_info,
2356 .raw_call_send = rpccli_bh_raw_call_send,
2357 .raw_call_recv = rpccli_bh_raw_call_recv,
2358 .disconnect_send = rpccli_bh_disconnect_send,
2359 .disconnect_recv = rpccli_bh_disconnect_recv,
2361 .ref_alloc = rpccli_bh_ref_alloc,
2362 .do_ndr_print = rpccli_bh_do_ndr_print,
2365 /* initialise a rpc_pipe_client binding handle */
2366 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
2367 const struct GUID *object,
2368 const struct ndr_interface_table *table)
2370 struct dcerpc_binding_handle *h;
2371 struct rpccli_bh_state *hs;
2373 h = dcerpc_binding_handle_create(c,
2378 struct rpccli_bh_state,
2388 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2389 struct pipe_auth_data **presult)
2391 struct pipe_auth_data *result;
2392 struct auth_generic_state *auth_generic_ctx;
2395 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2396 if (result == NULL) {
2397 return NT_STATUS_NO_MEMORY;
2400 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2401 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2402 result->auth_context_id = 0;
2404 status = auth_generic_client_prepare(result,
2406 if (!NT_STATUS_IS_OK(status)) {
2407 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2408 nt_errstr(status)));
2411 status = auth_generic_set_username(auth_generic_ctx, "");
2412 if (!NT_STATUS_IS_OK(status)) {
2413 DEBUG(1, ("Failed to set username: %s\n",
2414 nt_errstr(status)));
2417 status = auth_generic_set_domain(auth_generic_ctx, "");
2418 if (!NT_STATUS_IS_OK(status)) {
2419 DEBUG(1, ("Failed to set domain: %s\n",
2420 nt_errstr(status)));
2424 status = gensec_set_credentials(auth_generic_ctx->gensec_security,
2425 auth_generic_ctx->credentials);
2426 if (!NT_STATUS_IS_OK(status)) {
2427 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2428 nt_errstr(status)));
2431 talloc_unlink(auth_generic_ctx, auth_generic_ctx->credentials);
2432 auth_generic_ctx->credentials = NULL;
2434 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2435 talloc_free(auth_generic_ctx);
2437 return NT_STATUS_OK;
2440 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2441 enum dcerpc_AuthType auth_type,
2442 enum dcerpc_AuthLevel auth_level,
2444 const char *target_service,
2446 const char *username,
2447 const char *password,
2448 enum credentials_use_kerberos use_kerberos,
2449 struct netlogon_creds_CredentialState *creds,
2450 struct pipe_auth_data **presult)
2452 struct auth_generic_state *auth_generic_ctx;
2453 struct pipe_auth_data *result;
2456 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2457 if (result == NULL) {
2458 return NT_STATUS_NO_MEMORY;
2461 result->auth_type = auth_type;
2462 result->auth_level = auth_level;
2463 result->auth_context_id = 1;
2465 status = auth_generic_client_prepare(result,
2467 if (!NT_STATUS_IS_OK(status)) {
2471 status = auth_generic_set_username(auth_generic_ctx, username);
2472 if (!NT_STATUS_IS_OK(status)) {
2476 status = auth_generic_set_domain(auth_generic_ctx, domain);
2477 if (!NT_STATUS_IS_OK(status)) {
2481 status = auth_generic_set_password(auth_generic_ctx, password);
2482 if (!NT_STATUS_IS_OK(status)) {
2486 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2487 if (!NT_STATUS_IS_OK(status)) {
2491 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2492 if (!NT_STATUS_IS_OK(status)) {
2496 cli_credentials_set_kerberos_state(auth_generic_ctx->credentials,
2499 cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2501 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2502 if (!NT_STATUS_IS_OK(status)) {
2506 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2507 talloc_free(auth_generic_ctx);
2509 return NT_STATUS_OK;
2512 TALLOC_FREE(result);
2516 /* This routine steals the creds pointer that is passed in */
2517 static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx,
2518 enum dcerpc_AuthType auth_type,
2519 enum dcerpc_AuthLevel auth_level,
2521 const char *target_service,
2522 struct cli_credentials *creds,
2523 struct pipe_auth_data **presult)
2525 struct auth_generic_state *auth_generic_ctx;
2526 struct pipe_auth_data *result;
2529 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2530 if (result == NULL) {
2531 return NT_STATUS_NO_MEMORY;
2534 result->auth_type = auth_type;
2535 result->auth_level = auth_level;
2536 result->auth_context_id = 1;
2538 status = auth_generic_client_prepare(result,
2540 if (!NT_STATUS_IS_OK(status)) {
2544 status = auth_generic_set_creds(auth_generic_ctx, creds);
2545 if (!NT_STATUS_IS_OK(status)) {
2549 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2550 if (!NT_STATUS_IS_OK(status)) {
2554 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2555 if (!NT_STATUS_IS_OK(status)) {
2559 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2560 if (!NT_STATUS_IS_OK(status)) {
2564 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2565 talloc_free(auth_generic_ctx);
2567 return NT_STATUS_OK;
2570 TALLOC_FREE(result);
2574 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2575 struct pipe_auth_data **presult)
2577 return rpccli_generic_bind_data(mem_ctx,
2578 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
2579 DCERPC_AUTH_LEVEL_CONNECT,
2581 "host", /* target_service */
2582 NAME_NT_AUTHORITY, /* domain */
2584 NULL, /* password */
2585 CRED_USE_KERBEROS_DISABLED,
2586 NULL, /* netlogon_creds_CredentialState */
2591 * Create an rpc pipe client struct, connecting to a tcp port.
2593 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2594 const struct sockaddr_storage *ss_addr,
2596 const struct ndr_interface_table *table,
2597 struct rpc_pipe_client **presult)
2599 struct rpc_pipe_client *result;
2600 struct sockaddr_storage addr;
2604 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2605 if (result == NULL) {
2606 return NT_STATUS_NO_MEMORY;
2609 result->abstract_syntax = table->syntax_id;
2610 result->transfer_syntax = ndr_transfer_syntax_ndr;
2612 result->desthost = talloc_strdup(result, host);
2613 if (result->desthost == NULL) {
2614 status = NT_STATUS_NO_MEMORY;
2618 result->srv_name_slash = talloc_asprintf_strupper_m(
2619 result, "\\\\%s", result->desthost);
2620 if (result->srv_name_slash == NULL) {
2621 status = NT_STATUS_NO_MEMORY;
2625 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2627 if (ss_addr == NULL) {
2628 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2629 status = NT_STATUS_NOT_FOUND;
2636 status = open_socket_out(&addr, port, 60*1000, &fd);
2637 if (!NT_STATUS_IS_OK(status)) {
2640 set_socket_options(fd, lp_socket_options());
2642 status = rpc_transport_sock_init(result, fd, &result->transport);
2643 if (!NT_STATUS_IS_OK(status)) {
2648 result->transport->transport = NCACN_IP_TCP;
2650 result->binding_handle = rpccli_bh_create(result, NULL, table);
2651 if (result->binding_handle == NULL) {
2652 TALLOC_FREE(result);
2653 return NT_STATUS_NO_MEMORY;
2657 return NT_STATUS_OK;
2660 TALLOC_FREE(result);
2664 static NTSTATUS rpccli_epm_map_binding(
2665 struct dcerpc_binding_handle *epm_connection,
2666 struct dcerpc_binding *binding,
2667 TALLOC_CTX *mem_ctx,
2670 TALLOC_CTX *frame = talloc_stackframe();
2671 enum dcerpc_transport_t transport =
2672 dcerpc_binding_get_transport(binding);
2673 enum dcerpc_transport_t res_transport;
2674 struct dcerpc_binding *res_binding = NULL;
2675 struct epm_twr_t *map_tower = NULL;
2676 struct epm_twr_p_t res_towers = { .twr = NULL };
2677 struct policy_handle *entry_handle = NULL;
2678 uint32_t num_towers = 0;
2679 const uint32_t max_towers = 1;
2680 const char *endpoint = NULL;
2685 map_tower = talloc_zero(frame, struct epm_twr_t);
2686 if (map_tower == NULL) {
2690 status = dcerpc_binding_build_tower(
2691 frame, binding, &(map_tower->tower));
2692 if (!NT_STATUS_IS_OK(status)) {
2693 DBG_DEBUG("dcerpc_binding_build_tower failed: %s\n",
2698 res_towers.twr = talloc_array(frame, struct epm_twr_t, max_towers);
2699 if (res_towers.twr == NULL) {
2703 entry_handle = talloc_zero(frame, struct policy_handle);
2704 if (entry_handle == NULL) {
2708 status = dcerpc_epm_Map(
2719 if (!NT_STATUS_IS_OK(status)) {
2720 DBG_DEBUG("dcerpc_epm_Map failed: %s\n", nt_errstr(status));
2724 if (result != EPMAPPER_STATUS_OK) {
2725 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32"\n", result);
2726 status = NT_STATUS_NOT_FOUND;
2730 if (num_towers != 1) {
2731 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32" towers\n",
2733 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2737 status = dcerpc_binding_from_tower(
2738 frame, &(res_towers.twr->tower), &res_binding);
2739 if (!NT_STATUS_IS_OK(status)) {
2740 DBG_DEBUG("dcerpc_binding_from_tower failed: %s\n",
2745 res_transport = dcerpc_binding_get_transport(res_binding);
2746 if (res_transport != transport) {
2747 DBG_DEBUG("dcerpc_epm_Map returned transport %d, "
2751 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2755 endpoint = dcerpc_binding_get_string_option(res_binding, "endpoint");
2756 if (endpoint == NULL) {
2757 DBG_DEBUG("dcerpc_epm_Map returned no endpoint\n");
2758 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2762 tmp = talloc_strdup(mem_ctx, endpoint);
2768 status = NT_STATUS_OK;
2772 status = NT_STATUS_NO_MEMORY;
2778 static NTSTATUS rpccli_epm_map_interface(
2779 struct dcerpc_binding_handle *epm_connection,
2780 enum dcerpc_transport_t transport,
2781 const struct ndr_syntax_id *iface,
2782 TALLOC_CTX *mem_ctx,
2785 struct dcerpc_binding *binding = NULL;
2786 char *endpoint = NULL;
2789 status = dcerpc_parse_binding(mem_ctx, "", &binding);
2790 if (!NT_STATUS_IS_OK(status)) {
2791 DBG_DEBUG("dcerpc_parse_binding failed: %s\n",
2796 status = dcerpc_binding_set_transport(binding, transport);
2797 if (!NT_STATUS_IS_OK(status)) {
2798 DBG_DEBUG("dcerpc_binding_set_transport failed: %s\n",
2803 status = dcerpc_binding_set_abstract_syntax(binding, iface);
2804 if (!NT_STATUS_IS_OK(status)) {
2805 DBG_DEBUG("dcerpc_binding_set_abstract_syntax failed: %s\n",
2810 status = rpccli_epm_map_binding(
2811 epm_connection, binding, mem_ctx, &endpoint);
2812 if (!NT_STATUS_IS_OK(status)) {
2813 DBG_DEBUG("rpccli_epm_map_binding failed: %s\n",
2817 *pendpoint = endpoint;
2820 TALLOC_FREE(binding);
2825 * Determine the tcp port on which a dcerpc interface is listening
2826 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2829 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2830 const struct sockaddr_storage *addr,
2831 const struct ndr_interface_table *table,
2835 struct rpc_pipe_client *epm_pipe = NULL;
2836 struct pipe_auth_data *auth = NULL;
2837 char *endpoint = NULL;
2838 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2840 if (pport == NULL) {
2841 status = NT_STATUS_INVALID_PARAMETER;
2845 if (ndr_syntax_id_equal(&table->syntax_id,
2846 &ndr_table_epmapper.syntax_id)) {
2848 status = NT_STATUS_OK;
2852 /* open the connection to the endpoint mapper */
2853 status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2854 &ndr_table_epmapper,
2857 if (!NT_STATUS_IS_OK(status)) {
2861 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2862 if (!NT_STATUS_IS_OK(status)) {
2866 status = rpc_pipe_bind(epm_pipe, auth);
2867 if (!NT_STATUS_IS_OK(status)) {
2871 status = rpccli_epm_map_interface(
2872 epm_pipe->binding_handle,
2877 if (!NT_STATUS_IS_OK(status)) {
2878 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
2883 *pport = (uint16_t)atoi(endpoint);
2886 TALLOC_FREE(tmp_ctx);
2891 * Create a rpc pipe client struct, connecting to a host via tcp.
2892 * The port is determined by asking the endpoint mapper on the given
2895 static NTSTATUS rpc_pipe_open_tcp(
2896 TALLOC_CTX *mem_ctx,
2898 const struct sockaddr_storage *addr,
2899 const struct ndr_interface_table *table,
2900 struct rpc_pipe_client **presult)
2905 status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2906 if (!NT_STATUS_IS_OK(status)) {
2910 return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2914 static NTSTATUS rpc_pipe_get_ncalrpc_name(
2915 const struct ndr_syntax_id *iface,
2916 TALLOC_CTX *mem_ctx,
2917 char **psocket_name)
2919 TALLOC_CTX *frame = talloc_stackframe();
2920 struct rpc_pipe_client *epm_pipe = NULL;
2921 struct pipe_auth_data *auth = NULL;
2922 NTSTATUS status = NT_STATUS_OK;
2925 is_epm = ndr_syntax_id_equal(iface, &ndr_table_epmapper.syntax_id);
2927 char *endpoint = talloc_strdup(mem_ctx, "EPMAPPER");
2928 if (endpoint == NULL) {
2929 status = NT_STATUS_NO_MEMORY;
2932 *psocket_name = endpoint;
2936 status = rpc_pipe_open_ncalrpc(
2937 frame, &ndr_table_epmapper, &epm_pipe);
2938 if (!NT_STATUS_IS_OK(status)) {
2939 DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
2944 status = rpccli_anon_bind_data(epm_pipe, &auth);
2945 if (!NT_STATUS_IS_OK(status)) {
2946 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
2951 status = rpc_pipe_bind(epm_pipe, auth);
2952 if (!NT_STATUS_IS_OK(status)) {
2953 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
2957 status = rpccli_epm_map_interface(
2958 epm_pipe->binding_handle,
2963 if (!NT_STATUS_IS_OK(status)) {
2964 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
2973 /********************************************************************
2974 Create a rpc pipe client struct, connecting to a unix domain socket
2975 ********************************************************************/
2976 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx,
2977 const struct ndr_interface_table *table,
2978 struct rpc_pipe_client **presult)
2980 char *socket_name = NULL;
2981 struct rpc_pipe_client *result;
2982 struct sockaddr_un addr = { .sun_family = AF_UNIX };
2983 socklen_t salen = sizeof(addr);
2988 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2989 if (result == NULL) {
2990 return NT_STATUS_NO_MEMORY;
2993 status = rpc_pipe_get_ncalrpc_name(
2994 &table->syntax_id, result, &socket_name);
2995 if (!NT_STATUS_IS_OK(status)) {
2996 DBG_DEBUG("rpc_pipe_get_ncalrpc_name failed: %s\n",
3003 sizeof(addr.sun_path),
3007 if ((pathlen < 0) || ((size_t)pathlen >= sizeof(addr.sun_path))) {
3008 DBG_DEBUG("socket_path for %s too long\n", socket_name);
3009 status = NT_STATUS_NAME_TOO_LONG;
3012 TALLOC_FREE(socket_name);
3014 result->abstract_syntax = table->syntax_id;
3015 result->transfer_syntax = ndr_transfer_syntax_ndr;
3017 result->desthost = get_myname(result);
3018 if (result->desthost == NULL) {
3019 status = NT_STATUS_NO_MEMORY;
3023 result->srv_name_slash = talloc_asprintf_strupper_m(
3024 result, "\\\\%s", result->desthost);
3025 if (result->srv_name_slash == NULL) {
3026 status = NT_STATUS_NO_MEMORY;
3030 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3032 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3034 status = map_nt_error_from_unix(errno);
3038 if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
3039 DBG_WARNING("connect(%s) failed: %s\n",
3042 status = map_nt_error_from_unix(errno);
3046 status = rpc_transport_sock_init(result, fd, &result->transport);
3047 if (!NT_STATUS_IS_OK(status)) {
3052 result->transport->transport = NCALRPC;
3054 result->binding_handle = rpccli_bh_create(result, NULL, table);
3055 if (result->binding_handle == NULL) {
3056 status = NT_STATUS_NO_MEMORY;
3061 return NT_STATUS_OK;
3067 TALLOC_FREE(result);
3071 NTSTATUS rpc_pipe_open_local_np(
3072 TALLOC_CTX *mem_ctx,
3073 const struct ndr_interface_table *table,
3074 const char *remote_client_name,
3075 const struct tsocket_address *remote_client_addr,
3076 const char *local_server_name,
3077 const struct tsocket_address *local_server_addr,
3078 const struct auth_session_info *session_info,
3079 struct rpc_pipe_client **presult)
3081 struct rpc_pipe_client *result = NULL;
3082 struct pipe_auth_data *auth = NULL;
3083 const char *pipe_name = NULL;
3084 struct tstream_context *npa_stream = NULL;
3085 NTSTATUS status = NT_STATUS_NO_MEMORY;
3088 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3089 if (result == NULL) {
3092 result->abstract_syntax = table->syntax_id;
3093 result->transfer_syntax = ndr_transfer_syntax_ndr;
3094 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3096 pipe_name = dcerpc_default_transport_endpoint(
3097 result, NCACN_NP, table);
3098 if (pipe_name == NULL) {
3099 DBG_DEBUG("dcerpc_default_transport_endpoint failed\n");
3100 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3104 if (local_server_name == NULL) {
3105 result->desthost = get_myname(result);
3107 result->desthost = talloc_strdup(result, local_server_name);
3109 if (result->desthost == NULL) {
3112 result->srv_name_slash = talloc_asprintf_strupper_m(
3113 result, "\\\\%s", result->desthost);
3114 if (result->srv_name_slash == NULL) {
3118 ret = local_np_connect(
3130 DBG_DEBUG("local_np_connect for %s and "
3131 "user %s\\%s failed: %s\n",
3133 session_info->info->domain_name,
3134 session_info->info->account_name,
3136 status = map_nt_error_from_unix(ret);
3140 status = rpc_transport_tstream_init(
3141 result, &npa_stream, &result->transport);
3142 if (!NT_STATUS_IS_OK(status)) {
3143 DBG_DEBUG("rpc_transport_tstream_init failed: %s\n",
3148 result->binding_handle = rpccli_bh_create(result, NULL, table);
3149 if (result->binding_handle == NULL) {
3150 status = NT_STATUS_NO_MEMORY;
3151 DBG_DEBUG("Failed to create binding handle.\n");
3155 status = rpccli_anon_bind_data(result, &auth);
3156 if (!NT_STATUS_IS_OK(status)) {
3157 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3162 status = rpc_pipe_bind(result, auth);
3163 if (!NT_STATUS_IS_OK(status)) {
3164 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
3169 return NT_STATUS_OK;
3172 TALLOC_FREE(result);
3176 struct rpc_pipe_client_np_ref {
3177 struct cli_state *cli;
3178 struct rpc_pipe_client *pipe;
3181 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3183 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3187 /****************************************************************************
3188 Open a named pipe over SMB to a remote server.
3190 * CAVEAT CALLER OF THIS FUNCTION:
3191 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3192 * so be sure that this function is called AFTER any structure (vs pointer)
3193 * assignment of the cli. In particular, libsmbclient does structure
3194 * assignments of cli, which invalidates the data in the returned
3195 * rpc_pipe_client if this function is called before the structure assignment
3198 ****************************************************************************/
3200 struct rpc_pipe_open_np_state {
3201 struct cli_state *cli;
3202 const struct ndr_interface_table *table;
3203 struct rpc_pipe_client *result;
3206 static void rpc_pipe_open_np_done(struct tevent_req *subreq);
3208 struct tevent_req *rpc_pipe_open_np_send(
3209 TALLOC_CTX *mem_ctx,
3210 struct tevent_context *ev,
3211 struct cli_state *cli,
3212 const struct ndr_interface_table *table)
3214 struct tevent_req *req = NULL, *subreq = NULL;
3215 struct rpc_pipe_open_np_state *state = NULL;
3216 struct rpc_pipe_client *result = NULL;
3218 req = tevent_req_create(
3219 mem_ctx, &state, struct rpc_pipe_open_np_state);
3224 state->table = table;
3226 state->result = talloc_zero(state, struct rpc_pipe_client);
3227 if (tevent_req_nomem(state->result, req)) {
3228 return tevent_req_post(req, ev);
3230 result = state->result;
3232 result->abstract_syntax = table->syntax_id;
3233 result->transfer_syntax = ndr_transfer_syntax_ndr;
3235 result->desthost = talloc_strdup(
3236 result, smbXcli_conn_remote_name(cli->conn));
3237 if (tevent_req_nomem(result->desthost, req)) {
3238 return tevent_req_post(req, ev);
3241 result->srv_name_slash = talloc_asprintf_strupper_m(
3242 result, "\\\\%s", result->desthost);
3243 if (tevent_req_nomem(result->srv_name_slash, req)) {
3244 return tevent_req_post(req, ev);
3247 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3249 subreq = rpc_transport_np_init_send(state, ev, cli, table);
3250 if (tevent_req_nomem(subreq, req)) {
3251 return tevent_req_post(req, ev);
3253 tevent_req_set_callback(subreq, rpc_pipe_open_np_done, req);
3257 static void rpc_pipe_open_np_done(struct tevent_req *subreq)
3259 struct tevent_req *req = tevent_req_callback_data(
3260 subreq, struct tevent_req);
3261 struct rpc_pipe_open_np_state *state = tevent_req_data(
3262 req, struct rpc_pipe_open_np_state);
3263 struct rpc_pipe_client *result = state->result;
3264 struct rpc_pipe_client_np_ref *np_ref = NULL;
3267 status = rpc_transport_np_init_recv(
3268 subreq, result, &result->transport);
3269 TALLOC_FREE(subreq);
3270 if (tevent_req_nterror(req, status)) {
3274 result->transport->transport = NCACN_NP;
3276 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3277 if (tevent_req_nomem(np_ref, req)) {
3280 np_ref->cli = state->cli;
3281 np_ref->pipe = result;
3283 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3284 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3286 result->binding_handle = rpccli_bh_create(result, NULL, state->table);
3287 if (tevent_req_nomem(result->binding_handle, req)) {
3291 tevent_req_done(req);
3294 NTSTATUS rpc_pipe_open_np_recv(
3295 struct tevent_req *req,
3296 TALLOC_CTX *mem_ctx,
3297 struct rpc_pipe_client **_result)
3299 struct rpc_pipe_open_np_state *state = tevent_req_data(
3300 req, struct rpc_pipe_open_np_state);
3303 if (tevent_req_is_nterror(req, &status)) {
3306 *_result = talloc_move(mem_ctx, &state->result);
3307 return NT_STATUS_OK;
3310 NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3311 const struct ndr_interface_table *table,
3312 struct rpc_pipe_client **presult)
3314 struct tevent_context *ev = NULL;
3315 struct tevent_req *req = NULL;
3316 NTSTATUS status = NT_STATUS_NO_MEMORY;
3318 ev = samba_tevent_context_init(cli);
3322 req = rpc_pipe_open_np_send(ev, ev, cli, table);
3326 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3329 status = rpc_pipe_open_np_recv(req, NULL, presult);
3336 /****************************************************************************
3337 Open a pipe to a remote server.
3338 ****************************************************************************/
3340 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3341 enum dcerpc_transport_t transport,
3342 const struct ndr_interface_table *table,
3343 const char *remote_name,
3344 const struct sockaddr_storage *remote_sockaddr,
3345 struct rpc_pipe_client **presult)
3347 switch (transport) {
3349 return rpc_pipe_open_tcp(NULL,
3354 return rpc_pipe_open_np(cli, table, presult);
3356 return NT_STATUS_NOT_IMPLEMENTED;
3360 /****************************************************************************
3361 Open a named pipe to an SMB server and bind anonymously.
3362 ****************************************************************************/
3364 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3365 enum dcerpc_transport_t transport,
3366 const struct ndr_interface_table *table,
3367 const char *remote_name,
3368 const struct sockaddr_storage *remote_sockaddr,
3369 struct rpc_pipe_client **presult)
3371 struct rpc_pipe_client *result;
3372 struct pipe_auth_data *auth;
3375 status = cli_rpc_pipe_open(cli,
3381 if (!NT_STATUS_IS_OK(status)) {
3385 status = rpccli_anon_bind_data(result, &auth);
3386 if (!NT_STATUS_IS_OK(status)) {
3387 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3388 nt_errstr(status)));
3389 TALLOC_FREE(result);
3394 * This is a bit of an abstraction violation due to the fact that an
3395 * anonymous bind on an authenticated SMB inherits the user/domain
3396 * from the enclosing SMB creds
3399 if (transport == NCACN_NP) {
3400 struct smbXcli_session *session;
3402 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
3403 session = cli->smb2.session;
3405 session = cli->smb1.session;
3408 status = smbXcli_session_application_key(session, auth,
3409 &auth->transport_session_key);
3410 if (!NT_STATUS_IS_OK(status)) {
3411 auth->transport_session_key = data_blob_null;
3415 status = rpc_pipe_bind(result, auth);
3416 if (!NT_STATUS_IS_OK(status)) {
3418 if (ndr_syntax_id_equal(&table->syntax_id,
3419 &ndr_table_dssetup.syntax_id)) {
3420 /* non AD domains just don't have this pipe, avoid
3421 * level 0 statement in that case - gd */
3424 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3425 "%s failed with error %s\n",
3427 nt_errstr(status) ));
3428 TALLOC_FREE(result);
3432 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3433 "%s and bound anonymously.\n",
3438 return NT_STATUS_OK;
3441 /****************************************************************************
3442 ****************************************************************************/
3444 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3445 const struct ndr_interface_table *table,
3446 struct rpc_pipe_client **presult)
3448 const char *remote_name = smbXcli_conn_remote_name(cli->conn);
3449 const struct sockaddr_storage *remote_sockaddr =
3450 smbXcli_conn_remote_sockaddr(cli->conn);
3452 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3459 /****************************************************************************
3460 Open a named pipe to an SMB server and bind using the mech specified
3462 This routine references the creds pointer that is passed in
3463 ****************************************************************************/
3465 NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
3466 const struct ndr_interface_table *table,
3467 enum dcerpc_transport_t transport,
3468 enum dcerpc_AuthType auth_type,
3469 enum dcerpc_AuthLevel auth_level,
3471 const struct sockaddr_storage *remote_sockaddr,
3472 struct cli_credentials *creds,
3473 struct rpc_pipe_client **presult)
3475 struct rpc_pipe_client *result;
3476 struct pipe_auth_data *auth = NULL;
3477 const char *target_service = table->authservices->names[0];
3480 status = cli_rpc_pipe_open(cli,
3486 if (!NT_STATUS_IS_OK(status)) {
3490 status = rpccli_generic_bind_data_from_creds(result,
3491 auth_type, auth_level,
3492 server, target_service,
3495 if (!NT_STATUS_IS_OK(status)) {
3496 DBG_ERR("rpccli_generic_bind_data_from_creds returned %s\n",
3501 status = rpc_pipe_bind(result, auth);
3502 if (!NT_STATUS_IS_OK(status)) {
3503 DBG_ERR("cli_rpc_pipe_bind failed with error %s\n",
3508 DBG_DEBUG("opened pipe %s to machine %s and bound as user %s.\n",
3511 cli_credentials_get_unparsed_name(creds, talloc_tos()));
3514 return NT_STATUS_OK;
3518 TALLOC_FREE(result);
3522 NTSTATUS cli_rpc_pipe_open_bind_schannel(
3523 struct cli_state *cli,
3524 const struct ndr_interface_table *table,
3525 enum dcerpc_transport_t transport,
3526 struct netlogon_creds_cli_context *netlogon_creds,
3527 const char *remote_name,
3528 const struct sockaddr_storage *remote_sockaddr,
3529 struct rpc_pipe_client **_rpccli)
3531 struct rpc_pipe_client *rpccli;
3532 struct pipe_auth_data *rpcauth;
3533 const char *target_service = table->authservices->names[0];
3534 struct cli_credentials *cli_creds;
3535 enum dcerpc_AuthLevel auth_level;
3538 status = cli_rpc_pipe_open(cli,
3544 if (!NT_STATUS_IS_OK(status)) {
3548 auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
3550 status = netlogon_creds_bind_cli_credentials(
3551 netlogon_creds, rpccli, &cli_creds);
3552 if (!NT_STATUS_IS_OK(status)) {
3553 DBG_DEBUG("netlogon_creds_bind_cli_credentials failed: %s\n",
3555 TALLOC_FREE(rpccli);
3559 status = rpccli_generic_bind_data_from_creds(rpccli,
3560 DCERPC_AUTH_TYPE_SCHANNEL,
3566 if (!NT_STATUS_IS_OK(status)) {
3567 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
3568 nt_errstr(status)));
3569 TALLOC_FREE(rpccli);
3573 status = rpc_pipe_bind(rpccli, rpcauth);
3575 /* No TALLOC_FREE, gensec takes references */
3576 talloc_unlink(rpccli, cli_creds);
3579 if (!NT_STATUS_IS_OK(status)) {
3580 DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
3582 TALLOC_FREE(rpccli);
3588 return NT_STATUS_OK;
3591 NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
3592 const struct ndr_interface_table *table,
3593 enum dcerpc_transport_t transport,
3594 struct netlogon_creds_cli_context *netlogon_creds,
3595 const char *remote_name,
3596 const struct sockaddr_storage *remote_sockaddr,
3597 struct rpc_pipe_client **_rpccli)
3599 TALLOC_CTX *frame = talloc_stackframe();
3600 struct rpc_pipe_client *rpccli;
3601 struct netlogon_creds_cli_lck *lck;
3604 status = netlogon_creds_cli_lck(
3605 netlogon_creds, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE,
3607 if (!NT_STATUS_IS_OK(status)) {
3608 DBG_WARNING("netlogon_creds_cli_lck returned %s\n",
3614 status = cli_rpc_pipe_open_bind_schannel(cli,
3621 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3622 netlogon_creds_cli_delete_lck(netlogon_creds);
3624 if (!NT_STATUS_IS_OK(status)) {
3625 DBG_DEBUG("cli_rpc_pipe_open_bind_schannel failed: %s\n",
3631 if (ndr_syntax_id_equal(&table->syntax_id,
3632 &ndr_table_netlogon.syntax_id)) {
3633 status = netlogon_creds_cli_check(netlogon_creds,
3634 rpccli->binding_handle,
3636 if (!NT_STATUS_IS_OK(status)) {
3637 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3638 nt_errstr(status)));
3644 DBG_DEBUG("opened pipe %s to machine %s with key %s "
3645 "and bound using schannel.\n",
3646 table->name, rpccli->desthost,
3647 netlogon_creds_cli_debug_string(netlogon_creds, lck));
3652 return NT_STATUS_OK;
3655 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3656 struct rpc_pipe_client *cli,
3657 DATA_BLOB *session_key)
3660 struct pipe_auth_data *a;
3661 struct gensec_security *gensec_security;
3662 DATA_BLOB sk = { .data = NULL };
3663 bool make_dup = false;
3665 if (!session_key || !cli) {
3666 return NT_STATUS_INVALID_PARAMETER;
3672 return NT_STATUS_INVALID_PARAMETER;
3675 switch (cli->auth->auth_type) {
3676 case DCERPC_AUTH_TYPE_NONE:
3677 sk = data_blob_const(a->transport_session_key.data,
3678 a->transport_session_key.length);
3682 gensec_security = a->auth_ctx;
3683 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3684 if (!NT_STATUS_IS_OK(status)) {
3692 return NT_STATUS_NO_USER_SESSION_KEY;
3696 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3701 return NT_STATUS_OK;