2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../librpc/gen_ndr/ndr_dssetup.h"
24 #include "../librpc/gen_ndr/ndr_netlogon.h"
25 #include "../libcli/auth/schannel.h"
26 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "ntlmssp_wrap.h"
30 #include "rpc_client/cli_netlogon.h"
31 #include "librpc/gen_ndr/ndr_dcerpc.h"
32 #include "librpc/rpc/dcerpc.h"
33 #include "librpc/rpc/dcerpc_gssapi.h"
36 #define DBGC_CLASS DBGC_RPC_CLI
38 /********************************************************************
39 Pipe description for a DEBUG
40 ********************************************************************/
41 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
42 struct rpc_pipe_client *cli)
44 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
51 /********************************************************************
53 ********************************************************************/
55 static uint32 get_rpc_call_id(void)
57 static uint32 call_id = 0;
61 /*******************************************************************
62 Use SMBreadX to get rest of one fragment's worth of rpc data.
63 Reads the whole size or give an error message
64 ********************************************************************/
66 struct rpc_read_state {
67 struct event_context *ev;
68 struct rpc_cli_transport *transport;
74 static void rpc_read_done(struct tevent_req *subreq);
76 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
77 struct event_context *ev,
78 struct rpc_cli_transport *transport,
79 uint8_t *data, size_t size)
81 struct tevent_req *req, *subreq;
82 struct rpc_read_state *state;
84 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
89 state->transport = transport;
94 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
96 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
101 tevent_req_set_callback(subreq, rpc_read_done, req);
109 static void rpc_read_done(struct tevent_req *subreq)
111 struct tevent_req *req = tevent_req_callback_data(
112 subreq, struct tevent_req);
113 struct rpc_read_state *state = tevent_req_data(
114 req, struct rpc_read_state);
118 status = state->transport->read_recv(subreq, &received);
120 if (!NT_STATUS_IS_OK(status)) {
121 tevent_req_nterror(req, status);
125 state->num_read += received;
126 if (state->num_read == state->size) {
127 tevent_req_done(req);
131 subreq = state->transport->read_send(state, state->ev,
132 state->data + state->num_read,
133 state->size - state->num_read,
134 state->transport->priv);
135 if (tevent_req_nomem(subreq, req)) {
138 tevent_req_set_callback(subreq, rpc_read_done, req);
141 static NTSTATUS rpc_read_recv(struct tevent_req *req)
143 return tevent_req_simple_recv_ntstatus(req);
146 struct rpc_write_state {
147 struct event_context *ev;
148 struct rpc_cli_transport *transport;
154 static void rpc_write_done(struct tevent_req *subreq);
156 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
157 struct event_context *ev,
158 struct rpc_cli_transport *transport,
159 const uint8_t *data, size_t size)
161 struct tevent_req *req, *subreq;
162 struct rpc_write_state *state;
164 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
169 state->transport = transport;
172 state->num_written = 0;
174 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
176 subreq = transport->write_send(state, ev, data, size, transport->priv);
177 if (subreq == NULL) {
180 tevent_req_set_callback(subreq, rpc_write_done, req);
187 static void rpc_write_done(struct tevent_req *subreq)
189 struct tevent_req *req = tevent_req_callback_data(
190 subreq, struct tevent_req);
191 struct rpc_write_state *state = tevent_req_data(
192 req, struct rpc_write_state);
196 status = state->transport->write_recv(subreq, &written);
198 if (!NT_STATUS_IS_OK(status)) {
199 tevent_req_nterror(req, status);
203 state->num_written += written;
205 if (state->num_written == state->size) {
206 tevent_req_done(req);
210 subreq = state->transport->write_send(state, state->ev,
211 state->data + state->num_written,
212 state->size - state->num_written,
213 state->transport->priv);
214 if (tevent_req_nomem(subreq, req)) {
217 tevent_req_set_callback(subreq, rpc_write_done, req);
220 static NTSTATUS rpc_write_recv(struct tevent_req *req)
222 return tevent_req_simple_recv_ntstatus(req);
226 /****************************************************************************
227 Try and get a PDU's worth of data from current_pdu. If not, then read more
229 ****************************************************************************/
231 struct get_complete_frag_state {
232 struct event_context *ev;
233 struct rpc_pipe_client *cli;
238 static void get_complete_frag_got_header(struct tevent_req *subreq);
239 static void get_complete_frag_got_rest(struct tevent_req *subreq);
241 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
242 struct event_context *ev,
243 struct rpc_pipe_client *cli,
246 struct tevent_req *req, *subreq;
247 struct get_complete_frag_state *state;
251 req = tevent_req_create(mem_ctx, &state,
252 struct get_complete_frag_state);
258 state->frag_len = RPC_HEADER_LEN;
261 received = pdu->length;
262 if (received < RPC_HEADER_LEN) {
263 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
264 status = NT_STATUS_NO_MEMORY;
267 subreq = rpc_read_send(state, state->ev,
268 state->cli->transport,
269 pdu->data + received,
270 RPC_HEADER_LEN - received);
271 if (subreq == NULL) {
272 status = NT_STATUS_NO_MEMORY;
275 tevent_req_set_callback(subreq, get_complete_frag_got_header,
280 state->frag_len = dcerpc_get_frag_length(pdu);
283 * Ensure we have frag_len bytes of data.
285 if (received < state->frag_len) {
286 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
287 status = NT_STATUS_NO_MEMORY;
290 subreq = rpc_read_send(state, state->ev,
291 state->cli->transport,
292 pdu->data + received,
293 state->frag_len - received);
294 if (subreq == NULL) {
295 status = NT_STATUS_NO_MEMORY;
298 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
303 status = NT_STATUS_OK;
305 if (NT_STATUS_IS_OK(status)) {
306 tevent_req_done(req);
308 tevent_req_nterror(req, status);
310 return tevent_req_post(req, ev);
313 static void get_complete_frag_got_header(struct tevent_req *subreq)
315 struct tevent_req *req = tevent_req_callback_data(
316 subreq, struct tevent_req);
317 struct get_complete_frag_state *state = tevent_req_data(
318 req, struct get_complete_frag_state);
321 status = rpc_read_recv(subreq);
323 if (!NT_STATUS_IS_OK(status)) {
324 tevent_req_nterror(req, status);
328 state->frag_len = dcerpc_get_frag_length(state->pdu);
330 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
331 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
336 * We're here in this piece of code because we've read exactly
337 * RPC_HEADER_LEN bytes into state->pdu.
340 subreq = rpc_read_send(state, state->ev, state->cli->transport,
341 state->pdu->data + RPC_HEADER_LEN,
342 state->frag_len - RPC_HEADER_LEN);
343 if (tevent_req_nomem(subreq, req)) {
346 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
349 static void get_complete_frag_got_rest(struct tevent_req *subreq)
351 struct tevent_req *req = tevent_req_callback_data(
352 subreq, struct tevent_req);
355 status = rpc_read_recv(subreq);
357 if (!NT_STATUS_IS_OK(status)) {
358 tevent_req_nterror(req, status);
361 tevent_req_done(req);
364 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
366 return tevent_req_simple_recv_ntstatus(req);
369 /****************************************************************************
370 Do basic authentication checks on an incoming pdu.
371 ****************************************************************************/
373 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
374 struct rpc_pipe_client *cli,
375 struct ncacn_packet *pkt,
377 uint8_t expected_pkt_type,
379 DATA_BLOB *reply_pdu)
381 NTSTATUS ret = NT_STATUS_OK;
384 ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
385 if (!NT_STATUS_IS_OK(ret)) {
389 if (pdu->length != pkt->frag_length) {
390 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
391 (unsigned int)pdu->length,
392 (unsigned int)pkt->frag_length));
393 return NT_STATUS_INVALID_PARAMETER;
397 * Point the return values at the real data including the RPC
398 * header. Just in case the caller wants it.
402 /* Ensure we have the correct type. */
403 switch (pkt->ptype) {
404 case DCERPC_PKT_ALTER_RESP:
405 case DCERPC_PKT_BIND_ACK:
407 /* Alter context and bind ack share the same packet definitions. */
411 case DCERPC_PKT_RESPONSE:
413 /* Here's where we deal with incoming sign/seal. */
414 ret = dcerpc_check_auth(cli->auth, pkt,
415 &pkt->u.response.stub_and_verifier,
416 DCERPC_RESPONSE_LENGTH,
418 if (!NT_STATUS_IS_OK(ret)) {
422 if (pdu->length < DCERPC_RESPONSE_LENGTH + pad_len) {
423 return NT_STATUS_BUFFER_TOO_SMALL;
426 /* Point the return values at the NDR data. */
427 rdata->data = pdu->data + DCERPC_RESPONSE_LENGTH;
429 if (pkt->auth_length) {
430 /* We've already done integer wrap tests in
431 * dcerpc_check_auth(). */
432 rdata->length = pdu->length
433 - DCERPC_RESPONSE_LENGTH
435 - DCERPC_AUTH_TRAILER_LENGTH
438 rdata->length = pdu->length - DCERPC_RESPONSE_LENGTH;
441 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
442 (long unsigned int)pdu->length,
443 (long unsigned int)rdata->length,
444 (unsigned int)pad_len));
447 * If this is the first reply, and the allocation hint is
448 * reasonable, try and set up the reply_pdu DATA_BLOB to the
452 if ((reply_pdu->length == 0) &&
453 pkt->u.response.alloc_hint &&
454 (pkt->u.response.alloc_hint < 15*1024*1024)) {
455 if (!data_blob_realloc(mem_ctx, reply_pdu,
456 pkt->u.response.alloc_hint)) {
457 DEBUG(0, ("reply alloc hint %d too "
458 "large to allocate\n",
459 (int)pkt->u.response.alloc_hint));
460 return NT_STATUS_NO_MEMORY;
466 case DCERPC_PKT_BIND_NAK:
467 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
468 "received from %s!\n",
469 rpccli_pipe_txt(talloc_tos(), cli)));
470 /* Use this for now... */
471 return NT_STATUS_NETWORK_ACCESS_DENIED;
473 case DCERPC_PKT_FAULT:
475 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
476 "code %s received from %s!\n",
477 dcerpc_errstr(talloc_tos(),
478 pkt->u.fault.status),
479 rpccli_pipe_txt(talloc_tos(), cli)));
481 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
482 return NT_STATUS_UNSUCCESSFUL;
484 return NT_STATUS(pkt->u.fault.status);
488 DEBUG(0, ("Unknown packet type %u received from %s!\n",
489 (unsigned int)pkt->ptype,
490 rpccli_pipe_txt(talloc_tos(), cli)));
491 return NT_STATUS_INVALID_INFO_CLASS;
494 if (pkt->ptype != expected_pkt_type) {
495 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
496 "got an unexpected RPC packet type - %u, not %u\n",
497 rpccli_pipe_txt(talloc_tos(), cli),
500 return NT_STATUS_INVALID_INFO_CLASS;
503 /* Do this just before return - we don't want to modify any rpc header
504 data before now as we may have needed to do cryptographic actions on
507 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
508 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
509 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
510 "setting fragment first/last ON.\n"));
511 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
512 DCERPC_PFC_FLAG_LAST;
518 /****************************************************************************
519 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
520 ****************************************************************************/
522 struct cli_api_pipe_state {
523 struct event_context *ev;
524 struct rpc_cli_transport *transport;
529 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
530 static void cli_api_pipe_write_done(struct tevent_req *subreq);
531 static void cli_api_pipe_read_done(struct tevent_req *subreq);
533 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
534 struct event_context *ev,
535 struct rpc_cli_transport *transport,
536 uint8_t *data, size_t data_len,
537 uint32_t max_rdata_len)
539 struct tevent_req *req, *subreq;
540 struct cli_api_pipe_state *state;
543 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
548 state->transport = transport;
550 if (max_rdata_len < RPC_HEADER_LEN) {
552 * For a RPC reply we always need at least RPC_HEADER_LEN
553 * bytes. We check this here because we will receive
554 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
556 status = NT_STATUS_INVALID_PARAMETER;
560 if (transport->trans_send != NULL) {
561 subreq = transport->trans_send(state, ev, data, data_len,
562 max_rdata_len, transport->priv);
563 if (subreq == NULL) {
566 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
571 * If the transport does not provide a "trans" routine, i.e. for
572 * example the ncacn_ip_tcp transport, do the write/read step here.
575 subreq = rpc_write_send(state, ev, transport, data, data_len);
576 if (subreq == NULL) {
579 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
583 tevent_req_nterror(req, status);
584 return tevent_req_post(req, ev);
590 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
592 struct tevent_req *req = tevent_req_callback_data(
593 subreq, struct tevent_req);
594 struct cli_api_pipe_state *state = tevent_req_data(
595 req, struct cli_api_pipe_state);
598 status = state->transport->trans_recv(subreq, state, &state->rdata,
601 if (!NT_STATUS_IS_OK(status)) {
602 tevent_req_nterror(req, status);
605 tevent_req_done(req);
608 static void cli_api_pipe_write_done(struct tevent_req *subreq)
610 struct tevent_req *req = tevent_req_callback_data(
611 subreq, struct tevent_req);
612 struct cli_api_pipe_state *state = tevent_req_data(
613 req, struct cli_api_pipe_state);
616 status = rpc_write_recv(subreq);
618 if (!NT_STATUS_IS_OK(status)) {
619 tevent_req_nterror(req, status);
623 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
624 if (tevent_req_nomem(state->rdata, req)) {
629 * We don't need to use rpc_read_send here, the upper layer will cope
630 * with a short read, transport->trans_send could also return less
631 * than state->max_rdata_len.
633 subreq = state->transport->read_send(state, state->ev, state->rdata,
635 state->transport->priv);
636 if (tevent_req_nomem(subreq, req)) {
639 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
642 static void cli_api_pipe_read_done(struct tevent_req *subreq)
644 struct tevent_req *req = tevent_req_callback_data(
645 subreq, struct tevent_req);
646 struct cli_api_pipe_state *state = tevent_req_data(
647 req, struct cli_api_pipe_state);
651 status = state->transport->read_recv(subreq, &received);
653 if (!NT_STATUS_IS_OK(status)) {
654 tevent_req_nterror(req, status);
657 state->rdata_len = received;
658 tevent_req_done(req);
661 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
662 uint8_t **prdata, uint32_t *prdata_len)
664 struct cli_api_pipe_state *state = tevent_req_data(
665 req, struct cli_api_pipe_state);
668 if (tevent_req_is_nterror(req, &status)) {
672 *prdata = talloc_move(mem_ctx, &state->rdata);
673 *prdata_len = state->rdata_len;
677 /****************************************************************************
678 Send data on an rpc pipe via trans. The data must be the last
679 pdu fragment of an NDR data stream.
681 Receive response data from an rpc pipe, which may be large...
683 Read the first fragment: unfortunately have to use SMBtrans for the first
684 bit, then SMBreadX for subsequent bits.
686 If first fragment received also wasn't the last fragment, continue
687 getting fragments until we _do_ receive the last fragment.
689 Request/Response PDU's look like the following...
691 |<------------------PDU len----------------------------------------------->|
692 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
694 +------------+-----------------+-------------+---------------+-------------+
695 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
696 +------------+-----------------+-------------+---------------+-------------+
698 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
699 signing & sealing being negotiated.
701 ****************************************************************************/
703 struct rpc_api_pipe_state {
704 struct event_context *ev;
705 struct rpc_pipe_client *cli;
706 uint8_t expected_pkt_type;
708 DATA_BLOB incoming_frag;
709 struct ncacn_packet *pkt;
713 size_t reply_pdu_offset;
717 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
718 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
720 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
721 struct event_context *ev,
722 struct rpc_pipe_client *cli,
723 DATA_BLOB *data, /* Outgoing PDU */
724 uint8_t expected_pkt_type)
726 struct tevent_req *req, *subreq;
727 struct rpc_api_pipe_state *state;
728 uint16_t max_recv_frag;
731 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
737 state->expected_pkt_type = expected_pkt_type;
738 state->incoming_frag = data_blob_null;
739 state->reply_pdu = data_blob_null;
740 state->reply_pdu_offset = 0;
741 state->endianess = DCERPC_DREP_LE;
744 * Ensure we're not sending too much.
746 if (data->length > cli->max_xmit_frag) {
747 status = NT_STATUS_INVALID_PARAMETER;
751 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
753 /* get the header first, then fetch the rest once we have
754 * the frag_length available */
755 max_recv_frag = RPC_HEADER_LEN;
757 subreq = cli_api_pipe_send(state, ev, cli->transport,
758 data->data, data->length, max_recv_frag);
759 if (subreq == NULL) {
762 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
766 tevent_req_nterror(req, status);
767 return tevent_req_post(req, ev);
773 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
775 struct tevent_req *req = tevent_req_callback_data(
776 subreq, struct tevent_req);
777 struct rpc_api_pipe_state *state = tevent_req_data(
778 req, struct rpc_api_pipe_state);
780 uint8_t *rdata = NULL;
781 uint32_t rdata_len = 0;
783 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
785 if (!NT_STATUS_IS_OK(status)) {
786 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
787 tevent_req_nterror(req, status);
792 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
793 rpccli_pipe_txt(talloc_tos(), state->cli)));
794 tevent_req_done(req);
799 * Move data on state->incoming_frag.
801 state->incoming_frag.data = talloc_move(state, &rdata);
802 state->incoming_frag.length = rdata_len;
803 if (!state->incoming_frag.data) {
804 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
808 /* Ensure we have enough data for a pdu. */
809 subreq = get_complete_frag_send(state, state->ev, state->cli,
810 &state->incoming_frag);
811 if (tevent_req_nomem(subreq, req)) {
814 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
817 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
819 struct tevent_req *req = tevent_req_callback_data(
820 subreq, struct tevent_req);
821 struct rpc_api_pipe_state *state = tevent_req_data(
822 req, struct rpc_api_pipe_state);
824 DATA_BLOB rdata = data_blob_null;
826 status = get_complete_frag_recv(subreq);
828 if (!NT_STATUS_IS_OK(status)) {
829 DEBUG(5, ("get_complete_frag failed: %s\n",
831 tevent_req_nterror(req, status);
835 state->pkt = talloc(state, struct ncacn_packet);
837 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
841 status = cli_pipe_validate_current_pdu(state,
842 state->cli, state->pkt,
843 &state->incoming_frag,
844 state->expected_pkt_type,
848 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
849 (unsigned)state->incoming_frag.length,
850 (unsigned)state->reply_pdu_offset,
853 if (!NT_STATUS_IS_OK(status)) {
854 tevent_req_nterror(req, status);
858 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
859 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
861 * Set the data type correctly for big-endian data on the
864 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
866 rpccli_pipe_txt(talloc_tos(), state->cli)));
867 state->endianess = 0x00; /* BIG ENDIAN */
870 * Check endianness on subsequent packets.
872 if (state->endianess != state->pkt->drep[0]) {
873 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
875 state->endianess?"little":"big",
876 state->pkt->drep[0]?"little":"big"));
877 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
881 /* Now copy the data portion out of the pdu into rbuf. */
882 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
883 if (!data_blob_realloc(NULL, &state->reply_pdu,
884 state->reply_pdu_offset + rdata.length)) {
885 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
890 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
891 rdata.data, rdata.length);
892 state->reply_pdu_offset += rdata.length;
894 /* reset state->incoming_frag, there is no need to free it,
895 * it will be reallocated to the right size the next time
897 state->incoming_frag.length = 0;
899 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
900 /* make sure the pdu length is right now that we
901 * have all the data available (alloc hint may
902 * have allocated more than was actually used) */
903 state->reply_pdu.length = state->reply_pdu_offset;
904 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
905 rpccli_pipe_txt(talloc_tos(), state->cli),
906 (unsigned)state->reply_pdu.length));
907 tevent_req_done(req);
911 subreq = get_complete_frag_send(state, state->ev, state->cli,
912 &state->incoming_frag);
913 if (tevent_req_nomem(subreq, req)) {
916 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
919 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
920 struct ncacn_packet **pkt,
921 DATA_BLOB *reply_pdu)
923 struct rpc_api_pipe_state *state = tevent_req_data(
924 req, struct rpc_api_pipe_state);
927 if (tevent_req_is_nterror(req, &status)) {
931 /* return data to caller and assign it ownership of memory */
933 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
934 reply_pdu->length = state->reply_pdu.length;
935 state->reply_pdu.length = 0;
937 data_blob_free(&state->reply_pdu);
941 *pkt = talloc_steal(mem_ctx, state->pkt);
947 /*******************************************************************
948 Creates krb5 auth bind.
949 ********************************************************************/
951 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
952 struct pipe_auth_data *auth,
953 DATA_BLOB *auth_info)
955 DATA_BLOB in_token = data_blob_null;
956 DATA_BLOB auth_token = data_blob_null;
959 /* Negotiate the initial auth token */
960 status = gse_get_client_auth_token(mem_ctx,
961 auth->a_u.gssapi_state,
964 if (!NT_STATUS_IS_OK(status)) {
968 status = dcerpc_push_dcerpc_auth(mem_ctx,
971 0, /* auth_pad_length */
972 1, /* auth_context_id */
975 if (!NT_STATUS_IS_OK(status)) {
976 data_blob_free(&auth_token);
980 DEBUG(5, ("Created GSS Authentication Token:\n"));
981 dump_data(5, auth_token.data, auth_token.length);
983 data_blob_free(&auth_token);
987 /*******************************************************************
988 Creates SPNEGO NTLMSSP auth bind.
989 ********************************************************************/
991 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
992 enum dcerpc_AuthLevel auth_level,
993 DATA_BLOB *auth_info)
996 DATA_BLOB null_blob = data_blob_null;
997 DATA_BLOB request = data_blob_null;
998 DATA_BLOB spnego_msg = data_blob_null;
999 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1001 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1002 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1006 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1007 data_blob_free(&request);
1011 /* Wrap this in SPNEGO. */
1012 spnego_msg = spnego_gen_negTokenInit(talloc_tos(), OIDs_ntlm, &request, NULL);
1014 data_blob_free(&request);
1016 status = dcerpc_push_dcerpc_auth(cli,
1017 DCERPC_AUTH_TYPE_SPNEGO,
1019 0, /* auth_pad_length */
1020 1, /* auth_context_id */
1024 if (!NT_STATUS_IS_OK(status)) {
1025 data_blob_free(&spnego_msg);
1029 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1030 dump_data(5, spnego_msg.data, spnego_msg.length);
1031 data_blob_free(&spnego_msg);
1033 return NT_STATUS_OK;
1036 /*******************************************************************
1037 Creates NTLMSSP auth bind.
1038 ********************************************************************/
1040 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1041 enum dcerpc_AuthLevel auth_level,
1042 DATA_BLOB *auth_info)
1045 DATA_BLOB null_blob = data_blob_null;
1046 DATA_BLOB request = data_blob_null;
1048 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1049 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1053 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1054 data_blob_free(&request);
1058 status = dcerpc_push_dcerpc_auth(cli,
1059 DCERPC_AUTH_TYPE_NTLMSSP,
1061 0, /* auth_pad_length */
1062 1, /* auth_context_id */
1065 if (!NT_STATUS_IS_OK(status)) {
1066 data_blob_free(&request);
1070 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1071 dump_data(5, request.data, request.length);
1073 return NT_STATUS_OK;
1076 /*******************************************************************
1077 Creates schannel auth bind.
1078 ********************************************************************/
1080 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1081 enum dcerpc_AuthLevel auth_level,
1082 DATA_BLOB *auth_info)
1085 struct NL_AUTH_MESSAGE r;
1086 DATA_BLOB schannel_blob;
1088 /* Use lp_workgroup() if domain not specified */
1090 if (!cli->auth->domain || !cli->auth->domain[0]) {
1091 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1092 if (cli->auth->domain == NULL) {
1093 return NT_STATUS_NO_MEMORY;
1098 * Now marshall the data into the auth parse_struct.
1101 r.MessageType = NL_NEGOTIATE_REQUEST;
1102 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1103 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1104 r.oem_netbios_domain.a = cli->auth->domain;
1105 r.oem_netbios_computer.a = global_myname();
1107 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1108 if (!NT_STATUS_IS_OK(status)) {
1112 status = dcerpc_push_dcerpc_auth(cli,
1113 DCERPC_AUTH_TYPE_SCHANNEL,
1115 0, /* auth_pad_length */
1116 1, /* auth_context_id */
1119 if (!NT_STATUS_IS_OK(status)) {
1123 return NT_STATUS_OK;
1126 /*******************************************************************
1127 Creates the internals of a DCE/RPC bind request or alter context PDU.
1128 ********************************************************************/
1130 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1131 enum dcerpc_pkt_type ptype,
1133 const struct ndr_syntax_id *abstract,
1134 const struct ndr_syntax_id *transfer,
1135 const DATA_BLOB *auth_info,
1138 uint16 auth_len = auth_info->length;
1140 union dcerpc_payload u;
1141 struct dcerpc_ctx_list ctx_list;
1144 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1147 ctx_list.context_id = 0;
1148 ctx_list.num_transfer_syntaxes = 1;
1149 ctx_list.abstract_syntax = *abstract;
1150 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1152 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1153 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1154 u.bind.assoc_group_id = 0x0;
1155 u.bind.num_contexts = 1;
1156 u.bind.ctx_list = &ctx_list;
1157 u.bind.auth_info = *auth_info;
1159 status = dcerpc_push_ncacn_packet(mem_ctx,
1161 DCERPC_PFC_FLAG_FIRST |
1162 DCERPC_PFC_FLAG_LAST,
1167 if (!NT_STATUS_IS_OK(status)) {
1168 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1172 return NT_STATUS_OK;
1175 /*******************************************************************
1176 Creates a DCE/RPC bind request.
1177 ********************************************************************/
1179 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1180 struct rpc_pipe_client *cli,
1181 struct pipe_auth_data *auth,
1183 const struct ndr_syntax_id *abstract,
1184 const struct ndr_syntax_id *transfer,
1187 DATA_BLOB auth_info = data_blob_null;
1188 NTSTATUS ret = NT_STATUS_OK;
1190 switch (auth->auth_type) {
1191 case DCERPC_AUTH_TYPE_SCHANNEL:
1192 ret = create_schannel_auth_rpc_bind_req(cli,
1195 if (!NT_STATUS_IS_OK(ret)) {
1200 case DCERPC_AUTH_TYPE_NTLMSSP:
1201 ret = create_ntlmssp_auth_rpc_bind_req(cli,
1204 if (!NT_STATUS_IS_OK(ret)) {
1209 case DCERPC_AUTH_TYPE_SPNEGO:
1210 if (auth->spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1211 /* "Can't" happen. */
1212 return NT_STATUS_INVALID_INFO_CLASS;
1214 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli,
1217 if (!NT_STATUS_IS_OK(ret)) {
1222 case DCERPC_AUTH_TYPE_KRB5:
1223 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_info);
1224 if (!NT_STATUS_IS_OK(ret)) {
1229 case DCERPC_AUTH_TYPE_NONE:
1233 /* "Can't" happen. */
1234 return NT_STATUS_INVALID_INFO_CLASS;
1237 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1247 /*******************************************************************
1248 Calculate how much data we're going to send in this packet, also
1249 work out any sign/seal padding length.
1250 ********************************************************************/
1252 static NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli,
1254 uint32_t *data_to_send,
1255 uint16_t *p_frag_len,
1256 uint16_t *p_auth_len,
1257 uint32_t *p_ss_padding)
1259 uint32_t data_space, data_len;
1262 switch (cli->auth->auth_level) {
1263 case DCERPC_AUTH_LEVEL_NONE:
1264 case DCERPC_AUTH_LEVEL_CONNECT:
1265 case DCERPC_AUTH_LEVEL_PACKET:
1266 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1267 data_len = MIN(data_space, data_left);
1270 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1271 *data_to_send = data_len;
1272 return NT_STATUS_OK;
1274 case DCERPC_AUTH_LEVEL_INTEGRITY:
1275 case DCERPC_AUTH_LEVEL_PRIVACY:
1276 max_len = cli->max_xmit_frag
1277 - DCERPC_REQUEST_LENGTH
1278 - DCERPC_AUTH_TRAILER_LENGTH;
1280 /* Treat the same for all authenticated rpc requests. */
1281 switch(cli->auth->auth_type) {
1282 case DCERPC_AUTH_TYPE_SPNEGO:
1283 switch (cli->auth->spnego_type) {
1284 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1285 *p_auth_len = NTLMSSP_SIG_SIZE;
1287 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1288 *p_auth_len = 0; /* TODO */
1291 return NT_STATUS_INVALID_PARAMETER;
1293 case DCERPC_AUTH_TYPE_NTLMSSP:
1294 *p_auth_len = NTLMSSP_SIG_SIZE;
1296 case DCERPC_AUTH_TYPE_SCHANNEL:
1297 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1299 case DCERPC_AUTH_TYPE_KRB5:
1300 *p_auth_len = gse_get_signature_length(
1301 cli->auth->a_u.gssapi_state,
1302 (cli->auth->auth_level ==
1303 DCERPC_AUTH_LEVEL_PRIVACY),
1307 return NT_STATUS_INVALID_PARAMETER;
1310 data_space = max_len - *p_auth_len;
1312 data_len = MIN(data_space, data_left);
1314 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1315 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1317 *p_frag_len = DCERPC_REQUEST_LENGTH
1318 + data_len + *p_ss_padding
1319 + DCERPC_AUTH_TRAILER_LENGTH
1321 *data_to_send = data_len;
1322 return NT_STATUS_OK;
1328 return NT_STATUS_INVALID_PARAMETER;
1331 /*******************************************************************
1333 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1334 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1335 and deals with signing/sealing details.
1336 ********************************************************************/
1338 struct rpc_api_pipe_req_state {
1339 struct event_context *ev;
1340 struct rpc_pipe_client *cli;
1343 DATA_BLOB *req_data;
1344 uint32_t req_data_sent;
1346 DATA_BLOB reply_pdu;
1349 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1350 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1351 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1352 bool *is_last_frag);
1354 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1355 struct event_context *ev,
1356 struct rpc_pipe_client *cli,
1358 DATA_BLOB *req_data)
1360 struct tevent_req *req, *subreq;
1361 struct rpc_api_pipe_req_state *state;
1365 req = tevent_req_create(mem_ctx, &state,
1366 struct rpc_api_pipe_req_state);
1372 state->op_num = op_num;
1373 state->req_data = req_data;
1374 state->req_data_sent = 0;
1375 state->call_id = get_rpc_call_id();
1376 state->reply_pdu = data_blob_null;
1377 state->rpc_out = data_blob_null;
1379 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1380 + RPC_MAX_SIGN_SIZE) {
1381 /* Server is screwed up ! */
1382 status = NT_STATUS_INVALID_PARAMETER;
1386 status = prepare_next_frag(state, &is_last_frag);
1387 if (!NT_STATUS_IS_OK(status)) {
1392 subreq = rpc_api_pipe_send(state, ev, state->cli,
1394 DCERPC_PKT_RESPONSE);
1395 if (subreq == NULL) {
1398 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1400 subreq = rpc_write_send(state, ev, cli->transport,
1401 state->rpc_out.data,
1402 state->rpc_out.length);
1403 if (subreq == NULL) {
1406 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1412 tevent_req_nterror(req, status);
1413 return tevent_req_post(req, ev);
1419 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1422 uint32_t data_sent_thistime;
1429 union dcerpc_payload u;
1431 data_left = state->req_data->length - state->req_data_sent;
1433 status = calculate_data_len_tosend(state->cli, data_left,
1434 &data_sent_thistime,
1435 &frag_len, &auth_len,
1437 if (!NT_STATUS_IS_OK(status)) {
1441 if (state->req_data_sent == 0) {
1442 flags = DCERPC_PFC_FLAG_FIRST;
1445 if (data_sent_thistime == data_left) {
1446 flags |= DCERPC_PFC_FLAG_LAST;
1449 data_blob_free(&state->rpc_out);
1451 ZERO_STRUCT(u.request);
1453 u.request.alloc_hint = state->req_data->length;
1454 u.request.context_id = 0;
1455 u.request.opnum = state->op_num;
1457 status = dcerpc_push_ncacn_packet(state,
1464 if (!NT_STATUS_IS_OK(status)) {
1468 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1469 * compute it right for requests because the auth trailer is missing
1471 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1473 /* Copy in the data. */
1474 if (!data_blob_append(NULL, &state->rpc_out,
1475 state->req_data->data + state->req_data_sent,
1476 data_sent_thistime)) {
1477 return NT_STATUS_NO_MEMORY;
1480 switch (state->cli->auth->auth_level) {
1481 case DCERPC_AUTH_LEVEL_NONE:
1482 case DCERPC_AUTH_LEVEL_CONNECT:
1483 case DCERPC_AUTH_LEVEL_PACKET:
1485 case DCERPC_AUTH_LEVEL_INTEGRITY:
1486 case DCERPC_AUTH_LEVEL_PRIVACY:
1487 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1489 if (!NT_STATUS_IS_OK(status)) {
1494 return NT_STATUS_INVALID_PARAMETER;
1497 state->req_data_sent += data_sent_thistime;
1498 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1503 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1505 struct tevent_req *req = tevent_req_callback_data(
1506 subreq, struct tevent_req);
1507 struct rpc_api_pipe_req_state *state = tevent_req_data(
1508 req, struct rpc_api_pipe_req_state);
1512 status = rpc_write_recv(subreq);
1513 TALLOC_FREE(subreq);
1514 if (!NT_STATUS_IS_OK(status)) {
1515 tevent_req_nterror(req, status);
1519 status = prepare_next_frag(state, &is_last_frag);
1520 if (!NT_STATUS_IS_OK(status)) {
1521 tevent_req_nterror(req, status);
1526 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1528 DCERPC_PKT_RESPONSE);
1529 if (tevent_req_nomem(subreq, req)) {
1532 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1534 subreq = rpc_write_send(state, state->ev,
1535 state->cli->transport,
1536 state->rpc_out.data,
1537 state->rpc_out.length);
1538 if (tevent_req_nomem(subreq, req)) {
1541 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1546 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1548 struct tevent_req *req = tevent_req_callback_data(
1549 subreq, struct tevent_req);
1550 struct rpc_api_pipe_req_state *state = tevent_req_data(
1551 req, struct rpc_api_pipe_req_state);
1554 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1555 TALLOC_FREE(subreq);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 tevent_req_nterror(req, status);
1560 tevent_req_done(req);
1563 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1564 DATA_BLOB *reply_pdu)
1566 struct rpc_api_pipe_req_state *state = tevent_req_data(
1567 req, struct rpc_api_pipe_req_state);
1570 if (tevent_req_is_nterror(req, &status)) {
1572 * We always have to initialize to reply pdu, even if there is
1573 * none. The rpccli_* caller routines expect this.
1575 *reply_pdu = data_blob_null;
1579 /* return data to caller and assign it ownership of memory */
1580 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1581 reply_pdu->length = state->reply_pdu.length;
1582 state->reply_pdu.length = 0;
1584 return NT_STATUS_OK;
1588 /****************************************************************************
1589 Set the handle state.
1590 ****************************************************************************/
1592 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1593 const char *pipe_name, uint16 device_state)
1595 bool state_set = False;
1597 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1598 char *rparam = NULL;
1600 uint32 rparam_len, rdata_len;
1602 if (pipe_name == NULL)
1605 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1606 cli->fnum, pipe_name, device_state));
1608 /* create parameters: device state */
1609 SSVAL(param, 0, device_state);
1611 /* create setup parameters. */
1613 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1615 /* send the data on \PIPE\ */
1616 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1617 setup, 2, 0, /* setup, length, max */
1618 param, 2, 0, /* param, length, max */
1619 NULL, 0, 1024, /* data, length, max */
1620 &rparam, &rparam_len, /* return param, length */
1621 &rdata, &rdata_len)) /* return data, length */
1623 DEBUG(5, ("Set Handle state: return OK\n"));
1634 /****************************************************************************
1635 Check the rpc bind acknowledge response.
1636 ****************************************************************************/
1638 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1639 const struct ndr_syntax_id *transfer)
1641 struct dcerpc_ack_ctx ctx;
1643 if (r->secondary_address_size == 0) {
1644 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1647 if (r->num_results < 1 || !r->ctx_list) {
1651 ctx = r->ctx_list[0];
1653 /* check the transfer syntax */
1654 if ((ctx.syntax.if_version != transfer->if_version) ||
1655 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1656 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1660 if (r->num_results != 0x1 || ctx.result != 0) {
1661 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1662 r->num_results, ctx.reason));
1665 DEBUG(5,("check_bind_response: accepted!\n"));
1669 /*******************************************************************
1670 Creates a DCE/RPC bind authentication response.
1671 This is the packet that is sent back to the server once we
1672 have received a BIND-ACK, to finish the third leg of
1673 the authentication handshake.
1674 ********************************************************************/
1676 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1677 struct rpc_pipe_client *cli,
1679 enum dcerpc_AuthType auth_type,
1680 enum dcerpc_AuthLevel auth_level,
1681 DATA_BLOB *pauth_blob,
1685 union dcerpc_payload u;
1689 status = dcerpc_push_dcerpc_auth(mem_ctx,
1692 0, /* auth_pad_length */
1693 1, /* auth_context_id */
1695 &u.auth3.auth_info);
1696 if (!NT_STATUS_IS_OK(status)) {
1700 status = dcerpc_push_ncacn_packet(mem_ctx,
1702 DCERPC_PFC_FLAG_FIRST |
1703 DCERPC_PFC_FLAG_LAST,
1708 data_blob_free(&u.auth3.auth_info);
1709 if (!NT_STATUS_IS_OK(status)) {
1710 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1714 return NT_STATUS_OK;
1717 /*******************************************************************
1718 Creates a DCE/RPC bind alter context authentication request which
1719 may contain a spnego auth blobl
1720 ********************************************************************/
1722 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1723 enum dcerpc_AuthType auth_type,
1724 enum dcerpc_AuthLevel auth_level,
1726 const struct ndr_syntax_id *abstract,
1727 const struct ndr_syntax_id *transfer,
1728 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1731 DATA_BLOB auth_info;
1734 status = dcerpc_push_dcerpc_auth(mem_ctx,
1737 0, /* auth_pad_length */
1738 1, /* auth_context_id */
1741 if (!NT_STATUS_IS_OK(status)) {
1745 status = create_bind_or_alt_ctx_internal(mem_ctx,
1752 data_blob_free(&auth_info);
1756 /****************************************************************************
1758 ****************************************************************************/
1760 struct rpc_pipe_bind_state {
1761 struct event_context *ev;
1762 struct rpc_pipe_client *cli;
1764 uint32_t rpc_call_id;
1767 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1768 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1769 struct rpc_pipe_bind_state *state,
1770 DATA_BLOB *credentials);
1771 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1772 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1773 struct rpc_pipe_bind_state *state,
1774 DATA_BLOB *credentials);
1775 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1776 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1777 struct rpc_pipe_bind_state *state,
1778 DATA_BLOB *credentials);
1779 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1780 struct rpc_pipe_bind_state *state,
1781 DATA_BLOB *credentials);
1783 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1784 struct event_context *ev,
1785 struct rpc_pipe_client *cli,
1786 struct pipe_auth_data *auth)
1788 struct tevent_req *req, *subreq;
1789 struct rpc_pipe_bind_state *state;
1792 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1797 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1798 rpccli_pipe_txt(talloc_tos(), cli),
1799 (unsigned int)auth->auth_type,
1800 (unsigned int)auth->spnego_type,
1801 (unsigned int)auth->auth_level ));
1805 state->rpc_call_id = get_rpc_call_id();
1806 state->rpc_out = data_blob_null;
1808 cli->auth = talloc_move(cli, &auth);
1810 /* Marshall the outgoing data. */
1811 status = create_rpc_bind_req(state, cli,
1814 &cli->abstract_syntax,
1815 &cli->transfer_syntax,
1818 if (!NT_STATUS_IS_OK(status)) {
1822 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1823 DCERPC_PKT_BIND_ACK);
1824 if (subreq == NULL) {
1827 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1831 tevent_req_nterror(req, status);
1832 return tevent_req_post(req, ev);
1838 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1840 struct tevent_req *req = tevent_req_callback_data(
1841 subreq, struct tevent_req);
1842 struct rpc_pipe_bind_state *state = tevent_req_data(
1843 req, struct rpc_pipe_bind_state);
1844 struct pipe_auth_data *pauth = state->cli->auth;
1845 DATA_BLOB reply_pdu;
1846 struct ncacn_packet *pkt;
1847 struct dcerpc_auth auth;
1848 DATA_BLOB auth_token = data_blob_null;
1851 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1852 TALLOC_FREE(subreq);
1853 if (!NT_STATUS_IS_OK(status)) {
1854 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1855 rpccli_pipe_txt(talloc_tos(), state->cli),
1856 nt_errstr(status)));
1857 tevent_req_nterror(req, status);
1861 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1862 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1863 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1867 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1868 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1870 switch(state->cli->auth->auth_type) {
1872 case DCERPC_AUTH_TYPE_NONE:
1873 case DCERPC_AUTH_TYPE_SCHANNEL:
1874 /* Bind complete. */
1875 tevent_req_done(req);
1878 case DCERPC_AUTH_TYPE_NTLMSSP:
1879 case DCERPC_AUTH_TYPE_SPNEGO:
1880 case DCERPC_AUTH_TYPE_KRB5:
1881 /* Paranoid lenght checks */
1882 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1883 + pkt->auth_length) {
1884 tevent_req_nterror(req,
1885 NT_STATUS_INFO_LENGTH_MISMATCH);
1888 /* get auth credentials */
1889 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1890 &pkt->u.bind_ack.auth_info,
1892 if (!NT_STATUS_IS_OK(status)) {
1893 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1894 nt_errstr(status)));
1895 tevent_req_nterror(req, status);
1905 * For authenticated binds we may need to do 3 or 4 leg binds.
1908 switch(state->cli->auth->auth_type) {
1910 case DCERPC_AUTH_TYPE_NONE:
1911 case DCERPC_AUTH_TYPE_SCHANNEL:
1912 /* Bind complete. */
1913 tevent_req_done(req);
1916 case DCERPC_AUTH_TYPE_NTLMSSP:
1917 /* Need to send AUTH3 packet - no reply. */
1918 status = rpc_finish_auth3_bind_send(req, state,
1922 case DCERPC_AUTH_TYPE_SPNEGO:
1923 if (state->cli->auth->spnego_type !=
1924 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1927 /* Need to send alter context request and reply. */
1928 status = rpc_finish_spnego_ntlmssp_bind_send(req, state,
1932 case DCERPC_AUTH_TYPE_KRB5:
1933 status = gse_get_client_auth_token(state,
1934 pauth->a_u.gssapi_state,
1937 if (!NT_STATUS_IS_OK(status)) {
1941 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
1942 status = rpc_bind_next_send(req, state, &auth_token);
1944 status = rpc_bind_finish_send(req, state, &auth_token);
1952 if (!NT_STATUS_IS_OK(status)) {
1953 tevent_req_nterror(req, status);
1958 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
1959 (unsigned int)state->cli->auth->auth_type,
1960 (unsigned int)state->cli->auth->spnego_type));
1961 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1964 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1965 struct rpc_pipe_bind_state *state,
1966 DATA_BLOB *credentials)
1968 struct pipe_auth_data *auth = state->cli->auth;
1969 DATA_BLOB client_reply = data_blob_null;
1970 struct tevent_req *subreq;
1973 /* TODO - check auth_type/auth_level match. */
1975 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
1976 *credentials, &client_reply);
1978 if (!NT_STATUS_IS_OK(status)) {
1979 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
1980 "blob failed: %s.\n", nt_errstr(status)));
1984 data_blob_free(&state->rpc_out);
1986 status = create_rpc_bind_auth3(state, state->cli,
1992 data_blob_free(&client_reply);
1994 if (!NT_STATUS_IS_OK(status)) {
1998 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1999 state->rpc_out.data, state->rpc_out.length);
2000 if (subreq == NULL) {
2001 return NT_STATUS_NO_MEMORY;
2003 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2004 return NT_STATUS_OK;
2007 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2009 struct tevent_req *req = tevent_req_callback_data(
2010 subreq, struct tevent_req);
2013 status = rpc_write_recv(subreq);
2014 TALLOC_FREE(subreq);
2015 if (!NT_STATUS_IS_OK(status)) {
2016 tevent_req_nterror(req, status);
2019 tevent_req_done(req);
2022 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2023 struct rpc_pipe_bind_state *state,
2024 DATA_BLOB *credentials)
2026 struct pipe_auth_data *auth = state->cli->auth;
2027 DATA_BLOB server_ntlm_response = data_blob_null;
2028 DATA_BLOB client_reply = data_blob_null;
2029 DATA_BLOB tmp_blob = data_blob_null;
2030 struct tevent_req *subreq;
2034 * The server might give us back two challenges - tmp_blob is for the
2037 if (!spnego_parse_challenge(state, *credentials,
2038 &server_ntlm_response,
2040 data_blob_free(&server_ntlm_response);
2041 data_blob_free(&tmp_blob);
2042 return NT_STATUS_INVALID_PARAMETER;
2045 /* We're finished with the server spnego response and the tmp_blob. */
2046 data_blob_free(&tmp_blob);
2048 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2049 server_ntlm_response, &client_reply);
2051 /* Finished with the server_ntlm response */
2052 data_blob_free(&server_ntlm_response);
2054 if (!NT_STATUS_IS_OK(status)) {
2055 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2056 "using server blob failed.\n"));
2057 data_blob_free(&client_reply);
2061 /* SPNEGO wrap the client reply. */
2062 tmp_blob = spnego_gen_auth(state, client_reply);
2063 data_blob_free(&client_reply);
2064 client_reply = tmp_blob;
2065 tmp_blob = data_blob_null;
2067 /* Now prepare the alter context pdu. */
2068 data_blob_free(&state->rpc_out);
2070 status = create_rpc_alter_context(state,
2074 &state->cli->abstract_syntax,
2075 &state->cli->transfer_syntax,
2078 data_blob_free(&client_reply);
2080 if (!NT_STATUS_IS_OK(status)) {
2084 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2085 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2086 if (subreq == NULL) {
2087 return NT_STATUS_NO_MEMORY;
2089 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2090 return NT_STATUS_OK;
2093 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2095 struct tevent_req *req = tevent_req_callback_data(
2096 subreq, struct tevent_req);
2097 struct rpc_pipe_bind_state *state = tevent_req_data(
2098 req, struct rpc_pipe_bind_state);
2099 DATA_BLOB tmp_blob = data_blob_null;
2100 struct ncacn_packet *pkt;
2101 struct dcerpc_auth auth;
2104 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2105 TALLOC_FREE(subreq);
2106 if (!NT_STATUS_IS_OK(status)) {
2107 tevent_req_nterror(req, status);
2111 status = dcerpc_pull_dcerpc_auth(pkt,
2112 &pkt->u.alter_resp.auth_info,
2114 if (!NT_STATUS_IS_OK(status)) {
2115 tevent_req_nterror(req, status);
2119 /* Check we got a valid auth response. */
2120 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2122 OID_NTLMSSP, &tmp_blob)) {
2123 data_blob_free(&tmp_blob);
2124 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2128 data_blob_free(&tmp_blob);
2130 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2131 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2132 tevent_req_done(req);
2135 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2136 struct rpc_pipe_bind_state *state,
2137 DATA_BLOB *auth_token)
2139 struct pipe_auth_data *auth = state->cli->auth;
2140 struct tevent_req *subreq;
2143 /* Now prepare the alter context pdu. */
2144 data_blob_free(&state->rpc_out);
2146 status = create_rpc_alter_context(state,
2150 &state->cli->abstract_syntax,
2151 &state->cli->transfer_syntax,
2154 if (!NT_STATUS_IS_OK(status)) {
2158 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2159 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2160 if (subreq == NULL) {
2161 return NT_STATUS_NO_MEMORY;
2163 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2164 return NT_STATUS_OK;
2167 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2168 struct rpc_pipe_bind_state *state,
2169 DATA_BLOB *auth_token)
2171 struct pipe_auth_data *auth = state->cli->auth;
2172 struct tevent_req *subreq;
2175 /* Now prepare the auth3 context pdu. */
2176 data_blob_free(&state->rpc_out);
2178 status = create_rpc_bind_auth3(state, state->cli,
2184 if (!NT_STATUS_IS_OK(status)) {
2188 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2189 state->rpc_out.data, state->rpc_out.length);
2190 if (subreq == NULL) {
2191 return NT_STATUS_NO_MEMORY;
2193 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2194 return NT_STATUS_OK;
2197 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2199 return tevent_req_simple_recv_ntstatus(req);
2202 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2203 struct pipe_auth_data *auth)
2205 TALLOC_CTX *frame = talloc_stackframe();
2206 struct event_context *ev;
2207 struct tevent_req *req;
2208 NTSTATUS status = NT_STATUS_OK;
2210 ev = event_context_init(frame);
2212 status = NT_STATUS_NO_MEMORY;
2216 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2218 status = NT_STATUS_NO_MEMORY;
2222 if (!tevent_req_poll(req, ev)) {
2223 status = map_nt_error_from_unix(errno);
2227 status = rpc_pipe_bind_recv(req);
2233 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2235 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2236 unsigned int timeout)
2240 if (rpc_cli->transport == NULL) {
2241 return RPCCLI_DEFAULT_TIMEOUT;
2244 if (rpc_cli->transport->set_timeout == NULL) {
2245 return RPCCLI_DEFAULT_TIMEOUT;
2248 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2250 return RPCCLI_DEFAULT_TIMEOUT;
2256 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2258 if (rpc_cli == NULL) {
2262 if (rpc_cli->transport == NULL) {
2266 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2269 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2271 struct cli_state *cli;
2273 if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP)
2274 || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO
2275 && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2276 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2280 cli = rpc_pipe_np_smb_conn(rpc_cli);
2284 E_md4hash(cli->password ? cli->password : "", nt_hash);
2288 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2289 struct pipe_auth_data **presult)
2291 struct pipe_auth_data *result;
2293 result = talloc(mem_ctx, struct pipe_auth_data);
2294 if (result == NULL) {
2295 return NT_STATUS_NO_MEMORY;
2298 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2299 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2300 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2302 result->user_name = talloc_strdup(result, "");
2303 result->domain = talloc_strdup(result, "");
2304 if ((result->user_name == NULL) || (result->domain == NULL)) {
2305 TALLOC_FREE(result);
2306 return NT_STATUS_NO_MEMORY;
2310 return NT_STATUS_OK;
2313 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2315 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2319 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2320 enum dcerpc_AuthType auth_type,
2321 enum pipe_auth_type_spnego spnego_type,
2322 enum dcerpc_AuthLevel auth_level,
2324 const char *username,
2325 const char *password,
2326 struct pipe_auth_data **presult)
2328 struct pipe_auth_data *result;
2331 result = talloc(mem_ctx, struct pipe_auth_data);
2332 if (result == NULL) {
2333 return NT_STATUS_NO_MEMORY;
2336 result->auth_type = auth_type;
2337 result->spnego_type = spnego_type;
2338 result->auth_level = auth_level;
2340 result->user_name = talloc_strdup(result, username);
2341 result->domain = talloc_strdup(result, domain);
2342 if ((result->user_name == NULL) || (result->domain == NULL)) {
2343 status = NT_STATUS_NO_MEMORY;
2347 status = auth_ntlmssp_client_start(NULL,
2350 lp_client_ntlmv2_auth(),
2351 &result->a_u.auth_ntlmssp_state);
2352 if (!NT_STATUS_IS_OK(status)) {
2356 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2358 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2360 if (!NT_STATUS_IS_OK(status)) {
2364 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2366 if (!NT_STATUS_IS_OK(status)) {
2370 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2372 if (!NT_STATUS_IS_OK(status)) {
2377 * Turn off sign+seal to allow selected auth level to turn it back on.
2379 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2380 ~(NTLMSSP_NEGOTIATE_SIGN |
2381 NTLMSSP_NEGOTIATE_SEAL));
2383 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2384 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2385 NTLMSSP_NEGOTIATE_SIGN);
2386 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2387 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2388 NTLMSSP_NEGOTIATE_SEAL |
2389 NTLMSSP_NEGOTIATE_SIGN);
2393 return NT_STATUS_OK;
2396 TALLOC_FREE(result);
2400 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2401 enum dcerpc_AuthLevel auth_level,
2402 struct netlogon_creds_CredentialState *creds,
2403 struct pipe_auth_data **presult)
2405 struct pipe_auth_data *result;
2407 result = talloc(mem_ctx, struct pipe_auth_data);
2408 if (result == NULL) {
2409 return NT_STATUS_NO_MEMORY;
2412 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2413 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2414 result->auth_level = auth_level;
2416 result->user_name = talloc_strdup(result, "");
2417 result->domain = talloc_strdup(result, domain);
2418 if ((result->user_name == NULL) || (result->domain == NULL)) {
2422 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2423 if (result->a_u.schannel_auth == NULL) {
2427 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2428 result->a_u.schannel_auth->seq_num = 0;
2429 result->a_u.schannel_auth->initiator = true;
2430 result->a_u.schannel_auth->creds = creds;
2433 return NT_STATUS_OK;
2436 TALLOC_FREE(result);
2437 return NT_STATUS_NO_MEMORY;
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,
3343 const char *username,
3344 const char *password,
3345 struct rpc_pipe_client **presult)
3347 struct rpc_pipe_client *result;
3348 struct pipe_auth_data *auth;
3351 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3352 if (!NT_STATUS_IS_OK(status)) {
3356 auth = talloc(result, struct pipe_auth_data);
3358 status = NT_STATUS_NO_MEMORY;
3361 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3362 auth->auth_level = auth_level;
3367 auth->user_name = talloc_strdup(auth, username);
3368 if (!auth->user_name) {
3369 status = NT_STATUS_NO_MEMORY;
3373 /* Fixme, should we fetch/set the Realm ? */
3374 auth->domain = talloc_strdup(auth, "");
3375 if (!auth->domain) {
3376 status = NT_STATUS_NO_MEMORY;
3380 status = gse_init_client(auth, auth->auth_type, auth->auth_level,
3381 NULL, server, "cifs", username, password,
3382 GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3384 if (!NT_STATUS_IS_OK(status)) {
3385 DEBUG(0, ("gse_init_client returned %s\n",
3386 nt_errstr(status)));
3390 status = rpc_pipe_bind(result, auth);
3391 if (!NT_STATUS_IS_OK(status)) {
3392 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3393 nt_errstr(status)));
3398 return NT_STATUS_OK;
3401 TALLOC_FREE(result);
3405 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3406 const struct ndr_syntax_id *interface,
3407 enum dcerpc_transport_t transport,
3408 enum dcerpc_AuthLevel auth_level,
3410 const char *username,
3411 const char *password,
3412 struct rpc_pipe_client **presult)
3414 return NT_STATUS_NOT_IMPLEMENTED;
3417 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3418 struct rpc_pipe_client *cli,
3419 DATA_BLOB *session_key)
3421 struct pipe_auth_data *a = cli->auth;
3424 if (!session_key || !cli) {
3425 return NT_STATUS_INVALID_PARAMETER;
3429 return NT_STATUS_INVALID_PARAMETER;
3432 switch (cli->auth->auth_type) {
3433 case DCERPC_AUTH_TYPE_SCHANNEL:
3434 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3437 case DCERPC_AUTH_TYPE_SPNEGO:
3438 switch (cli->auth->spnego_type) {
3439 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3440 sk = auth_ntlmssp_get_session_key(
3441 a->a_u.auth_ntlmssp_state);
3443 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3444 sk = gse_get_session_key(a->a_u.gssapi_state);
3447 return NT_STATUS_NO_USER_SESSION_KEY;
3450 case DCERPC_AUTH_TYPE_NTLMSSP:
3451 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3453 case DCERPC_AUTH_TYPE_KRB5:
3454 sk = gse_get_session_key(a->a_u.gssapi_state);
3456 case DCERPC_AUTH_TYPE_NONE:
3457 sk = data_blob_const(a->user_session_key.data,
3458 a->user_session_key.length);
3461 return NT_STATUS_NO_USER_SESSION_KEY;
3464 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3465 return NT_STATUS_OK;