2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../librpc/gen_ndr/ndr_dssetup.h"
24 #include "../librpc/gen_ndr/ndr_netlogon.h"
25 #include "../libcli/auth/schannel.h"
26 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "ntlmssp_wrap.h"
30 #include "rpc_client/cli_netlogon.h"
31 #include "librpc/gen_ndr/ndr_dcerpc.h"
32 #include "librpc/rpc/dcerpc.h"
33 #include "librpc/rpc/dcerpc_gssapi.h"
34 #include "librpc/rpc/dcerpc_spnego.h"
37 #define DBGC_CLASS DBGC_RPC_CLI
39 /********************************************************************
40 Pipe description for a DEBUG
41 ********************************************************************/
42 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
43 struct rpc_pipe_client *cli)
45 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
52 /********************************************************************
54 ********************************************************************/
56 static uint32 get_rpc_call_id(void)
58 static uint32 call_id = 0;
62 /*******************************************************************
63 Use SMBreadX to get rest of one fragment's worth of rpc data.
64 Reads the whole size or give an error message
65 ********************************************************************/
67 struct rpc_read_state {
68 struct event_context *ev;
69 struct rpc_cli_transport *transport;
75 static void rpc_read_done(struct tevent_req *subreq);
77 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
78 struct event_context *ev,
79 struct rpc_cli_transport *transport,
80 uint8_t *data, size_t size)
82 struct tevent_req *req, *subreq;
83 struct rpc_read_state *state;
85 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
90 state->transport = transport;
95 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
97 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
102 tevent_req_set_callback(subreq, rpc_read_done, req);
110 static void rpc_read_done(struct tevent_req *subreq)
112 struct tevent_req *req = tevent_req_callback_data(
113 subreq, struct tevent_req);
114 struct rpc_read_state *state = tevent_req_data(
115 req, struct rpc_read_state);
119 status = state->transport->read_recv(subreq, &received);
121 if (!NT_STATUS_IS_OK(status)) {
122 tevent_req_nterror(req, status);
126 state->num_read += received;
127 if (state->num_read == state->size) {
128 tevent_req_done(req);
132 subreq = state->transport->read_send(state, state->ev,
133 state->data + state->num_read,
134 state->size - state->num_read,
135 state->transport->priv);
136 if (tevent_req_nomem(subreq, req)) {
139 tevent_req_set_callback(subreq, rpc_read_done, req);
142 static NTSTATUS rpc_read_recv(struct tevent_req *req)
144 return tevent_req_simple_recv_ntstatus(req);
147 struct rpc_write_state {
148 struct event_context *ev;
149 struct rpc_cli_transport *transport;
155 static void rpc_write_done(struct tevent_req *subreq);
157 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
158 struct event_context *ev,
159 struct rpc_cli_transport *transport,
160 const uint8_t *data, size_t size)
162 struct tevent_req *req, *subreq;
163 struct rpc_write_state *state;
165 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
170 state->transport = transport;
173 state->num_written = 0;
175 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
177 subreq = transport->write_send(state, ev, data, size, transport->priv);
178 if (subreq == NULL) {
181 tevent_req_set_callback(subreq, rpc_write_done, req);
188 static void rpc_write_done(struct tevent_req *subreq)
190 struct tevent_req *req = tevent_req_callback_data(
191 subreq, struct tevent_req);
192 struct rpc_write_state *state = tevent_req_data(
193 req, struct rpc_write_state);
197 status = state->transport->write_recv(subreq, &written);
199 if (!NT_STATUS_IS_OK(status)) {
200 tevent_req_nterror(req, status);
204 state->num_written += written;
206 if (state->num_written == state->size) {
207 tevent_req_done(req);
211 subreq = state->transport->write_send(state, state->ev,
212 state->data + state->num_written,
213 state->size - state->num_written,
214 state->transport->priv);
215 if (tevent_req_nomem(subreq, req)) {
218 tevent_req_set_callback(subreq, rpc_write_done, req);
221 static NTSTATUS rpc_write_recv(struct tevent_req *req)
223 return tevent_req_simple_recv_ntstatus(req);
227 /****************************************************************************
228 Try and get a PDU's worth of data from current_pdu. If not, then read more
230 ****************************************************************************/
232 struct get_complete_frag_state {
233 struct event_context *ev;
234 struct rpc_pipe_client *cli;
239 static void get_complete_frag_got_header(struct tevent_req *subreq);
240 static void get_complete_frag_got_rest(struct tevent_req *subreq);
242 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
243 struct event_context *ev,
244 struct rpc_pipe_client *cli,
247 struct tevent_req *req, *subreq;
248 struct get_complete_frag_state *state;
252 req = tevent_req_create(mem_ctx, &state,
253 struct get_complete_frag_state);
259 state->frag_len = RPC_HEADER_LEN;
262 received = pdu->length;
263 if (received < RPC_HEADER_LEN) {
264 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
265 status = NT_STATUS_NO_MEMORY;
268 subreq = rpc_read_send(state, state->ev,
269 state->cli->transport,
270 pdu->data + received,
271 RPC_HEADER_LEN - received);
272 if (subreq == NULL) {
273 status = NT_STATUS_NO_MEMORY;
276 tevent_req_set_callback(subreq, get_complete_frag_got_header,
281 state->frag_len = dcerpc_get_frag_length(pdu);
284 * Ensure we have frag_len bytes of data.
286 if (received < state->frag_len) {
287 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
288 status = NT_STATUS_NO_MEMORY;
291 subreq = rpc_read_send(state, state->ev,
292 state->cli->transport,
293 pdu->data + received,
294 state->frag_len - received);
295 if (subreq == NULL) {
296 status = NT_STATUS_NO_MEMORY;
299 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
304 status = NT_STATUS_OK;
306 if (NT_STATUS_IS_OK(status)) {
307 tevent_req_done(req);
309 tevent_req_nterror(req, status);
311 return tevent_req_post(req, ev);
314 static void get_complete_frag_got_header(struct tevent_req *subreq)
316 struct tevent_req *req = tevent_req_callback_data(
317 subreq, struct tevent_req);
318 struct get_complete_frag_state *state = tevent_req_data(
319 req, struct get_complete_frag_state);
322 status = rpc_read_recv(subreq);
324 if (!NT_STATUS_IS_OK(status)) {
325 tevent_req_nterror(req, status);
329 state->frag_len = dcerpc_get_frag_length(state->pdu);
331 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
332 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
337 * We're here in this piece of code because we've read exactly
338 * RPC_HEADER_LEN bytes into state->pdu.
341 subreq = rpc_read_send(state, state->ev, state->cli->transport,
342 state->pdu->data + RPC_HEADER_LEN,
343 state->frag_len - RPC_HEADER_LEN);
344 if (tevent_req_nomem(subreq, req)) {
347 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
350 static void get_complete_frag_got_rest(struct tevent_req *subreq)
352 struct tevent_req *req = tevent_req_callback_data(
353 subreq, struct tevent_req);
356 status = rpc_read_recv(subreq);
358 if (!NT_STATUS_IS_OK(status)) {
359 tevent_req_nterror(req, status);
362 tevent_req_done(req);
365 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
367 return tevent_req_simple_recv_ntstatus(req);
370 /****************************************************************************
371 Do basic authentication checks on an incoming pdu.
372 ****************************************************************************/
374 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
375 struct rpc_pipe_client *cli,
376 struct ncacn_packet *pkt,
378 uint8_t expected_pkt_type,
380 DATA_BLOB *reply_pdu)
382 NTSTATUS ret = NT_STATUS_OK;
385 ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
386 if (!NT_STATUS_IS_OK(ret)) {
390 if (pdu->length != pkt->frag_length) {
391 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
392 (unsigned int)pdu->length,
393 (unsigned int)pkt->frag_length));
394 return NT_STATUS_INVALID_PARAMETER;
398 * Point the return values at the real data including the RPC
399 * header. Just in case the caller wants it.
403 /* Ensure we have the correct type. */
404 switch (pkt->ptype) {
405 case DCERPC_PKT_ALTER_RESP:
406 case DCERPC_PKT_BIND_ACK:
408 /* Alter context and bind ack share the same packet definitions. */
412 case DCERPC_PKT_RESPONSE:
414 /* Here's where we deal with incoming sign/seal. */
415 ret = dcerpc_check_auth(cli->auth, pkt,
416 &pkt->u.response.stub_and_verifier,
417 DCERPC_RESPONSE_LENGTH,
419 if (!NT_STATUS_IS_OK(ret)) {
423 if (pdu->length < DCERPC_RESPONSE_LENGTH + pad_len) {
424 return NT_STATUS_BUFFER_TOO_SMALL;
427 /* Point the return values at the NDR data. */
428 rdata->data = pdu->data + DCERPC_RESPONSE_LENGTH;
430 if (pkt->auth_length) {
431 /* We've already done integer wrap tests in
432 * dcerpc_check_auth(). */
433 rdata->length = pdu->length
434 - DCERPC_RESPONSE_LENGTH
436 - DCERPC_AUTH_TRAILER_LENGTH
439 rdata->length = pdu->length - DCERPC_RESPONSE_LENGTH;
442 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
443 (long unsigned int)pdu->length,
444 (long unsigned int)rdata->length,
445 (unsigned int)pad_len));
448 * If this is the first reply, and the allocation hint is
449 * reasonable, try and set up the reply_pdu DATA_BLOB to the
453 if ((reply_pdu->length == 0) &&
454 pkt->u.response.alloc_hint &&
455 (pkt->u.response.alloc_hint < 15*1024*1024)) {
456 if (!data_blob_realloc(mem_ctx, reply_pdu,
457 pkt->u.response.alloc_hint)) {
458 DEBUG(0, ("reply alloc hint %d too "
459 "large to allocate\n",
460 (int)pkt->u.response.alloc_hint));
461 return NT_STATUS_NO_MEMORY;
467 case DCERPC_PKT_BIND_NAK:
468 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
469 "received from %s!\n",
470 rpccli_pipe_txt(talloc_tos(), cli)));
471 /* Use this for now... */
472 return NT_STATUS_NETWORK_ACCESS_DENIED;
474 case DCERPC_PKT_FAULT:
476 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
477 "code %s received from %s!\n",
478 dcerpc_errstr(talloc_tos(),
479 pkt->u.fault.status),
480 rpccli_pipe_txt(talloc_tos(), cli)));
482 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
483 return NT_STATUS_UNSUCCESSFUL;
485 return NT_STATUS(pkt->u.fault.status);
489 DEBUG(0, ("Unknown packet type %u received from %s!\n",
490 (unsigned int)pkt->ptype,
491 rpccli_pipe_txt(talloc_tos(), cli)));
492 return NT_STATUS_INVALID_INFO_CLASS;
495 if (pkt->ptype != expected_pkt_type) {
496 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
497 "got an unexpected RPC packet type - %u, not %u\n",
498 rpccli_pipe_txt(talloc_tos(), cli),
501 return NT_STATUS_INVALID_INFO_CLASS;
504 /* Do this just before return - we don't want to modify any rpc header
505 data before now as we may have needed to do cryptographic actions on
508 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
509 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
510 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
511 "setting fragment first/last ON.\n"));
512 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
513 DCERPC_PFC_FLAG_LAST;
519 /****************************************************************************
520 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
521 ****************************************************************************/
523 struct cli_api_pipe_state {
524 struct event_context *ev;
525 struct rpc_cli_transport *transport;
530 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
531 static void cli_api_pipe_write_done(struct tevent_req *subreq);
532 static void cli_api_pipe_read_done(struct tevent_req *subreq);
534 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
535 struct event_context *ev,
536 struct rpc_cli_transport *transport,
537 uint8_t *data, size_t data_len,
538 uint32_t max_rdata_len)
540 struct tevent_req *req, *subreq;
541 struct cli_api_pipe_state *state;
544 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
549 state->transport = transport;
551 if (max_rdata_len < RPC_HEADER_LEN) {
553 * For a RPC reply we always need at least RPC_HEADER_LEN
554 * bytes. We check this here because we will receive
555 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
557 status = NT_STATUS_INVALID_PARAMETER;
561 if (transport->trans_send != NULL) {
562 subreq = transport->trans_send(state, ev, data, data_len,
563 max_rdata_len, transport->priv);
564 if (subreq == NULL) {
567 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
572 * If the transport does not provide a "trans" routine, i.e. for
573 * example the ncacn_ip_tcp transport, do the write/read step here.
576 subreq = rpc_write_send(state, ev, transport, data, data_len);
577 if (subreq == NULL) {
580 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
584 tevent_req_nterror(req, status);
585 return tevent_req_post(req, ev);
591 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
593 struct tevent_req *req = tevent_req_callback_data(
594 subreq, struct tevent_req);
595 struct cli_api_pipe_state *state = tevent_req_data(
596 req, struct cli_api_pipe_state);
599 status = state->transport->trans_recv(subreq, state, &state->rdata,
602 if (!NT_STATUS_IS_OK(status)) {
603 tevent_req_nterror(req, status);
606 tevent_req_done(req);
609 static void cli_api_pipe_write_done(struct tevent_req *subreq)
611 struct tevent_req *req = tevent_req_callback_data(
612 subreq, struct tevent_req);
613 struct cli_api_pipe_state *state = tevent_req_data(
614 req, struct cli_api_pipe_state);
617 status = rpc_write_recv(subreq);
619 if (!NT_STATUS_IS_OK(status)) {
620 tevent_req_nterror(req, status);
624 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
625 if (tevent_req_nomem(state->rdata, req)) {
630 * We don't need to use rpc_read_send here, the upper layer will cope
631 * with a short read, transport->trans_send could also return less
632 * than state->max_rdata_len.
634 subreq = state->transport->read_send(state, state->ev, state->rdata,
636 state->transport->priv);
637 if (tevent_req_nomem(subreq, req)) {
640 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
643 static void cli_api_pipe_read_done(struct tevent_req *subreq)
645 struct tevent_req *req = tevent_req_callback_data(
646 subreq, struct tevent_req);
647 struct cli_api_pipe_state *state = tevent_req_data(
648 req, struct cli_api_pipe_state);
652 status = state->transport->read_recv(subreq, &received);
654 if (!NT_STATUS_IS_OK(status)) {
655 tevent_req_nterror(req, status);
658 state->rdata_len = received;
659 tevent_req_done(req);
662 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
663 uint8_t **prdata, uint32_t *prdata_len)
665 struct cli_api_pipe_state *state = tevent_req_data(
666 req, struct cli_api_pipe_state);
669 if (tevent_req_is_nterror(req, &status)) {
673 *prdata = talloc_move(mem_ctx, &state->rdata);
674 *prdata_len = state->rdata_len;
678 /****************************************************************************
679 Send data on an rpc pipe via trans. The data must be the last
680 pdu fragment of an NDR data stream.
682 Receive response data from an rpc pipe, which may be large...
684 Read the first fragment: unfortunately have to use SMBtrans for the first
685 bit, then SMBreadX for subsequent bits.
687 If first fragment received also wasn't the last fragment, continue
688 getting fragments until we _do_ receive the last fragment.
690 Request/Response PDU's look like the following...
692 |<------------------PDU len----------------------------------------------->|
693 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
695 +------------+-----------------+-------------+---------------+-------------+
696 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
697 +------------+-----------------+-------------+---------------+-------------+
699 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
700 signing & sealing being negotiated.
702 ****************************************************************************/
704 struct rpc_api_pipe_state {
705 struct event_context *ev;
706 struct rpc_pipe_client *cli;
707 uint8_t expected_pkt_type;
709 DATA_BLOB incoming_frag;
710 struct ncacn_packet *pkt;
714 size_t reply_pdu_offset;
718 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
719 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
721 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
722 struct event_context *ev,
723 struct rpc_pipe_client *cli,
724 DATA_BLOB *data, /* Outgoing PDU */
725 uint8_t expected_pkt_type)
727 struct tevent_req *req, *subreq;
728 struct rpc_api_pipe_state *state;
729 uint16_t max_recv_frag;
732 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
738 state->expected_pkt_type = expected_pkt_type;
739 state->incoming_frag = data_blob_null;
740 state->reply_pdu = data_blob_null;
741 state->reply_pdu_offset = 0;
742 state->endianess = DCERPC_DREP_LE;
745 * Ensure we're not sending too much.
747 if (data->length > cli->max_xmit_frag) {
748 status = NT_STATUS_INVALID_PARAMETER;
752 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
754 /* get the header first, then fetch the rest once we have
755 * the frag_length available */
756 max_recv_frag = RPC_HEADER_LEN;
758 subreq = cli_api_pipe_send(state, ev, cli->transport,
759 data->data, data->length, max_recv_frag);
760 if (subreq == NULL) {
763 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
767 tevent_req_nterror(req, status);
768 return tevent_req_post(req, ev);
774 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
776 struct tevent_req *req = tevent_req_callback_data(
777 subreq, struct tevent_req);
778 struct rpc_api_pipe_state *state = tevent_req_data(
779 req, struct rpc_api_pipe_state);
781 uint8_t *rdata = NULL;
782 uint32_t rdata_len = 0;
784 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
786 if (!NT_STATUS_IS_OK(status)) {
787 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
788 tevent_req_nterror(req, status);
793 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
794 rpccli_pipe_txt(talloc_tos(), state->cli)));
795 tevent_req_done(req);
800 * Move data on state->incoming_frag.
802 state->incoming_frag.data = talloc_move(state, &rdata);
803 state->incoming_frag.length = rdata_len;
804 if (!state->incoming_frag.data) {
805 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
809 /* Ensure we have enough data for a pdu. */
810 subreq = get_complete_frag_send(state, state->ev, state->cli,
811 &state->incoming_frag);
812 if (tevent_req_nomem(subreq, req)) {
815 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
818 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
820 struct tevent_req *req = tevent_req_callback_data(
821 subreq, struct tevent_req);
822 struct rpc_api_pipe_state *state = tevent_req_data(
823 req, struct rpc_api_pipe_state);
825 DATA_BLOB rdata = data_blob_null;
827 status = get_complete_frag_recv(subreq);
829 if (!NT_STATUS_IS_OK(status)) {
830 DEBUG(5, ("get_complete_frag failed: %s\n",
832 tevent_req_nterror(req, status);
836 state->pkt = talloc(state, struct ncacn_packet);
838 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
842 status = cli_pipe_validate_current_pdu(state,
843 state->cli, state->pkt,
844 &state->incoming_frag,
845 state->expected_pkt_type,
849 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
850 (unsigned)state->incoming_frag.length,
851 (unsigned)state->reply_pdu_offset,
854 if (!NT_STATUS_IS_OK(status)) {
855 tevent_req_nterror(req, status);
859 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
860 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
862 * Set the data type correctly for big-endian data on the
865 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
867 rpccli_pipe_txt(talloc_tos(), state->cli)));
868 state->endianess = 0x00; /* BIG ENDIAN */
871 * Check endianness on subsequent packets.
873 if (state->endianess != state->pkt->drep[0]) {
874 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
876 state->endianess?"little":"big",
877 state->pkt->drep[0]?"little":"big"));
878 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
882 /* Now copy the data portion out of the pdu into rbuf. */
883 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
884 if (!data_blob_realloc(NULL, &state->reply_pdu,
885 state->reply_pdu_offset + rdata.length)) {
886 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
891 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
892 rdata.data, rdata.length);
893 state->reply_pdu_offset += rdata.length;
895 /* reset state->incoming_frag, there is no need to free it,
896 * it will be reallocated to the right size the next time
898 state->incoming_frag.length = 0;
900 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
901 /* make sure the pdu length is right now that we
902 * have all the data available (alloc hint may
903 * have allocated more than was actually used) */
904 state->reply_pdu.length = state->reply_pdu_offset;
905 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
906 rpccli_pipe_txt(talloc_tos(), state->cli),
907 (unsigned)state->reply_pdu.length));
908 tevent_req_done(req);
912 subreq = get_complete_frag_send(state, state->ev, state->cli,
913 &state->incoming_frag);
914 if (tevent_req_nomem(subreq, req)) {
917 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
920 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
921 struct ncacn_packet **pkt,
922 DATA_BLOB *reply_pdu)
924 struct rpc_api_pipe_state *state = tevent_req_data(
925 req, struct rpc_api_pipe_state);
928 if (tevent_req_is_nterror(req, &status)) {
932 /* return data to caller and assign it ownership of memory */
934 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
935 reply_pdu->length = state->reply_pdu.length;
936 state->reply_pdu.length = 0;
938 data_blob_free(&state->reply_pdu);
942 *pkt = talloc_steal(mem_ctx, state->pkt);
948 /*******************************************************************
949 Creates spnego auth bind.
950 ********************************************************************/
952 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
953 struct pipe_auth_data *auth,
954 DATA_BLOB *auth_token)
956 DATA_BLOB in_token = data_blob_null;
959 /* Negotiate the initial auth token */
960 status = spnego_get_client_auth_token(mem_ctx,
961 auth->a_u.spnego_state,
962 &in_token, auth_token);
963 if (!NT_STATUS_IS_OK(status)) {
967 DEBUG(5, ("Created GSS Authentication Token:\n"));
968 dump_data(5, auth_token->data, auth_token->length);
973 /*******************************************************************
974 Creates krb5 auth bind.
975 ********************************************************************/
977 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
978 struct pipe_auth_data *auth,
979 DATA_BLOB *auth_token)
981 DATA_BLOB in_token = data_blob_null;
984 /* Negotiate the initial auth token */
985 status = gse_get_client_auth_token(mem_ctx,
986 auth->a_u.gssapi_state,
989 if (!NT_STATUS_IS_OK(status)) {
993 DEBUG(5, ("Created GSS Authentication Token:\n"));
994 dump_data(5, auth_token->data, auth_token->length);
999 /*******************************************************************
1000 Creates NTLMSSP auth bind.
1001 ********************************************************************/
1003 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1004 DATA_BLOB *auth_token)
1007 DATA_BLOB null_blob = data_blob_null;
1009 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1010 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1011 null_blob, auth_token);
1013 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1014 data_blob_free(auth_token);
1018 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1019 dump_data(5, auth_token->data, auth_token->length);
1021 return NT_STATUS_OK;
1024 /*******************************************************************
1025 Creates schannel auth bind.
1026 ********************************************************************/
1028 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1029 DATA_BLOB *auth_token)
1032 struct NL_AUTH_MESSAGE r;
1034 /* Use lp_workgroup() if domain not specified */
1036 if (!cli->auth->domain || !cli->auth->domain[0]) {
1037 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1038 if (cli->auth->domain == NULL) {
1039 return NT_STATUS_NO_MEMORY;
1044 * Now marshall the data into the auth parse_struct.
1047 r.MessageType = NL_NEGOTIATE_REQUEST;
1048 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1049 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1050 r.oem_netbios_domain.a = cli->auth->domain;
1051 r.oem_netbios_computer.a = global_myname();
1053 status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1054 if (!NT_STATUS_IS_OK(status)) {
1058 return NT_STATUS_OK;
1061 /*******************************************************************
1062 Creates the internals of a DCE/RPC bind request or alter context PDU.
1063 ********************************************************************/
1065 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1066 enum dcerpc_pkt_type ptype,
1068 const struct ndr_syntax_id *abstract,
1069 const struct ndr_syntax_id *transfer,
1070 const DATA_BLOB *auth_info,
1073 uint16 auth_len = auth_info->length;
1075 union dcerpc_payload u;
1076 struct dcerpc_ctx_list ctx_list;
1079 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1082 ctx_list.context_id = 0;
1083 ctx_list.num_transfer_syntaxes = 1;
1084 ctx_list.abstract_syntax = *abstract;
1085 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1087 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1088 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1089 u.bind.assoc_group_id = 0x0;
1090 u.bind.num_contexts = 1;
1091 u.bind.ctx_list = &ctx_list;
1092 u.bind.auth_info = *auth_info;
1094 status = dcerpc_push_ncacn_packet(mem_ctx,
1096 DCERPC_PFC_FLAG_FIRST |
1097 DCERPC_PFC_FLAG_LAST,
1102 if (!NT_STATUS_IS_OK(status)) {
1103 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1107 return NT_STATUS_OK;
1110 /*******************************************************************
1111 Creates a DCE/RPC bind request.
1112 ********************************************************************/
1114 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1115 struct rpc_pipe_client *cli,
1116 struct pipe_auth_data *auth,
1118 const struct ndr_syntax_id *abstract,
1119 const struct ndr_syntax_id *transfer,
1122 DATA_BLOB auth_token = data_blob_null;
1123 DATA_BLOB auth_info = data_blob_null;
1124 NTSTATUS ret = NT_STATUS_OK;
1126 switch (auth->auth_type) {
1127 case DCERPC_AUTH_TYPE_SCHANNEL:
1128 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1129 if (!NT_STATUS_IS_OK(ret)) {
1134 case DCERPC_AUTH_TYPE_NTLMSSP:
1135 ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token);
1136 if (!NT_STATUS_IS_OK(ret)) {
1141 case DCERPC_AUTH_TYPE_SPNEGO:
1142 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1143 if (!NT_STATUS_IS_OK(ret)) {
1148 case DCERPC_AUTH_TYPE_KRB5:
1149 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
1150 if (!NT_STATUS_IS_OK(ret)) {
1155 case DCERPC_AUTH_TYPE_NONE:
1159 /* "Can't" happen. */
1160 return NT_STATUS_INVALID_INFO_CLASS;
1163 if (auth_token.length != 0) {
1164 ret = dcerpc_push_dcerpc_auth(cli,
1167 0, /* auth_pad_length */
1168 1, /* auth_context_id */
1171 if (!NT_STATUS_IS_OK(ret)) {
1174 data_blob_free(&auth_token);
1177 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1187 /*******************************************************************
1189 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1190 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1191 and deals with signing/sealing details.
1192 ********************************************************************/
1194 struct rpc_api_pipe_req_state {
1195 struct event_context *ev;
1196 struct rpc_pipe_client *cli;
1199 DATA_BLOB *req_data;
1200 uint32_t req_data_sent;
1202 DATA_BLOB reply_pdu;
1205 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1206 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1207 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1208 bool *is_last_frag);
1210 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1211 struct event_context *ev,
1212 struct rpc_pipe_client *cli,
1214 DATA_BLOB *req_data)
1216 struct tevent_req *req, *subreq;
1217 struct rpc_api_pipe_req_state *state;
1221 req = tevent_req_create(mem_ctx, &state,
1222 struct rpc_api_pipe_req_state);
1228 state->op_num = op_num;
1229 state->req_data = req_data;
1230 state->req_data_sent = 0;
1231 state->call_id = get_rpc_call_id();
1232 state->reply_pdu = data_blob_null;
1233 state->rpc_out = data_blob_null;
1235 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1236 + RPC_MAX_SIGN_SIZE) {
1237 /* Server is screwed up ! */
1238 status = NT_STATUS_INVALID_PARAMETER;
1242 status = prepare_next_frag(state, &is_last_frag);
1243 if (!NT_STATUS_IS_OK(status)) {
1248 subreq = rpc_api_pipe_send(state, ev, state->cli,
1250 DCERPC_PKT_RESPONSE);
1251 if (subreq == NULL) {
1254 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1256 subreq = rpc_write_send(state, ev, cli->transport,
1257 state->rpc_out.data,
1258 state->rpc_out.length);
1259 if (subreq == NULL) {
1262 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1268 tevent_req_nterror(req, status);
1269 return tevent_req_post(req, ev);
1275 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1278 size_t data_sent_thistime;
1285 union dcerpc_payload u;
1287 data_left = state->req_data->length - state->req_data_sent;
1289 status = dcerpc_guess_sizes(state->cli->auth,
1290 DCERPC_REQUEST_LENGTH, data_left,
1291 state->cli->max_xmit_frag,
1292 CLIENT_NDR_PADDING_SIZE,
1293 &data_sent_thistime,
1294 &frag_len, &auth_len, &pad_len);
1295 if (!NT_STATUS_IS_OK(status)) {
1299 if (state->req_data_sent == 0) {
1300 flags = DCERPC_PFC_FLAG_FIRST;
1303 if (data_sent_thistime == data_left) {
1304 flags |= DCERPC_PFC_FLAG_LAST;
1307 data_blob_free(&state->rpc_out);
1309 ZERO_STRUCT(u.request);
1311 u.request.alloc_hint = state->req_data->length;
1312 u.request.context_id = 0;
1313 u.request.opnum = state->op_num;
1315 status = dcerpc_push_ncacn_packet(state,
1322 if (!NT_STATUS_IS_OK(status)) {
1326 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1327 * compute it right for requests because the auth trailer is missing
1329 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1331 /* Copy in the data. */
1332 if (!data_blob_append(NULL, &state->rpc_out,
1333 state->req_data->data + state->req_data_sent,
1334 data_sent_thistime)) {
1335 return NT_STATUS_NO_MEMORY;
1338 switch (state->cli->auth->auth_level) {
1339 case DCERPC_AUTH_LEVEL_NONE:
1340 case DCERPC_AUTH_LEVEL_CONNECT:
1341 case DCERPC_AUTH_LEVEL_PACKET:
1343 case DCERPC_AUTH_LEVEL_INTEGRITY:
1344 case DCERPC_AUTH_LEVEL_PRIVACY:
1345 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1347 if (!NT_STATUS_IS_OK(status)) {
1352 return NT_STATUS_INVALID_PARAMETER;
1355 state->req_data_sent += data_sent_thistime;
1356 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1361 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1363 struct tevent_req *req = tevent_req_callback_data(
1364 subreq, struct tevent_req);
1365 struct rpc_api_pipe_req_state *state = tevent_req_data(
1366 req, struct rpc_api_pipe_req_state);
1370 status = rpc_write_recv(subreq);
1371 TALLOC_FREE(subreq);
1372 if (!NT_STATUS_IS_OK(status)) {
1373 tevent_req_nterror(req, status);
1377 status = prepare_next_frag(state, &is_last_frag);
1378 if (!NT_STATUS_IS_OK(status)) {
1379 tevent_req_nterror(req, status);
1384 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1386 DCERPC_PKT_RESPONSE);
1387 if (tevent_req_nomem(subreq, req)) {
1390 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1392 subreq = rpc_write_send(state, state->ev,
1393 state->cli->transport,
1394 state->rpc_out.data,
1395 state->rpc_out.length);
1396 if (tevent_req_nomem(subreq, req)) {
1399 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1404 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1406 struct tevent_req *req = tevent_req_callback_data(
1407 subreq, struct tevent_req);
1408 struct rpc_api_pipe_req_state *state = tevent_req_data(
1409 req, struct rpc_api_pipe_req_state);
1412 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1413 TALLOC_FREE(subreq);
1414 if (!NT_STATUS_IS_OK(status)) {
1415 tevent_req_nterror(req, status);
1418 tevent_req_done(req);
1421 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1422 DATA_BLOB *reply_pdu)
1424 struct rpc_api_pipe_req_state *state = tevent_req_data(
1425 req, struct rpc_api_pipe_req_state);
1428 if (tevent_req_is_nterror(req, &status)) {
1430 * We always have to initialize to reply pdu, even if there is
1431 * none. The rpccli_* caller routines expect this.
1433 *reply_pdu = data_blob_null;
1437 /* return data to caller and assign it ownership of memory */
1438 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1439 reply_pdu->length = state->reply_pdu.length;
1440 state->reply_pdu.length = 0;
1442 return NT_STATUS_OK;
1446 /****************************************************************************
1447 Set the handle state.
1448 ****************************************************************************/
1450 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1451 const char *pipe_name, uint16 device_state)
1453 bool state_set = False;
1455 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1456 char *rparam = NULL;
1458 uint32 rparam_len, rdata_len;
1460 if (pipe_name == NULL)
1463 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1464 cli->fnum, pipe_name, device_state));
1466 /* create parameters: device state */
1467 SSVAL(param, 0, device_state);
1469 /* create setup parameters. */
1471 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1473 /* send the data on \PIPE\ */
1474 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1475 setup, 2, 0, /* setup, length, max */
1476 param, 2, 0, /* param, length, max */
1477 NULL, 0, 1024, /* data, length, max */
1478 &rparam, &rparam_len, /* return param, length */
1479 &rdata, &rdata_len)) /* return data, length */
1481 DEBUG(5, ("Set Handle state: return OK\n"));
1492 /****************************************************************************
1493 Check the rpc bind acknowledge response.
1494 ****************************************************************************/
1496 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1497 const struct ndr_syntax_id *transfer)
1499 struct dcerpc_ack_ctx ctx;
1501 if (r->secondary_address_size == 0) {
1502 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1505 if (r->num_results < 1 || !r->ctx_list) {
1509 ctx = r->ctx_list[0];
1511 /* check the transfer syntax */
1512 if ((ctx.syntax.if_version != transfer->if_version) ||
1513 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1514 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1518 if (r->num_results != 0x1 || ctx.result != 0) {
1519 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1520 r->num_results, ctx.reason));
1523 DEBUG(5,("check_bind_response: accepted!\n"));
1527 /*******************************************************************
1528 Creates a DCE/RPC bind authentication response.
1529 This is the packet that is sent back to the server once we
1530 have received a BIND-ACK, to finish the third leg of
1531 the authentication handshake.
1532 ********************************************************************/
1534 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1535 struct rpc_pipe_client *cli,
1537 enum dcerpc_AuthType auth_type,
1538 enum dcerpc_AuthLevel auth_level,
1539 DATA_BLOB *pauth_blob,
1543 union dcerpc_payload u;
1547 status = dcerpc_push_dcerpc_auth(mem_ctx,
1550 0, /* auth_pad_length */
1551 1, /* auth_context_id */
1553 &u.auth3.auth_info);
1554 if (!NT_STATUS_IS_OK(status)) {
1558 status = dcerpc_push_ncacn_packet(mem_ctx,
1560 DCERPC_PFC_FLAG_FIRST |
1561 DCERPC_PFC_FLAG_LAST,
1566 data_blob_free(&u.auth3.auth_info);
1567 if (!NT_STATUS_IS_OK(status)) {
1568 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1572 return NT_STATUS_OK;
1575 /*******************************************************************
1576 Creates a DCE/RPC bind alter context authentication request which
1577 may contain a spnego auth blobl
1578 ********************************************************************/
1580 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1581 enum dcerpc_AuthType auth_type,
1582 enum dcerpc_AuthLevel auth_level,
1584 const struct ndr_syntax_id *abstract,
1585 const struct ndr_syntax_id *transfer,
1586 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1589 DATA_BLOB auth_info;
1592 status = dcerpc_push_dcerpc_auth(mem_ctx,
1595 0, /* auth_pad_length */
1596 1, /* auth_context_id */
1599 if (!NT_STATUS_IS_OK(status)) {
1603 status = create_bind_or_alt_ctx_internal(mem_ctx,
1610 data_blob_free(&auth_info);
1614 /****************************************************************************
1616 ****************************************************************************/
1618 struct rpc_pipe_bind_state {
1619 struct event_context *ev;
1620 struct rpc_pipe_client *cli;
1622 uint32_t rpc_call_id;
1625 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1626 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1627 struct rpc_pipe_bind_state *state,
1628 DATA_BLOB *credentials);
1629 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1630 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1631 struct rpc_pipe_bind_state *state,
1632 DATA_BLOB *credentials);
1633 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1634 struct rpc_pipe_bind_state *state,
1635 DATA_BLOB *credentials);
1637 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1638 struct event_context *ev,
1639 struct rpc_pipe_client *cli,
1640 struct pipe_auth_data *auth)
1642 struct tevent_req *req, *subreq;
1643 struct rpc_pipe_bind_state *state;
1646 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1651 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1652 rpccli_pipe_txt(talloc_tos(), cli),
1653 (unsigned int)auth->auth_type,
1654 (unsigned int)auth->spnego_type,
1655 (unsigned int)auth->auth_level ));
1659 state->rpc_call_id = get_rpc_call_id();
1660 state->rpc_out = data_blob_null;
1662 cli->auth = talloc_move(cli, &auth);
1664 /* Marshall the outgoing data. */
1665 status = create_rpc_bind_req(state, cli,
1668 &cli->abstract_syntax,
1669 &cli->transfer_syntax,
1672 if (!NT_STATUS_IS_OK(status)) {
1676 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1677 DCERPC_PKT_BIND_ACK);
1678 if (subreq == NULL) {
1681 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1685 tevent_req_nterror(req, status);
1686 return tevent_req_post(req, ev);
1692 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1694 struct tevent_req *req = tevent_req_callback_data(
1695 subreq, struct tevent_req);
1696 struct rpc_pipe_bind_state *state = tevent_req_data(
1697 req, struct rpc_pipe_bind_state);
1698 struct pipe_auth_data *pauth = state->cli->auth;
1699 DATA_BLOB reply_pdu;
1700 struct ncacn_packet *pkt;
1701 struct dcerpc_auth auth;
1702 DATA_BLOB auth_token = data_blob_null;
1705 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1706 TALLOC_FREE(subreq);
1707 if (!NT_STATUS_IS_OK(status)) {
1708 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1709 rpccli_pipe_txt(talloc_tos(), state->cli),
1710 nt_errstr(status)));
1711 tevent_req_nterror(req, status);
1715 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1716 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1717 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1721 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1722 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1724 switch(state->cli->auth->auth_type) {
1726 case DCERPC_AUTH_TYPE_NONE:
1727 case DCERPC_AUTH_TYPE_SCHANNEL:
1728 /* Bind complete. */
1729 tevent_req_done(req);
1732 case DCERPC_AUTH_TYPE_NTLMSSP:
1733 case DCERPC_AUTH_TYPE_SPNEGO:
1734 case DCERPC_AUTH_TYPE_KRB5:
1735 /* Paranoid lenght checks */
1736 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1737 + pkt->auth_length) {
1738 tevent_req_nterror(req,
1739 NT_STATUS_INFO_LENGTH_MISMATCH);
1742 /* get auth credentials */
1743 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1744 &pkt->u.bind_ack.auth_info,
1746 if (!NT_STATUS_IS_OK(status)) {
1747 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1748 nt_errstr(status)));
1749 tevent_req_nterror(req, status);
1759 * For authenticated binds we may need to do 3 or 4 leg binds.
1762 switch(state->cli->auth->auth_type) {
1764 case DCERPC_AUTH_TYPE_NONE:
1765 case DCERPC_AUTH_TYPE_SCHANNEL:
1766 /* Bind complete. */
1767 tevent_req_done(req);
1770 case DCERPC_AUTH_TYPE_NTLMSSP:
1771 /* Need to send AUTH3 packet - no reply. */
1772 status = rpc_finish_auth3_bind_send(req, state,
1776 case DCERPC_AUTH_TYPE_SPNEGO:
1777 status = spnego_get_client_auth_token(state,
1778 pauth->a_u.spnego_state,
1781 if (!NT_STATUS_IS_OK(status)) {
1784 if (auth_token.length == 0) {
1785 /* Bind complete. */
1786 tevent_req_done(req);
1789 if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
1790 status = rpc_bind_next_send(req, state,
1793 status = rpc_bind_finish_send(req, state,
1798 case DCERPC_AUTH_TYPE_KRB5:
1799 status = gse_get_client_auth_token(state,
1800 pauth->a_u.gssapi_state,
1803 if (!NT_STATUS_IS_OK(status)) {
1807 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
1808 status = rpc_bind_next_send(req, state, &auth_token);
1810 status = rpc_bind_finish_send(req, state, &auth_token);
1818 if (!NT_STATUS_IS_OK(status)) {
1819 tevent_req_nterror(req, status);
1824 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
1825 (unsigned int)state->cli->auth->auth_type,
1826 (unsigned int)state->cli->auth->spnego_type));
1827 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1830 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1831 struct rpc_pipe_bind_state *state,
1832 DATA_BLOB *credentials)
1834 struct pipe_auth_data *auth = state->cli->auth;
1835 DATA_BLOB client_reply = data_blob_null;
1836 struct tevent_req *subreq;
1839 /* TODO - check auth_type/auth_level match. */
1841 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
1842 *credentials, &client_reply);
1844 if (!NT_STATUS_IS_OK(status)) {
1845 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
1846 "blob failed: %s.\n", nt_errstr(status)));
1850 data_blob_free(&state->rpc_out);
1852 status = create_rpc_bind_auth3(state, state->cli,
1858 data_blob_free(&client_reply);
1860 if (!NT_STATUS_IS_OK(status)) {
1864 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1865 state->rpc_out.data, state->rpc_out.length);
1866 if (subreq == NULL) {
1867 return NT_STATUS_NO_MEMORY;
1869 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
1870 return NT_STATUS_OK;
1873 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
1875 struct tevent_req *req = tevent_req_callback_data(
1876 subreq, struct tevent_req);
1879 status = rpc_write_recv(subreq);
1880 TALLOC_FREE(subreq);
1881 if (!NT_STATUS_IS_OK(status)) {
1882 tevent_req_nterror(req, status);
1885 tevent_req_done(req);
1888 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1889 struct rpc_pipe_bind_state *state,
1890 DATA_BLOB *auth_token)
1892 struct pipe_auth_data *auth = state->cli->auth;
1893 struct tevent_req *subreq;
1896 /* Now prepare the alter context pdu. */
1897 data_blob_free(&state->rpc_out);
1899 status = create_rpc_alter_context(state,
1903 &state->cli->abstract_syntax,
1904 &state->cli->transfer_syntax,
1907 if (!NT_STATUS_IS_OK(status)) {
1911 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1912 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1913 if (subreq == NULL) {
1914 return NT_STATUS_NO_MEMORY;
1916 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1917 return NT_STATUS_OK;
1920 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1921 struct rpc_pipe_bind_state *state,
1922 DATA_BLOB *auth_token)
1924 struct pipe_auth_data *auth = state->cli->auth;
1925 struct tevent_req *subreq;
1928 /* Now prepare the auth3 context pdu. */
1929 data_blob_free(&state->rpc_out);
1931 status = create_rpc_bind_auth3(state, state->cli,
1937 if (!NT_STATUS_IS_OK(status)) {
1941 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1942 state->rpc_out.data, state->rpc_out.length);
1943 if (subreq == NULL) {
1944 return NT_STATUS_NO_MEMORY;
1946 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
1947 return NT_STATUS_OK;
1950 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1952 return tevent_req_simple_recv_ntstatus(req);
1955 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1956 struct pipe_auth_data *auth)
1958 TALLOC_CTX *frame = talloc_stackframe();
1959 struct event_context *ev;
1960 struct tevent_req *req;
1961 NTSTATUS status = NT_STATUS_OK;
1963 ev = event_context_init(frame);
1965 status = NT_STATUS_NO_MEMORY;
1969 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1971 status = NT_STATUS_NO_MEMORY;
1975 if (!tevent_req_poll(req, ev)) {
1976 status = map_nt_error_from_unix(errno);
1980 status = rpc_pipe_bind_recv(req);
1986 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1988 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1989 unsigned int timeout)
1993 if (rpc_cli->transport == NULL) {
1994 return RPCCLI_DEFAULT_TIMEOUT;
1997 if (rpc_cli->transport->set_timeout == NULL) {
1998 return RPCCLI_DEFAULT_TIMEOUT;
2001 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2003 return RPCCLI_DEFAULT_TIMEOUT;
2009 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2011 if (rpc_cli == NULL) {
2015 if (rpc_cli->transport == NULL) {
2019 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2022 struct rpccli_bh_state {
2023 struct rpc_pipe_client *rpc_cli;
2026 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2028 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2029 struct rpccli_bh_state);
2031 return rpccli_is_connected(hs->rpc_cli);
2034 struct rpccli_bh_raw_call_state {
2040 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2042 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2043 struct tevent_context *ev,
2044 struct dcerpc_binding_handle *h,
2045 const struct GUID *object,
2048 const uint8_t *in_data,
2051 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2052 struct rpccli_bh_state);
2053 struct tevent_req *req;
2054 struct rpccli_bh_raw_call_state *state;
2056 struct tevent_req *subreq;
2058 req = tevent_req_create(mem_ctx, &state,
2059 struct rpccli_bh_raw_call_state);
2063 state->in_data.data = discard_const_p(uint8_t, in_data);
2064 state->in_data.length = in_length;
2066 ok = rpccli_bh_is_connected(h);
2068 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2069 return tevent_req_post(req, ev);
2072 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2073 opnum, &state->in_data);
2074 if (tevent_req_nomem(subreq, req)) {
2075 return tevent_req_post(req, ev);
2077 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2082 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2084 struct tevent_req *req =
2085 tevent_req_callback_data(subreq,
2087 struct rpccli_bh_raw_call_state *state =
2088 tevent_req_data(req,
2089 struct rpccli_bh_raw_call_state);
2092 state->out_flags = 0;
2094 /* TODO: support bigendian responses */
2096 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2097 TALLOC_FREE(subreq);
2098 if (!NT_STATUS_IS_OK(status)) {
2099 tevent_req_nterror(req, status);
2103 tevent_req_done(req);
2106 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2107 TALLOC_CTX *mem_ctx,
2110 uint32_t *out_flags)
2112 struct rpccli_bh_raw_call_state *state =
2113 tevent_req_data(req,
2114 struct rpccli_bh_raw_call_state);
2117 if (tevent_req_is_nterror(req, &status)) {
2118 tevent_req_received(req);
2122 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2123 *out_length = state->out_data.length;
2124 *out_flags = state->out_flags;
2125 tevent_req_received(req);
2126 return NT_STATUS_OK;
2129 struct rpccli_bh_disconnect_state {
2133 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2134 struct tevent_context *ev,
2135 struct dcerpc_binding_handle *h)
2137 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2138 struct rpccli_bh_state);
2139 struct tevent_req *req;
2140 struct rpccli_bh_disconnect_state *state;
2143 req = tevent_req_create(mem_ctx, &state,
2144 struct rpccli_bh_disconnect_state);
2149 ok = rpccli_bh_is_connected(h);
2151 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2152 return tevent_req_post(req, ev);
2156 * TODO: do a real async disconnect ...
2158 * For now the caller needs to free rpc_cli
2162 tevent_req_done(req);
2163 return tevent_req_post(req, ev);
2166 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2170 if (tevent_req_is_nterror(req, &status)) {
2171 tevent_req_received(req);
2175 tevent_req_received(req);
2176 return NT_STATUS_OK;
2179 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2184 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2186 const void *_struct_ptr,
2187 const struct ndr_interface_call *call)
2189 void *struct_ptr = discard_const(_struct_ptr);
2191 if (DEBUGLEVEL < 10) {
2195 if (ndr_flags & NDR_IN) {
2196 ndr_print_function_debug(call->ndr_print,
2201 if (ndr_flags & NDR_OUT) {
2202 ndr_print_function_debug(call->ndr_print,
2209 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2211 .is_connected = rpccli_bh_is_connected,
2212 .raw_call_send = rpccli_bh_raw_call_send,
2213 .raw_call_recv = rpccli_bh_raw_call_recv,
2214 .disconnect_send = rpccli_bh_disconnect_send,
2215 .disconnect_recv = rpccli_bh_disconnect_recv,
2217 .ref_alloc = rpccli_bh_ref_alloc,
2218 .do_ndr_print = rpccli_bh_do_ndr_print,
2221 /* initialise a rpc_pipe_client binding handle */
2222 static struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2224 struct dcerpc_binding_handle *h;
2225 struct rpccli_bh_state *hs;
2227 h = dcerpc_binding_handle_create(c,
2232 struct rpccli_bh_state,
2242 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2244 struct auth_ntlmssp_state *a = NULL;
2245 struct cli_state *cli;
2247 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2248 a = rpc_cli->auth->a_u.auth_ntlmssp_state;
2249 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2250 enum dcerpc_AuthType auth_type;
2254 status = spnego_get_negotiated_mech(
2255 rpc_cli->auth->a_u.spnego_state,
2256 &auth_type, &auth_ctx);
2257 if (!NT_STATUS_IS_OK(status)) {
2261 if (auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2262 a = talloc_get_type(auth_ctx,
2263 struct auth_ntlmssp_state);
2268 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2272 cli = rpc_pipe_np_smb_conn(rpc_cli);
2276 E_md4hash(cli->password ? cli->password : "", nt_hash);
2280 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2281 struct pipe_auth_data **presult)
2283 struct pipe_auth_data *result;
2285 result = talloc(mem_ctx, struct pipe_auth_data);
2286 if (result == NULL) {
2287 return NT_STATUS_NO_MEMORY;
2290 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2291 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2292 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2294 result->user_name = talloc_strdup(result, "");
2295 result->domain = talloc_strdup(result, "");
2296 if ((result->user_name == NULL) || (result->domain == NULL)) {
2297 TALLOC_FREE(result);
2298 return NT_STATUS_NO_MEMORY;
2302 return NT_STATUS_OK;
2305 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2307 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2311 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2312 enum dcerpc_AuthType auth_type,
2313 enum dcerpc_AuthLevel auth_level,
2315 const char *username,
2316 const char *password,
2317 struct pipe_auth_data **presult)
2319 struct pipe_auth_data *result;
2322 result = talloc(mem_ctx, struct pipe_auth_data);
2323 if (result == NULL) {
2324 return NT_STATUS_NO_MEMORY;
2327 result->auth_type = auth_type;
2328 result->auth_level = auth_level;
2330 result->user_name = talloc_strdup(result, username);
2331 result->domain = talloc_strdup(result, domain);
2332 if ((result->user_name == NULL) || (result->domain == NULL)) {
2333 status = NT_STATUS_NO_MEMORY;
2337 status = auth_ntlmssp_client_start(NULL,
2340 lp_client_ntlmv2_auth(),
2341 &result->a_u.auth_ntlmssp_state);
2342 if (!NT_STATUS_IS_OK(status)) {
2346 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2348 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2350 if (!NT_STATUS_IS_OK(status)) {
2354 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2356 if (!NT_STATUS_IS_OK(status)) {
2360 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2362 if (!NT_STATUS_IS_OK(status)) {
2367 * Turn off sign+seal to allow selected auth level to turn it back on.
2369 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2370 ~(NTLMSSP_NEGOTIATE_SIGN |
2371 NTLMSSP_NEGOTIATE_SEAL));
2373 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2374 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2375 NTLMSSP_NEGOTIATE_SIGN);
2376 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2377 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2378 NTLMSSP_NEGOTIATE_SEAL |
2379 NTLMSSP_NEGOTIATE_SIGN);
2383 return NT_STATUS_OK;
2386 TALLOC_FREE(result);
2390 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2391 enum dcerpc_AuthLevel auth_level,
2392 struct netlogon_creds_CredentialState *creds,
2393 struct pipe_auth_data **presult)
2395 struct pipe_auth_data *result;
2397 result = talloc(mem_ctx, struct pipe_auth_data);
2398 if (result == NULL) {
2399 return NT_STATUS_NO_MEMORY;
2402 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2403 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2404 result->auth_level = auth_level;
2406 result->user_name = talloc_strdup(result, "");
2407 result->domain = talloc_strdup(result, domain);
2408 if ((result->user_name == NULL) || (result->domain == NULL)) {
2412 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2413 if (result->a_u.schannel_auth == NULL) {
2417 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2418 result->a_u.schannel_auth->seq_num = 0;
2419 result->a_u.schannel_auth->initiator = true;
2420 result->a_u.schannel_auth->creds = creds;
2423 return NT_STATUS_OK;
2426 TALLOC_FREE(result);
2427 return NT_STATUS_NO_MEMORY;
2431 * Create an rpc pipe client struct, connecting to a tcp port.
2433 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2435 const struct ndr_syntax_id *abstract_syntax,
2436 struct rpc_pipe_client **presult)
2438 struct rpc_pipe_client *result;
2439 struct sockaddr_storage addr;
2443 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2444 if (result == NULL) {
2445 return NT_STATUS_NO_MEMORY;
2448 result->abstract_syntax = *abstract_syntax;
2449 result->transfer_syntax = ndr_transfer_syntax;
2451 result->desthost = talloc_strdup(result, host);
2452 result->srv_name_slash = talloc_asprintf_strupper_m(
2453 result, "\\\\%s", result->desthost);
2454 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2455 status = NT_STATUS_NO_MEMORY;
2459 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2460 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2462 if (!resolve_name(host, &addr, 0, false)) {
2463 status = NT_STATUS_NOT_FOUND;
2467 status = open_socket_out(&addr, port, 60, &fd);
2468 if (!NT_STATUS_IS_OK(status)) {
2471 set_socket_options(fd, lp_socket_options());
2473 status = rpc_transport_sock_init(result, fd, &result->transport);
2474 if (!NT_STATUS_IS_OK(status)) {
2479 result->transport->transport = NCACN_IP_TCP;
2481 result->binding_handle = rpccli_bh_create(result);
2482 if (result->binding_handle == NULL) {
2483 TALLOC_FREE(result);
2484 return NT_STATUS_NO_MEMORY;
2488 return NT_STATUS_OK;
2491 TALLOC_FREE(result);
2496 * Determine the tcp port on which a dcerpc interface is listening
2497 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2500 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2501 const struct ndr_syntax_id *abstract_syntax,
2505 struct rpc_pipe_client *epm_pipe = NULL;
2506 struct pipe_auth_data *auth = NULL;
2507 struct dcerpc_binding *map_binding = NULL;
2508 struct dcerpc_binding *res_binding = NULL;
2509 struct epm_twr_t *map_tower = NULL;
2510 struct epm_twr_t *res_towers = NULL;
2511 struct policy_handle *entry_handle = NULL;
2512 uint32_t num_towers = 0;
2513 uint32_t max_towers = 1;
2514 struct epm_twr_p_t towers;
2515 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2517 if (pport == NULL) {
2518 status = NT_STATUS_INVALID_PARAMETER;
2522 /* open the connection to the endpoint mapper */
2523 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2524 &ndr_table_epmapper.syntax_id,
2527 if (!NT_STATUS_IS_OK(status)) {
2531 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2532 if (!NT_STATUS_IS_OK(status)) {
2536 status = rpc_pipe_bind(epm_pipe, auth);
2537 if (!NT_STATUS_IS_OK(status)) {
2541 /* create tower for asking the epmapper */
2543 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2544 if (map_binding == NULL) {
2545 status = NT_STATUS_NO_MEMORY;
2549 map_binding->transport = NCACN_IP_TCP;
2550 map_binding->object = *abstract_syntax;
2551 map_binding->host = host; /* needed? */
2552 map_binding->endpoint = "0"; /* correct? needed? */
2554 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2555 if (map_tower == NULL) {
2556 status = NT_STATUS_NO_MEMORY;
2560 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2561 &(map_tower->tower));
2562 if (!NT_STATUS_IS_OK(status)) {
2566 /* allocate further parameters for the epm_Map call */
2568 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2569 if (res_towers == NULL) {
2570 status = NT_STATUS_NO_MEMORY;
2573 towers.twr = res_towers;
2575 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2576 if (entry_handle == NULL) {
2577 status = NT_STATUS_NO_MEMORY;
2581 /* ask the endpoint mapper for the port */
2583 status = rpccli_epm_Map(epm_pipe,
2585 CONST_DISCARD(struct GUID *,
2586 &(abstract_syntax->uuid)),
2593 if (!NT_STATUS_IS_OK(status)) {
2597 if (num_towers != 1) {
2598 status = NT_STATUS_UNSUCCESSFUL;
2602 /* extract the port from the answer */
2604 status = dcerpc_binding_from_tower(tmp_ctx,
2605 &(towers.twr->tower),
2607 if (!NT_STATUS_IS_OK(status)) {
2611 /* are further checks here necessary? */
2612 if (res_binding->transport != NCACN_IP_TCP) {
2613 status = NT_STATUS_UNSUCCESSFUL;
2617 *pport = (uint16_t)atoi(res_binding->endpoint);
2620 TALLOC_FREE(tmp_ctx);
2625 * Create a rpc pipe client struct, connecting to a host via tcp.
2626 * The port is determined by asking the endpoint mapper on the given
2629 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2630 const struct ndr_syntax_id *abstract_syntax,
2631 struct rpc_pipe_client **presult)
2636 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2637 if (!NT_STATUS_IS_OK(status)) {
2641 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2642 abstract_syntax, presult);
2645 /********************************************************************
2646 Create a rpc pipe client struct, connecting to a unix domain socket
2647 ********************************************************************/
2648 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2649 const struct ndr_syntax_id *abstract_syntax,
2650 struct rpc_pipe_client **presult)
2652 struct rpc_pipe_client *result;
2653 struct sockaddr_un addr;
2657 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2658 if (result == NULL) {
2659 return NT_STATUS_NO_MEMORY;
2662 result->abstract_syntax = *abstract_syntax;
2663 result->transfer_syntax = ndr_transfer_syntax;
2665 result->desthost = get_myname(result);
2666 result->srv_name_slash = talloc_asprintf_strupper_m(
2667 result, "\\\\%s", result->desthost);
2668 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2669 status = NT_STATUS_NO_MEMORY;
2673 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2674 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2676 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2678 status = map_nt_error_from_unix(errno);
2683 addr.sun_family = AF_UNIX;
2684 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2686 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2687 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2690 return map_nt_error_from_unix(errno);
2693 status = rpc_transport_sock_init(result, fd, &result->transport);
2694 if (!NT_STATUS_IS_OK(status)) {
2699 result->transport->transport = NCALRPC;
2701 result->binding_handle = rpccli_bh_create(result);
2702 if (result->binding_handle == NULL) {
2703 TALLOC_FREE(result);
2704 return NT_STATUS_NO_MEMORY;
2708 return NT_STATUS_OK;
2711 TALLOC_FREE(result);
2715 struct rpc_pipe_client_np_ref {
2716 struct cli_state *cli;
2717 struct rpc_pipe_client *pipe;
2720 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2722 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2726 /****************************************************************************
2727 Open a named pipe over SMB to a remote server.
2729 * CAVEAT CALLER OF THIS FUNCTION:
2730 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2731 * so be sure that this function is called AFTER any structure (vs pointer)
2732 * assignment of the cli. In particular, libsmbclient does structure
2733 * assignments of cli, which invalidates the data in the returned
2734 * rpc_pipe_client if this function is called before the structure assignment
2737 ****************************************************************************/
2739 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2740 const struct ndr_syntax_id *abstract_syntax,
2741 struct rpc_pipe_client **presult)
2743 struct rpc_pipe_client *result;
2745 struct rpc_pipe_client_np_ref *np_ref;
2747 /* sanity check to protect against crashes */
2750 return NT_STATUS_INVALID_HANDLE;
2753 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2754 if (result == NULL) {
2755 return NT_STATUS_NO_MEMORY;
2758 result->abstract_syntax = *abstract_syntax;
2759 result->transfer_syntax = ndr_transfer_syntax;
2760 result->desthost = talloc_strdup(result, cli->desthost);
2761 result->srv_name_slash = talloc_asprintf_strupper_m(
2762 result, "\\\\%s", result->desthost);
2764 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2765 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2767 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2768 TALLOC_FREE(result);
2769 return NT_STATUS_NO_MEMORY;
2772 status = rpc_transport_np_init(result, cli, abstract_syntax,
2773 &result->transport);
2774 if (!NT_STATUS_IS_OK(status)) {
2775 TALLOC_FREE(result);
2779 result->transport->transport = NCACN_NP;
2781 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2782 if (np_ref == NULL) {
2783 TALLOC_FREE(result);
2784 return NT_STATUS_NO_MEMORY;
2787 np_ref->pipe = result;
2789 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2790 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2792 result->binding_handle = rpccli_bh_create(result);
2793 if (result->binding_handle == NULL) {
2794 TALLOC_FREE(result);
2795 return NT_STATUS_NO_MEMORY;
2799 return NT_STATUS_OK;
2802 /****************************************************************************
2803 Open a pipe to a remote server.
2804 ****************************************************************************/
2806 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2807 enum dcerpc_transport_t transport,
2808 const struct ndr_syntax_id *interface,
2809 struct rpc_pipe_client **presult)
2811 switch (transport) {
2813 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2816 return rpc_pipe_open_np(cli, interface, presult);
2818 return NT_STATUS_NOT_IMPLEMENTED;
2822 /****************************************************************************
2823 Open a named pipe to an SMB server and bind anonymously.
2824 ****************************************************************************/
2826 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2827 enum dcerpc_transport_t transport,
2828 const struct ndr_syntax_id *interface,
2829 struct rpc_pipe_client **presult)
2831 struct rpc_pipe_client *result;
2832 struct pipe_auth_data *auth;
2835 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2836 if (!NT_STATUS_IS_OK(status)) {
2840 status = rpccli_anon_bind_data(result, &auth);
2841 if (!NT_STATUS_IS_OK(status)) {
2842 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2843 nt_errstr(status)));
2844 TALLOC_FREE(result);
2849 * This is a bit of an abstraction violation due to the fact that an
2850 * anonymous bind on an authenticated SMB inherits the user/domain
2851 * from the enclosing SMB creds
2854 TALLOC_FREE(auth->user_name);
2855 TALLOC_FREE(auth->domain);
2857 auth->user_name = talloc_strdup(auth, cli->user_name);
2858 auth->domain = talloc_strdup(auth, cli->domain);
2859 auth->user_session_key = data_blob_talloc(auth,
2860 cli->user_session_key.data,
2861 cli->user_session_key.length);
2863 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2864 TALLOC_FREE(result);
2865 return NT_STATUS_NO_MEMORY;
2868 status = rpc_pipe_bind(result, auth);
2869 if (!NT_STATUS_IS_OK(status)) {
2871 if (ndr_syntax_id_equal(interface,
2872 &ndr_table_dssetup.syntax_id)) {
2873 /* non AD domains just don't have this pipe, avoid
2874 * level 0 statement in that case - gd */
2877 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2878 "%s failed with error %s\n",
2879 get_pipe_name_from_syntax(talloc_tos(), interface),
2880 nt_errstr(status) ));
2881 TALLOC_FREE(result);
2885 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2886 "%s and bound anonymously.\n",
2887 get_pipe_name_from_syntax(talloc_tos(), interface),
2891 return NT_STATUS_OK;
2894 /****************************************************************************
2895 ****************************************************************************/
2897 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2898 const struct ndr_syntax_id *interface,
2899 struct rpc_pipe_client **presult)
2901 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2902 interface, presult);
2905 /****************************************************************************
2906 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2907 ****************************************************************************/
2909 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2910 const struct ndr_syntax_id *interface,
2911 enum dcerpc_transport_t transport,
2912 enum dcerpc_AuthLevel auth_level,
2914 const char *username,
2915 const char *password,
2916 struct rpc_pipe_client **presult)
2918 struct rpc_pipe_client *result;
2919 struct pipe_auth_data *auth = NULL;
2920 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2923 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2924 if (!NT_STATUS_IS_OK(status)) {
2928 status = rpccli_ntlmssp_bind_data(result,
2929 auth_type, auth_level,
2930 domain, username, password,
2932 if (!NT_STATUS_IS_OK(status)) {
2933 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2934 nt_errstr(status)));
2938 status = rpc_pipe_bind(result, auth);
2939 if (!NT_STATUS_IS_OK(status)) {
2940 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2941 nt_errstr(status) ));
2945 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2946 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2947 get_pipe_name_from_syntax(talloc_tos(), interface),
2948 cli->desthost, domain, username ));
2951 return NT_STATUS_OK;
2955 TALLOC_FREE(result);
2959 /****************************************************************************
2960 Get a the schannel session key out of an already opened netlogon pipe.
2961 ****************************************************************************/
2962 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2963 struct cli_state *cli,
2967 enum netr_SchannelType sec_chan_type = 0;
2968 unsigned char machine_pwd[16];
2969 const char *machine_account;
2972 /* Get the machine account credentials from secrets.tdb. */
2973 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2976 DEBUG(0, ("get_schannel_session_key: could not fetch "
2977 "trust account password for domain '%s'\n",
2979 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2982 status = rpccli_netlogon_setup_creds(netlogon_pipe,
2983 cli->desthost, /* server name */
2984 domain, /* domain */
2985 global_myname(), /* client name */
2986 machine_account, /* machine account name */
2991 if (!NT_STATUS_IS_OK(status)) {
2992 DEBUG(3, ("get_schannel_session_key_common: "
2993 "rpccli_netlogon_setup_creds failed with result %s "
2994 "to server %s, domain %s, machine account %s.\n",
2995 nt_errstr(status), cli->desthost, domain,
3000 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3001 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3003 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3006 return NT_STATUS_OK;;
3009 /****************************************************************************
3010 Open a netlogon pipe and get the schannel session key.
3011 Now exposed to external callers.
3012 ****************************************************************************/
3015 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3018 struct rpc_pipe_client **presult)
3020 struct rpc_pipe_client *netlogon_pipe = NULL;
3023 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3025 if (!NT_STATUS_IS_OK(status)) {
3029 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3031 if (!NT_STATUS_IS_OK(status)) {
3032 TALLOC_FREE(netlogon_pipe);
3036 *presult = netlogon_pipe;
3037 return NT_STATUS_OK;
3040 /****************************************************************************
3042 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3043 using session_key. sign and seal.
3045 The *pdc will be stolen onto this new pipe
3046 ****************************************************************************/
3048 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3049 const struct ndr_syntax_id *interface,
3050 enum dcerpc_transport_t transport,
3051 enum dcerpc_AuthLevel auth_level,
3053 struct netlogon_creds_CredentialState **pdc,
3054 struct rpc_pipe_client **presult)
3056 struct rpc_pipe_client *result;
3057 struct pipe_auth_data *auth;
3060 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3061 if (!NT_STATUS_IS_OK(status)) {
3065 status = rpccli_schannel_bind_data(result, domain, auth_level,
3067 if (!NT_STATUS_IS_OK(status)) {
3068 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3069 nt_errstr(status)));
3070 TALLOC_FREE(result);
3074 status = rpc_pipe_bind(result, auth);
3075 if (!NT_STATUS_IS_OK(status)) {
3076 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3077 "cli_rpc_pipe_bind failed with error %s\n",
3078 nt_errstr(status) ));
3079 TALLOC_FREE(result);
3084 * The credentials on a new netlogon pipe are the ones we are passed
3085 * in - reference them in
3087 result->dc = talloc_move(result, pdc);
3089 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3090 "for domain %s and bound using schannel.\n",
3091 get_pipe_name_from_syntax(talloc_tos(), interface),
3092 cli->desthost, domain ));
3095 return NT_STATUS_OK;
3098 /****************************************************************************
3099 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3100 Fetch the session key ourselves using a temporary netlogon pipe. This
3101 version uses an ntlmssp auth bound netlogon pipe to get the key.
3102 ****************************************************************************/
3104 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3106 const char *username,
3107 const char *password,
3109 struct rpc_pipe_client **presult)
3111 struct rpc_pipe_client *netlogon_pipe = NULL;
3114 status = cli_rpc_pipe_open_spnego_ntlmssp(
3115 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3116 DCERPC_AUTH_LEVEL_PRIVACY,
3117 domain, username, password, &netlogon_pipe);
3118 if (!NT_STATUS_IS_OK(status)) {
3122 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3124 if (!NT_STATUS_IS_OK(status)) {
3125 TALLOC_FREE(netlogon_pipe);
3129 *presult = netlogon_pipe;
3130 return NT_STATUS_OK;
3133 /****************************************************************************
3134 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3135 Fetch the session key ourselves using a temporary netlogon pipe. This version
3136 uses an ntlmssp bind to get the session key.
3137 ****************************************************************************/
3139 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3140 const struct ndr_syntax_id *interface,
3141 enum dcerpc_transport_t transport,
3142 enum dcerpc_AuthLevel auth_level,
3144 const char *username,
3145 const char *password,
3146 struct rpc_pipe_client **presult)
3148 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3149 struct rpc_pipe_client *netlogon_pipe = NULL;
3150 struct rpc_pipe_client *result = NULL;
3153 status = get_schannel_session_key_auth_ntlmssp(
3154 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3155 if (!NT_STATUS_IS_OK(status)) {
3156 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3157 "key from server %s for domain %s.\n",
3158 cli->desthost, domain ));
3162 status = cli_rpc_pipe_open_schannel_with_key(
3163 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3166 /* Now we've bound using the session key we can close the netlog pipe. */
3167 TALLOC_FREE(netlogon_pipe);
3169 if (NT_STATUS_IS_OK(status)) {
3175 /****************************************************************************
3176 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3177 Fetch the session key ourselves using a temporary netlogon pipe.
3178 ****************************************************************************/
3180 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3181 const struct ndr_syntax_id *interface,
3182 enum dcerpc_transport_t transport,
3183 enum dcerpc_AuthLevel auth_level,
3185 struct rpc_pipe_client **presult)
3187 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3188 struct rpc_pipe_client *netlogon_pipe = NULL;
3189 struct rpc_pipe_client *result = NULL;
3192 status = get_schannel_session_key(cli, domain, &neg_flags,
3194 if (!NT_STATUS_IS_OK(status)) {
3195 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3196 "key from server %s for domain %s.\n",
3197 cli->desthost, domain ));
3201 status = cli_rpc_pipe_open_schannel_with_key(
3202 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3205 /* Now we've bound using the session key we can close the netlog pipe. */
3206 TALLOC_FREE(netlogon_pipe);
3208 if (NT_STATUS_IS_OK(status)) {
3215 /****************************************************************************
3216 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3217 The idea is this can be called with service_princ, username and password all
3218 NULL so long as the caller has a TGT.
3219 ****************************************************************************/
3221 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3222 const struct ndr_syntax_id *interface,
3223 enum dcerpc_transport_t transport,
3224 enum dcerpc_AuthLevel auth_level,
3226 const char *username,
3227 const char *password,
3228 struct rpc_pipe_client **presult)
3230 struct rpc_pipe_client *result;
3231 struct pipe_auth_data *auth;
3234 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3235 if (!NT_STATUS_IS_OK(status)) {
3239 auth = talloc(result, struct pipe_auth_data);
3241 status = NT_STATUS_NO_MEMORY;
3244 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3245 auth->auth_level = auth_level;
3250 auth->user_name = talloc_strdup(auth, username);
3251 if (!auth->user_name) {
3252 status = NT_STATUS_NO_MEMORY;
3256 /* Fixme, should we fetch/set the Realm ? */
3257 auth->domain = talloc_strdup(auth, "");
3258 if (!auth->domain) {
3259 status = NT_STATUS_NO_MEMORY;
3263 status = gse_init_client(auth, auth->auth_type, auth->auth_level,
3264 NULL, server, "cifs", username, password,
3265 GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3267 if (!NT_STATUS_IS_OK(status)) {
3268 DEBUG(0, ("gse_init_client returned %s\n",
3269 nt_errstr(status)));
3273 status = rpc_pipe_bind(result, auth);
3274 if (!NT_STATUS_IS_OK(status)) {
3275 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3276 nt_errstr(status)));
3281 return NT_STATUS_OK;
3284 TALLOC_FREE(result);
3288 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3289 const struct ndr_syntax_id *interface,
3290 enum dcerpc_transport_t transport,
3291 enum dcerpc_AuthLevel auth_level,
3293 const char *username,
3294 const char *password,
3295 struct rpc_pipe_client **presult)
3297 struct rpc_pipe_client *result;
3298 struct pipe_auth_data *auth;
3301 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3302 if (!NT_STATUS_IS_OK(status)) {
3306 auth = talloc(result, struct pipe_auth_data);
3308 status = NT_STATUS_NO_MEMORY;
3311 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3312 auth->auth_level = auth_level;
3314 auth->spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
3319 auth->user_name = talloc_strdup(auth, username);
3320 if (!auth->user_name) {
3321 status = NT_STATUS_NO_MEMORY;
3325 /* Fixme, should we fetch/set the Realm ? */
3326 auth->domain = talloc_strdup(auth, "");
3327 if (!auth->domain) {
3328 status = NT_STATUS_NO_MEMORY;
3332 status = spnego_gssapi_init_client(auth, auth->auth_level,
3333 NULL, server, "cifs",
3336 &auth->a_u.spnego_state);
3337 if (!NT_STATUS_IS_OK(status)) {
3338 DEBUG(0, ("spnego_init_client returned %s\n",
3339 nt_errstr(status)));
3343 status = rpc_pipe_bind(result, auth);
3344 if (!NT_STATUS_IS_OK(status)) {
3345 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3346 nt_errstr(status)));
3351 return NT_STATUS_OK;
3354 TALLOC_FREE(result);
3358 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3359 const struct ndr_syntax_id *interface,
3360 enum dcerpc_transport_t transport,
3361 enum dcerpc_AuthLevel auth_level,
3363 const char *username,
3364 const char *password,
3365 struct rpc_pipe_client **presult)
3367 struct rpc_pipe_client *result;
3368 struct pipe_auth_data *auth;
3371 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3372 if (!NT_STATUS_IS_OK(status)) {
3376 auth = talloc(result, struct pipe_auth_data);
3378 status = NT_STATUS_NO_MEMORY;
3381 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3382 auth->auth_level = auth_level;
3387 auth->user_name = talloc_strdup(auth, username);
3388 if (!auth->user_name) {
3389 status = NT_STATUS_NO_MEMORY;
3396 auth->domain = talloc_strdup(auth, domain);
3397 if (!auth->domain) {
3398 status = NT_STATUS_NO_MEMORY;
3402 status = spnego_ntlmssp_init_client(auth, auth->auth_level,
3403 domain, username, password,
3404 &auth->a_u.spnego_state);
3405 if (!NT_STATUS_IS_OK(status)) {
3406 DEBUG(0, ("spnego_init_client returned %s\n",
3407 nt_errstr(status)));
3411 status = rpc_pipe_bind(result, auth);
3412 if (!NT_STATUS_IS_OK(status)) {
3413 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3414 nt_errstr(status)));
3419 return NT_STATUS_OK;
3422 TALLOC_FREE(result);
3426 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3427 struct rpc_pipe_client *cli,
3428 DATA_BLOB *session_key)
3430 struct pipe_auth_data *a = cli->auth;
3433 if (!session_key || !cli) {
3434 return NT_STATUS_INVALID_PARAMETER;
3438 return NT_STATUS_INVALID_PARAMETER;
3441 switch (cli->auth->auth_type) {
3442 case DCERPC_AUTH_TYPE_SCHANNEL:
3443 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3446 case DCERPC_AUTH_TYPE_SPNEGO:
3447 sk = spnego_get_session_key(a->a_u.spnego_state);
3448 if (sk.length == 0) {
3449 return NT_STATUS_NO_USER_SESSION_KEY;
3452 case DCERPC_AUTH_TYPE_NTLMSSP:
3453 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3455 case DCERPC_AUTH_TYPE_KRB5:
3456 sk = gse_get_session_key(a->a_u.gssapi_state);
3458 case DCERPC_AUTH_TYPE_NONE:
3459 sk = data_blob_const(a->user_session_key.data,
3460 a->user_session_key.length);
3463 return NT_STATUS_NO_USER_SESSION_KEY;
3466 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3467 return NT_STATUS_OK;