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"
35 #define DBGC_CLASS DBGC_RPC_CLI
37 /********************************************************************
38 Pipe description for a DEBUG
39 ********************************************************************/
40 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
41 struct rpc_pipe_client *cli)
43 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
50 /********************************************************************
52 ********************************************************************/
54 static uint32 get_rpc_call_id(void)
56 static uint32 call_id = 0;
60 /*******************************************************************
61 Use SMBreadX to get rest of one fragment's worth of rpc data.
62 Reads the whole size or give an error message
63 ********************************************************************/
65 struct rpc_read_state {
66 struct event_context *ev;
67 struct rpc_cli_transport *transport;
73 static void rpc_read_done(struct tevent_req *subreq);
75 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
76 struct event_context *ev,
77 struct rpc_cli_transport *transport,
78 uint8_t *data, size_t size)
80 struct tevent_req *req, *subreq;
81 struct rpc_read_state *state;
83 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
88 state->transport = transport;
93 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
95 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
100 tevent_req_set_callback(subreq, rpc_read_done, req);
108 static void rpc_read_done(struct tevent_req *subreq)
110 struct tevent_req *req = tevent_req_callback_data(
111 subreq, struct tevent_req);
112 struct rpc_read_state *state = tevent_req_data(
113 req, struct rpc_read_state);
117 status = state->transport->read_recv(subreq, &received);
119 if (!NT_STATUS_IS_OK(status)) {
120 tevent_req_nterror(req, status);
124 state->num_read += received;
125 if (state->num_read == state->size) {
126 tevent_req_done(req);
130 subreq = state->transport->read_send(state, state->ev,
131 state->data + state->num_read,
132 state->size - state->num_read,
133 state->transport->priv);
134 if (tevent_req_nomem(subreq, req)) {
137 tevent_req_set_callback(subreq, rpc_read_done, req);
140 static NTSTATUS rpc_read_recv(struct tevent_req *req)
142 return tevent_req_simple_recv_ntstatus(req);
145 struct rpc_write_state {
146 struct event_context *ev;
147 struct rpc_cli_transport *transport;
153 static void rpc_write_done(struct tevent_req *subreq);
155 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
156 struct event_context *ev,
157 struct rpc_cli_transport *transport,
158 const uint8_t *data, size_t size)
160 struct tevent_req *req, *subreq;
161 struct rpc_write_state *state;
163 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
168 state->transport = transport;
171 state->num_written = 0;
173 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
175 subreq = transport->write_send(state, ev, data, size, transport->priv);
176 if (subreq == NULL) {
179 tevent_req_set_callback(subreq, rpc_write_done, req);
186 static void rpc_write_done(struct tevent_req *subreq)
188 struct tevent_req *req = tevent_req_callback_data(
189 subreq, struct tevent_req);
190 struct rpc_write_state *state = tevent_req_data(
191 req, struct rpc_write_state);
195 status = state->transport->write_recv(subreq, &written);
197 if (!NT_STATUS_IS_OK(status)) {
198 tevent_req_nterror(req, status);
202 state->num_written += written;
204 if (state->num_written == state->size) {
205 tevent_req_done(req);
209 subreq = state->transport->write_send(state, state->ev,
210 state->data + state->num_written,
211 state->size - state->num_written,
212 state->transport->priv);
213 if (tevent_req_nomem(subreq, req)) {
216 tevent_req_set_callback(subreq, rpc_write_done, req);
219 static NTSTATUS rpc_write_recv(struct tevent_req *req)
221 return tevent_req_simple_recv_ntstatus(req);
225 /****************************************************************************
226 Try and get a PDU's worth of data from current_pdu. If not, then read more
228 ****************************************************************************/
230 struct get_complete_frag_state {
231 struct event_context *ev;
232 struct rpc_pipe_client *cli;
237 static void get_complete_frag_got_header(struct tevent_req *subreq);
238 static void get_complete_frag_got_rest(struct tevent_req *subreq);
240 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
241 struct event_context *ev,
242 struct rpc_pipe_client *cli,
245 struct tevent_req *req, *subreq;
246 struct get_complete_frag_state *state;
250 req = tevent_req_create(mem_ctx, &state,
251 struct get_complete_frag_state);
257 state->frag_len = RPC_HEADER_LEN;
260 received = pdu->length;
261 if (received < RPC_HEADER_LEN) {
262 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
263 status = NT_STATUS_NO_MEMORY;
266 subreq = rpc_read_send(state, state->ev,
267 state->cli->transport,
268 pdu->data + received,
269 RPC_HEADER_LEN - received);
270 if (subreq == NULL) {
271 status = NT_STATUS_NO_MEMORY;
274 tevent_req_set_callback(subreq, get_complete_frag_got_header,
279 state->frag_len = dcerpc_get_frag_length(pdu);
282 * Ensure we have frag_len bytes of data.
284 if (received < state->frag_len) {
285 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
286 status = NT_STATUS_NO_MEMORY;
289 subreq = rpc_read_send(state, state->ev,
290 state->cli->transport,
291 pdu->data + received,
292 state->frag_len - received);
293 if (subreq == NULL) {
294 status = NT_STATUS_NO_MEMORY;
297 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
302 status = NT_STATUS_OK;
304 if (NT_STATUS_IS_OK(status)) {
305 tevent_req_done(req);
307 tevent_req_nterror(req, status);
309 return tevent_req_post(req, ev);
312 static void get_complete_frag_got_header(struct tevent_req *subreq)
314 struct tevent_req *req = tevent_req_callback_data(
315 subreq, struct tevent_req);
316 struct get_complete_frag_state *state = tevent_req_data(
317 req, struct get_complete_frag_state);
320 status = rpc_read_recv(subreq);
322 if (!NT_STATUS_IS_OK(status)) {
323 tevent_req_nterror(req, status);
327 state->frag_len = dcerpc_get_frag_length(state->pdu);
329 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
330 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
335 * We're here in this piece of code because we've read exactly
336 * RPC_HEADER_LEN bytes into state->pdu.
339 subreq = rpc_read_send(state, state->ev, state->cli->transport,
340 state->pdu->data + RPC_HEADER_LEN,
341 state->frag_len - RPC_HEADER_LEN);
342 if (tevent_req_nomem(subreq, req)) {
345 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
348 static void get_complete_frag_got_rest(struct tevent_req *subreq)
350 struct tevent_req *req = tevent_req_callback_data(
351 subreq, struct tevent_req);
354 status = rpc_read_recv(subreq);
356 if (!NT_STATUS_IS_OK(status)) {
357 tevent_req_nterror(req, status);
360 tevent_req_done(req);
363 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
365 return tevent_req_simple_recv_ntstatus(req);
368 /****************************************************************************
369 Do basic authentication checks on an incoming pdu.
370 ****************************************************************************/
372 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
373 struct rpc_pipe_client *cli,
374 struct ncacn_packet *pkt,
376 uint8_t expected_pkt_type,
378 DATA_BLOB *reply_pdu)
380 NTSTATUS ret = NT_STATUS_OK;
383 ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
384 if (!NT_STATUS_IS_OK(ret)) {
388 if (pdu->length != pkt->frag_length) {
389 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
390 (unsigned int)pdu->length,
391 (unsigned int)pkt->frag_length));
392 return NT_STATUS_INVALID_PARAMETER;
396 * Point the return values at the real data including the RPC
397 * header. Just in case the caller wants it.
401 /* Ensure we have the correct type. */
402 switch (pkt->ptype) {
403 case DCERPC_PKT_ALTER_RESP:
404 case DCERPC_PKT_BIND_ACK:
406 /* Alter context and bind ack share the same packet definitions. */
410 case DCERPC_PKT_RESPONSE:
412 /* Here's where we deal with incoming sign/seal. */
413 ret = dcerpc_check_auth(cli->auth, pkt,
414 &pkt->u.response.stub_and_verifier,
415 DCERPC_RESPONSE_LENGTH,
417 if (!NT_STATUS_IS_OK(ret)) {
421 if (pdu->length < DCERPC_RESPONSE_LENGTH + pad_len) {
422 return NT_STATUS_BUFFER_TOO_SMALL;
425 /* Point the return values at the NDR data. */
426 rdata->data = pdu->data + DCERPC_RESPONSE_LENGTH;
428 if (pkt->auth_length) {
429 /* We've already done integer wrap tests in
430 * dcerpc_check_auth(). */
431 rdata->length = pdu->length
432 - DCERPC_RESPONSE_LENGTH
434 - DCERPC_AUTH_TRAILER_LENGTH
437 rdata->length = pdu->length - DCERPC_RESPONSE_LENGTH;
440 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
441 (long unsigned int)pdu->length,
442 (long unsigned int)rdata->length,
443 (unsigned int)pad_len));
446 * If this is the first reply, and the allocation hint is
447 * reasonable, try and set up the reply_pdu DATA_BLOB to the
451 if ((reply_pdu->length == 0) &&
452 pkt->u.response.alloc_hint &&
453 (pkt->u.response.alloc_hint < 15*1024*1024)) {
454 if (!data_blob_realloc(mem_ctx, reply_pdu,
455 pkt->u.response.alloc_hint)) {
456 DEBUG(0, ("reply alloc hint %d too "
457 "large to allocate\n",
458 (int)pkt->u.response.alloc_hint));
459 return NT_STATUS_NO_MEMORY;
465 case DCERPC_PKT_BIND_NAK:
466 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
467 "received from %s!\n",
468 rpccli_pipe_txt(talloc_tos(), cli)));
469 /* Use this for now... */
470 return NT_STATUS_NETWORK_ACCESS_DENIED;
472 case DCERPC_PKT_FAULT:
474 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
475 "code %s received from %s!\n",
476 dcerpc_errstr(talloc_tos(),
477 pkt->u.fault.status),
478 rpccli_pipe_txt(talloc_tos(), cli)));
480 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
481 return NT_STATUS_UNSUCCESSFUL;
483 return NT_STATUS(pkt->u.fault.status);
487 DEBUG(0, ("Unknown packet type %u received from %s!\n",
488 (unsigned int)pkt->ptype,
489 rpccli_pipe_txt(talloc_tos(), cli)));
490 return NT_STATUS_INVALID_INFO_CLASS;
493 if (pkt->ptype != expected_pkt_type) {
494 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
495 "got an unexpected RPC packet type - %u, not %u\n",
496 rpccli_pipe_txt(talloc_tos(), cli),
499 return NT_STATUS_INVALID_INFO_CLASS;
502 /* Do this just before return - we don't want to modify any rpc header
503 data before now as we may have needed to do cryptographic actions on
506 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
507 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
508 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
509 "setting fragment first/last ON.\n"));
510 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
511 DCERPC_PFC_FLAG_LAST;
517 /****************************************************************************
518 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
519 ****************************************************************************/
521 struct cli_api_pipe_state {
522 struct event_context *ev;
523 struct rpc_cli_transport *transport;
528 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
529 static void cli_api_pipe_write_done(struct tevent_req *subreq);
530 static void cli_api_pipe_read_done(struct tevent_req *subreq);
532 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
533 struct event_context *ev,
534 struct rpc_cli_transport *transport,
535 uint8_t *data, size_t data_len,
536 uint32_t max_rdata_len)
538 struct tevent_req *req, *subreq;
539 struct cli_api_pipe_state *state;
542 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
547 state->transport = transport;
549 if (max_rdata_len < RPC_HEADER_LEN) {
551 * For a RPC reply we always need at least RPC_HEADER_LEN
552 * bytes. We check this here because we will receive
553 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
555 status = NT_STATUS_INVALID_PARAMETER;
559 if (transport->trans_send != NULL) {
560 subreq = transport->trans_send(state, ev, data, data_len,
561 max_rdata_len, transport->priv);
562 if (subreq == NULL) {
565 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
570 * If the transport does not provide a "trans" routine, i.e. for
571 * example the ncacn_ip_tcp transport, do the write/read step here.
574 subreq = rpc_write_send(state, ev, transport, data, data_len);
575 if (subreq == NULL) {
578 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
582 tevent_req_nterror(req, status);
583 return tevent_req_post(req, ev);
589 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
591 struct tevent_req *req = tevent_req_callback_data(
592 subreq, struct tevent_req);
593 struct cli_api_pipe_state *state = tevent_req_data(
594 req, struct cli_api_pipe_state);
597 status = state->transport->trans_recv(subreq, state, &state->rdata,
600 if (!NT_STATUS_IS_OK(status)) {
601 tevent_req_nterror(req, status);
604 tevent_req_done(req);
607 static void cli_api_pipe_write_done(struct tevent_req *subreq)
609 struct tevent_req *req = tevent_req_callback_data(
610 subreq, struct tevent_req);
611 struct cli_api_pipe_state *state = tevent_req_data(
612 req, struct cli_api_pipe_state);
615 status = rpc_write_recv(subreq);
617 if (!NT_STATUS_IS_OK(status)) {
618 tevent_req_nterror(req, status);
622 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
623 if (tevent_req_nomem(state->rdata, req)) {
628 * We don't need to use rpc_read_send here, the upper layer will cope
629 * with a short read, transport->trans_send could also return less
630 * than state->max_rdata_len.
632 subreq = state->transport->read_send(state, state->ev, state->rdata,
634 state->transport->priv);
635 if (tevent_req_nomem(subreq, req)) {
638 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
641 static void cli_api_pipe_read_done(struct tevent_req *subreq)
643 struct tevent_req *req = tevent_req_callback_data(
644 subreq, struct tevent_req);
645 struct cli_api_pipe_state *state = tevent_req_data(
646 req, struct cli_api_pipe_state);
650 status = state->transport->read_recv(subreq, &received);
652 if (!NT_STATUS_IS_OK(status)) {
653 tevent_req_nterror(req, status);
656 state->rdata_len = received;
657 tevent_req_done(req);
660 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
661 uint8_t **prdata, uint32_t *prdata_len)
663 struct cli_api_pipe_state *state = tevent_req_data(
664 req, struct cli_api_pipe_state);
667 if (tevent_req_is_nterror(req, &status)) {
671 *prdata = talloc_move(mem_ctx, &state->rdata);
672 *prdata_len = state->rdata_len;
676 /****************************************************************************
677 Send data on an rpc pipe via trans. The data must be the last
678 pdu fragment of an NDR data stream.
680 Receive response data from an rpc pipe, which may be large...
682 Read the first fragment: unfortunately have to use SMBtrans for the first
683 bit, then SMBreadX for subsequent bits.
685 If first fragment received also wasn't the last fragment, continue
686 getting fragments until we _do_ receive the last fragment.
688 Request/Response PDU's look like the following...
690 |<------------------PDU len----------------------------------------------->|
691 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
693 +------------+-----------------+-------------+---------------+-------------+
694 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
695 +------------+-----------------+-------------+---------------+-------------+
697 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
698 signing & sealing being negotiated.
700 ****************************************************************************/
702 struct rpc_api_pipe_state {
703 struct event_context *ev;
704 struct rpc_pipe_client *cli;
705 uint8_t expected_pkt_type;
707 DATA_BLOB incoming_frag;
708 struct ncacn_packet *pkt;
712 size_t reply_pdu_offset;
716 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
717 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
719 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
720 struct event_context *ev,
721 struct rpc_pipe_client *cli,
722 DATA_BLOB *data, /* Outgoing PDU */
723 uint8_t expected_pkt_type)
725 struct tevent_req *req, *subreq;
726 struct rpc_api_pipe_state *state;
727 uint16_t max_recv_frag;
730 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
736 state->expected_pkt_type = expected_pkt_type;
737 state->incoming_frag = data_blob_null;
738 state->reply_pdu = data_blob_null;
739 state->reply_pdu_offset = 0;
740 state->endianess = DCERPC_DREP_LE;
743 * Ensure we're not sending too much.
745 if (data->length > cli->max_xmit_frag) {
746 status = NT_STATUS_INVALID_PARAMETER;
750 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
752 /* get the header first, then fetch the rest once we have
753 * the frag_length available */
754 max_recv_frag = RPC_HEADER_LEN;
756 subreq = cli_api_pipe_send(state, ev, cli->transport,
757 data->data, data->length, max_recv_frag);
758 if (subreq == NULL) {
761 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
765 tevent_req_nterror(req, status);
766 return tevent_req_post(req, ev);
772 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
774 struct tevent_req *req = tevent_req_callback_data(
775 subreq, struct tevent_req);
776 struct rpc_api_pipe_state *state = tevent_req_data(
777 req, struct rpc_api_pipe_state);
779 uint8_t *rdata = NULL;
780 uint32_t rdata_len = 0;
782 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
784 if (!NT_STATUS_IS_OK(status)) {
785 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
786 tevent_req_nterror(req, status);
791 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
792 rpccli_pipe_txt(talloc_tos(), state->cli)));
793 tevent_req_done(req);
798 * Move data on state->incoming_frag.
800 state->incoming_frag.data = talloc_move(state, &rdata);
801 state->incoming_frag.length = rdata_len;
802 if (!state->incoming_frag.data) {
803 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
807 /* Ensure we have enough data for a pdu. */
808 subreq = get_complete_frag_send(state, state->ev, state->cli,
809 &state->incoming_frag);
810 if (tevent_req_nomem(subreq, req)) {
813 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
816 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
818 struct tevent_req *req = tevent_req_callback_data(
819 subreq, struct tevent_req);
820 struct rpc_api_pipe_state *state = tevent_req_data(
821 req, struct rpc_api_pipe_state);
823 DATA_BLOB rdata = data_blob_null;
825 status = get_complete_frag_recv(subreq);
827 if (!NT_STATUS_IS_OK(status)) {
828 DEBUG(5, ("get_complete_frag failed: %s\n",
830 tevent_req_nterror(req, status);
834 state->pkt = talloc(state, struct ncacn_packet);
836 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
840 status = cli_pipe_validate_current_pdu(state,
841 state->cli, state->pkt,
842 &state->incoming_frag,
843 state->expected_pkt_type,
847 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
848 (unsigned)state->incoming_frag.length,
849 (unsigned)state->reply_pdu_offset,
852 if (!NT_STATUS_IS_OK(status)) {
853 tevent_req_nterror(req, status);
857 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
858 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
860 * Set the data type correctly for big-endian data on the
863 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
865 rpccli_pipe_txt(talloc_tos(), state->cli)));
866 state->endianess = 0x00; /* BIG ENDIAN */
869 * Check endianness on subsequent packets.
871 if (state->endianess != state->pkt->drep[0]) {
872 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
874 state->endianess?"little":"big",
875 state->pkt->drep[0]?"little":"big"));
876 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
880 /* Now copy the data portion out of the pdu into rbuf. */
881 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
882 if (!data_blob_realloc(NULL, &state->reply_pdu,
883 state->reply_pdu_offset + rdata.length)) {
884 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
889 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
890 rdata.data, rdata.length);
891 state->reply_pdu_offset += rdata.length;
893 /* reset state->incoming_frag, there is no need to free it,
894 * it will be reallocated to the right size the next time
896 state->incoming_frag.length = 0;
898 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
899 /* make sure the pdu length is right now that we
900 * have all the data available (alloc hint may
901 * have allocated more than was actually used) */
902 state->reply_pdu.length = state->reply_pdu_offset;
903 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
904 rpccli_pipe_txt(talloc_tos(), state->cli),
905 (unsigned)state->reply_pdu.length));
906 tevent_req_done(req);
910 subreq = get_complete_frag_send(state, state->ev, state->cli,
911 &state->incoming_frag);
912 if (tevent_req_nomem(subreq, req)) {
915 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
918 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
919 struct ncacn_packet **pkt,
920 DATA_BLOB *reply_pdu)
922 struct rpc_api_pipe_state *state = tevent_req_data(
923 req, struct rpc_api_pipe_state);
926 if (tevent_req_is_nterror(req, &status)) {
930 /* return data to caller and assign it ownership of memory */
932 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
933 reply_pdu->length = state->reply_pdu.length;
934 state->reply_pdu.length = 0;
936 data_blob_free(&state->reply_pdu);
940 *pkt = talloc_steal(mem_ctx, state->pkt);
946 /*******************************************************************
947 Creates krb5 auth bind.
948 ********************************************************************/
950 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
951 enum dcerpc_AuthLevel auth_level,
952 DATA_BLOB *auth_info)
957 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
958 DATA_BLOB tkt = data_blob_null;
959 DATA_BLOB tkt_wrapped = data_blob_null;
961 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
962 a->service_principal ));
964 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
966 ret = cli_krb5_get_ticket(a, a->service_principal, 0,
967 &tkt, &a->session_key,
968 AP_OPTS_MUTUAL_REQUIRED, NULL,
972 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
974 a->service_principal,
975 error_message(ret) ));
977 data_blob_free(&tkt);
978 return NT_STATUS_INVALID_PARAMETER;
981 /* wrap that up in a nice GSS-API wrapping */
982 tkt_wrapped = spnego_gen_krb5_wrap(talloc_tos(), tkt, TOK_ID_KRB_AP_REQ);
984 data_blob_free(&tkt);
986 status = dcerpc_push_dcerpc_auth(cli,
987 DCERPC_AUTH_TYPE_KRB5,
989 0, /* auth_pad_length */
990 1, /* auth_context_id */
993 if (!NT_STATUS_IS_OK(status)) {
994 data_blob_free(&tkt_wrapped);
998 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
999 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1001 return NT_STATUS_OK;
1003 return NT_STATUS_INVALID_PARAMETER;
1007 /*******************************************************************
1008 Creates SPNEGO NTLMSSP auth bind.
1009 ********************************************************************/
1011 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1012 enum dcerpc_AuthLevel auth_level,
1013 DATA_BLOB *auth_info)
1016 DATA_BLOB null_blob = data_blob_null;
1017 DATA_BLOB request = data_blob_null;
1018 DATA_BLOB spnego_msg = data_blob_null;
1019 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1021 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1022 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1026 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1027 data_blob_free(&request);
1031 /* Wrap this in SPNEGO. */
1032 spnego_msg = spnego_gen_negTokenInit(talloc_tos(), OIDs_ntlm, &request, NULL);
1034 data_blob_free(&request);
1036 status = dcerpc_push_dcerpc_auth(cli,
1037 DCERPC_AUTH_TYPE_SPNEGO,
1039 0, /* auth_pad_length */
1040 1, /* auth_context_id */
1044 if (!NT_STATUS_IS_OK(status)) {
1045 data_blob_free(&spnego_msg);
1049 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1050 dump_data(5, spnego_msg.data, spnego_msg.length);
1051 data_blob_free(&spnego_msg);
1053 return NT_STATUS_OK;
1056 /*******************************************************************
1057 Creates NTLMSSP auth bind.
1058 ********************************************************************/
1060 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1061 enum dcerpc_AuthLevel auth_level,
1062 DATA_BLOB *auth_info)
1065 DATA_BLOB null_blob = data_blob_null;
1066 DATA_BLOB request = data_blob_null;
1068 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1069 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1073 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1074 data_blob_free(&request);
1078 status = dcerpc_push_dcerpc_auth(cli,
1079 DCERPC_AUTH_TYPE_NTLMSSP,
1081 0, /* auth_pad_length */
1082 1, /* auth_context_id */
1085 if (!NT_STATUS_IS_OK(status)) {
1086 data_blob_free(&request);
1090 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1091 dump_data(5, request.data, request.length);
1093 return NT_STATUS_OK;
1096 /*******************************************************************
1097 Creates schannel auth bind.
1098 ********************************************************************/
1100 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1101 enum dcerpc_AuthLevel auth_level,
1102 DATA_BLOB *auth_info)
1105 struct NL_AUTH_MESSAGE r;
1106 DATA_BLOB schannel_blob;
1108 /* Use lp_workgroup() if domain not specified */
1110 if (!cli->auth->domain || !cli->auth->domain[0]) {
1111 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1112 if (cli->auth->domain == NULL) {
1113 return NT_STATUS_NO_MEMORY;
1118 * Now marshall the data into the auth parse_struct.
1121 r.MessageType = NL_NEGOTIATE_REQUEST;
1122 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1123 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1124 r.oem_netbios_domain.a = cli->auth->domain;
1125 r.oem_netbios_computer.a = global_myname();
1127 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1128 if (!NT_STATUS_IS_OK(status)) {
1132 status = dcerpc_push_dcerpc_auth(cli,
1133 DCERPC_AUTH_TYPE_SCHANNEL,
1135 0, /* auth_pad_length */
1136 1, /* auth_context_id */
1139 if (!NT_STATUS_IS_OK(status)) {
1143 return NT_STATUS_OK;
1146 /*******************************************************************
1147 Creates the internals of a DCE/RPC bind request or alter context PDU.
1148 ********************************************************************/
1150 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1151 enum dcerpc_pkt_type ptype,
1153 const struct ndr_syntax_id *abstract,
1154 const struct ndr_syntax_id *transfer,
1155 const DATA_BLOB *auth_info,
1158 uint16 auth_len = auth_info->length;
1160 union dcerpc_payload u;
1161 struct dcerpc_ctx_list ctx_list;
1164 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1167 ctx_list.context_id = 0;
1168 ctx_list.num_transfer_syntaxes = 1;
1169 ctx_list.abstract_syntax = *abstract;
1170 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1172 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1173 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1174 u.bind.assoc_group_id = 0x0;
1175 u.bind.num_contexts = 1;
1176 u.bind.ctx_list = &ctx_list;
1177 u.bind.auth_info = *auth_info;
1179 status = dcerpc_push_ncacn_packet(mem_ctx,
1181 DCERPC_PFC_FLAG_FIRST |
1182 DCERPC_PFC_FLAG_LAST,
1187 if (!NT_STATUS_IS_OK(status)) {
1188 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1192 return NT_STATUS_OK;
1195 /*******************************************************************
1196 Creates a DCE/RPC bind request.
1197 ********************************************************************/
1199 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1200 struct rpc_pipe_client *cli,
1201 struct pipe_auth_data *auth,
1203 const struct ndr_syntax_id *abstract,
1204 const struct ndr_syntax_id *transfer,
1207 DATA_BLOB auth_info = data_blob_null;
1208 NTSTATUS ret = NT_STATUS_OK;
1210 switch (auth->auth_type) {
1211 case DCERPC_AUTH_TYPE_SCHANNEL:
1212 ret = create_schannel_auth_rpc_bind_req(cli,
1215 if (!NT_STATUS_IS_OK(ret)) {
1220 case DCERPC_AUTH_TYPE_NTLMSSP:
1221 ret = create_ntlmssp_auth_rpc_bind_req(cli,
1224 if (!NT_STATUS_IS_OK(ret)) {
1229 case DCERPC_AUTH_TYPE_SPNEGO:
1230 if (auth->spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1231 /* "Can't" happen. */
1232 return NT_STATUS_INVALID_INFO_CLASS;
1234 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli,
1237 if (!NT_STATUS_IS_OK(ret)) {
1242 case DCERPC_AUTH_TYPE_KRB5:
1243 ret = create_krb5_auth_bind_req(cli,
1246 if (!NT_STATUS_IS_OK(ret)) {
1251 case DCERPC_AUTH_TYPE_NONE:
1255 /* "Can't" happen. */
1256 return NT_STATUS_INVALID_INFO_CLASS;
1259 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1269 /*******************************************************************
1270 Calculate how much data we're going to send in this packet, also
1271 work out any sign/seal padding length.
1272 ********************************************************************/
1274 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1278 uint32 *p_ss_padding)
1280 uint32 data_space, data_len;
1283 if ((data_left > 0) && (sys_random() % 2)) {
1284 data_left = MAX(data_left/2, 1);
1288 switch (cli->auth->auth_level) {
1289 case DCERPC_AUTH_LEVEL_NONE:
1290 case DCERPC_AUTH_LEVEL_CONNECT:
1291 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1292 data_len = MIN(data_space, data_left);
1295 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1298 case DCERPC_AUTH_LEVEL_INTEGRITY:
1299 case DCERPC_AUTH_LEVEL_PRIVACY:
1300 /* Treat the same for all authenticated rpc requests. */
1301 switch(cli->auth->auth_type) {
1302 case DCERPC_AUTH_TYPE_SPNEGO:
1303 switch (cli->auth->spnego_type) {
1304 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1305 *p_auth_len = NTLMSSP_SIG_SIZE;
1308 smb_panic("bad auth type");
1311 case DCERPC_AUTH_TYPE_NTLMSSP:
1312 *p_auth_len = NTLMSSP_SIG_SIZE;
1314 case DCERPC_AUTH_TYPE_SCHANNEL:
1315 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1318 smb_panic("bad auth type");
1322 data_space = cli->max_xmit_frag
1323 - DCERPC_REQUEST_LENGTH
1324 - DCERPC_AUTH_TRAILER_LENGTH
1327 data_len = MIN(data_space, data_left);
1329 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1330 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1332 *p_frag_len = DCERPC_REQUEST_LENGTH
1333 + data_len + *p_ss_padding
1334 + DCERPC_AUTH_TRAILER_LENGTH
1339 smb_panic("bad auth level");
1345 /*******************************************************************
1347 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1348 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1349 and deals with signing/sealing details.
1350 ********************************************************************/
1352 struct rpc_api_pipe_req_state {
1353 struct event_context *ev;
1354 struct rpc_pipe_client *cli;
1357 DATA_BLOB *req_data;
1358 uint32_t req_data_sent;
1360 DATA_BLOB reply_pdu;
1363 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1364 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1365 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1366 bool *is_last_frag);
1368 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1369 struct event_context *ev,
1370 struct rpc_pipe_client *cli,
1372 DATA_BLOB *req_data)
1374 struct tevent_req *req, *subreq;
1375 struct rpc_api_pipe_req_state *state;
1379 req = tevent_req_create(mem_ctx, &state,
1380 struct rpc_api_pipe_req_state);
1386 state->op_num = op_num;
1387 state->req_data = req_data;
1388 state->req_data_sent = 0;
1389 state->call_id = get_rpc_call_id();
1390 state->reply_pdu = data_blob_null;
1391 state->rpc_out = data_blob_null;
1393 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1394 + RPC_MAX_SIGN_SIZE) {
1395 /* Server is screwed up ! */
1396 status = NT_STATUS_INVALID_PARAMETER;
1400 status = prepare_next_frag(state, &is_last_frag);
1401 if (!NT_STATUS_IS_OK(status)) {
1406 subreq = rpc_api_pipe_send(state, ev, state->cli,
1408 DCERPC_PKT_RESPONSE);
1409 if (subreq == NULL) {
1412 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1414 subreq = rpc_write_send(state, ev, cli->transport,
1415 state->rpc_out.data,
1416 state->rpc_out.length);
1417 if (subreq == NULL) {
1420 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1426 tevent_req_nterror(req, status);
1427 return tevent_req_post(req, ev);
1433 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1436 uint32_t data_sent_thistime;
1440 uint32_t ss_padding;
1443 union dcerpc_payload u;
1445 data_left = state->req_data->length - state->req_data_sent;
1447 data_sent_thistime = calculate_data_len_tosend(
1448 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
1450 if (state->req_data_sent == 0) {
1451 flags = DCERPC_PFC_FLAG_FIRST;
1454 if (data_sent_thistime == data_left) {
1455 flags |= DCERPC_PFC_FLAG_LAST;
1458 data_blob_free(&state->rpc_out);
1460 ZERO_STRUCT(u.request);
1462 u.request.alloc_hint = state->req_data->length;
1463 u.request.context_id = 0;
1464 u.request.opnum = state->op_num;
1466 status = dcerpc_push_ncacn_packet(state,
1473 if (!NT_STATUS_IS_OK(status)) {
1477 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1478 * compute it right for requests because the auth trailer is missing
1480 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1482 /* Copy in the data. */
1483 if (!data_blob_append(NULL, &state->rpc_out,
1484 state->req_data->data + state->req_data_sent,
1485 data_sent_thistime)) {
1486 return NT_STATUS_NO_MEMORY;
1489 status = dcerpc_add_auth_footer(state->cli->auth, ss_padding,
1491 if (!NT_STATUS_IS_OK(status)) {
1495 state->req_data_sent += data_sent_thistime;
1496 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1501 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1503 struct tevent_req *req = tevent_req_callback_data(
1504 subreq, struct tevent_req);
1505 struct rpc_api_pipe_req_state *state = tevent_req_data(
1506 req, struct rpc_api_pipe_req_state);
1510 status = rpc_write_recv(subreq);
1511 TALLOC_FREE(subreq);
1512 if (!NT_STATUS_IS_OK(status)) {
1513 tevent_req_nterror(req, status);
1517 status = prepare_next_frag(state, &is_last_frag);
1518 if (!NT_STATUS_IS_OK(status)) {
1519 tevent_req_nterror(req, status);
1524 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1526 DCERPC_PKT_RESPONSE);
1527 if (tevent_req_nomem(subreq, req)) {
1530 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1532 subreq = rpc_write_send(state, state->ev,
1533 state->cli->transport,
1534 state->rpc_out.data,
1535 state->rpc_out.length);
1536 if (tevent_req_nomem(subreq, req)) {
1539 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1544 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1546 struct tevent_req *req = tevent_req_callback_data(
1547 subreq, struct tevent_req);
1548 struct rpc_api_pipe_req_state *state = tevent_req_data(
1549 req, struct rpc_api_pipe_req_state);
1552 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1553 TALLOC_FREE(subreq);
1554 if (!NT_STATUS_IS_OK(status)) {
1555 tevent_req_nterror(req, status);
1558 tevent_req_done(req);
1561 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1562 DATA_BLOB *reply_pdu)
1564 struct rpc_api_pipe_req_state *state = tevent_req_data(
1565 req, struct rpc_api_pipe_req_state);
1568 if (tevent_req_is_nterror(req, &status)) {
1570 * We always have to initialize to reply pdu, even if there is
1571 * none. The rpccli_* caller routines expect this.
1573 *reply_pdu = data_blob_null;
1577 /* return data to caller and assign it ownership of memory */
1578 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1579 reply_pdu->length = state->reply_pdu.length;
1580 state->reply_pdu.length = 0;
1582 return NT_STATUS_OK;
1586 /****************************************************************************
1587 Set the handle state.
1588 ****************************************************************************/
1590 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1591 const char *pipe_name, uint16 device_state)
1593 bool state_set = False;
1595 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1596 char *rparam = NULL;
1598 uint32 rparam_len, rdata_len;
1600 if (pipe_name == NULL)
1603 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1604 cli->fnum, pipe_name, device_state));
1606 /* create parameters: device state */
1607 SSVAL(param, 0, device_state);
1609 /* create setup parameters. */
1611 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1613 /* send the data on \PIPE\ */
1614 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1615 setup, 2, 0, /* setup, length, max */
1616 param, 2, 0, /* param, length, max */
1617 NULL, 0, 1024, /* data, length, max */
1618 &rparam, &rparam_len, /* return param, length */
1619 &rdata, &rdata_len)) /* return data, length */
1621 DEBUG(5, ("Set Handle state: return OK\n"));
1632 /****************************************************************************
1633 Check the rpc bind acknowledge response.
1634 ****************************************************************************/
1636 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1637 const struct ndr_syntax_id *transfer)
1639 struct dcerpc_ack_ctx ctx;
1641 if (r->secondary_address_size == 0) {
1642 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1645 if (r->num_results < 1 || !r->ctx_list) {
1649 ctx = r->ctx_list[0];
1651 /* check the transfer syntax */
1652 if ((ctx.syntax.if_version != transfer->if_version) ||
1653 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1654 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1658 if (r->num_results != 0x1 || ctx.result != 0) {
1659 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1660 r->num_results, ctx.reason));
1663 DEBUG(5,("check_bind_response: accepted!\n"));
1667 /*******************************************************************
1668 Creates a DCE/RPC bind authentication response.
1669 This is the packet that is sent back to the server once we
1670 have received a BIND-ACK, to finish the third leg of
1671 the authentication handshake.
1672 ********************************************************************/
1674 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1675 struct rpc_pipe_client *cli,
1677 enum dcerpc_AuthType auth_type,
1678 enum dcerpc_AuthLevel auth_level,
1679 DATA_BLOB *pauth_blob,
1683 union dcerpc_payload u;
1687 status = dcerpc_push_dcerpc_auth(mem_ctx,
1690 0, /* auth_pad_length */
1691 1, /* auth_context_id */
1693 &u.auth3.auth_info);
1694 if (!NT_STATUS_IS_OK(status)) {
1698 status = dcerpc_push_ncacn_packet(mem_ctx,
1700 DCERPC_PFC_FLAG_FIRST |
1701 DCERPC_PFC_FLAG_LAST,
1706 data_blob_free(&u.auth3.auth_info);
1707 if (!NT_STATUS_IS_OK(status)) {
1708 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1712 return NT_STATUS_OK;
1715 /*******************************************************************
1716 Creates a DCE/RPC bind alter context authentication request which
1717 may contain a spnego auth blobl
1718 ********************************************************************/
1720 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1722 const struct ndr_syntax_id *abstract,
1723 const struct ndr_syntax_id *transfer,
1724 enum dcerpc_AuthLevel auth_level,
1725 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1728 DATA_BLOB auth_info;
1731 status = dcerpc_push_dcerpc_auth(mem_ctx,
1732 DCERPC_AUTH_TYPE_SPNEGO,
1734 0, /* auth_pad_length */
1735 1, /* auth_context_id */
1738 if (!NT_STATUS_IS_OK(status)) {
1742 status = create_bind_or_alt_ctx_internal(mem_ctx,
1749 data_blob_free(&auth_info);
1753 /****************************************************************************
1755 ****************************************************************************/
1757 struct rpc_pipe_bind_state {
1758 struct event_context *ev;
1759 struct rpc_pipe_client *cli;
1761 uint32_t rpc_call_id;
1764 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1765 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1766 struct rpc_pipe_bind_state *state,
1767 DATA_BLOB *credentials);
1768 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1769 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1770 struct rpc_pipe_bind_state *state,
1771 DATA_BLOB *credentials);
1772 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1774 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1775 struct event_context *ev,
1776 struct rpc_pipe_client *cli,
1777 struct pipe_auth_data *auth)
1779 struct tevent_req *req, *subreq;
1780 struct rpc_pipe_bind_state *state;
1783 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1788 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1789 rpccli_pipe_txt(talloc_tos(), cli),
1790 (unsigned int)auth->auth_type,
1791 (unsigned int)auth->spnego_type,
1792 (unsigned int)auth->auth_level ));
1796 state->rpc_call_id = get_rpc_call_id();
1797 state->rpc_out = data_blob_null;
1799 cli->auth = talloc_move(cli, &auth);
1801 /* Marshall the outgoing data. */
1802 status = create_rpc_bind_req(state, cli,
1805 &cli->abstract_syntax,
1806 &cli->transfer_syntax,
1809 if (!NT_STATUS_IS_OK(status)) {
1813 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1814 DCERPC_PKT_BIND_ACK);
1815 if (subreq == NULL) {
1818 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1822 tevent_req_nterror(req, status);
1823 return tevent_req_post(req, ev);
1829 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1831 struct tevent_req *req = tevent_req_callback_data(
1832 subreq, struct tevent_req);
1833 struct rpc_pipe_bind_state *state = tevent_req_data(
1834 req, struct rpc_pipe_bind_state);
1835 DATA_BLOB reply_pdu;
1836 struct ncacn_packet *pkt;
1837 struct dcerpc_auth auth;
1840 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1841 TALLOC_FREE(subreq);
1842 if (!NT_STATUS_IS_OK(status)) {
1843 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1844 rpccli_pipe_txt(talloc_tos(), state->cli),
1845 nt_errstr(status)));
1846 tevent_req_nterror(req, status);
1850 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1851 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1852 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1856 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1857 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1859 switch(state->cli->auth->auth_type) {
1861 case DCERPC_AUTH_TYPE_NONE:
1862 case DCERPC_AUTH_TYPE_SCHANNEL:
1863 /* Bind complete. */
1864 tevent_req_done(req);
1867 case DCERPC_AUTH_TYPE_NTLMSSP:
1868 case DCERPC_AUTH_TYPE_SPNEGO:
1869 case DCERPC_AUTH_TYPE_KRB5:
1870 /* Paranoid lenght checks */
1871 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1872 + pkt->auth_length) {
1873 tevent_req_nterror(req,
1874 NT_STATUS_INFO_LENGTH_MISMATCH);
1877 /* get auth credentials */
1878 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1879 &pkt->u.bind_ack.auth_info,
1881 if (!NT_STATUS_IS_OK(status)) {
1882 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1883 nt_errstr(status)));
1884 tevent_req_nterror(req, status);
1894 * For authenticated binds we may need to do 3 or 4 leg binds.
1897 switch(state->cli->auth->auth_type) {
1899 case DCERPC_AUTH_TYPE_NONE:
1900 case DCERPC_AUTH_TYPE_SCHANNEL:
1901 /* Bind complete. */
1902 tevent_req_done(req);
1905 case DCERPC_AUTH_TYPE_NTLMSSP:
1906 /* Need to send AUTH3 packet - no reply. */
1907 status = rpc_finish_auth3_bind_send(req, state,
1911 case DCERPC_AUTH_TYPE_SPNEGO:
1912 if (state->cli->auth->spnego_type !=
1913 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1916 /* Need to send alter context request and reply. */
1917 status = rpc_finish_spnego_ntlmssp_bind_send(req, state,
1921 case DCERPC_AUTH_TYPE_KRB5:
1922 status = NT_STATUS_NOT_IMPLEMENTED;
1929 if (!NT_STATUS_IS_OK(status)) {
1930 tevent_req_nterror(req, status);
1935 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
1936 (unsigned int)state->cli->auth->auth_type,
1937 (unsigned int)state->cli->auth->spnego_type));
1938 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1941 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1942 struct rpc_pipe_bind_state *state,
1943 DATA_BLOB *credentials)
1945 struct pipe_auth_data *auth = state->cli->auth;
1946 DATA_BLOB client_reply = data_blob_null;
1947 struct tevent_req *subreq;
1950 /* TODO - check auth_type/auth_level match. */
1952 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
1953 *credentials, &client_reply);
1955 if (!NT_STATUS_IS_OK(status)) {
1956 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
1957 "blob failed: %s.\n", nt_errstr(status)));
1961 data_blob_free(&state->rpc_out);
1963 status = create_rpc_bind_auth3(state, state->cli,
1969 data_blob_free(&client_reply);
1971 if (!NT_STATUS_IS_OK(status)) {
1975 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1976 state->rpc_out.data, state->rpc_out.length);
1977 if (subreq == NULL) {
1978 return NT_STATUS_NO_MEMORY;
1980 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
1981 return NT_STATUS_OK;
1984 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
1986 struct tevent_req *req = tevent_req_callback_data(
1987 subreq, struct tevent_req);
1990 status = rpc_write_recv(subreq);
1991 TALLOC_FREE(subreq);
1992 if (!NT_STATUS_IS_OK(status)) {
1993 tevent_req_nterror(req, status);
1996 tevent_req_done(req);
1999 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2000 struct rpc_pipe_bind_state *state,
2001 DATA_BLOB *credentials)
2003 struct pipe_auth_data *auth = state->cli->auth;
2004 DATA_BLOB server_ntlm_response = data_blob_null;
2005 DATA_BLOB client_reply = data_blob_null;
2006 DATA_BLOB tmp_blob = data_blob_null;
2007 struct tevent_req *subreq;
2011 * The server might give us back two challenges - tmp_blob is for the
2014 if (!spnego_parse_challenge(state, *credentials,
2015 &server_ntlm_response,
2017 data_blob_free(&server_ntlm_response);
2018 data_blob_free(&tmp_blob);
2019 return NT_STATUS_INVALID_PARAMETER;
2022 /* We're finished with the server spnego response and the tmp_blob. */
2023 data_blob_free(&tmp_blob);
2025 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2026 server_ntlm_response, &client_reply);
2028 /* Finished with the server_ntlm response */
2029 data_blob_free(&server_ntlm_response);
2031 if (!NT_STATUS_IS_OK(status)) {
2032 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2033 "using server blob failed.\n"));
2034 data_blob_free(&client_reply);
2038 /* SPNEGO wrap the client reply. */
2039 tmp_blob = spnego_gen_auth(state, client_reply);
2040 data_blob_free(&client_reply);
2041 client_reply = tmp_blob;
2042 tmp_blob = data_blob_null;
2044 /* Now prepare the alter context pdu. */
2045 data_blob_free(&state->rpc_out);
2047 status = create_rpc_alter_context(state,
2049 &state->cli->abstract_syntax,
2050 &state->cli->transfer_syntax,
2054 data_blob_free(&client_reply);
2056 if (!NT_STATUS_IS_OK(status)) {
2060 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2061 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2062 if (subreq == NULL) {
2063 return NT_STATUS_NO_MEMORY;
2065 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2066 return NT_STATUS_OK;
2069 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2071 struct tevent_req *req = tevent_req_callback_data(
2072 subreq, struct tevent_req);
2073 struct rpc_pipe_bind_state *state = tevent_req_data(
2074 req, struct rpc_pipe_bind_state);
2075 DATA_BLOB tmp_blob = data_blob_null;
2076 struct ncacn_packet *pkt;
2077 struct dcerpc_auth auth;
2080 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2081 TALLOC_FREE(subreq);
2082 if (!NT_STATUS_IS_OK(status)) {
2083 tevent_req_nterror(req, status);
2087 status = dcerpc_pull_dcerpc_auth(pkt,
2088 &pkt->u.alter_resp.auth_info,
2090 if (!NT_STATUS_IS_OK(status)) {
2091 tevent_req_nterror(req, status);
2095 /* Check we got a valid auth response. */
2096 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2098 OID_NTLMSSP, &tmp_blob)) {
2099 data_blob_free(&tmp_blob);
2100 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2104 data_blob_free(&tmp_blob);
2106 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2107 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2108 tevent_req_done(req);
2111 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2113 return tevent_req_simple_recv_ntstatus(req);
2116 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2117 struct pipe_auth_data *auth)
2119 TALLOC_CTX *frame = talloc_stackframe();
2120 struct event_context *ev;
2121 struct tevent_req *req;
2122 NTSTATUS status = NT_STATUS_OK;
2124 ev = event_context_init(frame);
2126 status = NT_STATUS_NO_MEMORY;
2130 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2132 status = NT_STATUS_NO_MEMORY;
2136 if (!tevent_req_poll(req, ev)) {
2137 status = map_nt_error_from_unix(errno);
2141 status = rpc_pipe_bind_recv(req);
2147 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2149 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2150 unsigned int timeout)
2154 if (rpc_cli->transport == NULL) {
2155 return RPCCLI_DEFAULT_TIMEOUT;
2158 if (rpc_cli->transport->set_timeout == NULL) {
2159 return RPCCLI_DEFAULT_TIMEOUT;
2162 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2164 return RPCCLI_DEFAULT_TIMEOUT;
2170 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2172 if (rpc_cli == NULL) {
2176 if (rpc_cli->transport == NULL) {
2180 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2183 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2185 struct cli_state *cli;
2187 if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP)
2188 || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO
2189 && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2190 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2194 cli = rpc_pipe_np_smb_conn(rpc_cli);
2198 E_md4hash(cli->password ? cli->password : "", nt_hash);
2202 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2203 struct pipe_auth_data **presult)
2205 struct pipe_auth_data *result;
2207 result = talloc(mem_ctx, struct pipe_auth_data);
2208 if (result == NULL) {
2209 return NT_STATUS_NO_MEMORY;
2212 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2213 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2214 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2216 result->user_name = talloc_strdup(result, "");
2217 result->domain = talloc_strdup(result, "");
2218 if ((result->user_name == NULL) || (result->domain == NULL)) {
2219 TALLOC_FREE(result);
2220 return NT_STATUS_NO_MEMORY;
2224 return NT_STATUS_OK;
2227 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2229 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2233 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2234 enum dcerpc_AuthType auth_type,
2235 enum pipe_auth_type_spnego spnego_type,
2236 enum dcerpc_AuthLevel auth_level,
2238 const char *username,
2239 const char *password,
2240 struct pipe_auth_data **presult)
2242 struct pipe_auth_data *result;
2245 result = talloc(mem_ctx, struct pipe_auth_data);
2246 if (result == NULL) {
2247 return NT_STATUS_NO_MEMORY;
2250 result->auth_type = auth_type;
2251 result->spnego_type = spnego_type;
2252 result->auth_level = auth_level;
2254 result->user_name = talloc_strdup(result, username);
2255 result->domain = talloc_strdup(result, domain);
2256 if ((result->user_name == NULL) || (result->domain == NULL)) {
2257 status = NT_STATUS_NO_MEMORY;
2261 status = auth_ntlmssp_client_start(NULL,
2264 lp_client_ntlmv2_auth(),
2265 &result->a_u.auth_ntlmssp_state);
2266 if (!NT_STATUS_IS_OK(status)) {
2270 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2272 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2274 if (!NT_STATUS_IS_OK(status)) {
2278 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2280 if (!NT_STATUS_IS_OK(status)) {
2284 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2286 if (!NT_STATUS_IS_OK(status)) {
2291 * Turn off sign+seal to allow selected auth level to turn it back on.
2293 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2294 ~(NTLMSSP_NEGOTIATE_SIGN |
2295 NTLMSSP_NEGOTIATE_SEAL));
2297 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2298 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2299 NTLMSSP_NEGOTIATE_SIGN);
2300 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2301 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2302 NTLMSSP_NEGOTIATE_SEAL |
2303 NTLMSSP_NEGOTIATE_SIGN);
2307 return NT_STATUS_OK;
2310 TALLOC_FREE(result);
2314 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2315 enum dcerpc_AuthLevel auth_level,
2316 struct netlogon_creds_CredentialState *creds,
2317 struct pipe_auth_data **presult)
2319 struct pipe_auth_data *result;
2321 result = talloc(mem_ctx, struct pipe_auth_data);
2322 if (result == NULL) {
2323 return NT_STATUS_NO_MEMORY;
2326 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2327 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2328 result->auth_level = auth_level;
2330 result->user_name = talloc_strdup(result, "");
2331 result->domain = talloc_strdup(result, domain);
2332 if ((result->user_name == NULL) || (result->domain == NULL)) {
2336 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2337 if (result->a_u.schannel_auth == NULL) {
2341 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2342 result->a_u.schannel_auth->seq_num = 0;
2343 result->a_u.schannel_auth->initiator = true;
2344 result->a_u.schannel_auth->creds = creds;
2347 return NT_STATUS_OK;
2350 TALLOC_FREE(result);
2351 return NT_STATUS_NO_MEMORY;
2355 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2357 data_blob_free(&auth->session_key);
2362 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2363 enum dcerpc_AuthLevel auth_level,
2364 const char *service_princ,
2365 const char *username,
2366 const char *password,
2367 struct pipe_auth_data **presult)
2370 struct pipe_auth_data *result;
2372 if ((username != NULL) && (password != NULL)) {
2373 int ret = kerberos_kinit_password(username, password, 0, NULL);
2375 return NT_STATUS_ACCESS_DENIED;
2379 result = talloc(mem_ctx, struct pipe_auth_data);
2380 if (result == NULL) {
2381 return NT_STATUS_NO_MEMORY;
2384 result->auth_type = DCERPC_AUTH_TYPE_KRB5;
2385 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2386 result->auth_level = auth_level;
2389 * Username / domain need fixing!
2391 result->user_name = talloc_strdup(result, "");
2392 result->domain = talloc_strdup(result, "");
2393 if ((result->user_name == NULL) || (result->domain == NULL)) {
2397 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2398 result, struct kerberos_auth_struct);
2399 if (result->a_u.kerberos_auth == NULL) {
2402 talloc_set_destructor(result->a_u.kerberos_auth,
2403 cli_auth_kerberos_data_destructor);
2405 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2406 result, service_princ);
2407 if (result->a_u.kerberos_auth->service_principal == NULL) {
2412 return NT_STATUS_OK;
2415 TALLOC_FREE(result);
2416 return NT_STATUS_NO_MEMORY;
2418 return NT_STATUS_NOT_SUPPORTED;
2423 * Create an rpc pipe client struct, connecting to a tcp port.
2425 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2427 const struct ndr_syntax_id *abstract_syntax,
2428 struct rpc_pipe_client **presult)
2430 struct rpc_pipe_client *result;
2431 struct sockaddr_storage addr;
2435 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2436 if (result == NULL) {
2437 return NT_STATUS_NO_MEMORY;
2440 result->abstract_syntax = *abstract_syntax;
2441 result->transfer_syntax = ndr_transfer_syntax;
2442 result->dispatch = cli_do_rpc_ndr;
2443 result->dispatch_send = cli_do_rpc_ndr_send;
2444 result->dispatch_recv = cli_do_rpc_ndr_recv;
2446 result->desthost = talloc_strdup(result, host);
2447 result->srv_name_slash = talloc_asprintf_strupper_m(
2448 result, "\\\\%s", result->desthost);
2449 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2450 status = NT_STATUS_NO_MEMORY;
2454 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2455 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2457 if (!resolve_name(host, &addr, 0, false)) {
2458 status = NT_STATUS_NOT_FOUND;
2462 status = open_socket_out(&addr, port, 60, &fd);
2463 if (!NT_STATUS_IS_OK(status)) {
2466 set_socket_options(fd, lp_socket_options());
2468 status = rpc_transport_sock_init(result, fd, &result->transport);
2469 if (!NT_STATUS_IS_OK(status)) {
2474 result->transport->transport = NCACN_IP_TCP;
2477 return NT_STATUS_OK;
2480 TALLOC_FREE(result);
2485 * Determine the tcp port on which a dcerpc interface is listening
2486 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2489 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2490 const struct ndr_syntax_id *abstract_syntax,
2494 struct rpc_pipe_client *epm_pipe = NULL;
2495 struct pipe_auth_data *auth = NULL;
2496 struct dcerpc_binding *map_binding = NULL;
2497 struct dcerpc_binding *res_binding = NULL;
2498 struct epm_twr_t *map_tower = NULL;
2499 struct epm_twr_t *res_towers = NULL;
2500 struct policy_handle *entry_handle = NULL;
2501 uint32_t num_towers = 0;
2502 uint32_t max_towers = 1;
2503 struct epm_twr_p_t towers;
2504 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2506 if (pport == NULL) {
2507 status = NT_STATUS_INVALID_PARAMETER;
2511 /* open the connection to the endpoint mapper */
2512 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2513 &ndr_table_epmapper.syntax_id,
2516 if (!NT_STATUS_IS_OK(status)) {
2520 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2521 if (!NT_STATUS_IS_OK(status)) {
2525 status = rpc_pipe_bind(epm_pipe, auth);
2526 if (!NT_STATUS_IS_OK(status)) {
2530 /* create tower for asking the epmapper */
2532 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2533 if (map_binding == NULL) {
2534 status = NT_STATUS_NO_MEMORY;
2538 map_binding->transport = NCACN_IP_TCP;
2539 map_binding->object = *abstract_syntax;
2540 map_binding->host = host; /* needed? */
2541 map_binding->endpoint = "0"; /* correct? needed? */
2543 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2544 if (map_tower == NULL) {
2545 status = NT_STATUS_NO_MEMORY;
2549 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2550 &(map_tower->tower));
2551 if (!NT_STATUS_IS_OK(status)) {
2555 /* allocate further parameters for the epm_Map call */
2557 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2558 if (res_towers == NULL) {
2559 status = NT_STATUS_NO_MEMORY;
2562 towers.twr = res_towers;
2564 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2565 if (entry_handle == NULL) {
2566 status = NT_STATUS_NO_MEMORY;
2570 /* ask the endpoint mapper for the port */
2572 status = rpccli_epm_Map(epm_pipe,
2574 CONST_DISCARD(struct GUID *,
2575 &(abstract_syntax->uuid)),
2582 if (!NT_STATUS_IS_OK(status)) {
2586 if (num_towers != 1) {
2587 status = NT_STATUS_UNSUCCESSFUL;
2591 /* extract the port from the answer */
2593 status = dcerpc_binding_from_tower(tmp_ctx,
2594 &(towers.twr->tower),
2596 if (!NT_STATUS_IS_OK(status)) {
2600 /* are further checks here necessary? */
2601 if (res_binding->transport != NCACN_IP_TCP) {
2602 status = NT_STATUS_UNSUCCESSFUL;
2606 *pport = (uint16_t)atoi(res_binding->endpoint);
2609 TALLOC_FREE(tmp_ctx);
2614 * Create a rpc pipe client struct, connecting to a host via tcp.
2615 * The port is determined by asking the endpoint mapper on the given
2618 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2619 const struct ndr_syntax_id *abstract_syntax,
2620 struct rpc_pipe_client **presult)
2625 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2626 if (!NT_STATUS_IS_OK(status)) {
2630 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2631 abstract_syntax, presult);
2634 /********************************************************************
2635 Create a rpc pipe client struct, connecting to a unix domain socket
2636 ********************************************************************/
2637 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2638 const struct ndr_syntax_id *abstract_syntax,
2639 struct rpc_pipe_client **presult)
2641 struct rpc_pipe_client *result;
2642 struct sockaddr_un addr;
2646 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2647 if (result == NULL) {
2648 return NT_STATUS_NO_MEMORY;
2651 result->abstract_syntax = *abstract_syntax;
2652 result->transfer_syntax = ndr_transfer_syntax;
2653 result->dispatch = cli_do_rpc_ndr;
2654 result->dispatch_send = cli_do_rpc_ndr_send;
2655 result->dispatch_recv = cli_do_rpc_ndr_recv;
2657 result->desthost = get_myname(result);
2658 result->srv_name_slash = talloc_asprintf_strupper_m(
2659 result, "\\\\%s", result->desthost);
2660 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2661 status = NT_STATUS_NO_MEMORY;
2665 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2666 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2668 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2670 status = map_nt_error_from_unix(errno);
2675 addr.sun_family = AF_UNIX;
2676 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2678 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2679 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2682 return map_nt_error_from_unix(errno);
2685 status = rpc_transport_sock_init(result, fd, &result->transport);
2686 if (!NT_STATUS_IS_OK(status)) {
2691 result->transport->transport = NCALRPC;
2694 return NT_STATUS_OK;
2697 TALLOC_FREE(result);
2701 struct rpc_pipe_client_np_ref {
2702 struct cli_state *cli;
2703 struct rpc_pipe_client *pipe;
2706 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2708 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2712 /****************************************************************************
2713 Open a named pipe over SMB to a remote server.
2715 * CAVEAT CALLER OF THIS FUNCTION:
2716 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2717 * so be sure that this function is called AFTER any structure (vs pointer)
2718 * assignment of the cli. In particular, libsmbclient does structure
2719 * assignments of cli, which invalidates the data in the returned
2720 * rpc_pipe_client if this function is called before the structure assignment
2723 ****************************************************************************/
2725 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2726 const struct ndr_syntax_id *abstract_syntax,
2727 struct rpc_pipe_client **presult)
2729 struct rpc_pipe_client *result;
2731 struct rpc_pipe_client_np_ref *np_ref;
2733 /* sanity check to protect against crashes */
2736 return NT_STATUS_INVALID_HANDLE;
2739 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2740 if (result == NULL) {
2741 return NT_STATUS_NO_MEMORY;
2744 result->abstract_syntax = *abstract_syntax;
2745 result->transfer_syntax = ndr_transfer_syntax;
2746 result->dispatch = cli_do_rpc_ndr;
2747 result->dispatch_send = cli_do_rpc_ndr_send;
2748 result->dispatch_recv = cli_do_rpc_ndr_recv;
2749 result->desthost = talloc_strdup(result, cli->desthost);
2750 result->srv_name_slash = talloc_asprintf_strupper_m(
2751 result, "\\\\%s", result->desthost);
2753 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2754 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2756 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2757 TALLOC_FREE(result);
2758 return NT_STATUS_NO_MEMORY;
2761 status = rpc_transport_np_init(result, cli, abstract_syntax,
2762 &result->transport);
2763 if (!NT_STATUS_IS_OK(status)) {
2764 TALLOC_FREE(result);
2768 result->transport->transport = NCACN_NP;
2770 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2771 if (np_ref == NULL) {
2772 TALLOC_FREE(result);
2773 return NT_STATUS_NO_MEMORY;
2776 np_ref->pipe = result;
2778 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2779 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2782 return NT_STATUS_OK;
2785 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2786 struct rpc_cli_smbd_conn *conn,
2787 const struct ndr_syntax_id *syntax,
2788 struct rpc_pipe_client **presult)
2790 struct rpc_pipe_client *result;
2791 struct pipe_auth_data *auth;
2794 result = talloc(mem_ctx, struct rpc_pipe_client);
2795 if (result == NULL) {
2796 return NT_STATUS_NO_MEMORY;
2798 result->abstract_syntax = *syntax;
2799 result->transfer_syntax = ndr_transfer_syntax;
2800 result->dispatch = cli_do_rpc_ndr;
2801 result->dispatch_send = cli_do_rpc_ndr_send;
2802 result->dispatch_recv = cli_do_rpc_ndr_recv;
2803 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2804 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2806 result->desthost = talloc_strdup(result, global_myname());
2807 result->srv_name_slash = talloc_asprintf_strupper_m(
2808 result, "\\\\%s", global_myname());
2809 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2810 TALLOC_FREE(result);
2811 return NT_STATUS_NO_MEMORY;
2814 status = rpc_transport_smbd_init(result, conn, syntax,
2815 &result->transport);
2816 if (!NT_STATUS_IS_OK(status)) {
2817 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2818 nt_errstr(status)));
2819 TALLOC_FREE(result);
2823 status = rpccli_anon_bind_data(result, &auth);
2824 if (!NT_STATUS_IS_OK(status)) {
2825 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2826 nt_errstr(status)));
2827 TALLOC_FREE(result);
2831 status = rpc_pipe_bind(result, auth);
2832 if (!NT_STATUS_IS_OK(status)) {
2833 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2834 TALLOC_FREE(result);
2838 result->transport->transport = NCACN_INTERNAL;
2841 return NT_STATUS_OK;
2844 /****************************************************************************
2845 Open a pipe to a remote server.
2846 ****************************************************************************/
2848 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2849 enum dcerpc_transport_t transport,
2850 const struct ndr_syntax_id *interface,
2851 struct rpc_pipe_client **presult)
2853 switch (transport) {
2855 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2858 return rpc_pipe_open_np(cli, interface, presult);
2860 return NT_STATUS_NOT_IMPLEMENTED;
2864 /****************************************************************************
2865 Open a named pipe to an SMB server and bind anonymously.
2866 ****************************************************************************/
2868 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2869 enum dcerpc_transport_t transport,
2870 const struct ndr_syntax_id *interface,
2871 struct rpc_pipe_client **presult)
2873 struct rpc_pipe_client *result;
2874 struct pipe_auth_data *auth;
2877 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2878 if (!NT_STATUS_IS_OK(status)) {
2882 status = rpccli_anon_bind_data(result, &auth);
2883 if (!NT_STATUS_IS_OK(status)) {
2884 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2885 nt_errstr(status)));
2886 TALLOC_FREE(result);
2891 * This is a bit of an abstraction violation due to the fact that an
2892 * anonymous bind on an authenticated SMB inherits the user/domain
2893 * from the enclosing SMB creds
2896 TALLOC_FREE(auth->user_name);
2897 TALLOC_FREE(auth->domain);
2899 auth->user_name = talloc_strdup(auth, cli->user_name);
2900 auth->domain = talloc_strdup(auth, cli->domain);
2901 auth->user_session_key = data_blob_talloc(auth,
2902 cli->user_session_key.data,
2903 cli->user_session_key.length);
2905 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2906 TALLOC_FREE(result);
2907 return NT_STATUS_NO_MEMORY;
2910 status = rpc_pipe_bind(result, auth);
2911 if (!NT_STATUS_IS_OK(status)) {
2913 if (ndr_syntax_id_equal(interface,
2914 &ndr_table_dssetup.syntax_id)) {
2915 /* non AD domains just don't have this pipe, avoid
2916 * level 0 statement in that case - gd */
2919 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2920 "%s failed with error %s\n",
2921 get_pipe_name_from_syntax(talloc_tos(), interface),
2922 nt_errstr(status) ));
2923 TALLOC_FREE(result);
2927 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2928 "%s and bound anonymously.\n",
2929 get_pipe_name_from_syntax(talloc_tos(), interface),
2933 return NT_STATUS_OK;
2936 /****************************************************************************
2937 ****************************************************************************/
2939 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2940 const struct ndr_syntax_id *interface,
2941 struct rpc_pipe_client **presult)
2943 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2944 interface, presult);
2947 /****************************************************************************
2948 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2949 ****************************************************************************/
2951 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2952 const struct ndr_syntax_id *interface,
2953 enum dcerpc_transport_t transport,
2955 enum dcerpc_AuthLevel auth_level,
2957 const char *username,
2958 const char *password,
2959 struct rpc_pipe_client **presult)
2961 struct rpc_pipe_client *result;
2962 struct pipe_auth_data *auth;
2963 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2964 enum pipe_auth_type_spnego spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2967 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2968 if (!NT_STATUS_IS_OK(status)) {
2973 auth_type = DCERPC_AUTH_TYPE_SPNEGO;
2974 spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
2977 status = rpccli_ntlmssp_bind_data(result,
2978 auth_type, spnego_type, auth_level,
2979 domain, username, password,
2981 if (!NT_STATUS_IS_OK(status)) {
2982 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2983 nt_errstr(status)));
2987 status = rpc_pipe_bind(result, auth);
2988 if (!NT_STATUS_IS_OK(status)) {
2989 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2990 nt_errstr(status) ));
2994 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2995 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2996 get_pipe_name_from_syntax(talloc_tos(), interface),
2997 cli->desthost, domain, username ));
3000 return NT_STATUS_OK;
3004 TALLOC_FREE(result);
3008 /****************************************************************************
3010 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3011 ****************************************************************************/
3013 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3014 const struct ndr_syntax_id *interface,
3015 enum dcerpc_transport_t transport,
3016 enum dcerpc_AuthLevel auth_level,
3018 const char *username,
3019 const char *password,
3020 struct rpc_pipe_client **presult)
3022 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3033 /****************************************************************************
3035 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3036 ****************************************************************************/
3038 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3039 const struct ndr_syntax_id *interface,
3040 enum dcerpc_transport_t transport,
3041 enum dcerpc_AuthLevel auth_level,
3043 const char *username,
3044 const char *password,
3045 struct rpc_pipe_client **presult)
3047 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3058 /****************************************************************************
3059 Get a the schannel session key out of an already opened netlogon pipe.
3060 ****************************************************************************/
3061 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3062 struct cli_state *cli,
3066 enum netr_SchannelType sec_chan_type = 0;
3067 unsigned char machine_pwd[16];
3068 const char *machine_account;
3071 /* Get the machine account credentials from secrets.tdb. */
3072 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3075 DEBUG(0, ("get_schannel_session_key: could not fetch "
3076 "trust account password for domain '%s'\n",
3078 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3081 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3082 cli->desthost, /* server name */
3083 domain, /* domain */
3084 global_myname(), /* client name */
3085 machine_account, /* machine account name */
3090 if (!NT_STATUS_IS_OK(status)) {
3091 DEBUG(3, ("get_schannel_session_key_common: "
3092 "rpccli_netlogon_setup_creds failed with result %s "
3093 "to server %s, domain %s, machine account %s.\n",
3094 nt_errstr(status), cli->desthost, domain,
3099 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3100 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3102 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3105 return NT_STATUS_OK;;
3108 /****************************************************************************
3109 Open a netlogon pipe and get the schannel session key.
3110 Now exposed to external callers.
3111 ****************************************************************************/
3114 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3117 struct rpc_pipe_client **presult)
3119 struct rpc_pipe_client *netlogon_pipe = NULL;
3122 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3124 if (!NT_STATUS_IS_OK(status)) {
3128 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3130 if (!NT_STATUS_IS_OK(status)) {
3131 TALLOC_FREE(netlogon_pipe);
3135 *presult = netlogon_pipe;
3136 return NT_STATUS_OK;
3139 /****************************************************************************
3141 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3142 using session_key. sign and seal.
3144 The *pdc will be stolen onto this new pipe
3145 ****************************************************************************/
3147 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3148 const struct ndr_syntax_id *interface,
3149 enum dcerpc_transport_t transport,
3150 enum dcerpc_AuthLevel auth_level,
3152 struct netlogon_creds_CredentialState **pdc,
3153 struct rpc_pipe_client **presult)
3155 struct rpc_pipe_client *result;
3156 struct pipe_auth_data *auth;
3159 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3160 if (!NT_STATUS_IS_OK(status)) {
3164 status = rpccli_schannel_bind_data(result, domain, auth_level,
3166 if (!NT_STATUS_IS_OK(status)) {
3167 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3168 nt_errstr(status)));
3169 TALLOC_FREE(result);
3173 status = rpc_pipe_bind(result, auth);
3174 if (!NT_STATUS_IS_OK(status)) {
3175 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3176 "cli_rpc_pipe_bind failed with error %s\n",
3177 nt_errstr(status) ));
3178 TALLOC_FREE(result);
3183 * The credentials on a new netlogon pipe are the ones we are passed
3184 * in - reference them in
3186 result->dc = talloc_move(result, pdc);
3188 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3189 "for domain %s and bound using schannel.\n",
3190 get_pipe_name_from_syntax(talloc_tos(), interface),
3191 cli->desthost, domain ));
3194 return NT_STATUS_OK;
3197 /****************************************************************************
3198 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3199 Fetch the session key ourselves using a temporary netlogon pipe. This
3200 version uses an ntlmssp auth bound netlogon pipe to get the key.
3201 ****************************************************************************/
3203 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3205 const char *username,
3206 const char *password,
3208 struct rpc_pipe_client **presult)
3210 struct rpc_pipe_client *netlogon_pipe = NULL;
3213 status = cli_rpc_pipe_open_spnego_ntlmssp(
3214 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3215 DCERPC_AUTH_LEVEL_PRIVACY,
3216 domain, username, password, &netlogon_pipe);
3217 if (!NT_STATUS_IS_OK(status)) {
3221 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3223 if (!NT_STATUS_IS_OK(status)) {
3224 TALLOC_FREE(netlogon_pipe);
3228 *presult = netlogon_pipe;
3229 return NT_STATUS_OK;
3232 /****************************************************************************
3233 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3234 Fetch the session key ourselves using a temporary netlogon pipe. This version
3235 uses an ntlmssp bind to get the session key.
3236 ****************************************************************************/
3238 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3239 const struct ndr_syntax_id *interface,
3240 enum dcerpc_transport_t transport,
3241 enum dcerpc_AuthLevel auth_level,
3243 const char *username,
3244 const char *password,
3245 struct rpc_pipe_client **presult)
3247 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3248 struct rpc_pipe_client *netlogon_pipe = NULL;
3249 struct rpc_pipe_client *result = NULL;
3252 status = get_schannel_session_key_auth_ntlmssp(
3253 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3254 if (!NT_STATUS_IS_OK(status)) {
3255 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3256 "key from server %s for domain %s.\n",
3257 cli->desthost, domain ));
3261 status = cli_rpc_pipe_open_schannel_with_key(
3262 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3265 /* Now we've bound using the session key we can close the netlog pipe. */
3266 TALLOC_FREE(netlogon_pipe);
3268 if (NT_STATUS_IS_OK(status)) {
3274 /****************************************************************************
3275 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3276 Fetch the session key ourselves using a temporary netlogon pipe.
3277 ****************************************************************************/
3279 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3280 const struct ndr_syntax_id *interface,
3281 enum dcerpc_transport_t transport,
3282 enum dcerpc_AuthLevel auth_level,
3284 struct rpc_pipe_client **presult)
3286 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3287 struct rpc_pipe_client *netlogon_pipe = NULL;
3288 struct rpc_pipe_client *result = NULL;
3291 status = get_schannel_session_key(cli, domain, &neg_flags,
3293 if (!NT_STATUS_IS_OK(status)) {
3294 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3295 "key from server %s for domain %s.\n",
3296 cli->desthost, domain ));
3300 status = cli_rpc_pipe_open_schannel_with_key(
3301 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3304 /* Now we've bound using the session key we can close the netlog pipe. */
3305 TALLOC_FREE(netlogon_pipe);
3307 if (NT_STATUS_IS_OK(status)) {
3314 /****************************************************************************
3315 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3316 The idea is this can be called with service_princ, username and password all
3317 NULL so long as the caller has a TGT.
3318 ****************************************************************************/
3320 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3321 const struct ndr_syntax_id *interface,
3322 enum dcerpc_transport_t transport,
3323 enum dcerpc_AuthLevel auth_level,
3324 const char *service_princ,
3325 const char *username,
3326 const char *password,
3327 struct rpc_pipe_client **presult)
3330 struct rpc_pipe_client *result;
3331 struct pipe_auth_data *auth;
3334 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3335 if (!NT_STATUS_IS_OK(status)) {
3339 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3340 username, password, &auth);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3343 nt_errstr(status)));
3344 TALLOC_FREE(result);
3348 status = rpc_pipe_bind(result, auth);
3349 if (!NT_STATUS_IS_OK(status)) {
3350 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3351 "with error %s\n", nt_errstr(status)));
3352 TALLOC_FREE(result);
3357 return NT_STATUS_OK;
3359 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3360 return NT_STATUS_NOT_IMPLEMENTED;
3364 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3365 struct rpc_pipe_client *cli,
3366 DATA_BLOB *session_key)
3368 struct pipe_auth_data *a = cli->auth;
3371 if (!session_key || !cli) {
3372 return NT_STATUS_INVALID_PARAMETER;
3376 return NT_STATUS_INVALID_PARAMETER;
3379 switch (cli->auth->auth_type) {
3380 case DCERPC_AUTH_TYPE_SCHANNEL:
3381 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3384 case DCERPC_AUTH_TYPE_SPNEGO:
3385 switch (cli->auth->spnego_type) {
3386 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3387 sk = auth_ntlmssp_get_session_key(
3388 a->a_u.auth_ntlmssp_state);
3390 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3391 sk = data_blob_const(
3392 a->a_u.kerberos_auth->session_key.data,
3393 a->a_u.kerberos_auth->session_key.length);
3396 return NT_STATUS_NO_USER_SESSION_KEY;
3399 case DCERPC_AUTH_TYPE_NTLMSSP:
3400 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3402 case DCERPC_AUTH_TYPE_KRB5:
3403 sk = data_blob_const(a->a_u.kerberos_auth->session_key.data,
3404 a->a_u.kerberos_auth->session_key.length);
3406 case DCERPC_AUTH_TYPE_NONE:
3407 sk = data_blob_const(a->user_session_key.data,
3408 a->user_session_key.length);
3411 return NT_STATUS_NO_USER_SESSION_KEY;
3414 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3415 return NT_STATUS_OK;