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,
1202 const struct ndr_syntax_id *abstract,
1203 const struct ndr_syntax_id *transfer,
1204 enum pipe_auth_type auth_type,
1205 enum dcerpc_AuthLevel auth_level,
1208 DATA_BLOB auth_info = data_blob_null;
1209 NTSTATUS ret = NT_STATUS_OK;
1211 switch (auth_type) {
1212 case PIPE_AUTH_TYPE_SCHANNEL:
1213 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
1214 if (!NT_STATUS_IS_OK(ret)) {
1219 case PIPE_AUTH_TYPE_NTLMSSP:
1220 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1221 if (!NT_STATUS_IS_OK(ret)) {
1226 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1227 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1228 if (!NT_STATUS_IS_OK(ret)) {
1233 case PIPE_AUTH_TYPE_KRB5:
1234 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
1235 if (!NT_STATUS_IS_OK(ret)) {
1240 case PIPE_AUTH_TYPE_NONE:
1244 /* "Can't" happen. */
1245 return NT_STATUS_INVALID_INFO_CLASS;
1248 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1258 /*******************************************************************
1259 Calculate how much data we're going to send in this packet, also
1260 work out any sign/seal padding length.
1261 ********************************************************************/
1263 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1267 uint32 *p_ss_padding)
1269 uint32 data_space, data_len;
1272 if ((data_left > 0) && (sys_random() % 2)) {
1273 data_left = MAX(data_left/2, 1);
1277 switch (cli->auth->auth_level) {
1278 case DCERPC_AUTH_LEVEL_NONE:
1279 case DCERPC_AUTH_LEVEL_CONNECT:
1280 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1281 data_len = MIN(data_space, data_left);
1284 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1287 case DCERPC_AUTH_LEVEL_INTEGRITY:
1288 case DCERPC_AUTH_LEVEL_PRIVACY:
1289 /* Treat the same for all authenticated rpc requests. */
1290 switch(cli->auth->auth_type) {
1291 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1292 case PIPE_AUTH_TYPE_NTLMSSP:
1293 *p_auth_len = NTLMSSP_SIG_SIZE;
1295 case PIPE_AUTH_TYPE_SCHANNEL:
1296 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1299 smb_panic("bad auth type");
1303 data_space = cli->max_xmit_frag
1304 - DCERPC_REQUEST_LENGTH
1305 - DCERPC_AUTH_TRAILER_LENGTH
1308 data_len = MIN(data_space, data_left);
1310 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1311 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1313 *p_frag_len = DCERPC_REQUEST_LENGTH
1314 + data_len + *p_ss_padding
1315 + DCERPC_AUTH_TRAILER_LENGTH
1320 smb_panic("bad auth level");
1326 /*******************************************************************
1328 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1329 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1330 and deals with signing/sealing details.
1331 ********************************************************************/
1333 struct rpc_api_pipe_req_state {
1334 struct event_context *ev;
1335 struct rpc_pipe_client *cli;
1338 DATA_BLOB *req_data;
1339 uint32_t req_data_sent;
1341 DATA_BLOB reply_pdu;
1344 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1345 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1346 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1347 bool *is_last_frag);
1349 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1350 struct event_context *ev,
1351 struct rpc_pipe_client *cli,
1353 DATA_BLOB *req_data)
1355 struct tevent_req *req, *subreq;
1356 struct rpc_api_pipe_req_state *state;
1360 req = tevent_req_create(mem_ctx, &state,
1361 struct rpc_api_pipe_req_state);
1367 state->op_num = op_num;
1368 state->req_data = req_data;
1369 state->req_data_sent = 0;
1370 state->call_id = get_rpc_call_id();
1371 state->reply_pdu = data_blob_null;
1372 state->rpc_out = data_blob_null;
1374 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1375 + RPC_MAX_SIGN_SIZE) {
1376 /* Server is screwed up ! */
1377 status = NT_STATUS_INVALID_PARAMETER;
1381 status = prepare_next_frag(state, &is_last_frag);
1382 if (!NT_STATUS_IS_OK(status)) {
1387 subreq = rpc_api_pipe_send(state, ev, state->cli,
1389 DCERPC_PKT_RESPONSE);
1390 if (subreq == NULL) {
1393 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1395 subreq = rpc_write_send(state, ev, cli->transport,
1396 state->rpc_out.data,
1397 state->rpc_out.length);
1398 if (subreq == NULL) {
1401 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1407 tevent_req_nterror(req, status);
1408 return tevent_req_post(req, ev);
1414 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1417 uint32_t data_sent_thistime;
1421 uint32_t ss_padding;
1424 union dcerpc_payload u;
1426 data_left = state->req_data->length - state->req_data_sent;
1428 data_sent_thistime = calculate_data_len_tosend(
1429 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
1431 if (state->req_data_sent == 0) {
1432 flags = DCERPC_PFC_FLAG_FIRST;
1435 if (data_sent_thistime == data_left) {
1436 flags |= DCERPC_PFC_FLAG_LAST;
1439 data_blob_free(&state->rpc_out);
1441 ZERO_STRUCT(u.request);
1443 u.request.alloc_hint = state->req_data->length;
1444 u.request.context_id = 0;
1445 u.request.opnum = state->op_num;
1447 status = dcerpc_push_ncacn_packet(state,
1454 if (!NT_STATUS_IS_OK(status)) {
1458 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1459 * compute it right for requests because the auth trailer is missing
1461 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1463 /* Copy in the data. */
1464 if (!data_blob_append(NULL, &state->rpc_out,
1465 state->req_data->data + state->req_data_sent,
1466 data_sent_thistime)) {
1467 return NT_STATUS_NO_MEMORY;
1470 status = dcerpc_add_auth_footer(state->cli->auth, ss_padding,
1472 if (!NT_STATUS_IS_OK(status)) {
1476 state->req_data_sent += data_sent_thistime;
1477 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1482 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1484 struct tevent_req *req = tevent_req_callback_data(
1485 subreq, struct tevent_req);
1486 struct rpc_api_pipe_req_state *state = tevent_req_data(
1487 req, struct rpc_api_pipe_req_state);
1491 status = rpc_write_recv(subreq);
1492 TALLOC_FREE(subreq);
1493 if (!NT_STATUS_IS_OK(status)) {
1494 tevent_req_nterror(req, status);
1498 status = prepare_next_frag(state, &is_last_frag);
1499 if (!NT_STATUS_IS_OK(status)) {
1500 tevent_req_nterror(req, status);
1505 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1507 DCERPC_PKT_RESPONSE);
1508 if (tevent_req_nomem(subreq, req)) {
1511 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1513 subreq = rpc_write_send(state, state->ev,
1514 state->cli->transport,
1515 state->rpc_out.data,
1516 state->rpc_out.length);
1517 if (tevent_req_nomem(subreq, req)) {
1520 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1525 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1527 struct tevent_req *req = tevent_req_callback_data(
1528 subreq, struct tevent_req);
1529 struct rpc_api_pipe_req_state *state = tevent_req_data(
1530 req, struct rpc_api_pipe_req_state);
1533 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1534 TALLOC_FREE(subreq);
1535 if (!NT_STATUS_IS_OK(status)) {
1536 tevent_req_nterror(req, status);
1539 tevent_req_done(req);
1542 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1543 DATA_BLOB *reply_pdu)
1545 struct rpc_api_pipe_req_state *state = tevent_req_data(
1546 req, struct rpc_api_pipe_req_state);
1549 if (tevent_req_is_nterror(req, &status)) {
1551 * We always have to initialize to reply pdu, even if there is
1552 * none. The rpccli_* caller routines expect this.
1554 *reply_pdu = data_blob_null;
1558 /* return data to caller and assign it ownership of memory */
1559 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1560 reply_pdu->length = state->reply_pdu.length;
1561 state->reply_pdu.length = 0;
1563 return NT_STATUS_OK;
1567 /****************************************************************************
1568 Set the handle state.
1569 ****************************************************************************/
1571 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1572 const char *pipe_name, uint16 device_state)
1574 bool state_set = False;
1576 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1577 char *rparam = NULL;
1579 uint32 rparam_len, rdata_len;
1581 if (pipe_name == NULL)
1584 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1585 cli->fnum, pipe_name, device_state));
1587 /* create parameters: device state */
1588 SSVAL(param, 0, device_state);
1590 /* create setup parameters. */
1592 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1594 /* send the data on \PIPE\ */
1595 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1596 setup, 2, 0, /* setup, length, max */
1597 param, 2, 0, /* param, length, max */
1598 NULL, 0, 1024, /* data, length, max */
1599 &rparam, &rparam_len, /* return param, length */
1600 &rdata, &rdata_len)) /* return data, length */
1602 DEBUG(5, ("Set Handle state: return OK\n"));
1613 /****************************************************************************
1614 Check the rpc bind acknowledge response.
1615 ****************************************************************************/
1617 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1618 const struct ndr_syntax_id *transfer)
1620 struct dcerpc_ack_ctx ctx;
1622 if (r->secondary_address_size == 0) {
1623 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1626 if (r->num_results < 1 || !r->ctx_list) {
1630 ctx = r->ctx_list[0];
1632 /* check the transfer syntax */
1633 if ((ctx.syntax.if_version != transfer->if_version) ||
1634 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1635 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1639 if (r->num_results != 0x1 || ctx.result != 0) {
1640 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1641 r->num_results, ctx.reason));
1644 DEBUG(5,("check_bind_response: accepted!\n"));
1648 /*******************************************************************
1649 Creates a DCE/RPC bind authentication response.
1650 This is the packet that is sent back to the server once we
1651 have received a BIND-ACK, to finish the third leg of
1652 the authentication handshake.
1653 ********************************************************************/
1655 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1656 struct rpc_pipe_client *cli,
1658 enum pipe_auth_type auth_type,
1659 enum dcerpc_AuthLevel auth_level,
1660 DATA_BLOB *pauth_blob,
1664 union dcerpc_payload u;
1668 status = dcerpc_push_dcerpc_auth(mem_ctx,
1669 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1671 0, /* auth_pad_length */
1672 1, /* auth_context_id */
1674 &u.auth3.auth_info);
1675 if (!NT_STATUS_IS_OK(status)) {
1679 status = dcerpc_push_ncacn_packet(mem_ctx,
1681 DCERPC_PFC_FLAG_FIRST |
1682 DCERPC_PFC_FLAG_LAST,
1687 data_blob_free(&u.auth3.auth_info);
1688 if (!NT_STATUS_IS_OK(status)) {
1689 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1693 return NT_STATUS_OK;
1696 /*******************************************************************
1697 Creates a DCE/RPC bind alter context authentication request which
1698 may contain a spnego auth blobl
1699 ********************************************************************/
1701 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1703 const struct ndr_syntax_id *abstract,
1704 const struct ndr_syntax_id *transfer,
1705 enum dcerpc_AuthLevel auth_level,
1706 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1709 DATA_BLOB auth_info;
1712 status = dcerpc_push_dcerpc_auth(mem_ctx,
1713 DCERPC_AUTH_TYPE_SPNEGO,
1715 0, /* auth_pad_length */
1716 1, /* auth_context_id */
1719 if (!NT_STATUS_IS_OK(status)) {
1723 status = create_bind_or_alt_ctx_internal(mem_ctx,
1730 data_blob_free(&auth_info);
1734 /****************************************************************************
1736 ****************************************************************************/
1738 struct rpc_pipe_bind_state {
1739 struct event_context *ev;
1740 struct rpc_pipe_client *cli;
1742 uint32_t rpc_call_id;
1745 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1746 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1747 struct rpc_pipe_bind_state *state,
1748 struct ncacn_packet *r);
1749 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1750 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1751 struct rpc_pipe_bind_state *state,
1752 struct ncacn_packet *r,
1753 DATA_BLOB *reply_pdu);
1754 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1756 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1757 struct event_context *ev,
1758 struct rpc_pipe_client *cli,
1759 struct pipe_auth_data *auth)
1761 struct tevent_req *req, *subreq;
1762 struct rpc_pipe_bind_state *state;
1765 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1770 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1771 rpccli_pipe_txt(talloc_tos(), cli),
1772 (unsigned int)auth->auth_type,
1773 (unsigned int)auth->auth_level ));
1777 state->rpc_call_id = get_rpc_call_id();
1778 state->rpc_out = data_blob_null;
1780 cli->auth = talloc_move(cli, &auth);
1782 /* Marshall the outgoing data. */
1783 status = create_rpc_bind_req(state, cli,
1785 &cli->abstract_syntax,
1786 &cli->transfer_syntax,
1787 cli->auth->auth_type,
1788 cli->auth->auth_level,
1791 if (!NT_STATUS_IS_OK(status)) {
1795 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1796 DCERPC_PKT_BIND_ACK);
1797 if (subreq == NULL) {
1800 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1804 tevent_req_nterror(req, status);
1805 return tevent_req_post(req, ev);
1811 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1813 struct tevent_req *req = tevent_req_callback_data(
1814 subreq, struct tevent_req);
1815 struct rpc_pipe_bind_state *state = tevent_req_data(
1816 req, struct rpc_pipe_bind_state);
1817 DATA_BLOB reply_pdu;
1818 struct ncacn_packet *pkt;
1821 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1822 TALLOC_FREE(subreq);
1823 if (!NT_STATUS_IS_OK(status)) {
1824 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1825 rpccli_pipe_txt(talloc_tos(), state->cli),
1826 nt_errstr(status)));
1827 tevent_req_nterror(req, status);
1831 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1832 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1833 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1837 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1838 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1841 * For authenticated binds we may need to do 3 or 4 leg binds.
1844 switch(state->cli->auth->auth_type) {
1846 case PIPE_AUTH_TYPE_NONE:
1847 case PIPE_AUTH_TYPE_SCHANNEL:
1848 /* Bind complete. */
1849 tevent_req_done(req);
1852 case PIPE_AUTH_TYPE_NTLMSSP:
1853 /* Need to send AUTH3 packet - no reply. */
1854 status = rpc_finish_auth3_bind_send(req, state, pkt);
1855 if (!NT_STATUS_IS_OK(status)) {
1856 tevent_req_nterror(req, status);
1860 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1861 /* Need to send alter context request and reply. */
1862 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, pkt,
1864 if (!NT_STATUS_IS_OK(status)) {
1865 tevent_req_nterror(req, status);
1869 case PIPE_AUTH_TYPE_KRB5:
1873 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1874 (unsigned int)state->cli->auth->auth_type));
1875 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1879 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1880 struct rpc_pipe_bind_state *state,
1881 struct ncacn_packet *r)
1883 DATA_BLOB client_reply = data_blob_null;
1884 struct dcerpc_auth auth;
1885 struct tevent_req *subreq;
1888 if ((r->auth_length == 0)
1889 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1890 + r->auth_length)) {
1891 return NT_STATUS_INVALID_PARAMETER;
1894 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1895 &r->u.bind_ack.auth_info,
1897 if (!NT_STATUS_IS_OK(status)) {
1898 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1899 nt_errstr(status)));
1903 /* TODO - check auth_type/auth_level match. */
1905 status = auth_ntlmssp_update(state->cli->auth->a_u.auth_ntlmssp_state,
1906 auth.credentials, &client_reply);
1908 if (!NT_STATUS_IS_OK(status)) {
1909 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
1910 "blob failed: %s.\n", nt_errstr(status)));
1914 data_blob_free(&state->rpc_out);
1916 status = create_rpc_bind_auth3(state,
1917 state->cli, state->rpc_call_id,
1918 state->cli->auth->auth_type,
1919 state->cli->auth->auth_level,
1920 &client_reply, &state->rpc_out);
1921 data_blob_free(&client_reply);
1923 if (!NT_STATUS_IS_OK(status)) {
1927 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1928 state->rpc_out.data, state->rpc_out.length);
1929 if (subreq == NULL) {
1930 return NT_STATUS_NO_MEMORY;
1932 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
1933 return NT_STATUS_OK;
1936 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
1938 struct tevent_req *req = tevent_req_callback_data(
1939 subreq, struct tevent_req);
1942 status = rpc_write_recv(subreq);
1943 TALLOC_FREE(subreq);
1944 if (!NT_STATUS_IS_OK(status)) {
1945 tevent_req_nterror(req, status);
1948 tevent_req_done(req);
1951 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1952 struct rpc_pipe_bind_state *state,
1953 struct ncacn_packet *r,
1954 DATA_BLOB *reply_pdu)
1956 DATA_BLOB server_ntlm_response = data_blob_null;
1957 DATA_BLOB client_reply = data_blob_null;
1958 DATA_BLOB tmp_blob = data_blob_null;
1959 struct dcerpc_auth auth_info;
1960 DATA_BLOB auth_blob;
1961 struct tevent_req *subreq;
1964 if ((r->auth_length == 0)
1965 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1966 + r->auth_length)) {
1967 return NT_STATUS_INVALID_PARAMETER;
1970 /* Process the returned NTLMSSP blob first. */
1971 auth_blob = data_blob_const(reply_pdu->data
1973 - DCERPC_AUTH_TRAILER_LENGTH
1975 DCERPC_AUTH_TRAILER_LENGTH
1978 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info, false);
1979 if (!NT_STATUS_IS_OK(status)) {
1980 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
1985 * The server might give us back two challenges - tmp_blob is for the
1988 if (!spnego_parse_challenge(state, auth_info.credentials,
1989 &server_ntlm_response, &tmp_blob)) {
1990 data_blob_free(&server_ntlm_response);
1991 data_blob_free(&tmp_blob);
1992 return NT_STATUS_INVALID_PARAMETER;
1995 /* We're finished with the server spnego response and the tmp_blob. */
1996 data_blob_free(&tmp_blob);
1998 status = auth_ntlmssp_update(state->cli->auth->a_u.auth_ntlmssp_state,
1999 server_ntlm_response, &client_reply);
2001 /* Finished with the server_ntlm response */
2002 data_blob_free(&server_ntlm_response);
2004 if (!NT_STATUS_IS_OK(status)) {
2005 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2006 "using server blob failed.\n"));
2007 data_blob_free(&client_reply);
2011 /* SPNEGO wrap the client reply. */
2012 tmp_blob = spnego_gen_auth(state, client_reply);
2013 data_blob_free(&client_reply);
2014 client_reply = tmp_blob;
2015 tmp_blob = data_blob_null;
2017 /* Now prepare the alter context pdu. */
2018 data_blob_free(&state->rpc_out);
2020 status = create_rpc_alter_context(state,
2022 &state->cli->abstract_syntax,
2023 &state->cli->transfer_syntax,
2024 state->cli->auth->auth_level,
2027 data_blob_free(&client_reply);
2029 if (!NT_STATUS_IS_OK(status)) {
2033 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2034 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2035 if (subreq == NULL) {
2036 return NT_STATUS_NO_MEMORY;
2038 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2039 return NT_STATUS_OK;
2042 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2044 struct tevent_req *req = tevent_req_callback_data(
2045 subreq, struct tevent_req);
2046 struct rpc_pipe_bind_state *state = tevent_req_data(
2047 req, struct rpc_pipe_bind_state);
2048 DATA_BLOB tmp_blob = data_blob_null;
2049 struct ncacn_packet *pkt;
2050 struct dcerpc_auth auth;
2053 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2054 TALLOC_FREE(subreq);
2055 if (!NT_STATUS_IS_OK(status)) {
2056 tevent_req_nterror(req, status);
2060 status = dcerpc_pull_dcerpc_auth(pkt,
2061 &pkt->u.alter_resp.auth_info,
2063 if (!NT_STATUS_IS_OK(status)) {
2064 tevent_req_nterror(req, status);
2068 /* Check we got a valid auth response. */
2069 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2071 OID_NTLMSSP, &tmp_blob)) {
2072 data_blob_free(&tmp_blob);
2073 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2077 data_blob_free(&tmp_blob);
2079 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2080 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2081 tevent_req_done(req);
2084 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2086 return tevent_req_simple_recv_ntstatus(req);
2089 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2090 struct pipe_auth_data *auth)
2092 TALLOC_CTX *frame = talloc_stackframe();
2093 struct event_context *ev;
2094 struct tevent_req *req;
2095 NTSTATUS status = NT_STATUS_OK;
2097 ev = event_context_init(frame);
2099 status = NT_STATUS_NO_MEMORY;
2103 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2105 status = NT_STATUS_NO_MEMORY;
2109 if (!tevent_req_poll(req, ev)) {
2110 status = map_nt_error_from_unix(errno);
2114 status = rpc_pipe_bind_recv(req);
2120 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2122 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2123 unsigned int timeout)
2127 if (rpc_cli->transport == NULL) {
2128 return RPCCLI_DEFAULT_TIMEOUT;
2131 if (rpc_cli->transport->set_timeout == NULL) {
2132 return RPCCLI_DEFAULT_TIMEOUT;
2135 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2137 return RPCCLI_DEFAULT_TIMEOUT;
2143 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2145 if (rpc_cli == NULL) {
2149 if (rpc_cli->transport == NULL) {
2153 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2156 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2158 struct cli_state *cli;
2160 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2161 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2162 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2166 cli = rpc_pipe_np_smb_conn(rpc_cli);
2170 E_md4hash(cli->password ? cli->password : "", nt_hash);
2174 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2175 struct pipe_auth_data **presult)
2177 struct pipe_auth_data *result;
2179 result = talloc(mem_ctx, struct pipe_auth_data);
2180 if (result == NULL) {
2181 return NT_STATUS_NO_MEMORY;
2184 result->auth_type = PIPE_AUTH_TYPE_NONE;
2185 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2187 result->user_name = talloc_strdup(result, "");
2188 result->domain = talloc_strdup(result, "");
2189 if ((result->user_name == NULL) || (result->domain == NULL)) {
2190 TALLOC_FREE(result);
2191 return NT_STATUS_NO_MEMORY;
2195 return NT_STATUS_OK;
2198 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2200 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2204 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2205 enum pipe_auth_type auth_type,
2206 enum dcerpc_AuthLevel auth_level,
2208 const char *username,
2209 const char *password,
2210 struct pipe_auth_data **presult)
2212 struct pipe_auth_data *result;
2215 result = talloc(mem_ctx, struct pipe_auth_data);
2216 if (result == NULL) {
2217 return NT_STATUS_NO_MEMORY;
2220 result->auth_type = auth_type;
2221 result->auth_level = auth_level;
2223 result->user_name = talloc_strdup(result, username);
2224 result->domain = talloc_strdup(result, domain);
2225 if ((result->user_name == NULL) || (result->domain == NULL)) {
2226 status = NT_STATUS_NO_MEMORY;
2230 status = auth_ntlmssp_client_start(NULL,
2233 lp_client_ntlmv2_auth(),
2234 &result->a_u.auth_ntlmssp_state);
2235 if (!NT_STATUS_IS_OK(status)) {
2239 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2241 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2243 if (!NT_STATUS_IS_OK(status)) {
2247 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2249 if (!NT_STATUS_IS_OK(status)) {
2253 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2255 if (!NT_STATUS_IS_OK(status)) {
2260 * Turn off sign+seal to allow selected auth level to turn it back on.
2262 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2263 ~(NTLMSSP_NEGOTIATE_SIGN |
2264 NTLMSSP_NEGOTIATE_SEAL));
2266 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2267 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2268 NTLMSSP_NEGOTIATE_SIGN);
2269 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2270 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2271 NTLMSSP_NEGOTIATE_SEAL |
2272 NTLMSSP_NEGOTIATE_SIGN);
2276 return NT_STATUS_OK;
2279 TALLOC_FREE(result);
2283 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2284 enum dcerpc_AuthLevel auth_level,
2285 struct netlogon_creds_CredentialState *creds,
2286 struct pipe_auth_data **presult)
2288 struct pipe_auth_data *result;
2290 result = talloc(mem_ctx, struct pipe_auth_data);
2291 if (result == NULL) {
2292 return NT_STATUS_NO_MEMORY;
2295 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2296 result->auth_level = auth_level;
2298 result->user_name = talloc_strdup(result, "");
2299 result->domain = talloc_strdup(result, domain);
2300 if ((result->user_name == NULL) || (result->domain == NULL)) {
2304 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2305 if (result->a_u.schannel_auth == NULL) {
2309 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2310 result->a_u.schannel_auth->seq_num = 0;
2311 result->a_u.schannel_auth->initiator = true;
2312 result->a_u.schannel_auth->creds = creds;
2315 return NT_STATUS_OK;
2318 TALLOC_FREE(result);
2319 return NT_STATUS_NO_MEMORY;
2323 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2325 data_blob_free(&auth->session_key);
2330 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2331 enum dcerpc_AuthLevel auth_level,
2332 const char *service_princ,
2333 const char *username,
2334 const char *password,
2335 struct pipe_auth_data **presult)
2338 struct pipe_auth_data *result;
2340 if ((username != NULL) && (password != NULL)) {
2341 int ret = kerberos_kinit_password(username, password, 0, NULL);
2343 return NT_STATUS_ACCESS_DENIED;
2347 result = talloc(mem_ctx, struct pipe_auth_data);
2348 if (result == NULL) {
2349 return NT_STATUS_NO_MEMORY;
2352 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2353 result->auth_level = auth_level;
2356 * Username / domain need fixing!
2358 result->user_name = talloc_strdup(result, "");
2359 result->domain = talloc_strdup(result, "");
2360 if ((result->user_name == NULL) || (result->domain == NULL)) {
2364 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2365 result, struct kerberos_auth_struct);
2366 if (result->a_u.kerberos_auth == NULL) {
2369 talloc_set_destructor(result->a_u.kerberos_auth,
2370 cli_auth_kerberos_data_destructor);
2372 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2373 result, service_princ);
2374 if (result->a_u.kerberos_auth->service_principal == NULL) {
2379 return NT_STATUS_OK;
2382 TALLOC_FREE(result);
2383 return NT_STATUS_NO_MEMORY;
2385 return NT_STATUS_NOT_SUPPORTED;
2390 * Create an rpc pipe client struct, connecting to a tcp port.
2392 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2394 const struct ndr_syntax_id *abstract_syntax,
2395 struct rpc_pipe_client **presult)
2397 struct rpc_pipe_client *result;
2398 struct sockaddr_storage addr;
2402 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2403 if (result == NULL) {
2404 return NT_STATUS_NO_MEMORY;
2407 result->abstract_syntax = *abstract_syntax;
2408 result->transfer_syntax = ndr_transfer_syntax;
2409 result->dispatch = cli_do_rpc_ndr;
2410 result->dispatch_send = cli_do_rpc_ndr_send;
2411 result->dispatch_recv = cli_do_rpc_ndr_recv;
2413 result->desthost = talloc_strdup(result, host);
2414 result->srv_name_slash = talloc_asprintf_strupper_m(
2415 result, "\\\\%s", result->desthost);
2416 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2417 status = NT_STATUS_NO_MEMORY;
2421 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2422 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2424 if (!resolve_name(host, &addr, 0, false)) {
2425 status = NT_STATUS_NOT_FOUND;
2429 status = open_socket_out(&addr, port, 60, &fd);
2430 if (!NT_STATUS_IS_OK(status)) {
2433 set_socket_options(fd, lp_socket_options());
2435 status = rpc_transport_sock_init(result, fd, &result->transport);
2436 if (!NT_STATUS_IS_OK(status)) {
2441 result->transport->transport = NCACN_IP_TCP;
2444 return NT_STATUS_OK;
2447 TALLOC_FREE(result);
2452 * Determine the tcp port on which a dcerpc interface is listening
2453 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2456 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2457 const struct ndr_syntax_id *abstract_syntax,
2461 struct rpc_pipe_client *epm_pipe = NULL;
2462 struct pipe_auth_data *auth = NULL;
2463 struct dcerpc_binding *map_binding = NULL;
2464 struct dcerpc_binding *res_binding = NULL;
2465 struct epm_twr_t *map_tower = NULL;
2466 struct epm_twr_t *res_towers = NULL;
2467 struct policy_handle *entry_handle = NULL;
2468 uint32_t num_towers = 0;
2469 uint32_t max_towers = 1;
2470 struct epm_twr_p_t towers;
2471 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2473 if (pport == NULL) {
2474 status = NT_STATUS_INVALID_PARAMETER;
2478 /* open the connection to the endpoint mapper */
2479 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2480 &ndr_table_epmapper.syntax_id,
2483 if (!NT_STATUS_IS_OK(status)) {
2487 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2488 if (!NT_STATUS_IS_OK(status)) {
2492 status = rpc_pipe_bind(epm_pipe, auth);
2493 if (!NT_STATUS_IS_OK(status)) {
2497 /* create tower for asking the epmapper */
2499 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2500 if (map_binding == NULL) {
2501 status = NT_STATUS_NO_MEMORY;
2505 map_binding->transport = NCACN_IP_TCP;
2506 map_binding->object = *abstract_syntax;
2507 map_binding->host = host; /* needed? */
2508 map_binding->endpoint = "0"; /* correct? needed? */
2510 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2511 if (map_tower == NULL) {
2512 status = NT_STATUS_NO_MEMORY;
2516 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2517 &(map_tower->tower));
2518 if (!NT_STATUS_IS_OK(status)) {
2522 /* allocate further parameters for the epm_Map call */
2524 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2525 if (res_towers == NULL) {
2526 status = NT_STATUS_NO_MEMORY;
2529 towers.twr = res_towers;
2531 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2532 if (entry_handle == NULL) {
2533 status = NT_STATUS_NO_MEMORY;
2537 /* ask the endpoint mapper for the port */
2539 status = rpccli_epm_Map(epm_pipe,
2541 CONST_DISCARD(struct GUID *,
2542 &(abstract_syntax->uuid)),
2549 if (!NT_STATUS_IS_OK(status)) {
2553 if (num_towers != 1) {
2554 status = NT_STATUS_UNSUCCESSFUL;
2558 /* extract the port from the answer */
2560 status = dcerpc_binding_from_tower(tmp_ctx,
2561 &(towers.twr->tower),
2563 if (!NT_STATUS_IS_OK(status)) {
2567 /* are further checks here necessary? */
2568 if (res_binding->transport != NCACN_IP_TCP) {
2569 status = NT_STATUS_UNSUCCESSFUL;
2573 *pport = (uint16_t)atoi(res_binding->endpoint);
2576 TALLOC_FREE(tmp_ctx);
2581 * Create a rpc pipe client struct, connecting to a host via tcp.
2582 * The port is determined by asking the endpoint mapper on the given
2585 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2586 const struct ndr_syntax_id *abstract_syntax,
2587 struct rpc_pipe_client **presult)
2592 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2593 if (!NT_STATUS_IS_OK(status)) {
2597 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2598 abstract_syntax, presult);
2601 /********************************************************************
2602 Create a rpc pipe client struct, connecting to a unix domain socket
2603 ********************************************************************/
2604 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2605 const struct ndr_syntax_id *abstract_syntax,
2606 struct rpc_pipe_client **presult)
2608 struct rpc_pipe_client *result;
2609 struct sockaddr_un addr;
2613 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2614 if (result == NULL) {
2615 return NT_STATUS_NO_MEMORY;
2618 result->abstract_syntax = *abstract_syntax;
2619 result->transfer_syntax = ndr_transfer_syntax;
2620 result->dispatch = cli_do_rpc_ndr;
2621 result->dispatch_send = cli_do_rpc_ndr_send;
2622 result->dispatch_recv = cli_do_rpc_ndr_recv;
2624 result->desthost = get_myname(result);
2625 result->srv_name_slash = talloc_asprintf_strupper_m(
2626 result, "\\\\%s", result->desthost);
2627 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2628 status = NT_STATUS_NO_MEMORY;
2632 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2633 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2635 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2637 status = map_nt_error_from_unix(errno);
2642 addr.sun_family = AF_UNIX;
2643 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2645 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2646 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2649 return map_nt_error_from_unix(errno);
2652 status = rpc_transport_sock_init(result, fd, &result->transport);
2653 if (!NT_STATUS_IS_OK(status)) {
2658 result->transport->transport = NCALRPC;
2661 return NT_STATUS_OK;
2664 TALLOC_FREE(result);
2668 struct rpc_pipe_client_np_ref {
2669 struct cli_state *cli;
2670 struct rpc_pipe_client *pipe;
2673 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2675 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2679 /****************************************************************************
2680 Open a named pipe over SMB to a remote server.
2682 * CAVEAT CALLER OF THIS FUNCTION:
2683 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2684 * so be sure that this function is called AFTER any structure (vs pointer)
2685 * assignment of the cli. In particular, libsmbclient does structure
2686 * assignments of cli, which invalidates the data in the returned
2687 * rpc_pipe_client if this function is called before the structure assignment
2690 ****************************************************************************/
2692 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2693 const struct ndr_syntax_id *abstract_syntax,
2694 struct rpc_pipe_client **presult)
2696 struct rpc_pipe_client *result;
2698 struct rpc_pipe_client_np_ref *np_ref;
2700 /* sanity check to protect against crashes */
2703 return NT_STATUS_INVALID_HANDLE;
2706 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2707 if (result == NULL) {
2708 return NT_STATUS_NO_MEMORY;
2711 result->abstract_syntax = *abstract_syntax;
2712 result->transfer_syntax = ndr_transfer_syntax;
2713 result->dispatch = cli_do_rpc_ndr;
2714 result->dispatch_send = cli_do_rpc_ndr_send;
2715 result->dispatch_recv = cli_do_rpc_ndr_recv;
2716 result->desthost = talloc_strdup(result, cli->desthost);
2717 result->srv_name_slash = talloc_asprintf_strupper_m(
2718 result, "\\\\%s", result->desthost);
2720 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2721 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2723 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2724 TALLOC_FREE(result);
2725 return NT_STATUS_NO_MEMORY;
2728 status = rpc_transport_np_init(result, cli, abstract_syntax,
2729 &result->transport);
2730 if (!NT_STATUS_IS_OK(status)) {
2731 TALLOC_FREE(result);
2735 result->transport->transport = NCACN_NP;
2737 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2738 if (np_ref == NULL) {
2739 TALLOC_FREE(result);
2740 return NT_STATUS_NO_MEMORY;
2743 np_ref->pipe = result;
2745 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2746 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2749 return NT_STATUS_OK;
2752 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2753 struct rpc_cli_smbd_conn *conn,
2754 const struct ndr_syntax_id *syntax,
2755 struct rpc_pipe_client **presult)
2757 struct rpc_pipe_client *result;
2758 struct pipe_auth_data *auth;
2761 result = talloc(mem_ctx, struct rpc_pipe_client);
2762 if (result == NULL) {
2763 return NT_STATUS_NO_MEMORY;
2765 result->abstract_syntax = *syntax;
2766 result->transfer_syntax = ndr_transfer_syntax;
2767 result->dispatch = cli_do_rpc_ndr;
2768 result->dispatch_send = cli_do_rpc_ndr_send;
2769 result->dispatch_recv = cli_do_rpc_ndr_recv;
2770 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2771 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2773 result->desthost = talloc_strdup(result, global_myname());
2774 result->srv_name_slash = talloc_asprintf_strupper_m(
2775 result, "\\\\%s", global_myname());
2776 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2777 TALLOC_FREE(result);
2778 return NT_STATUS_NO_MEMORY;
2781 status = rpc_transport_smbd_init(result, conn, syntax,
2782 &result->transport);
2783 if (!NT_STATUS_IS_OK(status)) {
2784 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2785 nt_errstr(status)));
2786 TALLOC_FREE(result);
2790 status = rpccli_anon_bind_data(result, &auth);
2791 if (!NT_STATUS_IS_OK(status)) {
2792 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2793 nt_errstr(status)));
2794 TALLOC_FREE(result);
2798 status = rpc_pipe_bind(result, auth);
2799 if (!NT_STATUS_IS_OK(status)) {
2800 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2801 TALLOC_FREE(result);
2805 result->transport->transport = NCACN_INTERNAL;
2808 return NT_STATUS_OK;
2811 /****************************************************************************
2812 Open a pipe to a remote server.
2813 ****************************************************************************/
2815 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2816 enum dcerpc_transport_t transport,
2817 const struct ndr_syntax_id *interface,
2818 struct rpc_pipe_client **presult)
2820 switch (transport) {
2822 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2825 return rpc_pipe_open_np(cli, interface, presult);
2827 return NT_STATUS_NOT_IMPLEMENTED;
2831 /****************************************************************************
2832 Open a named pipe to an SMB server and bind anonymously.
2833 ****************************************************************************/
2835 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2836 enum dcerpc_transport_t transport,
2837 const struct ndr_syntax_id *interface,
2838 struct rpc_pipe_client **presult)
2840 struct rpc_pipe_client *result;
2841 struct pipe_auth_data *auth;
2844 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2845 if (!NT_STATUS_IS_OK(status)) {
2849 status = rpccli_anon_bind_data(result, &auth);
2850 if (!NT_STATUS_IS_OK(status)) {
2851 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2852 nt_errstr(status)));
2853 TALLOC_FREE(result);
2858 * This is a bit of an abstraction violation due to the fact that an
2859 * anonymous bind on an authenticated SMB inherits the user/domain
2860 * from the enclosing SMB creds
2863 TALLOC_FREE(auth->user_name);
2864 TALLOC_FREE(auth->domain);
2866 auth->user_name = talloc_strdup(auth, cli->user_name);
2867 auth->domain = talloc_strdup(auth, cli->domain);
2868 auth->user_session_key = data_blob_talloc(auth,
2869 cli->user_session_key.data,
2870 cli->user_session_key.length);
2872 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2873 TALLOC_FREE(result);
2874 return NT_STATUS_NO_MEMORY;
2877 status = rpc_pipe_bind(result, auth);
2878 if (!NT_STATUS_IS_OK(status)) {
2880 if (ndr_syntax_id_equal(interface,
2881 &ndr_table_dssetup.syntax_id)) {
2882 /* non AD domains just don't have this pipe, avoid
2883 * level 0 statement in that case - gd */
2886 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2887 "%s failed with error %s\n",
2888 get_pipe_name_from_syntax(talloc_tos(), interface),
2889 nt_errstr(status) ));
2890 TALLOC_FREE(result);
2894 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2895 "%s and bound anonymously.\n",
2896 get_pipe_name_from_syntax(talloc_tos(), interface),
2900 return NT_STATUS_OK;
2903 /****************************************************************************
2904 ****************************************************************************/
2906 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2907 const struct ndr_syntax_id *interface,
2908 struct rpc_pipe_client **presult)
2910 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2911 interface, presult);
2914 /****************************************************************************
2915 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2916 ****************************************************************************/
2918 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2919 const struct ndr_syntax_id *interface,
2920 enum dcerpc_transport_t transport,
2921 enum pipe_auth_type auth_type,
2922 enum dcerpc_AuthLevel auth_level,
2924 const char *username,
2925 const char *password,
2926 struct rpc_pipe_client **presult)
2928 struct rpc_pipe_client *result;
2929 struct pipe_auth_data *auth;
2932 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2933 if (!NT_STATUS_IS_OK(status)) {
2937 status = rpccli_ntlmssp_bind_data(
2938 result, auth_type, auth_level, domain, username,
2940 if (!NT_STATUS_IS_OK(status)) {
2941 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2942 nt_errstr(status)));
2946 status = rpc_pipe_bind(result, auth);
2947 if (!NT_STATUS_IS_OK(status)) {
2948 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2949 nt_errstr(status) ));
2953 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2954 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2955 get_pipe_name_from_syntax(talloc_tos(), interface),
2956 cli->desthost, domain, username ));
2959 return NT_STATUS_OK;
2963 TALLOC_FREE(result);
2967 /****************************************************************************
2969 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2970 ****************************************************************************/
2972 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2973 const struct ndr_syntax_id *interface,
2974 enum dcerpc_transport_t transport,
2975 enum dcerpc_AuthLevel auth_level,
2977 const char *username,
2978 const char *password,
2979 struct rpc_pipe_client **presult)
2981 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2984 PIPE_AUTH_TYPE_NTLMSSP,
2992 /****************************************************************************
2994 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2995 ****************************************************************************/
2997 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2998 const struct ndr_syntax_id *interface,
2999 enum dcerpc_transport_t transport,
3000 enum dcerpc_AuthLevel auth_level,
3002 const char *username,
3003 const char *password,
3004 struct rpc_pipe_client **presult)
3006 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3009 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3017 /****************************************************************************
3018 Get a the schannel session key out of an already opened netlogon pipe.
3019 ****************************************************************************/
3020 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3021 struct cli_state *cli,
3025 enum netr_SchannelType sec_chan_type = 0;
3026 unsigned char machine_pwd[16];
3027 const char *machine_account;
3030 /* Get the machine account credentials from secrets.tdb. */
3031 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3034 DEBUG(0, ("get_schannel_session_key: could not fetch "
3035 "trust account password for domain '%s'\n",
3037 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3040 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3041 cli->desthost, /* server name */
3042 domain, /* domain */
3043 global_myname(), /* client name */
3044 machine_account, /* machine account name */
3049 if (!NT_STATUS_IS_OK(status)) {
3050 DEBUG(3, ("get_schannel_session_key_common: "
3051 "rpccli_netlogon_setup_creds failed with result %s "
3052 "to server %s, domain %s, machine account %s.\n",
3053 nt_errstr(status), cli->desthost, domain,
3058 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3059 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3061 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3064 return NT_STATUS_OK;;
3067 /****************************************************************************
3068 Open a netlogon pipe and get the schannel session key.
3069 Now exposed to external callers.
3070 ****************************************************************************/
3073 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3076 struct rpc_pipe_client **presult)
3078 struct rpc_pipe_client *netlogon_pipe = NULL;
3081 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3083 if (!NT_STATUS_IS_OK(status)) {
3087 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3089 if (!NT_STATUS_IS_OK(status)) {
3090 TALLOC_FREE(netlogon_pipe);
3094 *presult = netlogon_pipe;
3095 return NT_STATUS_OK;
3098 /****************************************************************************
3100 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3101 using session_key. sign and seal.
3103 The *pdc will be stolen onto this new pipe
3104 ****************************************************************************/
3106 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3107 const struct ndr_syntax_id *interface,
3108 enum dcerpc_transport_t transport,
3109 enum dcerpc_AuthLevel auth_level,
3111 struct netlogon_creds_CredentialState **pdc,
3112 struct rpc_pipe_client **presult)
3114 struct rpc_pipe_client *result;
3115 struct pipe_auth_data *auth;
3118 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3119 if (!NT_STATUS_IS_OK(status)) {
3123 status = rpccli_schannel_bind_data(result, domain, auth_level,
3125 if (!NT_STATUS_IS_OK(status)) {
3126 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3127 nt_errstr(status)));
3128 TALLOC_FREE(result);
3132 status = rpc_pipe_bind(result, auth);
3133 if (!NT_STATUS_IS_OK(status)) {
3134 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3135 "cli_rpc_pipe_bind failed with error %s\n",
3136 nt_errstr(status) ));
3137 TALLOC_FREE(result);
3142 * The credentials on a new netlogon pipe are the ones we are passed
3143 * in - reference them in
3145 result->dc = talloc_move(result, pdc);
3147 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3148 "for domain %s and bound using schannel.\n",
3149 get_pipe_name_from_syntax(talloc_tos(), interface),
3150 cli->desthost, domain ));
3153 return NT_STATUS_OK;
3156 /****************************************************************************
3157 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3158 Fetch the session key ourselves using a temporary netlogon pipe. This
3159 version uses an ntlmssp auth bound netlogon pipe to get the key.
3160 ****************************************************************************/
3162 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3164 const char *username,
3165 const char *password,
3167 struct rpc_pipe_client **presult)
3169 struct rpc_pipe_client *netlogon_pipe = NULL;
3172 status = cli_rpc_pipe_open_spnego_ntlmssp(
3173 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3174 DCERPC_AUTH_LEVEL_PRIVACY,
3175 domain, username, password, &netlogon_pipe);
3176 if (!NT_STATUS_IS_OK(status)) {
3180 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3182 if (!NT_STATUS_IS_OK(status)) {
3183 TALLOC_FREE(netlogon_pipe);
3187 *presult = netlogon_pipe;
3188 return NT_STATUS_OK;
3191 /****************************************************************************
3192 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3193 Fetch the session key ourselves using a temporary netlogon pipe. This version
3194 uses an ntlmssp bind to get the session key.
3195 ****************************************************************************/
3197 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3198 const struct ndr_syntax_id *interface,
3199 enum dcerpc_transport_t transport,
3200 enum dcerpc_AuthLevel auth_level,
3202 const char *username,
3203 const char *password,
3204 struct rpc_pipe_client **presult)
3206 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3207 struct rpc_pipe_client *netlogon_pipe = NULL;
3208 struct rpc_pipe_client *result = NULL;
3211 status = get_schannel_session_key_auth_ntlmssp(
3212 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3215 "key from server %s for domain %s.\n",
3216 cli->desthost, domain ));
3220 status = cli_rpc_pipe_open_schannel_with_key(
3221 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3224 /* Now we've bound using the session key we can close the netlog pipe. */
3225 TALLOC_FREE(netlogon_pipe);
3227 if (NT_STATUS_IS_OK(status)) {
3233 /****************************************************************************
3234 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3235 Fetch the session key ourselves using a temporary netlogon pipe.
3236 ****************************************************************************/
3238 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3239 const struct ndr_syntax_id *interface,
3240 enum dcerpc_transport_t transport,
3241 enum dcerpc_AuthLevel auth_level,
3243 struct rpc_pipe_client **presult)
3245 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3246 struct rpc_pipe_client *netlogon_pipe = NULL;
3247 struct rpc_pipe_client *result = NULL;
3250 status = get_schannel_session_key(cli, domain, &neg_flags,
3252 if (!NT_STATUS_IS_OK(status)) {
3253 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3254 "key from server %s for domain %s.\n",
3255 cli->desthost, domain ));
3259 status = cli_rpc_pipe_open_schannel_with_key(
3260 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3263 /* Now we've bound using the session key we can close the netlog pipe. */
3264 TALLOC_FREE(netlogon_pipe);
3266 if (NT_STATUS_IS_OK(status)) {
3273 /****************************************************************************
3274 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3275 The idea is this can be called with service_princ, username and password all
3276 NULL so long as the caller has a TGT.
3277 ****************************************************************************/
3279 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3280 const struct ndr_syntax_id *interface,
3281 enum dcerpc_AuthLevel auth_level,
3282 const char *service_princ,
3283 const char *username,
3284 const char *password,
3285 struct rpc_pipe_client **presult)
3288 struct rpc_pipe_client *result;
3289 struct pipe_auth_data *auth;
3292 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
3293 if (!NT_STATUS_IS_OK(status)) {
3297 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3298 username, password, &auth);
3299 if (!NT_STATUS_IS_OK(status)) {
3300 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3301 nt_errstr(status)));
3302 TALLOC_FREE(result);
3306 status = rpc_pipe_bind(result, auth);
3307 if (!NT_STATUS_IS_OK(status)) {
3308 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3309 "with error %s\n", nt_errstr(status)));
3310 TALLOC_FREE(result);
3315 return NT_STATUS_OK;
3317 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3318 return NT_STATUS_NOT_IMPLEMENTED;
3322 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3323 struct rpc_pipe_client *cli,
3324 DATA_BLOB *session_key)
3326 struct pipe_auth_data *a = cli->auth;
3329 if (!session_key || !cli) {
3330 return NT_STATUS_INVALID_PARAMETER;
3334 return NT_STATUS_INVALID_PARAMETER;
3337 switch (cli->auth->auth_type) {
3338 case PIPE_AUTH_TYPE_SCHANNEL:
3339 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3342 case PIPE_AUTH_TYPE_NTLMSSP:
3343 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3344 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3346 case PIPE_AUTH_TYPE_KRB5:
3347 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3348 sk = data_blob_const(a->a_u.kerberos_auth->session_key.data,
3349 a->a_u.kerberos_auth->session_key.length);
3351 case PIPE_AUTH_TYPE_NONE:
3352 sk = data_blob_const(a->user_session_key.data,
3353 a->user_session_key.length);
3356 return NT_STATUS_NO_USER_SESSION_KEY;
3359 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3360 return NT_STATUS_OK;