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 NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli,
1276 uint32_t *data_to_send,
1277 uint16_t *p_frag_len,
1278 uint16_t *p_auth_len,
1279 uint32_t *p_ss_padding)
1281 uint32_t data_space, data_len;
1283 switch (cli->auth->auth_level) {
1284 case DCERPC_AUTH_LEVEL_NONE:
1285 case DCERPC_AUTH_LEVEL_CONNECT:
1286 case DCERPC_AUTH_LEVEL_PACKET:
1287 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1288 data_len = MIN(data_space, data_left);
1291 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1292 *data_to_send = data_len;
1293 return NT_STATUS_OK;
1295 case DCERPC_AUTH_LEVEL_INTEGRITY:
1296 case DCERPC_AUTH_LEVEL_PRIVACY:
1297 /* Treat the same for all authenticated rpc requests. */
1298 switch(cli->auth->auth_type) {
1299 case DCERPC_AUTH_TYPE_SPNEGO:
1300 switch (cli->auth->spnego_type) {
1301 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1302 *p_auth_len = NTLMSSP_SIG_SIZE;
1304 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1305 *p_auth_len = 0; /* no signing */
1308 return NT_STATUS_INVALID_PARAMETER;
1310 case DCERPC_AUTH_TYPE_NTLMSSP:
1311 *p_auth_len = NTLMSSP_SIG_SIZE;
1313 case DCERPC_AUTH_TYPE_SCHANNEL:
1314 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1316 case DCERPC_AUTH_TYPE_KRB5:
1317 *p_auth_len = 0; /* no signing */
1320 return NT_STATUS_INVALID_PARAMETER;
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
1337 *data_to_send = data_len;
1338 return NT_STATUS_OK;
1344 return NT_STATUS_INVALID_PARAMETER;
1347 /*******************************************************************
1349 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1350 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1351 and deals with signing/sealing details.
1352 ********************************************************************/
1354 struct rpc_api_pipe_req_state {
1355 struct event_context *ev;
1356 struct rpc_pipe_client *cli;
1359 DATA_BLOB *req_data;
1360 uint32_t req_data_sent;
1362 DATA_BLOB reply_pdu;
1365 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1366 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1367 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1368 bool *is_last_frag);
1370 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1371 struct event_context *ev,
1372 struct rpc_pipe_client *cli,
1374 DATA_BLOB *req_data)
1376 struct tevent_req *req, *subreq;
1377 struct rpc_api_pipe_req_state *state;
1381 req = tevent_req_create(mem_ctx, &state,
1382 struct rpc_api_pipe_req_state);
1388 state->op_num = op_num;
1389 state->req_data = req_data;
1390 state->req_data_sent = 0;
1391 state->call_id = get_rpc_call_id();
1392 state->reply_pdu = data_blob_null;
1393 state->rpc_out = data_blob_null;
1395 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1396 + RPC_MAX_SIGN_SIZE) {
1397 /* Server is screwed up ! */
1398 status = NT_STATUS_INVALID_PARAMETER;
1402 status = prepare_next_frag(state, &is_last_frag);
1403 if (!NT_STATUS_IS_OK(status)) {
1408 subreq = rpc_api_pipe_send(state, ev, state->cli,
1410 DCERPC_PKT_RESPONSE);
1411 if (subreq == NULL) {
1414 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1416 subreq = rpc_write_send(state, ev, cli->transport,
1417 state->rpc_out.data,
1418 state->rpc_out.length);
1419 if (subreq == NULL) {
1422 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1428 tevent_req_nterror(req, status);
1429 return tevent_req_post(req, ev);
1435 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1438 uint32_t data_sent_thistime;
1445 union dcerpc_payload u;
1447 data_left = state->req_data->length - state->req_data_sent;
1449 status = calculate_data_len_tosend(state->cli, data_left,
1450 &data_sent_thistime,
1451 &frag_len, &auth_len,
1453 if (!NT_STATUS_IS_OK(status)) {
1457 if (state->req_data_sent == 0) {
1458 flags = DCERPC_PFC_FLAG_FIRST;
1461 if (data_sent_thistime == data_left) {
1462 flags |= DCERPC_PFC_FLAG_LAST;
1465 data_blob_free(&state->rpc_out);
1467 ZERO_STRUCT(u.request);
1469 u.request.alloc_hint = state->req_data->length;
1470 u.request.context_id = 0;
1471 u.request.opnum = state->op_num;
1473 status = dcerpc_push_ncacn_packet(state,
1480 if (!NT_STATUS_IS_OK(status)) {
1484 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1485 * compute it right for requests because the auth trailer is missing
1487 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1489 /* Copy in the data. */
1490 if (!data_blob_append(NULL, &state->rpc_out,
1491 state->req_data->data + state->req_data_sent,
1492 data_sent_thistime)) {
1493 return NT_STATUS_NO_MEMORY;
1496 switch (state->cli->auth->auth_level) {
1497 case DCERPC_AUTH_LEVEL_NONE:
1498 case DCERPC_AUTH_LEVEL_CONNECT:
1499 case DCERPC_AUTH_LEVEL_PACKET:
1501 case DCERPC_AUTH_LEVEL_INTEGRITY:
1502 case DCERPC_AUTH_LEVEL_PRIVACY:
1503 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1505 if (!NT_STATUS_IS_OK(status)) {
1510 return NT_STATUS_INVALID_PARAMETER;
1513 state->req_data_sent += data_sent_thistime;
1514 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1519 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1521 struct tevent_req *req = tevent_req_callback_data(
1522 subreq, struct tevent_req);
1523 struct rpc_api_pipe_req_state *state = tevent_req_data(
1524 req, struct rpc_api_pipe_req_state);
1528 status = rpc_write_recv(subreq);
1529 TALLOC_FREE(subreq);
1530 if (!NT_STATUS_IS_OK(status)) {
1531 tevent_req_nterror(req, status);
1535 status = prepare_next_frag(state, &is_last_frag);
1536 if (!NT_STATUS_IS_OK(status)) {
1537 tevent_req_nterror(req, status);
1542 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1544 DCERPC_PKT_RESPONSE);
1545 if (tevent_req_nomem(subreq, req)) {
1548 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1550 subreq = rpc_write_send(state, state->ev,
1551 state->cli->transport,
1552 state->rpc_out.data,
1553 state->rpc_out.length);
1554 if (tevent_req_nomem(subreq, req)) {
1557 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1562 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1564 struct tevent_req *req = tevent_req_callback_data(
1565 subreq, struct tevent_req);
1566 struct rpc_api_pipe_req_state *state = tevent_req_data(
1567 req, struct rpc_api_pipe_req_state);
1570 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1571 TALLOC_FREE(subreq);
1572 if (!NT_STATUS_IS_OK(status)) {
1573 tevent_req_nterror(req, status);
1576 tevent_req_done(req);
1579 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1580 DATA_BLOB *reply_pdu)
1582 struct rpc_api_pipe_req_state *state = tevent_req_data(
1583 req, struct rpc_api_pipe_req_state);
1586 if (tevent_req_is_nterror(req, &status)) {
1588 * We always have to initialize to reply pdu, even if there is
1589 * none. The rpccli_* caller routines expect this.
1591 *reply_pdu = data_blob_null;
1595 /* return data to caller and assign it ownership of memory */
1596 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1597 reply_pdu->length = state->reply_pdu.length;
1598 state->reply_pdu.length = 0;
1600 return NT_STATUS_OK;
1604 /****************************************************************************
1605 Set the handle state.
1606 ****************************************************************************/
1608 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1609 const char *pipe_name, uint16 device_state)
1611 bool state_set = False;
1613 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1614 char *rparam = NULL;
1616 uint32 rparam_len, rdata_len;
1618 if (pipe_name == NULL)
1621 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1622 cli->fnum, pipe_name, device_state));
1624 /* create parameters: device state */
1625 SSVAL(param, 0, device_state);
1627 /* create setup parameters. */
1629 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1631 /* send the data on \PIPE\ */
1632 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1633 setup, 2, 0, /* setup, length, max */
1634 param, 2, 0, /* param, length, max */
1635 NULL, 0, 1024, /* data, length, max */
1636 &rparam, &rparam_len, /* return param, length */
1637 &rdata, &rdata_len)) /* return data, length */
1639 DEBUG(5, ("Set Handle state: return OK\n"));
1650 /****************************************************************************
1651 Check the rpc bind acknowledge response.
1652 ****************************************************************************/
1654 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1655 const struct ndr_syntax_id *transfer)
1657 struct dcerpc_ack_ctx ctx;
1659 if (r->secondary_address_size == 0) {
1660 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1663 if (r->num_results < 1 || !r->ctx_list) {
1667 ctx = r->ctx_list[0];
1669 /* check the transfer syntax */
1670 if ((ctx.syntax.if_version != transfer->if_version) ||
1671 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1672 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1676 if (r->num_results != 0x1 || ctx.result != 0) {
1677 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1678 r->num_results, ctx.reason));
1681 DEBUG(5,("check_bind_response: accepted!\n"));
1685 /*******************************************************************
1686 Creates a DCE/RPC bind authentication response.
1687 This is the packet that is sent back to the server once we
1688 have received a BIND-ACK, to finish the third leg of
1689 the authentication handshake.
1690 ********************************************************************/
1692 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1693 struct rpc_pipe_client *cli,
1695 enum dcerpc_AuthType auth_type,
1696 enum dcerpc_AuthLevel auth_level,
1697 DATA_BLOB *pauth_blob,
1701 union dcerpc_payload u;
1705 status = dcerpc_push_dcerpc_auth(mem_ctx,
1708 0, /* auth_pad_length */
1709 1, /* auth_context_id */
1711 &u.auth3.auth_info);
1712 if (!NT_STATUS_IS_OK(status)) {
1716 status = dcerpc_push_ncacn_packet(mem_ctx,
1718 DCERPC_PFC_FLAG_FIRST |
1719 DCERPC_PFC_FLAG_LAST,
1724 data_blob_free(&u.auth3.auth_info);
1725 if (!NT_STATUS_IS_OK(status)) {
1726 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1730 return NT_STATUS_OK;
1733 /*******************************************************************
1734 Creates a DCE/RPC bind alter context authentication request which
1735 may contain a spnego auth blobl
1736 ********************************************************************/
1738 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1740 const struct ndr_syntax_id *abstract,
1741 const struct ndr_syntax_id *transfer,
1742 enum dcerpc_AuthLevel auth_level,
1743 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1746 DATA_BLOB auth_info;
1749 status = dcerpc_push_dcerpc_auth(mem_ctx,
1750 DCERPC_AUTH_TYPE_SPNEGO,
1752 0, /* auth_pad_length */
1753 1, /* auth_context_id */
1756 if (!NT_STATUS_IS_OK(status)) {
1760 status = create_bind_or_alt_ctx_internal(mem_ctx,
1767 data_blob_free(&auth_info);
1771 /****************************************************************************
1773 ****************************************************************************/
1775 struct rpc_pipe_bind_state {
1776 struct event_context *ev;
1777 struct rpc_pipe_client *cli;
1779 uint32_t rpc_call_id;
1782 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1783 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1784 struct rpc_pipe_bind_state *state,
1785 DATA_BLOB *credentials);
1786 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1787 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1788 struct rpc_pipe_bind_state *state,
1789 DATA_BLOB *credentials);
1790 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1792 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1793 struct event_context *ev,
1794 struct rpc_pipe_client *cli,
1795 struct pipe_auth_data *auth)
1797 struct tevent_req *req, *subreq;
1798 struct rpc_pipe_bind_state *state;
1801 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1806 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1807 rpccli_pipe_txt(talloc_tos(), cli),
1808 (unsigned int)auth->auth_type,
1809 (unsigned int)auth->spnego_type,
1810 (unsigned int)auth->auth_level ));
1814 state->rpc_call_id = get_rpc_call_id();
1815 state->rpc_out = data_blob_null;
1817 cli->auth = talloc_move(cli, &auth);
1819 /* Marshall the outgoing data. */
1820 status = create_rpc_bind_req(state, cli,
1823 &cli->abstract_syntax,
1824 &cli->transfer_syntax,
1827 if (!NT_STATUS_IS_OK(status)) {
1831 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1832 DCERPC_PKT_BIND_ACK);
1833 if (subreq == NULL) {
1836 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1840 tevent_req_nterror(req, status);
1841 return tevent_req_post(req, ev);
1847 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1849 struct tevent_req *req = tevent_req_callback_data(
1850 subreq, struct tevent_req);
1851 struct rpc_pipe_bind_state *state = tevent_req_data(
1852 req, struct rpc_pipe_bind_state);
1853 DATA_BLOB reply_pdu;
1854 struct ncacn_packet *pkt;
1855 struct dcerpc_auth auth;
1858 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1859 TALLOC_FREE(subreq);
1860 if (!NT_STATUS_IS_OK(status)) {
1861 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1862 rpccli_pipe_txt(talloc_tos(), state->cli),
1863 nt_errstr(status)));
1864 tevent_req_nterror(req, status);
1868 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1869 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1870 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1874 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1875 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1877 switch(state->cli->auth->auth_type) {
1879 case DCERPC_AUTH_TYPE_NONE:
1880 case DCERPC_AUTH_TYPE_SCHANNEL:
1881 /* Bind complete. */
1882 tevent_req_done(req);
1885 case DCERPC_AUTH_TYPE_NTLMSSP:
1886 case DCERPC_AUTH_TYPE_SPNEGO:
1887 case DCERPC_AUTH_TYPE_KRB5:
1888 /* Paranoid lenght checks */
1889 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1890 + pkt->auth_length) {
1891 tevent_req_nterror(req,
1892 NT_STATUS_INFO_LENGTH_MISMATCH);
1895 /* get auth credentials */
1896 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1897 &pkt->u.bind_ack.auth_info,
1899 if (!NT_STATUS_IS_OK(status)) {
1900 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1901 nt_errstr(status)));
1902 tevent_req_nterror(req, status);
1912 * For authenticated binds we may need to do 3 or 4 leg binds.
1915 switch(state->cli->auth->auth_type) {
1917 case DCERPC_AUTH_TYPE_NONE:
1918 case DCERPC_AUTH_TYPE_SCHANNEL:
1919 /* Bind complete. */
1920 tevent_req_done(req);
1923 case DCERPC_AUTH_TYPE_NTLMSSP:
1924 /* Need to send AUTH3 packet - no reply. */
1925 status = rpc_finish_auth3_bind_send(req, state,
1929 case DCERPC_AUTH_TYPE_SPNEGO:
1930 if (state->cli->auth->spnego_type !=
1931 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1934 /* Need to send alter context request and reply. */
1935 status = rpc_finish_spnego_ntlmssp_bind_send(req, state,
1939 case DCERPC_AUTH_TYPE_KRB5:
1940 status = NT_STATUS_NOT_IMPLEMENTED;
1947 if (!NT_STATUS_IS_OK(status)) {
1948 tevent_req_nterror(req, status);
1953 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
1954 (unsigned int)state->cli->auth->auth_type,
1955 (unsigned int)state->cli->auth->spnego_type));
1956 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1959 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1960 struct rpc_pipe_bind_state *state,
1961 DATA_BLOB *credentials)
1963 struct pipe_auth_data *auth = state->cli->auth;
1964 DATA_BLOB client_reply = data_blob_null;
1965 struct tevent_req *subreq;
1968 /* TODO - check auth_type/auth_level match. */
1970 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
1971 *credentials, &client_reply);
1973 if (!NT_STATUS_IS_OK(status)) {
1974 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
1975 "blob failed: %s.\n", nt_errstr(status)));
1979 data_blob_free(&state->rpc_out);
1981 status = create_rpc_bind_auth3(state, state->cli,
1987 data_blob_free(&client_reply);
1989 if (!NT_STATUS_IS_OK(status)) {
1993 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1994 state->rpc_out.data, state->rpc_out.length);
1995 if (subreq == NULL) {
1996 return NT_STATUS_NO_MEMORY;
1998 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
1999 return NT_STATUS_OK;
2002 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2004 struct tevent_req *req = tevent_req_callback_data(
2005 subreq, struct tevent_req);
2008 status = rpc_write_recv(subreq);
2009 TALLOC_FREE(subreq);
2010 if (!NT_STATUS_IS_OK(status)) {
2011 tevent_req_nterror(req, status);
2014 tevent_req_done(req);
2017 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2018 struct rpc_pipe_bind_state *state,
2019 DATA_BLOB *credentials)
2021 struct pipe_auth_data *auth = state->cli->auth;
2022 DATA_BLOB server_ntlm_response = data_blob_null;
2023 DATA_BLOB client_reply = data_blob_null;
2024 DATA_BLOB tmp_blob = data_blob_null;
2025 struct tevent_req *subreq;
2029 * The server might give us back two challenges - tmp_blob is for the
2032 if (!spnego_parse_challenge(state, *credentials,
2033 &server_ntlm_response,
2035 data_blob_free(&server_ntlm_response);
2036 data_blob_free(&tmp_blob);
2037 return NT_STATUS_INVALID_PARAMETER;
2040 /* We're finished with the server spnego response and the tmp_blob. */
2041 data_blob_free(&tmp_blob);
2043 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2044 server_ntlm_response, &client_reply);
2046 /* Finished with the server_ntlm response */
2047 data_blob_free(&server_ntlm_response);
2049 if (!NT_STATUS_IS_OK(status)) {
2050 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2051 "using server blob failed.\n"));
2052 data_blob_free(&client_reply);
2056 /* SPNEGO wrap the client reply. */
2057 tmp_blob = spnego_gen_auth(state, client_reply);
2058 data_blob_free(&client_reply);
2059 client_reply = tmp_blob;
2060 tmp_blob = data_blob_null;
2062 /* Now prepare the alter context pdu. */
2063 data_blob_free(&state->rpc_out);
2065 status = create_rpc_alter_context(state,
2067 &state->cli->abstract_syntax,
2068 &state->cli->transfer_syntax,
2072 data_blob_free(&client_reply);
2074 if (!NT_STATUS_IS_OK(status)) {
2078 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2079 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2080 if (subreq == NULL) {
2081 return NT_STATUS_NO_MEMORY;
2083 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2084 return NT_STATUS_OK;
2087 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2089 struct tevent_req *req = tevent_req_callback_data(
2090 subreq, struct tevent_req);
2091 struct rpc_pipe_bind_state *state = tevent_req_data(
2092 req, struct rpc_pipe_bind_state);
2093 DATA_BLOB tmp_blob = data_blob_null;
2094 struct ncacn_packet *pkt;
2095 struct dcerpc_auth auth;
2098 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2099 TALLOC_FREE(subreq);
2100 if (!NT_STATUS_IS_OK(status)) {
2101 tevent_req_nterror(req, status);
2105 status = dcerpc_pull_dcerpc_auth(pkt,
2106 &pkt->u.alter_resp.auth_info,
2108 if (!NT_STATUS_IS_OK(status)) {
2109 tevent_req_nterror(req, status);
2113 /* Check we got a valid auth response. */
2114 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2116 OID_NTLMSSP, &tmp_blob)) {
2117 data_blob_free(&tmp_blob);
2118 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2122 data_blob_free(&tmp_blob);
2124 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2125 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2126 tevent_req_done(req);
2129 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2131 return tevent_req_simple_recv_ntstatus(req);
2134 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2135 struct pipe_auth_data *auth)
2137 TALLOC_CTX *frame = talloc_stackframe();
2138 struct event_context *ev;
2139 struct tevent_req *req;
2140 NTSTATUS status = NT_STATUS_OK;
2142 ev = event_context_init(frame);
2144 status = NT_STATUS_NO_MEMORY;
2148 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2150 status = NT_STATUS_NO_MEMORY;
2154 if (!tevent_req_poll(req, ev)) {
2155 status = map_nt_error_from_unix(errno);
2159 status = rpc_pipe_bind_recv(req);
2165 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2167 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2168 unsigned int timeout)
2172 if (rpc_cli->transport == NULL) {
2173 return RPCCLI_DEFAULT_TIMEOUT;
2176 if (rpc_cli->transport->set_timeout == NULL) {
2177 return RPCCLI_DEFAULT_TIMEOUT;
2180 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2182 return RPCCLI_DEFAULT_TIMEOUT;
2188 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2190 if (rpc_cli == NULL) {
2194 if (rpc_cli->transport == NULL) {
2198 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2201 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2203 struct cli_state *cli;
2205 if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP)
2206 || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO
2207 && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2208 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2212 cli = rpc_pipe_np_smb_conn(rpc_cli);
2216 E_md4hash(cli->password ? cli->password : "", nt_hash);
2220 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2221 struct pipe_auth_data **presult)
2223 struct pipe_auth_data *result;
2225 result = talloc(mem_ctx, struct pipe_auth_data);
2226 if (result == NULL) {
2227 return NT_STATUS_NO_MEMORY;
2230 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2231 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2232 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2234 result->user_name = talloc_strdup(result, "");
2235 result->domain = talloc_strdup(result, "");
2236 if ((result->user_name == NULL) || (result->domain == NULL)) {
2237 TALLOC_FREE(result);
2238 return NT_STATUS_NO_MEMORY;
2242 return NT_STATUS_OK;
2245 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2247 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2251 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2252 enum dcerpc_AuthType auth_type,
2253 enum pipe_auth_type_spnego spnego_type,
2254 enum dcerpc_AuthLevel auth_level,
2256 const char *username,
2257 const char *password,
2258 struct pipe_auth_data **presult)
2260 struct pipe_auth_data *result;
2263 result = talloc(mem_ctx, struct pipe_auth_data);
2264 if (result == NULL) {
2265 return NT_STATUS_NO_MEMORY;
2268 result->auth_type = auth_type;
2269 result->spnego_type = spnego_type;
2270 result->auth_level = auth_level;
2272 result->user_name = talloc_strdup(result, username);
2273 result->domain = talloc_strdup(result, domain);
2274 if ((result->user_name == NULL) || (result->domain == NULL)) {
2275 status = NT_STATUS_NO_MEMORY;
2279 status = auth_ntlmssp_client_start(NULL,
2282 lp_client_ntlmv2_auth(),
2283 &result->a_u.auth_ntlmssp_state);
2284 if (!NT_STATUS_IS_OK(status)) {
2288 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2290 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2292 if (!NT_STATUS_IS_OK(status)) {
2296 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2298 if (!NT_STATUS_IS_OK(status)) {
2302 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2304 if (!NT_STATUS_IS_OK(status)) {
2309 * Turn off sign+seal to allow selected auth level to turn it back on.
2311 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2312 ~(NTLMSSP_NEGOTIATE_SIGN |
2313 NTLMSSP_NEGOTIATE_SEAL));
2315 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2316 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2317 NTLMSSP_NEGOTIATE_SIGN);
2318 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2319 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2320 NTLMSSP_NEGOTIATE_SEAL |
2321 NTLMSSP_NEGOTIATE_SIGN);
2325 return NT_STATUS_OK;
2328 TALLOC_FREE(result);
2332 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2333 enum dcerpc_AuthLevel auth_level,
2334 struct netlogon_creds_CredentialState *creds,
2335 struct pipe_auth_data **presult)
2337 struct pipe_auth_data *result;
2339 result = talloc(mem_ctx, struct pipe_auth_data);
2340 if (result == NULL) {
2341 return NT_STATUS_NO_MEMORY;
2344 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2345 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2346 result->auth_level = auth_level;
2348 result->user_name = talloc_strdup(result, "");
2349 result->domain = talloc_strdup(result, domain);
2350 if ((result->user_name == NULL) || (result->domain == NULL)) {
2354 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2355 if (result->a_u.schannel_auth == NULL) {
2359 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2360 result->a_u.schannel_auth->seq_num = 0;
2361 result->a_u.schannel_auth->initiator = true;
2362 result->a_u.schannel_auth->creds = creds;
2365 return NT_STATUS_OK;
2368 TALLOC_FREE(result);
2369 return NT_STATUS_NO_MEMORY;
2373 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2375 data_blob_free(&auth->session_key);
2380 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2381 enum dcerpc_AuthLevel auth_level,
2382 const char *service_princ,
2383 const char *username,
2384 const char *password,
2385 struct pipe_auth_data **presult)
2388 struct pipe_auth_data *result;
2390 if ((username != NULL) && (password != NULL)) {
2391 int ret = kerberos_kinit_password(username, password, 0, NULL);
2393 return NT_STATUS_ACCESS_DENIED;
2397 result = talloc(mem_ctx, struct pipe_auth_data);
2398 if (result == NULL) {
2399 return NT_STATUS_NO_MEMORY;
2402 result->auth_type = DCERPC_AUTH_TYPE_KRB5;
2403 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2404 result->auth_level = auth_level;
2407 * Username / domain need fixing!
2409 result->user_name = talloc_strdup(result, "");
2410 result->domain = talloc_strdup(result, "");
2411 if ((result->user_name == NULL) || (result->domain == NULL)) {
2415 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2416 result, struct kerberos_auth_struct);
2417 if (result->a_u.kerberos_auth == NULL) {
2420 talloc_set_destructor(result->a_u.kerberos_auth,
2421 cli_auth_kerberos_data_destructor);
2423 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2424 result, service_princ);
2425 if (result->a_u.kerberos_auth->service_principal == NULL) {
2430 return NT_STATUS_OK;
2433 TALLOC_FREE(result);
2434 return NT_STATUS_NO_MEMORY;
2436 return NT_STATUS_NOT_SUPPORTED;
2441 * Create an rpc pipe client struct, connecting to a tcp port.
2443 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2445 const struct ndr_syntax_id *abstract_syntax,
2446 struct rpc_pipe_client **presult)
2448 struct rpc_pipe_client *result;
2449 struct sockaddr_storage addr;
2453 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2454 if (result == NULL) {
2455 return NT_STATUS_NO_MEMORY;
2458 result->abstract_syntax = *abstract_syntax;
2459 result->transfer_syntax = ndr_transfer_syntax;
2460 result->dispatch = cli_do_rpc_ndr;
2461 result->dispatch_send = cli_do_rpc_ndr_send;
2462 result->dispatch_recv = cli_do_rpc_ndr_recv;
2464 result->desthost = talloc_strdup(result, host);
2465 result->srv_name_slash = talloc_asprintf_strupper_m(
2466 result, "\\\\%s", result->desthost);
2467 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2468 status = NT_STATUS_NO_MEMORY;
2472 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2473 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2475 if (!resolve_name(host, &addr, 0, false)) {
2476 status = NT_STATUS_NOT_FOUND;
2480 status = open_socket_out(&addr, port, 60, &fd);
2481 if (!NT_STATUS_IS_OK(status)) {
2484 set_socket_options(fd, lp_socket_options());
2486 status = rpc_transport_sock_init(result, fd, &result->transport);
2487 if (!NT_STATUS_IS_OK(status)) {
2492 result->transport->transport = NCACN_IP_TCP;
2495 return NT_STATUS_OK;
2498 TALLOC_FREE(result);
2503 * Determine the tcp port on which a dcerpc interface is listening
2504 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2507 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2508 const struct ndr_syntax_id *abstract_syntax,
2512 struct rpc_pipe_client *epm_pipe = NULL;
2513 struct pipe_auth_data *auth = NULL;
2514 struct dcerpc_binding *map_binding = NULL;
2515 struct dcerpc_binding *res_binding = NULL;
2516 struct epm_twr_t *map_tower = NULL;
2517 struct epm_twr_t *res_towers = NULL;
2518 struct policy_handle *entry_handle = NULL;
2519 uint32_t num_towers = 0;
2520 uint32_t max_towers = 1;
2521 struct epm_twr_p_t towers;
2522 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2524 if (pport == NULL) {
2525 status = NT_STATUS_INVALID_PARAMETER;
2529 /* open the connection to the endpoint mapper */
2530 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2531 &ndr_table_epmapper.syntax_id,
2534 if (!NT_STATUS_IS_OK(status)) {
2538 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2539 if (!NT_STATUS_IS_OK(status)) {
2543 status = rpc_pipe_bind(epm_pipe, auth);
2544 if (!NT_STATUS_IS_OK(status)) {
2548 /* create tower for asking the epmapper */
2550 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2551 if (map_binding == NULL) {
2552 status = NT_STATUS_NO_MEMORY;
2556 map_binding->transport = NCACN_IP_TCP;
2557 map_binding->object = *abstract_syntax;
2558 map_binding->host = host; /* needed? */
2559 map_binding->endpoint = "0"; /* correct? needed? */
2561 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2562 if (map_tower == NULL) {
2563 status = NT_STATUS_NO_MEMORY;
2567 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2568 &(map_tower->tower));
2569 if (!NT_STATUS_IS_OK(status)) {
2573 /* allocate further parameters for the epm_Map call */
2575 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2576 if (res_towers == NULL) {
2577 status = NT_STATUS_NO_MEMORY;
2580 towers.twr = res_towers;
2582 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2583 if (entry_handle == NULL) {
2584 status = NT_STATUS_NO_MEMORY;
2588 /* ask the endpoint mapper for the port */
2590 status = rpccli_epm_Map(epm_pipe,
2592 CONST_DISCARD(struct GUID *,
2593 &(abstract_syntax->uuid)),
2600 if (!NT_STATUS_IS_OK(status)) {
2604 if (num_towers != 1) {
2605 status = NT_STATUS_UNSUCCESSFUL;
2609 /* extract the port from the answer */
2611 status = dcerpc_binding_from_tower(tmp_ctx,
2612 &(towers.twr->tower),
2614 if (!NT_STATUS_IS_OK(status)) {
2618 /* are further checks here necessary? */
2619 if (res_binding->transport != NCACN_IP_TCP) {
2620 status = NT_STATUS_UNSUCCESSFUL;
2624 *pport = (uint16_t)atoi(res_binding->endpoint);
2627 TALLOC_FREE(tmp_ctx);
2632 * Create a rpc pipe client struct, connecting to a host via tcp.
2633 * The port is determined by asking the endpoint mapper on the given
2636 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2637 const struct ndr_syntax_id *abstract_syntax,
2638 struct rpc_pipe_client **presult)
2643 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2644 if (!NT_STATUS_IS_OK(status)) {
2648 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2649 abstract_syntax, presult);
2652 /********************************************************************
2653 Create a rpc pipe client struct, connecting to a unix domain socket
2654 ********************************************************************/
2655 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2656 const struct ndr_syntax_id *abstract_syntax,
2657 struct rpc_pipe_client **presult)
2659 struct rpc_pipe_client *result;
2660 struct sockaddr_un addr;
2664 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2665 if (result == NULL) {
2666 return NT_STATUS_NO_MEMORY;
2669 result->abstract_syntax = *abstract_syntax;
2670 result->transfer_syntax = ndr_transfer_syntax;
2671 result->dispatch = cli_do_rpc_ndr;
2672 result->dispatch_send = cli_do_rpc_ndr_send;
2673 result->dispatch_recv = cli_do_rpc_ndr_recv;
2675 result->desthost = get_myname(result);
2676 result->srv_name_slash = talloc_asprintf_strupper_m(
2677 result, "\\\\%s", result->desthost);
2678 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2679 status = NT_STATUS_NO_MEMORY;
2683 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2684 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2686 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2688 status = map_nt_error_from_unix(errno);
2693 addr.sun_family = AF_UNIX;
2694 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2696 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2697 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2700 return map_nt_error_from_unix(errno);
2703 status = rpc_transport_sock_init(result, fd, &result->transport);
2704 if (!NT_STATUS_IS_OK(status)) {
2709 result->transport->transport = NCALRPC;
2712 return NT_STATUS_OK;
2715 TALLOC_FREE(result);
2719 struct rpc_pipe_client_np_ref {
2720 struct cli_state *cli;
2721 struct rpc_pipe_client *pipe;
2724 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2726 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2730 /****************************************************************************
2731 Open a named pipe over SMB to a remote server.
2733 * CAVEAT CALLER OF THIS FUNCTION:
2734 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2735 * so be sure that this function is called AFTER any structure (vs pointer)
2736 * assignment of the cli. In particular, libsmbclient does structure
2737 * assignments of cli, which invalidates the data in the returned
2738 * rpc_pipe_client if this function is called before the structure assignment
2741 ****************************************************************************/
2743 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2744 const struct ndr_syntax_id *abstract_syntax,
2745 struct rpc_pipe_client **presult)
2747 struct rpc_pipe_client *result;
2749 struct rpc_pipe_client_np_ref *np_ref;
2751 /* sanity check to protect against crashes */
2754 return NT_STATUS_INVALID_HANDLE;
2757 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2758 if (result == NULL) {
2759 return NT_STATUS_NO_MEMORY;
2762 result->abstract_syntax = *abstract_syntax;
2763 result->transfer_syntax = ndr_transfer_syntax;
2764 result->dispatch = cli_do_rpc_ndr;
2765 result->dispatch_send = cli_do_rpc_ndr_send;
2766 result->dispatch_recv = cli_do_rpc_ndr_recv;
2767 result->desthost = talloc_strdup(result, cli->desthost);
2768 result->srv_name_slash = talloc_asprintf_strupper_m(
2769 result, "\\\\%s", result->desthost);
2771 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2772 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2774 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2775 TALLOC_FREE(result);
2776 return NT_STATUS_NO_MEMORY;
2779 status = rpc_transport_np_init(result, cli, abstract_syntax,
2780 &result->transport);
2781 if (!NT_STATUS_IS_OK(status)) {
2782 TALLOC_FREE(result);
2786 result->transport->transport = NCACN_NP;
2788 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2789 if (np_ref == NULL) {
2790 TALLOC_FREE(result);
2791 return NT_STATUS_NO_MEMORY;
2794 np_ref->pipe = result;
2796 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2797 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2800 return NT_STATUS_OK;
2803 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2804 struct rpc_cli_smbd_conn *conn,
2805 const struct ndr_syntax_id *syntax,
2806 struct rpc_pipe_client **presult)
2808 struct rpc_pipe_client *result;
2809 struct pipe_auth_data *auth;
2812 result = talloc(mem_ctx, struct rpc_pipe_client);
2813 if (result == NULL) {
2814 return NT_STATUS_NO_MEMORY;
2816 result->abstract_syntax = *syntax;
2817 result->transfer_syntax = ndr_transfer_syntax;
2818 result->dispatch = cli_do_rpc_ndr;
2819 result->dispatch_send = cli_do_rpc_ndr_send;
2820 result->dispatch_recv = cli_do_rpc_ndr_recv;
2821 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2822 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2824 result->desthost = talloc_strdup(result, global_myname());
2825 result->srv_name_slash = talloc_asprintf_strupper_m(
2826 result, "\\\\%s", global_myname());
2827 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2828 TALLOC_FREE(result);
2829 return NT_STATUS_NO_MEMORY;
2832 status = rpc_transport_smbd_init(result, conn, syntax,
2833 &result->transport);
2834 if (!NT_STATUS_IS_OK(status)) {
2835 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2836 nt_errstr(status)));
2837 TALLOC_FREE(result);
2841 status = rpccli_anon_bind_data(result, &auth);
2842 if (!NT_STATUS_IS_OK(status)) {
2843 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2844 nt_errstr(status)));
2845 TALLOC_FREE(result);
2849 status = rpc_pipe_bind(result, auth);
2850 if (!NT_STATUS_IS_OK(status)) {
2851 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2852 TALLOC_FREE(result);
2856 result->transport->transport = NCACN_INTERNAL;
2859 return NT_STATUS_OK;
2862 /****************************************************************************
2863 Open a pipe to a remote server.
2864 ****************************************************************************/
2866 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2867 enum dcerpc_transport_t transport,
2868 const struct ndr_syntax_id *interface,
2869 struct rpc_pipe_client **presult)
2871 switch (transport) {
2873 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2876 return rpc_pipe_open_np(cli, interface, presult);
2878 return NT_STATUS_NOT_IMPLEMENTED;
2882 /****************************************************************************
2883 Open a named pipe to an SMB server and bind anonymously.
2884 ****************************************************************************/
2886 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2887 enum dcerpc_transport_t transport,
2888 const struct ndr_syntax_id *interface,
2889 struct rpc_pipe_client **presult)
2891 struct rpc_pipe_client *result;
2892 struct pipe_auth_data *auth;
2895 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2896 if (!NT_STATUS_IS_OK(status)) {
2900 status = rpccli_anon_bind_data(result, &auth);
2901 if (!NT_STATUS_IS_OK(status)) {
2902 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2903 nt_errstr(status)));
2904 TALLOC_FREE(result);
2909 * This is a bit of an abstraction violation due to the fact that an
2910 * anonymous bind on an authenticated SMB inherits the user/domain
2911 * from the enclosing SMB creds
2914 TALLOC_FREE(auth->user_name);
2915 TALLOC_FREE(auth->domain);
2917 auth->user_name = talloc_strdup(auth, cli->user_name);
2918 auth->domain = talloc_strdup(auth, cli->domain);
2919 auth->user_session_key = data_blob_talloc(auth,
2920 cli->user_session_key.data,
2921 cli->user_session_key.length);
2923 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2924 TALLOC_FREE(result);
2925 return NT_STATUS_NO_MEMORY;
2928 status = rpc_pipe_bind(result, auth);
2929 if (!NT_STATUS_IS_OK(status)) {
2931 if (ndr_syntax_id_equal(interface,
2932 &ndr_table_dssetup.syntax_id)) {
2933 /* non AD domains just don't have this pipe, avoid
2934 * level 0 statement in that case - gd */
2937 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2938 "%s failed with error %s\n",
2939 get_pipe_name_from_syntax(talloc_tos(), interface),
2940 nt_errstr(status) ));
2941 TALLOC_FREE(result);
2945 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2946 "%s and bound anonymously.\n",
2947 get_pipe_name_from_syntax(talloc_tos(), interface),
2951 return NT_STATUS_OK;
2954 /****************************************************************************
2955 ****************************************************************************/
2957 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2958 const struct ndr_syntax_id *interface,
2959 struct rpc_pipe_client **presult)
2961 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2962 interface, presult);
2965 /****************************************************************************
2966 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2967 ****************************************************************************/
2969 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2970 const struct ndr_syntax_id *interface,
2971 enum dcerpc_transport_t transport,
2973 enum dcerpc_AuthLevel auth_level,
2975 const char *username,
2976 const char *password,
2977 struct rpc_pipe_client **presult)
2979 struct rpc_pipe_client *result;
2980 struct pipe_auth_data *auth;
2981 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2982 enum pipe_auth_type_spnego spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2985 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2986 if (!NT_STATUS_IS_OK(status)) {
2991 auth_type = DCERPC_AUTH_TYPE_SPNEGO;
2992 spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
2995 status = rpccli_ntlmssp_bind_data(result,
2996 auth_type, spnego_type, auth_level,
2997 domain, username, password,
2999 if (!NT_STATUS_IS_OK(status)) {
3000 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3001 nt_errstr(status)));
3005 status = rpc_pipe_bind(result, auth);
3006 if (!NT_STATUS_IS_OK(status)) {
3007 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3008 nt_errstr(status) ));
3012 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3013 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3014 get_pipe_name_from_syntax(talloc_tos(), interface),
3015 cli->desthost, domain, username ));
3018 return NT_STATUS_OK;
3022 TALLOC_FREE(result);
3026 /****************************************************************************
3028 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3029 ****************************************************************************/
3031 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3032 const struct ndr_syntax_id *interface,
3033 enum dcerpc_transport_t transport,
3034 enum dcerpc_AuthLevel auth_level,
3036 const char *username,
3037 const char *password,
3038 struct rpc_pipe_client **presult)
3040 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3051 /****************************************************************************
3053 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3054 ****************************************************************************/
3056 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3057 const struct ndr_syntax_id *interface,
3058 enum dcerpc_transport_t transport,
3059 enum dcerpc_AuthLevel auth_level,
3061 const char *username,
3062 const char *password,
3063 struct rpc_pipe_client **presult)
3065 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3076 /****************************************************************************
3077 Get a the schannel session key out of an already opened netlogon pipe.
3078 ****************************************************************************/
3079 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3080 struct cli_state *cli,
3084 enum netr_SchannelType sec_chan_type = 0;
3085 unsigned char machine_pwd[16];
3086 const char *machine_account;
3089 /* Get the machine account credentials from secrets.tdb. */
3090 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3093 DEBUG(0, ("get_schannel_session_key: could not fetch "
3094 "trust account password for domain '%s'\n",
3096 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3099 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3100 cli->desthost, /* server name */
3101 domain, /* domain */
3102 global_myname(), /* client name */
3103 machine_account, /* machine account name */
3108 if (!NT_STATUS_IS_OK(status)) {
3109 DEBUG(3, ("get_schannel_session_key_common: "
3110 "rpccli_netlogon_setup_creds failed with result %s "
3111 "to server %s, domain %s, machine account %s.\n",
3112 nt_errstr(status), cli->desthost, domain,
3117 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3118 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3120 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3123 return NT_STATUS_OK;;
3126 /****************************************************************************
3127 Open a netlogon pipe and get the schannel session key.
3128 Now exposed to external callers.
3129 ****************************************************************************/
3132 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3135 struct rpc_pipe_client **presult)
3137 struct rpc_pipe_client *netlogon_pipe = NULL;
3140 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3142 if (!NT_STATUS_IS_OK(status)) {
3146 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3148 if (!NT_STATUS_IS_OK(status)) {
3149 TALLOC_FREE(netlogon_pipe);
3153 *presult = netlogon_pipe;
3154 return NT_STATUS_OK;
3157 /****************************************************************************
3159 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3160 using session_key. sign and seal.
3162 The *pdc will be stolen onto this new pipe
3163 ****************************************************************************/
3165 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3166 const struct ndr_syntax_id *interface,
3167 enum dcerpc_transport_t transport,
3168 enum dcerpc_AuthLevel auth_level,
3170 struct netlogon_creds_CredentialState **pdc,
3171 struct rpc_pipe_client **presult)
3173 struct rpc_pipe_client *result;
3174 struct pipe_auth_data *auth;
3177 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3178 if (!NT_STATUS_IS_OK(status)) {
3182 status = rpccli_schannel_bind_data(result, domain, auth_level,
3184 if (!NT_STATUS_IS_OK(status)) {
3185 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3186 nt_errstr(status)));
3187 TALLOC_FREE(result);
3191 status = rpc_pipe_bind(result, auth);
3192 if (!NT_STATUS_IS_OK(status)) {
3193 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3194 "cli_rpc_pipe_bind failed with error %s\n",
3195 nt_errstr(status) ));
3196 TALLOC_FREE(result);
3201 * The credentials on a new netlogon pipe are the ones we are passed
3202 * in - reference them in
3204 result->dc = talloc_move(result, pdc);
3206 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3207 "for domain %s and bound using schannel.\n",
3208 get_pipe_name_from_syntax(talloc_tos(), interface),
3209 cli->desthost, domain ));
3212 return NT_STATUS_OK;
3215 /****************************************************************************
3216 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3217 Fetch the session key ourselves using a temporary netlogon pipe. This
3218 version uses an ntlmssp auth bound netlogon pipe to get the key.
3219 ****************************************************************************/
3221 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3223 const char *username,
3224 const char *password,
3226 struct rpc_pipe_client **presult)
3228 struct rpc_pipe_client *netlogon_pipe = NULL;
3231 status = cli_rpc_pipe_open_spnego_ntlmssp(
3232 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3233 DCERPC_AUTH_LEVEL_PRIVACY,
3234 domain, username, password, &netlogon_pipe);
3235 if (!NT_STATUS_IS_OK(status)) {
3239 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3241 if (!NT_STATUS_IS_OK(status)) {
3242 TALLOC_FREE(netlogon_pipe);
3246 *presult = netlogon_pipe;
3247 return NT_STATUS_OK;
3250 /****************************************************************************
3251 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3252 Fetch the session key ourselves using a temporary netlogon pipe. This version
3253 uses an ntlmssp bind to get the session key.
3254 ****************************************************************************/
3256 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3257 const struct ndr_syntax_id *interface,
3258 enum dcerpc_transport_t transport,
3259 enum dcerpc_AuthLevel auth_level,
3261 const char *username,
3262 const char *password,
3263 struct rpc_pipe_client **presult)
3265 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3266 struct rpc_pipe_client *netlogon_pipe = NULL;
3267 struct rpc_pipe_client *result = NULL;
3270 status = get_schannel_session_key_auth_ntlmssp(
3271 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3272 if (!NT_STATUS_IS_OK(status)) {
3273 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3274 "key from server %s for domain %s.\n",
3275 cli->desthost, domain ));
3279 status = cli_rpc_pipe_open_schannel_with_key(
3280 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3283 /* Now we've bound using the session key we can close the netlog pipe. */
3284 TALLOC_FREE(netlogon_pipe);
3286 if (NT_STATUS_IS_OK(status)) {
3292 /****************************************************************************
3293 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3294 Fetch the session key ourselves using a temporary netlogon pipe.
3295 ****************************************************************************/
3297 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3298 const struct ndr_syntax_id *interface,
3299 enum dcerpc_transport_t transport,
3300 enum dcerpc_AuthLevel auth_level,
3302 struct rpc_pipe_client **presult)
3304 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3305 struct rpc_pipe_client *netlogon_pipe = NULL;
3306 struct rpc_pipe_client *result = NULL;
3309 status = get_schannel_session_key(cli, domain, &neg_flags,
3311 if (!NT_STATUS_IS_OK(status)) {
3312 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3313 "key from server %s for domain %s.\n",
3314 cli->desthost, domain ));
3318 status = cli_rpc_pipe_open_schannel_with_key(
3319 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3322 /* Now we've bound using the session key we can close the netlog pipe. */
3323 TALLOC_FREE(netlogon_pipe);
3325 if (NT_STATUS_IS_OK(status)) {
3332 /****************************************************************************
3333 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3334 The idea is this can be called with service_princ, username and password all
3335 NULL so long as the caller has a TGT.
3336 ****************************************************************************/
3338 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3339 const struct ndr_syntax_id *interface,
3340 enum dcerpc_transport_t transport,
3341 enum dcerpc_AuthLevel auth_level,
3342 const char *service_princ,
3343 const char *username,
3344 const char *password,
3345 struct rpc_pipe_client **presult)
3348 struct rpc_pipe_client *result;
3349 struct pipe_auth_data *auth;
3352 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3353 if (!NT_STATUS_IS_OK(status)) {
3357 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3358 username, password, &auth);
3359 if (!NT_STATUS_IS_OK(status)) {
3360 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3361 nt_errstr(status)));
3362 TALLOC_FREE(result);
3366 status = rpc_pipe_bind(result, auth);
3367 if (!NT_STATUS_IS_OK(status)) {
3368 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3369 "with error %s\n", nt_errstr(status)));
3370 TALLOC_FREE(result);
3375 return NT_STATUS_OK;
3377 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3378 return NT_STATUS_NOT_IMPLEMENTED;
3382 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3383 struct rpc_pipe_client *cli,
3384 DATA_BLOB *session_key)
3386 struct pipe_auth_data *a = cli->auth;
3389 if (!session_key || !cli) {
3390 return NT_STATUS_INVALID_PARAMETER;
3394 return NT_STATUS_INVALID_PARAMETER;
3397 switch (cli->auth->auth_type) {
3398 case DCERPC_AUTH_TYPE_SCHANNEL:
3399 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3402 case DCERPC_AUTH_TYPE_SPNEGO:
3403 switch (cli->auth->spnego_type) {
3404 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3405 sk = auth_ntlmssp_get_session_key(
3406 a->a_u.auth_ntlmssp_state);
3408 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3409 sk = data_blob_const(
3410 a->a_u.kerberos_auth->session_key.data,
3411 a->a_u.kerberos_auth->session_key.length);
3414 return NT_STATUS_NO_USER_SESSION_KEY;
3417 case DCERPC_AUTH_TYPE_NTLMSSP:
3418 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3420 case DCERPC_AUTH_TYPE_KRB5:
3421 sk = data_blob_const(a->a_u.kerberos_auth->session_key.data,
3422 a->a_u.kerberos_auth->session_key.length);
3424 case DCERPC_AUTH_TYPE_NONE:
3425 sk = data_blob_const(a->user_session_key.data,
3426 a->user_session_key.length);
3429 return NT_STATUS_NO_USER_SESSION_KEY;
3432 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3433 return NT_STATUS_OK;