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 case DCERPC_AUTH_LEVEL_PACKET:
1292 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1293 data_len = MIN(data_space, data_left);
1296 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1299 case DCERPC_AUTH_LEVEL_INTEGRITY:
1300 case DCERPC_AUTH_LEVEL_PRIVACY:
1301 /* Treat the same for all authenticated rpc requests. */
1302 switch(cli->auth->auth_type) {
1303 case DCERPC_AUTH_TYPE_SPNEGO:
1304 switch (cli->auth->spnego_type) {
1305 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1306 *p_auth_len = NTLMSSP_SIG_SIZE;
1309 smb_panic("bad auth type");
1312 case DCERPC_AUTH_TYPE_NTLMSSP:
1313 *p_auth_len = NTLMSSP_SIG_SIZE;
1315 case DCERPC_AUTH_TYPE_SCHANNEL:
1316 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1319 smb_panic("bad auth type");
1323 data_space = cli->max_xmit_frag
1324 - DCERPC_REQUEST_LENGTH
1325 - DCERPC_AUTH_TRAILER_LENGTH
1328 data_len = MIN(data_space, data_left);
1330 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1331 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1333 *p_frag_len = DCERPC_REQUEST_LENGTH
1334 + data_len + *p_ss_padding
1335 + DCERPC_AUTH_TRAILER_LENGTH
1340 smb_panic("bad auth level");
1346 /*******************************************************************
1348 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1349 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1350 and deals with signing/sealing details.
1351 ********************************************************************/
1353 struct rpc_api_pipe_req_state {
1354 struct event_context *ev;
1355 struct rpc_pipe_client *cli;
1358 DATA_BLOB *req_data;
1359 uint32_t req_data_sent;
1361 DATA_BLOB reply_pdu;
1364 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1365 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1366 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1367 bool *is_last_frag);
1369 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1370 struct event_context *ev,
1371 struct rpc_pipe_client *cli,
1373 DATA_BLOB *req_data)
1375 struct tevent_req *req, *subreq;
1376 struct rpc_api_pipe_req_state *state;
1380 req = tevent_req_create(mem_ctx, &state,
1381 struct rpc_api_pipe_req_state);
1387 state->op_num = op_num;
1388 state->req_data = req_data;
1389 state->req_data_sent = 0;
1390 state->call_id = get_rpc_call_id();
1391 state->reply_pdu = data_blob_null;
1392 state->rpc_out = data_blob_null;
1394 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1395 + RPC_MAX_SIGN_SIZE) {
1396 /* Server is screwed up ! */
1397 status = NT_STATUS_INVALID_PARAMETER;
1401 status = prepare_next_frag(state, &is_last_frag);
1402 if (!NT_STATUS_IS_OK(status)) {
1407 subreq = rpc_api_pipe_send(state, ev, state->cli,
1409 DCERPC_PKT_RESPONSE);
1410 if (subreq == NULL) {
1413 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1415 subreq = rpc_write_send(state, ev, cli->transport,
1416 state->rpc_out.data,
1417 state->rpc_out.length);
1418 if (subreq == NULL) {
1421 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1427 tevent_req_nterror(req, status);
1428 return tevent_req_post(req, ev);
1434 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1437 uint32_t data_sent_thistime;
1441 uint32_t ss_padding;
1444 union dcerpc_payload u;
1446 data_left = state->req_data->length - state->req_data_sent;
1448 data_sent_thistime = calculate_data_len_tosend(
1449 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
1451 if (state->req_data_sent == 0) {
1452 flags = DCERPC_PFC_FLAG_FIRST;
1455 if (data_sent_thistime == data_left) {
1456 flags |= DCERPC_PFC_FLAG_LAST;
1459 data_blob_free(&state->rpc_out);
1461 ZERO_STRUCT(u.request);
1463 u.request.alloc_hint = state->req_data->length;
1464 u.request.context_id = 0;
1465 u.request.opnum = state->op_num;
1467 status = dcerpc_push_ncacn_packet(state,
1474 if (!NT_STATUS_IS_OK(status)) {
1478 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1479 * compute it right for requests because the auth trailer is missing
1481 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1483 /* Copy in the data. */
1484 if (!data_blob_append(NULL, &state->rpc_out,
1485 state->req_data->data + state->req_data_sent,
1486 data_sent_thistime)) {
1487 return NT_STATUS_NO_MEMORY;
1490 switch (state->cli->auth->auth_level) {
1491 case DCERPC_AUTH_LEVEL_NONE:
1492 case DCERPC_AUTH_LEVEL_CONNECT:
1493 case DCERPC_AUTH_LEVEL_PACKET:
1495 case DCERPC_AUTH_LEVEL_INTEGRITY:
1496 case DCERPC_AUTH_LEVEL_PRIVACY:
1497 status = dcerpc_add_auth_footer(state->cli->auth, ss_padding,
1499 if (!NT_STATUS_IS_OK(status)) {
1504 return NT_STATUS_INVALID_PARAMETER;
1507 state->req_data_sent += data_sent_thistime;
1508 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1513 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1515 struct tevent_req *req = tevent_req_callback_data(
1516 subreq, struct tevent_req);
1517 struct rpc_api_pipe_req_state *state = tevent_req_data(
1518 req, struct rpc_api_pipe_req_state);
1522 status = rpc_write_recv(subreq);
1523 TALLOC_FREE(subreq);
1524 if (!NT_STATUS_IS_OK(status)) {
1525 tevent_req_nterror(req, status);
1529 status = prepare_next_frag(state, &is_last_frag);
1530 if (!NT_STATUS_IS_OK(status)) {
1531 tevent_req_nterror(req, status);
1536 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1538 DCERPC_PKT_RESPONSE);
1539 if (tevent_req_nomem(subreq, req)) {
1542 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1544 subreq = rpc_write_send(state, state->ev,
1545 state->cli->transport,
1546 state->rpc_out.data,
1547 state->rpc_out.length);
1548 if (tevent_req_nomem(subreq, req)) {
1551 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1556 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1558 struct tevent_req *req = tevent_req_callback_data(
1559 subreq, struct tevent_req);
1560 struct rpc_api_pipe_req_state *state = tevent_req_data(
1561 req, struct rpc_api_pipe_req_state);
1564 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1565 TALLOC_FREE(subreq);
1566 if (!NT_STATUS_IS_OK(status)) {
1567 tevent_req_nterror(req, status);
1570 tevent_req_done(req);
1573 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1574 DATA_BLOB *reply_pdu)
1576 struct rpc_api_pipe_req_state *state = tevent_req_data(
1577 req, struct rpc_api_pipe_req_state);
1580 if (tevent_req_is_nterror(req, &status)) {
1582 * We always have to initialize to reply pdu, even if there is
1583 * none. The rpccli_* caller routines expect this.
1585 *reply_pdu = data_blob_null;
1589 /* return data to caller and assign it ownership of memory */
1590 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1591 reply_pdu->length = state->reply_pdu.length;
1592 state->reply_pdu.length = 0;
1594 return NT_STATUS_OK;
1598 /****************************************************************************
1599 Set the handle state.
1600 ****************************************************************************/
1602 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1603 const char *pipe_name, uint16 device_state)
1605 bool state_set = False;
1607 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1608 char *rparam = NULL;
1610 uint32 rparam_len, rdata_len;
1612 if (pipe_name == NULL)
1615 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1616 cli->fnum, pipe_name, device_state));
1618 /* create parameters: device state */
1619 SSVAL(param, 0, device_state);
1621 /* create setup parameters. */
1623 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1625 /* send the data on \PIPE\ */
1626 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1627 setup, 2, 0, /* setup, length, max */
1628 param, 2, 0, /* param, length, max */
1629 NULL, 0, 1024, /* data, length, max */
1630 &rparam, &rparam_len, /* return param, length */
1631 &rdata, &rdata_len)) /* return data, length */
1633 DEBUG(5, ("Set Handle state: return OK\n"));
1644 /****************************************************************************
1645 Check the rpc bind acknowledge response.
1646 ****************************************************************************/
1648 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1649 const struct ndr_syntax_id *transfer)
1651 struct dcerpc_ack_ctx ctx;
1653 if (r->secondary_address_size == 0) {
1654 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1657 if (r->num_results < 1 || !r->ctx_list) {
1661 ctx = r->ctx_list[0];
1663 /* check the transfer syntax */
1664 if ((ctx.syntax.if_version != transfer->if_version) ||
1665 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1666 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1670 if (r->num_results != 0x1 || ctx.result != 0) {
1671 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1672 r->num_results, ctx.reason));
1675 DEBUG(5,("check_bind_response: accepted!\n"));
1679 /*******************************************************************
1680 Creates a DCE/RPC bind authentication response.
1681 This is the packet that is sent back to the server once we
1682 have received a BIND-ACK, to finish the third leg of
1683 the authentication handshake.
1684 ********************************************************************/
1686 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1687 struct rpc_pipe_client *cli,
1689 enum dcerpc_AuthType auth_type,
1690 enum dcerpc_AuthLevel auth_level,
1691 DATA_BLOB *pauth_blob,
1695 union dcerpc_payload u;
1699 status = dcerpc_push_dcerpc_auth(mem_ctx,
1702 0, /* auth_pad_length */
1703 1, /* auth_context_id */
1705 &u.auth3.auth_info);
1706 if (!NT_STATUS_IS_OK(status)) {
1710 status = dcerpc_push_ncacn_packet(mem_ctx,
1712 DCERPC_PFC_FLAG_FIRST |
1713 DCERPC_PFC_FLAG_LAST,
1718 data_blob_free(&u.auth3.auth_info);
1719 if (!NT_STATUS_IS_OK(status)) {
1720 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1724 return NT_STATUS_OK;
1727 /*******************************************************************
1728 Creates a DCE/RPC bind alter context authentication request which
1729 may contain a spnego auth blobl
1730 ********************************************************************/
1732 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1734 const struct ndr_syntax_id *abstract,
1735 const struct ndr_syntax_id *transfer,
1736 enum dcerpc_AuthLevel auth_level,
1737 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1740 DATA_BLOB auth_info;
1743 status = dcerpc_push_dcerpc_auth(mem_ctx,
1744 DCERPC_AUTH_TYPE_SPNEGO,
1746 0, /* auth_pad_length */
1747 1, /* auth_context_id */
1750 if (!NT_STATUS_IS_OK(status)) {
1754 status = create_bind_or_alt_ctx_internal(mem_ctx,
1761 data_blob_free(&auth_info);
1765 /****************************************************************************
1767 ****************************************************************************/
1769 struct rpc_pipe_bind_state {
1770 struct event_context *ev;
1771 struct rpc_pipe_client *cli;
1773 uint32_t rpc_call_id;
1776 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1777 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1778 struct rpc_pipe_bind_state *state,
1779 DATA_BLOB *credentials);
1780 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1781 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1782 struct rpc_pipe_bind_state *state,
1783 DATA_BLOB *credentials);
1784 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1786 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1787 struct event_context *ev,
1788 struct rpc_pipe_client *cli,
1789 struct pipe_auth_data *auth)
1791 struct tevent_req *req, *subreq;
1792 struct rpc_pipe_bind_state *state;
1795 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1800 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1801 rpccli_pipe_txt(talloc_tos(), cli),
1802 (unsigned int)auth->auth_type,
1803 (unsigned int)auth->spnego_type,
1804 (unsigned int)auth->auth_level ));
1808 state->rpc_call_id = get_rpc_call_id();
1809 state->rpc_out = data_blob_null;
1811 cli->auth = talloc_move(cli, &auth);
1813 /* Marshall the outgoing data. */
1814 status = create_rpc_bind_req(state, cli,
1817 &cli->abstract_syntax,
1818 &cli->transfer_syntax,
1821 if (!NT_STATUS_IS_OK(status)) {
1825 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1826 DCERPC_PKT_BIND_ACK);
1827 if (subreq == NULL) {
1830 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1834 tevent_req_nterror(req, status);
1835 return tevent_req_post(req, ev);
1841 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1843 struct tevent_req *req = tevent_req_callback_data(
1844 subreq, struct tevent_req);
1845 struct rpc_pipe_bind_state *state = tevent_req_data(
1846 req, struct rpc_pipe_bind_state);
1847 DATA_BLOB reply_pdu;
1848 struct ncacn_packet *pkt;
1849 struct dcerpc_auth auth;
1852 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1853 TALLOC_FREE(subreq);
1854 if (!NT_STATUS_IS_OK(status)) {
1855 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1856 rpccli_pipe_txt(talloc_tos(), state->cli),
1857 nt_errstr(status)));
1858 tevent_req_nterror(req, status);
1862 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1863 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1864 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1868 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1869 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1871 switch(state->cli->auth->auth_type) {
1873 case DCERPC_AUTH_TYPE_NONE:
1874 case DCERPC_AUTH_TYPE_SCHANNEL:
1875 /* Bind complete. */
1876 tevent_req_done(req);
1879 case DCERPC_AUTH_TYPE_NTLMSSP:
1880 case DCERPC_AUTH_TYPE_SPNEGO:
1881 case DCERPC_AUTH_TYPE_KRB5:
1882 /* Paranoid lenght checks */
1883 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1884 + pkt->auth_length) {
1885 tevent_req_nterror(req,
1886 NT_STATUS_INFO_LENGTH_MISMATCH);
1889 /* get auth credentials */
1890 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1891 &pkt->u.bind_ack.auth_info,
1893 if (!NT_STATUS_IS_OK(status)) {
1894 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1895 nt_errstr(status)));
1896 tevent_req_nterror(req, status);
1906 * For authenticated binds we may need to do 3 or 4 leg binds.
1909 switch(state->cli->auth->auth_type) {
1911 case DCERPC_AUTH_TYPE_NONE:
1912 case DCERPC_AUTH_TYPE_SCHANNEL:
1913 /* Bind complete. */
1914 tevent_req_done(req);
1917 case DCERPC_AUTH_TYPE_NTLMSSP:
1918 /* Need to send AUTH3 packet - no reply. */
1919 status = rpc_finish_auth3_bind_send(req, state,
1923 case DCERPC_AUTH_TYPE_SPNEGO:
1924 if (state->cli->auth->spnego_type !=
1925 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1928 /* Need to send alter context request and reply. */
1929 status = rpc_finish_spnego_ntlmssp_bind_send(req, state,
1933 case DCERPC_AUTH_TYPE_KRB5:
1934 status = NT_STATUS_NOT_IMPLEMENTED;
1941 if (!NT_STATUS_IS_OK(status)) {
1942 tevent_req_nterror(req, status);
1947 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
1948 (unsigned int)state->cli->auth->auth_type,
1949 (unsigned int)state->cli->auth->spnego_type));
1950 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1953 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1954 struct rpc_pipe_bind_state *state,
1955 DATA_BLOB *credentials)
1957 struct pipe_auth_data *auth = state->cli->auth;
1958 DATA_BLOB client_reply = data_blob_null;
1959 struct tevent_req *subreq;
1962 /* TODO - check auth_type/auth_level match. */
1964 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
1965 *credentials, &client_reply);
1967 if (!NT_STATUS_IS_OK(status)) {
1968 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
1969 "blob failed: %s.\n", nt_errstr(status)));
1973 data_blob_free(&state->rpc_out);
1975 status = create_rpc_bind_auth3(state, state->cli,
1981 data_blob_free(&client_reply);
1983 if (!NT_STATUS_IS_OK(status)) {
1987 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1988 state->rpc_out.data, state->rpc_out.length);
1989 if (subreq == NULL) {
1990 return NT_STATUS_NO_MEMORY;
1992 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
1993 return NT_STATUS_OK;
1996 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
1998 struct tevent_req *req = tevent_req_callback_data(
1999 subreq, struct tevent_req);
2002 status = rpc_write_recv(subreq);
2003 TALLOC_FREE(subreq);
2004 if (!NT_STATUS_IS_OK(status)) {
2005 tevent_req_nterror(req, status);
2008 tevent_req_done(req);
2011 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2012 struct rpc_pipe_bind_state *state,
2013 DATA_BLOB *credentials)
2015 struct pipe_auth_data *auth = state->cli->auth;
2016 DATA_BLOB server_ntlm_response = data_blob_null;
2017 DATA_BLOB client_reply = data_blob_null;
2018 DATA_BLOB tmp_blob = data_blob_null;
2019 struct tevent_req *subreq;
2023 * The server might give us back two challenges - tmp_blob is for the
2026 if (!spnego_parse_challenge(state, *credentials,
2027 &server_ntlm_response,
2029 data_blob_free(&server_ntlm_response);
2030 data_blob_free(&tmp_blob);
2031 return NT_STATUS_INVALID_PARAMETER;
2034 /* We're finished with the server spnego response and the tmp_blob. */
2035 data_blob_free(&tmp_blob);
2037 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2038 server_ntlm_response, &client_reply);
2040 /* Finished with the server_ntlm response */
2041 data_blob_free(&server_ntlm_response);
2043 if (!NT_STATUS_IS_OK(status)) {
2044 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2045 "using server blob failed.\n"));
2046 data_blob_free(&client_reply);
2050 /* SPNEGO wrap the client reply. */
2051 tmp_blob = spnego_gen_auth(state, client_reply);
2052 data_blob_free(&client_reply);
2053 client_reply = tmp_blob;
2054 tmp_blob = data_blob_null;
2056 /* Now prepare the alter context pdu. */
2057 data_blob_free(&state->rpc_out);
2059 status = create_rpc_alter_context(state,
2061 &state->cli->abstract_syntax,
2062 &state->cli->transfer_syntax,
2066 data_blob_free(&client_reply);
2068 if (!NT_STATUS_IS_OK(status)) {
2072 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2073 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2074 if (subreq == NULL) {
2075 return NT_STATUS_NO_MEMORY;
2077 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2078 return NT_STATUS_OK;
2081 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2083 struct tevent_req *req = tevent_req_callback_data(
2084 subreq, struct tevent_req);
2085 struct rpc_pipe_bind_state *state = tevent_req_data(
2086 req, struct rpc_pipe_bind_state);
2087 DATA_BLOB tmp_blob = data_blob_null;
2088 struct ncacn_packet *pkt;
2089 struct dcerpc_auth auth;
2092 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2093 TALLOC_FREE(subreq);
2094 if (!NT_STATUS_IS_OK(status)) {
2095 tevent_req_nterror(req, status);
2099 status = dcerpc_pull_dcerpc_auth(pkt,
2100 &pkt->u.alter_resp.auth_info,
2102 if (!NT_STATUS_IS_OK(status)) {
2103 tevent_req_nterror(req, status);
2107 /* Check we got a valid auth response. */
2108 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2110 OID_NTLMSSP, &tmp_blob)) {
2111 data_blob_free(&tmp_blob);
2112 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2116 data_blob_free(&tmp_blob);
2118 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2119 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2120 tevent_req_done(req);
2123 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2125 return tevent_req_simple_recv_ntstatus(req);
2128 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2129 struct pipe_auth_data *auth)
2131 TALLOC_CTX *frame = talloc_stackframe();
2132 struct event_context *ev;
2133 struct tevent_req *req;
2134 NTSTATUS status = NT_STATUS_OK;
2136 ev = event_context_init(frame);
2138 status = NT_STATUS_NO_MEMORY;
2142 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2144 status = NT_STATUS_NO_MEMORY;
2148 if (!tevent_req_poll(req, ev)) {
2149 status = map_nt_error_from_unix(errno);
2153 status = rpc_pipe_bind_recv(req);
2159 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2161 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2162 unsigned int timeout)
2166 if (rpc_cli->transport == NULL) {
2167 return RPCCLI_DEFAULT_TIMEOUT;
2170 if (rpc_cli->transport->set_timeout == NULL) {
2171 return RPCCLI_DEFAULT_TIMEOUT;
2174 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2176 return RPCCLI_DEFAULT_TIMEOUT;
2182 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2184 if (rpc_cli == NULL) {
2188 if (rpc_cli->transport == NULL) {
2192 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2195 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2197 struct cli_state *cli;
2199 if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP)
2200 || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO
2201 && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2202 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2206 cli = rpc_pipe_np_smb_conn(rpc_cli);
2210 E_md4hash(cli->password ? cli->password : "", nt_hash);
2214 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2215 struct pipe_auth_data **presult)
2217 struct pipe_auth_data *result;
2219 result = talloc(mem_ctx, struct pipe_auth_data);
2220 if (result == NULL) {
2221 return NT_STATUS_NO_MEMORY;
2224 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2225 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2226 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2228 result->user_name = talloc_strdup(result, "");
2229 result->domain = talloc_strdup(result, "");
2230 if ((result->user_name == NULL) || (result->domain == NULL)) {
2231 TALLOC_FREE(result);
2232 return NT_STATUS_NO_MEMORY;
2236 return NT_STATUS_OK;
2239 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2241 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2245 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2246 enum dcerpc_AuthType auth_type,
2247 enum pipe_auth_type_spnego spnego_type,
2248 enum dcerpc_AuthLevel auth_level,
2250 const char *username,
2251 const char *password,
2252 struct pipe_auth_data **presult)
2254 struct pipe_auth_data *result;
2257 result = talloc(mem_ctx, struct pipe_auth_data);
2258 if (result == NULL) {
2259 return NT_STATUS_NO_MEMORY;
2262 result->auth_type = auth_type;
2263 result->spnego_type = spnego_type;
2264 result->auth_level = auth_level;
2266 result->user_name = talloc_strdup(result, username);
2267 result->domain = talloc_strdup(result, domain);
2268 if ((result->user_name == NULL) || (result->domain == NULL)) {
2269 status = NT_STATUS_NO_MEMORY;
2273 status = auth_ntlmssp_client_start(NULL,
2276 lp_client_ntlmv2_auth(),
2277 &result->a_u.auth_ntlmssp_state);
2278 if (!NT_STATUS_IS_OK(status)) {
2282 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2284 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2286 if (!NT_STATUS_IS_OK(status)) {
2290 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2292 if (!NT_STATUS_IS_OK(status)) {
2296 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2298 if (!NT_STATUS_IS_OK(status)) {
2303 * Turn off sign+seal to allow selected auth level to turn it back on.
2305 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2306 ~(NTLMSSP_NEGOTIATE_SIGN |
2307 NTLMSSP_NEGOTIATE_SEAL));
2309 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2310 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2311 NTLMSSP_NEGOTIATE_SIGN);
2312 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2313 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2314 NTLMSSP_NEGOTIATE_SEAL |
2315 NTLMSSP_NEGOTIATE_SIGN);
2319 return NT_STATUS_OK;
2322 TALLOC_FREE(result);
2326 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2327 enum dcerpc_AuthLevel auth_level,
2328 struct netlogon_creds_CredentialState *creds,
2329 struct pipe_auth_data **presult)
2331 struct pipe_auth_data *result;
2333 result = talloc(mem_ctx, struct pipe_auth_data);
2334 if (result == NULL) {
2335 return NT_STATUS_NO_MEMORY;
2338 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2339 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2340 result->auth_level = auth_level;
2342 result->user_name = talloc_strdup(result, "");
2343 result->domain = talloc_strdup(result, domain);
2344 if ((result->user_name == NULL) || (result->domain == NULL)) {
2348 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2349 if (result->a_u.schannel_auth == NULL) {
2353 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2354 result->a_u.schannel_auth->seq_num = 0;
2355 result->a_u.schannel_auth->initiator = true;
2356 result->a_u.schannel_auth->creds = creds;
2359 return NT_STATUS_OK;
2362 TALLOC_FREE(result);
2363 return NT_STATUS_NO_MEMORY;
2367 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2369 data_blob_free(&auth->session_key);
2374 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2375 enum dcerpc_AuthLevel auth_level,
2376 const char *service_princ,
2377 const char *username,
2378 const char *password,
2379 struct pipe_auth_data **presult)
2382 struct pipe_auth_data *result;
2384 if ((username != NULL) && (password != NULL)) {
2385 int ret = kerberos_kinit_password(username, password, 0, NULL);
2387 return NT_STATUS_ACCESS_DENIED;
2391 result = talloc(mem_ctx, struct pipe_auth_data);
2392 if (result == NULL) {
2393 return NT_STATUS_NO_MEMORY;
2396 result->auth_type = DCERPC_AUTH_TYPE_KRB5;
2397 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2398 result->auth_level = auth_level;
2401 * Username / domain need fixing!
2403 result->user_name = talloc_strdup(result, "");
2404 result->domain = talloc_strdup(result, "");
2405 if ((result->user_name == NULL) || (result->domain == NULL)) {
2409 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2410 result, struct kerberos_auth_struct);
2411 if (result->a_u.kerberos_auth == NULL) {
2414 talloc_set_destructor(result->a_u.kerberos_auth,
2415 cli_auth_kerberos_data_destructor);
2417 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2418 result, service_princ);
2419 if (result->a_u.kerberos_auth->service_principal == NULL) {
2424 return NT_STATUS_OK;
2427 TALLOC_FREE(result);
2428 return NT_STATUS_NO_MEMORY;
2430 return NT_STATUS_NOT_SUPPORTED;
2435 * Create an rpc pipe client struct, connecting to a tcp port.
2437 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2439 const struct ndr_syntax_id *abstract_syntax,
2440 struct rpc_pipe_client **presult)
2442 struct rpc_pipe_client *result;
2443 struct sockaddr_storage addr;
2447 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2448 if (result == NULL) {
2449 return NT_STATUS_NO_MEMORY;
2452 result->abstract_syntax = *abstract_syntax;
2453 result->transfer_syntax = ndr_transfer_syntax;
2454 result->dispatch = cli_do_rpc_ndr;
2455 result->dispatch_send = cli_do_rpc_ndr_send;
2456 result->dispatch_recv = cli_do_rpc_ndr_recv;
2458 result->desthost = talloc_strdup(result, host);
2459 result->srv_name_slash = talloc_asprintf_strupper_m(
2460 result, "\\\\%s", result->desthost);
2461 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2462 status = NT_STATUS_NO_MEMORY;
2466 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2467 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2469 if (!resolve_name(host, &addr, 0, false)) {
2470 status = NT_STATUS_NOT_FOUND;
2474 status = open_socket_out(&addr, port, 60, &fd);
2475 if (!NT_STATUS_IS_OK(status)) {
2478 set_socket_options(fd, lp_socket_options());
2480 status = rpc_transport_sock_init(result, fd, &result->transport);
2481 if (!NT_STATUS_IS_OK(status)) {
2486 result->transport->transport = NCACN_IP_TCP;
2489 return NT_STATUS_OK;
2492 TALLOC_FREE(result);
2497 * Determine the tcp port on which a dcerpc interface is listening
2498 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2501 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2502 const struct ndr_syntax_id *abstract_syntax,
2506 struct rpc_pipe_client *epm_pipe = NULL;
2507 struct pipe_auth_data *auth = NULL;
2508 struct dcerpc_binding *map_binding = NULL;
2509 struct dcerpc_binding *res_binding = NULL;
2510 struct epm_twr_t *map_tower = NULL;
2511 struct epm_twr_t *res_towers = NULL;
2512 struct policy_handle *entry_handle = NULL;
2513 uint32_t num_towers = 0;
2514 uint32_t max_towers = 1;
2515 struct epm_twr_p_t towers;
2516 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2518 if (pport == NULL) {
2519 status = NT_STATUS_INVALID_PARAMETER;
2523 /* open the connection to the endpoint mapper */
2524 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2525 &ndr_table_epmapper.syntax_id,
2528 if (!NT_STATUS_IS_OK(status)) {
2532 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2533 if (!NT_STATUS_IS_OK(status)) {
2537 status = rpc_pipe_bind(epm_pipe, auth);
2538 if (!NT_STATUS_IS_OK(status)) {
2542 /* create tower for asking the epmapper */
2544 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2545 if (map_binding == NULL) {
2546 status = NT_STATUS_NO_MEMORY;
2550 map_binding->transport = NCACN_IP_TCP;
2551 map_binding->object = *abstract_syntax;
2552 map_binding->host = host; /* needed? */
2553 map_binding->endpoint = "0"; /* correct? needed? */
2555 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2556 if (map_tower == NULL) {
2557 status = NT_STATUS_NO_MEMORY;
2561 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2562 &(map_tower->tower));
2563 if (!NT_STATUS_IS_OK(status)) {
2567 /* allocate further parameters for the epm_Map call */
2569 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2570 if (res_towers == NULL) {
2571 status = NT_STATUS_NO_MEMORY;
2574 towers.twr = res_towers;
2576 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2577 if (entry_handle == NULL) {
2578 status = NT_STATUS_NO_MEMORY;
2582 /* ask the endpoint mapper for the port */
2584 status = rpccli_epm_Map(epm_pipe,
2586 CONST_DISCARD(struct GUID *,
2587 &(abstract_syntax->uuid)),
2594 if (!NT_STATUS_IS_OK(status)) {
2598 if (num_towers != 1) {
2599 status = NT_STATUS_UNSUCCESSFUL;
2603 /* extract the port from the answer */
2605 status = dcerpc_binding_from_tower(tmp_ctx,
2606 &(towers.twr->tower),
2608 if (!NT_STATUS_IS_OK(status)) {
2612 /* are further checks here necessary? */
2613 if (res_binding->transport != NCACN_IP_TCP) {
2614 status = NT_STATUS_UNSUCCESSFUL;
2618 *pport = (uint16_t)atoi(res_binding->endpoint);
2621 TALLOC_FREE(tmp_ctx);
2626 * Create a rpc pipe client struct, connecting to a host via tcp.
2627 * The port is determined by asking the endpoint mapper on the given
2630 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2631 const struct ndr_syntax_id *abstract_syntax,
2632 struct rpc_pipe_client **presult)
2637 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2638 if (!NT_STATUS_IS_OK(status)) {
2642 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2643 abstract_syntax, presult);
2646 /********************************************************************
2647 Create a rpc pipe client struct, connecting to a unix domain socket
2648 ********************************************************************/
2649 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2650 const struct ndr_syntax_id *abstract_syntax,
2651 struct rpc_pipe_client **presult)
2653 struct rpc_pipe_client *result;
2654 struct sockaddr_un addr;
2658 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2659 if (result == NULL) {
2660 return NT_STATUS_NO_MEMORY;
2663 result->abstract_syntax = *abstract_syntax;
2664 result->transfer_syntax = ndr_transfer_syntax;
2665 result->dispatch = cli_do_rpc_ndr;
2666 result->dispatch_send = cli_do_rpc_ndr_send;
2667 result->dispatch_recv = cli_do_rpc_ndr_recv;
2669 result->desthost = get_myname(result);
2670 result->srv_name_slash = talloc_asprintf_strupper_m(
2671 result, "\\\\%s", result->desthost);
2672 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2673 status = NT_STATUS_NO_MEMORY;
2677 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2678 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2680 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2682 status = map_nt_error_from_unix(errno);
2687 addr.sun_family = AF_UNIX;
2688 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2690 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2691 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2694 return map_nt_error_from_unix(errno);
2697 status = rpc_transport_sock_init(result, fd, &result->transport);
2698 if (!NT_STATUS_IS_OK(status)) {
2703 result->transport->transport = NCALRPC;
2706 return NT_STATUS_OK;
2709 TALLOC_FREE(result);
2713 struct rpc_pipe_client_np_ref {
2714 struct cli_state *cli;
2715 struct rpc_pipe_client *pipe;
2718 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2720 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2724 /****************************************************************************
2725 Open a named pipe over SMB to a remote server.
2727 * CAVEAT CALLER OF THIS FUNCTION:
2728 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2729 * so be sure that this function is called AFTER any structure (vs pointer)
2730 * assignment of the cli. In particular, libsmbclient does structure
2731 * assignments of cli, which invalidates the data in the returned
2732 * rpc_pipe_client if this function is called before the structure assignment
2735 ****************************************************************************/
2737 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2738 const struct ndr_syntax_id *abstract_syntax,
2739 struct rpc_pipe_client **presult)
2741 struct rpc_pipe_client *result;
2743 struct rpc_pipe_client_np_ref *np_ref;
2745 /* sanity check to protect against crashes */
2748 return NT_STATUS_INVALID_HANDLE;
2751 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2752 if (result == NULL) {
2753 return NT_STATUS_NO_MEMORY;
2756 result->abstract_syntax = *abstract_syntax;
2757 result->transfer_syntax = ndr_transfer_syntax;
2758 result->dispatch = cli_do_rpc_ndr;
2759 result->dispatch_send = cli_do_rpc_ndr_send;
2760 result->dispatch_recv = cli_do_rpc_ndr_recv;
2761 result->desthost = talloc_strdup(result, cli->desthost);
2762 result->srv_name_slash = talloc_asprintf_strupper_m(
2763 result, "\\\\%s", result->desthost);
2765 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2766 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2768 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2769 TALLOC_FREE(result);
2770 return NT_STATUS_NO_MEMORY;
2773 status = rpc_transport_np_init(result, cli, abstract_syntax,
2774 &result->transport);
2775 if (!NT_STATUS_IS_OK(status)) {
2776 TALLOC_FREE(result);
2780 result->transport->transport = NCACN_NP;
2782 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2783 if (np_ref == NULL) {
2784 TALLOC_FREE(result);
2785 return NT_STATUS_NO_MEMORY;
2788 np_ref->pipe = result;
2790 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2791 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2794 return NT_STATUS_OK;
2797 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2798 struct rpc_cli_smbd_conn *conn,
2799 const struct ndr_syntax_id *syntax,
2800 struct rpc_pipe_client **presult)
2802 struct rpc_pipe_client *result;
2803 struct pipe_auth_data *auth;
2806 result = talloc(mem_ctx, struct rpc_pipe_client);
2807 if (result == NULL) {
2808 return NT_STATUS_NO_MEMORY;
2810 result->abstract_syntax = *syntax;
2811 result->transfer_syntax = ndr_transfer_syntax;
2812 result->dispatch = cli_do_rpc_ndr;
2813 result->dispatch_send = cli_do_rpc_ndr_send;
2814 result->dispatch_recv = cli_do_rpc_ndr_recv;
2815 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2816 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2818 result->desthost = talloc_strdup(result, global_myname());
2819 result->srv_name_slash = talloc_asprintf_strupper_m(
2820 result, "\\\\%s", global_myname());
2821 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2822 TALLOC_FREE(result);
2823 return NT_STATUS_NO_MEMORY;
2826 status = rpc_transport_smbd_init(result, conn, syntax,
2827 &result->transport);
2828 if (!NT_STATUS_IS_OK(status)) {
2829 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2830 nt_errstr(status)));
2831 TALLOC_FREE(result);
2835 status = rpccli_anon_bind_data(result, &auth);
2836 if (!NT_STATUS_IS_OK(status)) {
2837 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2838 nt_errstr(status)));
2839 TALLOC_FREE(result);
2843 status = rpc_pipe_bind(result, auth);
2844 if (!NT_STATUS_IS_OK(status)) {
2845 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2846 TALLOC_FREE(result);
2850 result->transport->transport = NCACN_INTERNAL;
2853 return NT_STATUS_OK;
2856 /****************************************************************************
2857 Open a pipe to a remote server.
2858 ****************************************************************************/
2860 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2861 enum dcerpc_transport_t transport,
2862 const struct ndr_syntax_id *interface,
2863 struct rpc_pipe_client **presult)
2865 switch (transport) {
2867 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2870 return rpc_pipe_open_np(cli, interface, presult);
2872 return NT_STATUS_NOT_IMPLEMENTED;
2876 /****************************************************************************
2877 Open a named pipe to an SMB server and bind anonymously.
2878 ****************************************************************************/
2880 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2881 enum dcerpc_transport_t transport,
2882 const struct ndr_syntax_id *interface,
2883 struct rpc_pipe_client **presult)
2885 struct rpc_pipe_client *result;
2886 struct pipe_auth_data *auth;
2889 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2890 if (!NT_STATUS_IS_OK(status)) {
2894 status = rpccli_anon_bind_data(result, &auth);
2895 if (!NT_STATUS_IS_OK(status)) {
2896 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2897 nt_errstr(status)));
2898 TALLOC_FREE(result);
2903 * This is a bit of an abstraction violation due to the fact that an
2904 * anonymous bind on an authenticated SMB inherits the user/domain
2905 * from the enclosing SMB creds
2908 TALLOC_FREE(auth->user_name);
2909 TALLOC_FREE(auth->domain);
2911 auth->user_name = talloc_strdup(auth, cli->user_name);
2912 auth->domain = talloc_strdup(auth, cli->domain);
2913 auth->user_session_key = data_blob_talloc(auth,
2914 cli->user_session_key.data,
2915 cli->user_session_key.length);
2917 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2918 TALLOC_FREE(result);
2919 return NT_STATUS_NO_MEMORY;
2922 status = rpc_pipe_bind(result, auth);
2923 if (!NT_STATUS_IS_OK(status)) {
2925 if (ndr_syntax_id_equal(interface,
2926 &ndr_table_dssetup.syntax_id)) {
2927 /* non AD domains just don't have this pipe, avoid
2928 * level 0 statement in that case - gd */
2931 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2932 "%s failed with error %s\n",
2933 get_pipe_name_from_syntax(talloc_tos(), interface),
2934 nt_errstr(status) ));
2935 TALLOC_FREE(result);
2939 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2940 "%s and bound anonymously.\n",
2941 get_pipe_name_from_syntax(talloc_tos(), interface),
2945 return NT_STATUS_OK;
2948 /****************************************************************************
2949 ****************************************************************************/
2951 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2952 const struct ndr_syntax_id *interface,
2953 struct rpc_pipe_client **presult)
2955 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2956 interface, presult);
2959 /****************************************************************************
2960 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2961 ****************************************************************************/
2963 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2964 const struct ndr_syntax_id *interface,
2965 enum dcerpc_transport_t transport,
2967 enum dcerpc_AuthLevel auth_level,
2969 const char *username,
2970 const char *password,
2971 struct rpc_pipe_client **presult)
2973 struct rpc_pipe_client *result;
2974 struct pipe_auth_data *auth;
2975 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2976 enum pipe_auth_type_spnego spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2979 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2980 if (!NT_STATUS_IS_OK(status)) {
2985 auth_type = DCERPC_AUTH_TYPE_SPNEGO;
2986 spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
2989 status = rpccli_ntlmssp_bind_data(result,
2990 auth_type, spnego_type, auth_level,
2991 domain, username, password,
2993 if (!NT_STATUS_IS_OK(status)) {
2994 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2995 nt_errstr(status)));
2999 status = rpc_pipe_bind(result, auth);
3000 if (!NT_STATUS_IS_OK(status)) {
3001 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3002 nt_errstr(status) ));
3006 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3007 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3008 get_pipe_name_from_syntax(talloc_tos(), interface),
3009 cli->desthost, domain, username ));
3012 return NT_STATUS_OK;
3016 TALLOC_FREE(result);
3020 /****************************************************************************
3022 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3023 ****************************************************************************/
3025 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3026 const struct ndr_syntax_id *interface,
3027 enum dcerpc_transport_t transport,
3028 enum dcerpc_AuthLevel auth_level,
3030 const char *username,
3031 const char *password,
3032 struct rpc_pipe_client **presult)
3034 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3045 /****************************************************************************
3047 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3048 ****************************************************************************/
3050 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3051 const struct ndr_syntax_id *interface,
3052 enum dcerpc_transport_t transport,
3053 enum dcerpc_AuthLevel auth_level,
3055 const char *username,
3056 const char *password,
3057 struct rpc_pipe_client **presult)
3059 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3070 /****************************************************************************
3071 Get a the schannel session key out of an already opened netlogon pipe.
3072 ****************************************************************************/
3073 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3074 struct cli_state *cli,
3078 enum netr_SchannelType sec_chan_type = 0;
3079 unsigned char machine_pwd[16];
3080 const char *machine_account;
3083 /* Get the machine account credentials from secrets.tdb. */
3084 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3087 DEBUG(0, ("get_schannel_session_key: could not fetch "
3088 "trust account password for domain '%s'\n",
3090 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3093 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3094 cli->desthost, /* server name */
3095 domain, /* domain */
3096 global_myname(), /* client name */
3097 machine_account, /* machine account name */
3102 if (!NT_STATUS_IS_OK(status)) {
3103 DEBUG(3, ("get_schannel_session_key_common: "
3104 "rpccli_netlogon_setup_creds failed with result %s "
3105 "to server %s, domain %s, machine account %s.\n",
3106 nt_errstr(status), cli->desthost, domain,
3111 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3112 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3114 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3117 return NT_STATUS_OK;;
3120 /****************************************************************************
3121 Open a netlogon pipe and get the schannel session key.
3122 Now exposed to external callers.
3123 ****************************************************************************/
3126 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3129 struct rpc_pipe_client **presult)
3131 struct rpc_pipe_client *netlogon_pipe = NULL;
3134 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3136 if (!NT_STATUS_IS_OK(status)) {
3140 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3142 if (!NT_STATUS_IS_OK(status)) {
3143 TALLOC_FREE(netlogon_pipe);
3147 *presult = netlogon_pipe;
3148 return NT_STATUS_OK;
3151 /****************************************************************************
3153 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3154 using session_key. sign and seal.
3156 The *pdc will be stolen onto this new pipe
3157 ****************************************************************************/
3159 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3160 const struct ndr_syntax_id *interface,
3161 enum dcerpc_transport_t transport,
3162 enum dcerpc_AuthLevel auth_level,
3164 struct netlogon_creds_CredentialState **pdc,
3165 struct rpc_pipe_client **presult)
3167 struct rpc_pipe_client *result;
3168 struct pipe_auth_data *auth;
3171 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3172 if (!NT_STATUS_IS_OK(status)) {
3176 status = rpccli_schannel_bind_data(result, domain, auth_level,
3178 if (!NT_STATUS_IS_OK(status)) {
3179 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3180 nt_errstr(status)));
3181 TALLOC_FREE(result);
3185 status = rpc_pipe_bind(result, auth);
3186 if (!NT_STATUS_IS_OK(status)) {
3187 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3188 "cli_rpc_pipe_bind failed with error %s\n",
3189 nt_errstr(status) ));
3190 TALLOC_FREE(result);
3195 * The credentials on a new netlogon pipe are the ones we are passed
3196 * in - reference them in
3198 result->dc = talloc_move(result, pdc);
3200 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3201 "for domain %s and bound using schannel.\n",
3202 get_pipe_name_from_syntax(talloc_tos(), interface),
3203 cli->desthost, domain ));
3206 return NT_STATUS_OK;
3209 /****************************************************************************
3210 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3211 Fetch the session key ourselves using a temporary netlogon pipe. This
3212 version uses an ntlmssp auth bound netlogon pipe to get the key.
3213 ****************************************************************************/
3215 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3217 const char *username,
3218 const char *password,
3220 struct rpc_pipe_client **presult)
3222 struct rpc_pipe_client *netlogon_pipe = NULL;
3225 status = cli_rpc_pipe_open_spnego_ntlmssp(
3226 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3227 DCERPC_AUTH_LEVEL_PRIVACY,
3228 domain, username, password, &netlogon_pipe);
3229 if (!NT_STATUS_IS_OK(status)) {
3233 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3235 if (!NT_STATUS_IS_OK(status)) {
3236 TALLOC_FREE(netlogon_pipe);
3240 *presult = netlogon_pipe;
3241 return NT_STATUS_OK;
3244 /****************************************************************************
3245 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3246 Fetch the session key ourselves using a temporary netlogon pipe. This version
3247 uses an ntlmssp bind to get the session key.
3248 ****************************************************************************/
3250 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3251 const struct ndr_syntax_id *interface,
3252 enum dcerpc_transport_t transport,
3253 enum dcerpc_AuthLevel auth_level,
3255 const char *username,
3256 const char *password,
3257 struct rpc_pipe_client **presult)
3259 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3260 struct rpc_pipe_client *netlogon_pipe = NULL;
3261 struct rpc_pipe_client *result = NULL;
3264 status = get_schannel_session_key_auth_ntlmssp(
3265 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3266 if (!NT_STATUS_IS_OK(status)) {
3267 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3268 "key from server %s for domain %s.\n",
3269 cli->desthost, domain ));
3273 status = cli_rpc_pipe_open_schannel_with_key(
3274 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3277 /* Now we've bound using the session key we can close the netlog pipe. */
3278 TALLOC_FREE(netlogon_pipe);
3280 if (NT_STATUS_IS_OK(status)) {
3286 /****************************************************************************
3287 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3288 Fetch the session key ourselves using a temporary netlogon pipe.
3289 ****************************************************************************/
3291 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3292 const struct ndr_syntax_id *interface,
3293 enum dcerpc_transport_t transport,
3294 enum dcerpc_AuthLevel auth_level,
3296 struct rpc_pipe_client **presult)
3298 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3299 struct rpc_pipe_client *netlogon_pipe = NULL;
3300 struct rpc_pipe_client *result = NULL;
3303 status = get_schannel_session_key(cli, domain, &neg_flags,
3305 if (!NT_STATUS_IS_OK(status)) {
3306 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3307 "key from server %s for domain %s.\n",
3308 cli->desthost, domain ));
3312 status = cli_rpc_pipe_open_schannel_with_key(
3313 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3316 /* Now we've bound using the session key we can close the netlog pipe. */
3317 TALLOC_FREE(netlogon_pipe);
3319 if (NT_STATUS_IS_OK(status)) {
3326 /****************************************************************************
3327 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3328 The idea is this can be called with service_princ, username and password all
3329 NULL so long as the caller has a TGT.
3330 ****************************************************************************/
3332 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3333 const struct ndr_syntax_id *interface,
3334 enum dcerpc_transport_t transport,
3335 enum dcerpc_AuthLevel auth_level,
3336 const char *service_princ,
3337 const char *username,
3338 const char *password,
3339 struct rpc_pipe_client **presult)
3342 struct rpc_pipe_client *result;
3343 struct pipe_auth_data *auth;
3346 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3347 if (!NT_STATUS_IS_OK(status)) {
3351 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3352 username, password, &auth);
3353 if (!NT_STATUS_IS_OK(status)) {
3354 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3355 nt_errstr(status)));
3356 TALLOC_FREE(result);
3360 status = rpc_pipe_bind(result, auth);
3361 if (!NT_STATUS_IS_OK(status)) {
3362 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3363 "with error %s\n", nt_errstr(status)));
3364 TALLOC_FREE(result);
3369 return NT_STATUS_OK;
3371 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3372 return NT_STATUS_NOT_IMPLEMENTED;
3376 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3377 struct rpc_pipe_client *cli,
3378 DATA_BLOB *session_key)
3380 struct pipe_auth_data *a = cli->auth;
3383 if (!session_key || !cli) {
3384 return NT_STATUS_INVALID_PARAMETER;
3388 return NT_STATUS_INVALID_PARAMETER;
3391 switch (cli->auth->auth_type) {
3392 case DCERPC_AUTH_TYPE_SCHANNEL:
3393 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3396 case DCERPC_AUTH_TYPE_SPNEGO:
3397 switch (cli->auth->spnego_type) {
3398 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3399 sk = auth_ntlmssp_get_session_key(
3400 a->a_u.auth_ntlmssp_state);
3402 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3403 sk = data_blob_const(
3404 a->a_u.kerberos_auth->session_key.data,
3405 a->a_u.kerberos_auth->session_key.length);
3408 return NT_STATUS_NO_USER_SESSION_KEY;
3411 case DCERPC_AUTH_TYPE_NTLMSSP:
3412 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3414 case DCERPC_AUTH_TYPE_KRB5:
3415 sk = data_blob_const(a->a_u.kerberos_auth->session_key.data,
3416 a->a_u.kerberos_auth->session_key.length);
3418 case DCERPC_AUTH_TYPE_NONE:
3419 sk = data_blob_const(a->user_session_key.data,
3420 a->user_session_key.length);
3423 return NT_STATUS_NO_USER_SESSION_KEY;
3426 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3427 return NT_STATUS_OK;