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"
34 #include "librpc/rpc/dcerpc_spnego.h"
37 #define DBGC_CLASS DBGC_RPC_CLI
39 /********************************************************************
40 Pipe description for a DEBUG
41 ********************************************************************/
42 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
43 struct rpc_pipe_client *cli)
45 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
52 /********************************************************************
54 ********************************************************************/
56 static uint32 get_rpc_call_id(void)
58 static uint32 call_id = 0;
62 /*******************************************************************
63 Use SMBreadX to get rest of one fragment's worth of rpc data.
64 Reads the whole size or give an error message
65 ********************************************************************/
67 struct rpc_read_state {
68 struct event_context *ev;
69 struct rpc_cli_transport *transport;
75 static void rpc_read_done(struct tevent_req *subreq);
77 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
78 struct event_context *ev,
79 struct rpc_cli_transport *transport,
80 uint8_t *data, size_t size)
82 struct tevent_req *req, *subreq;
83 struct rpc_read_state *state;
85 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
90 state->transport = transport;
95 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
97 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
102 tevent_req_set_callback(subreq, rpc_read_done, req);
110 static void rpc_read_done(struct tevent_req *subreq)
112 struct tevent_req *req = tevent_req_callback_data(
113 subreq, struct tevent_req);
114 struct rpc_read_state *state = tevent_req_data(
115 req, struct rpc_read_state);
119 status = state->transport->read_recv(subreq, &received);
121 if (!NT_STATUS_IS_OK(status)) {
122 tevent_req_nterror(req, status);
126 state->num_read += received;
127 if (state->num_read == state->size) {
128 tevent_req_done(req);
132 subreq = state->transport->read_send(state, state->ev,
133 state->data + state->num_read,
134 state->size - state->num_read,
135 state->transport->priv);
136 if (tevent_req_nomem(subreq, req)) {
139 tevent_req_set_callback(subreq, rpc_read_done, req);
142 static NTSTATUS rpc_read_recv(struct tevent_req *req)
144 return tevent_req_simple_recv_ntstatus(req);
147 struct rpc_write_state {
148 struct event_context *ev;
149 struct rpc_cli_transport *transport;
155 static void rpc_write_done(struct tevent_req *subreq);
157 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
158 struct event_context *ev,
159 struct rpc_cli_transport *transport,
160 const uint8_t *data, size_t size)
162 struct tevent_req *req, *subreq;
163 struct rpc_write_state *state;
165 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
170 state->transport = transport;
173 state->num_written = 0;
175 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
177 subreq = transport->write_send(state, ev, data, size, transport->priv);
178 if (subreq == NULL) {
181 tevent_req_set_callback(subreq, rpc_write_done, req);
188 static void rpc_write_done(struct tevent_req *subreq)
190 struct tevent_req *req = tevent_req_callback_data(
191 subreq, struct tevent_req);
192 struct rpc_write_state *state = tevent_req_data(
193 req, struct rpc_write_state);
197 status = state->transport->write_recv(subreq, &written);
199 if (!NT_STATUS_IS_OK(status)) {
200 tevent_req_nterror(req, status);
204 state->num_written += written;
206 if (state->num_written == state->size) {
207 tevent_req_done(req);
211 subreq = state->transport->write_send(state, state->ev,
212 state->data + state->num_written,
213 state->size - state->num_written,
214 state->transport->priv);
215 if (tevent_req_nomem(subreq, req)) {
218 tevent_req_set_callback(subreq, rpc_write_done, req);
221 static NTSTATUS rpc_write_recv(struct tevent_req *req)
223 return tevent_req_simple_recv_ntstatus(req);
227 /****************************************************************************
228 Try and get a PDU's worth of data from current_pdu. If not, then read more
230 ****************************************************************************/
232 struct get_complete_frag_state {
233 struct event_context *ev;
234 struct rpc_pipe_client *cli;
239 static void get_complete_frag_got_header(struct tevent_req *subreq);
240 static void get_complete_frag_got_rest(struct tevent_req *subreq);
242 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
243 struct event_context *ev,
244 struct rpc_pipe_client *cli,
247 struct tevent_req *req, *subreq;
248 struct get_complete_frag_state *state;
252 req = tevent_req_create(mem_ctx, &state,
253 struct get_complete_frag_state);
259 state->frag_len = RPC_HEADER_LEN;
262 received = pdu->length;
263 if (received < RPC_HEADER_LEN) {
264 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
265 status = NT_STATUS_NO_MEMORY;
268 subreq = rpc_read_send(state, state->ev,
269 state->cli->transport,
270 pdu->data + received,
271 RPC_HEADER_LEN - received);
272 if (subreq == NULL) {
273 status = NT_STATUS_NO_MEMORY;
276 tevent_req_set_callback(subreq, get_complete_frag_got_header,
281 state->frag_len = dcerpc_get_frag_length(pdu);
284 * Ensure we have frag_len bytes of data.
286 if (received < state->frag_len) {
287 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
288 status = NT_STATUS_NO_MEMORY;
291 subreq = rpc_read_send(state, state->ev,
292 state->cli->transport,
293 pdu->data + received,
294 state->frag_len - received);
295 if (subreq == NULL) {
296 status = NT_STATUS_NO_MEMORY;
299 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
304 status = NT_STATUS_OK;
306 if (NT_STATUS_IS_OK(status)) {
307 tevent_req_done(req);
309 tevent_req_nterror(req, status);
311 return tevent_req_post(req, ev);
314 static void get_complete_frag_got_header(struct tevent_req *subreq)
316 struct tevent_req *req = tevent_req_callback_data(
317 subreq, struct tevent_req);
318 struct get_complete_frag_state *state = tevent_req_data(
319 req, struct get_complete_frag_state);
322 status = rpc_read_recv(subreq);
324 if (!NT_STATUS_IS_OK(status)) {
325 tevent_req_nterror(req, status);
329 state->frag_len = dcerpc_get_frag_length(state->pdu);
331 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
332 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
337 * We're here in this piece of code because we've read exactly
338 * RPC_HEADER_LEN bytes into state->pdu.
341 subreq = rpc_read_send(state, state->ev, state->cli->transport,
342 state->pdu->data + RPC_HEADER_LEN,
343 state->frag_len - RPC_HEADER_LEN);
344 if (tevent_req_nomem(subreq, req)) {
347 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
350 static void get_complete_frag_got_rest(struct tevent_req *subreq)
352 struct tevent_req *req = tevent_req_callback_data(
353 subreq, struct tevent_req);
356 status = rpc_read_recv(subreq);
358 if (!NT_STATUS_IS_OK(status)) {
359 tevent_req_nterror(req, status);
362 tevent_req_done(req);
365 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
367 return tevent_req_simple_recv_ntstatus(req);
370 /****************************************************************************
371 Do basic authentication checks on an incoming pdu.
372 ****************************************************************************/
374 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
375 struct rpc_pipe_client *cli,
376 struct ncacn_packet *pkt,
378 uint8_t expected_pkt_type,
380 DATA_BLOB *reply_pdu)
382 NTSTATUS ret = NT_STATUS_OK;
385 ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
386 if (!NT_STATUS_IS_OK(ret)) {
390 if (pdu->length != pkt->frag_length) {
391 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
392 (unsigned int)pdu->length,
393 (unsigned int)pkt->frag_length));
394 return NT_STATUS_INVALID_PARAMETER;
398 * Point the return values at the real data including the RPC
399 * header. Just in case the caller wants it.
403 /* Ensure we have the correct type. */
404 switch (pkt->ptype) {
405 case DCERPC_PKT_ALTER_RESP:
406 case DCERPC_PKT_BIND_ACK:
408 /* Alter context and bind ack share the same packet definitions. */
412 case DCERPC_PKT_RESPONSE:
414 /* Here's where we deal with incoming sign/seal. */
415 ret = dcerpc_check_auth(cli->auth, pkt,
416 &pkt->u.response.stub_and_verifier,
417 DCERPC_RESPONSE_LENGTH,
419 if (!NT_STATUS_IS_OK(ret)) {
423 if (pdu->length < DCERPC_RESPONSE_LENGTH + pad_len) {
424 return NT_STATUS_BUFFER_TOO_SMALL;
427 /* Point the return values at the NDR data. */
428 rdata->data = pdu->data + DCERPC_RESPONSE_LENGTH;
430 if (pkt->auth_length) {
431 /* We've already done integer wrap tests in
432 * dcerpc_check_auth(). */
433 rdata->length = pdu->length
434 - DCERPC_RESPONSE_LENGTH
436 - DCERPC_AUTH_TRAILER_LENGTH
439 rdata->length = pdu->length - DCERPC_RESPONSE_LENGTH;
442 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
443 (long unsigned int)pdu->length,
444 (long unsigned int)rdata->length,
445 (unsigned int)pad_len));
448 * If this is the first reply, and the allocation hint is
449 * reasonable, try and set up the reply_pdu DATA_BLOB to the
453 if ((reply_pdu->length == 0) &&
454 pkt->u.response.alloc_hint &&
455 (pkt->u.response.alloc_hint < 15*1024*1024)) {
456 if (!data_blob_realloc(mem_ctx, reply_pdu,
457 pkt->u.response.alloc_hint)) {
458 DEBUG(0, ("reply alloc hint %d too "
459 "large to allocate\n",
460 (int)pkt->u.response.alloc_hint));
461 return NT_STATUS_NO_MEMORY;
467 case DCERPC_PKT_BIND_NAK:
468 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
469 "received from %s!\n",
470 rpccli_pipe_txt(talloc_tos(), cli)));
471 /* Use this for now... */
472 return NT_STATUS_NETWORK_ACCESS_DENIED;
474 case DCERPC_PKT_FAULT:
476 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
477 "code %s received from %s!\n",
478 dcerpc_errstr(talloc_tos(),
479 pkt->u.fault.status),
480 rpccli_pipe_txt(talloc_tos(), cli)));
482 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
483 return NT_STATUS_UNSUCCESSFUL;
485 return NT_STATUS(pkt->u.fault.status);
489 DEBUG(0, ("Unknown packet type %u received from %s!\n",
490 (unsigned int)pkt->ptype,
491 rpccli_pipe_txt(talloc_tos(), cli)));
492 return NT_STATUS_INVALID_INFO_CLASS;
495 if (pkt->ptype != expected_pkt_type) {
496 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
497 "got an unexpected RPC packet type - %u, not %u\n",
498 rpccli_pipe_txt(talloc_tos(), cli),
501 return NT_STATUS_INVALID_INFO_CLASS;
504 /* Do this just before return - we don't want to modify any rpc header
505 data before now as we may have needed to do cryptographic actions on
508 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
509 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
510 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
511 "setting fragment first/last ON.\n"));
512 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
513 DCERPC_PFC_FLAG_LAST;
519 /****************************************************************************
520 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
521 ****************************************************************************/
523 struct cli_api_pipe_state {
524 struct event_context *ev;
525 struct rpc_cli_transport *transport;
530 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
531 static void cli_api_pipe_write_done(struct tevent_req *subreq);
532 static void cli_api_pipe_read_done(struct tevent_req *subreq);
534 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
535 struct event_context *ev,
536 struct rpc_cli_transport *transport,
537 uint8_t *data, size_t data_len,
538 uint32_t max_rdata_len)
540 struct tevent_req *req, *subreq;
541 struct cli_api_pipe_state *state;
544 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
549 state->transport = transport;
551 if (max_rdata_len < RPC_HEADER_LEN) {
553 * For a RPC reply we always need at least RPC_HEADER_LEN
554 * bytes. We check this here because we will receive
555 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
557 status = NT_STATUS_INVALID_PARAMETER;
561 if (transport->trans_send != NULL) {
562 subreq = transport->trans_send(state, ev, data, data_len,
563 max_rdata_len, transport->priv);
564 if (subreq == NULL) {
567 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
572 * If the transport does not provide a "trans" routine, i.e. for
573 * example the ncacn_ip_tcp transport, do the write/read step here.
576 subreq = rpc_write_send(state, ev, transport, data, data_len);
577 if (subreq == NULL) {
580 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
584 tevent_req_nterror(req, status);
585 return tevent_req_post(req, ev);
591 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
593 struct tevent_req *req = tevent_req_callback_data(
594 subreq, struct tevent_req);
595 struct cli_api_pipe_state *state = tevent_req_data(
596 req, struct cli_api_pipe_state);
599 status = state->transport->trans_recv(subreq, state, &state->rdata,
602 if (!NT_STATUS_IS_OK(status)) {
603 tevent_req_nterror(req, status);
606 tevent_req_done(req);
609 static void cli_api_pipe_write_done(struct tevent_req *subreq)
611 struct tevent_req *req = tevent_req_callback_data(
612 subreq, struct tevent_req);
613 struct cli_api_pipe_state *state = tevent_req_data(
614 req, struct cli_api_pipe_state);
617 status = rpc_write_recv(subreq);
619 if (!NT_STATUS_IS_OK(status)) {
620 tevent_req_nterror(req, status);
624 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
625 if (tevent_req_nomem(state->rdata, req)) {
630 * We don't need to use rpc_read_send here, the upper layer will cope
631 * with a short read, transport->trans_send could also return less
632 * than state->max_rdata_len.
634 subreq = state->transport->read_send(state, state->ev, state->rdata,
636 state->transport->priv);
637 if (tevent_req_nomem(subreq, req)) {
640 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
643 static void cli_api_pipe_read_done(struct tevent_req *subreq)
645 struct tevent_req *req = tevent_req_callback_data(
646 subreq, struct tevent_req);
647 struct cli_api_pipe_state *state = tevent_req_data(
648 req, struct cli_api_pipe_state);
652 status = state->transport->read_recv(subreq, &received);
654 if (!NT_STATUS_IS_OK(status)) {
655 tevent_req_nterror(req, status);
658 state->rdata_len = received;
659 tevent_req_done(req);
662 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
663 uint8_t **prdata, uint32_t *prdata_len)
665 struct cli_api_pipe_state *state = tevent_req_data(
666 req, struct cli_api_pipe_state);
669 if (tevent_req_is_nterror(req, &status)) {
673 *prdata = talloc_move(mem_ctx, &state->rdata);
674 *prdata_len = state->rdata_len;
678 /****************************************************************************
679 Send data on an rpc pipe via trans. The data must be the last
680 pdu fragment of an NDR data stream.
682 Receive response data from an rpc pipe, which may be large...
684 Read the first fragment: unfortunately have to use SMBtrans for the first
685 bit, then SMBreadX for subsequent bits.
687 If first fragment received also wasn't the last fragment, continue
688 getting fragments until we _do_ receive the last fragment.
690 Request/Response PDU's look like the following...
692 |<------------------PDU len----------------------------------------------->|
693 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
695 +------------+-----------------+-------------+---------------+-------------+
696 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
697 +------------+-----------------+-------------+---------------+-------------+
699 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
700 signing & sealing being negotiated.
702 ****************************************************************************/
704 struct rpc_api_pipe_state {
705 struct event_context *ev;
706 struct rpc_pipe_client *cli;
707 uint8_t expected_pkt_type;
709 DATA_BLOB incoming_frag;
710 struct ncacn_packet *pkt;
714 size_t reply_pdu_offset;
718 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
719 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
721 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
722 struct event_context *ev,
723 struct rpc_pipe_client *cli,
724 DATA_BLOB *data, /* Outgoing PDU */
725 uint8_t expected_pkt_type)
727 struct tevent_req *req, *subreq;
728 struct rpc_api_pipe_state *state;
729 uint16_t max_recv_frag;
732 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
738 state->expected_pkt_type = expected_pkt_type;
739 state->incoming_frag = data_blob_null;
740 state->reply_pdu = data_blob_null;
741 state->reply_pdu_offset = 0;
742 state->endianess = DCERPC_DREP_LE;
745 * Ensure we're not sending too much.
747 if (data->length > cli->max_xmit_frag) {
748 status = NT_STATUS_INVALID_PARAMETER;
752 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
754 /* get the header first, then fetch the rest once we have
755 * the frag_length available */
756 max_recv_frag = RPC_HEADER_LEN;
758 subreq = cli_api_pipe_send(state, ev, cli->transport,
759 data->data, data->length, max_recv_frag);
760 if (subreq == NULL) {
763 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
767 tevent_req_nterror(req, status);
768 return tevent_req_post(req, ev);
774 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
776 struct tevent_req *req = tevent_req_callback_data(
777 subreq, struct tevent_req);
778 struct rpc_api_pipe_state *state = tevent_req_data(
779 req, struct rpc_api_pipe_state);
781 uint8_t *rdata = NULL;
782 uint32_t rdata_len = 0;
784 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
786 if (!NT_STATUS_IS_OK(status)) {
787 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
788 tevent_req_nterror(req, status);
793 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
794 rpccli_pipe_txt(talloc_tos(), state->cli)));
795 tevent_req_done(req);
800 * Move data on state->incoming_frag.
802 state->incoming_frag.data = talloc_move(state, &rdata);
803 state->incoming_frag.length = rdata_len;
804 if (!state->incoming_frag.data) {
805 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
809 /* Ensure we have enough data for a pdu. */
810 subreq = get_complete_frag_send(state, state->ev, state->cli,
811 &state->incoming_frag);
812 if (tevent_req_nomem(subreq, req)) {
815 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
818 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
820 struct tevent_req *req = tevent_req_callback_data(
821 subreq, struct tevent_req);
822 struct rpc_api_pipe_state *state = tevent_req_data(
823 req, struct rpc_api_pipe_state);
825 DATA_BLOB rdata = data_blob_null;
827 status = get_complete_frag_recv(subreq);
829 if (!NT_STATUS_IS_OK(status)) {
830 DEBUG(5, ("get_complete_frag failed: %s\n",
832 tevent_req_nterror(req, status);
836 state->pkt = talloc(state, struct ncacn_packet);
838 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
842 status = cli_pipe_validate_current_pdu(state,
843 state->cli, state->pkt,
844 &state->incoming_frag,
845 state->expected_pkt_type,
849 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
850 (unsigned)state->incoming_frag.length,
851 (unsigned)state->reply_pdu_offset,
854 if (!NT_STATUS_IS_OK(status)) {
855 tevent_req_nterror(req, status);
859 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
860 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
862 * Set the data type correctly for big-endian data on the
865 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
867 rpccli_pipe_txt(talloc_tos(), state->cli)));
868 state->endianess = 0x00; /* BIG ENDIAN */
871 * Check endianness on subsequent packets.
873 if (state->endianess != state->pkt->drep[0]) {
874 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
876 state->endianess?"little":"big",
877 state->pkt->drep[0]?"little":"big"));
878 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
882 /* Now copy the data portion out of the pdu into rbuf. */
883 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
884 if (!data_blob_realloc(NULL, &state->reply_pdu,
885 state->reply_pdu_offset + rdata.length)) {
886 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
891 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
892 rdata.data, rdata.length);
893 state->reply_pdu_offset += rdata.length;
895 /* reset state->incoming_frag, there is no need to free it,
896 * it will be reallocated to the right size the next time
898 state->incoming_frag.length = 0;
900 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
901 /* make sure the pdu length is right now that we
902 * have all the data available (alloc hint may
903 * have allocated more than was actually used) */
904 state->reply_pdu.length = state->reply_pdu_offset;
905 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
906 rpccli_pipe_txt(talloc_tos(), state->cli),
907 (unsigned)state->reply_pdu.length));
908 tevent_req_done(req);
912 subreq = get_complete_frag_send(state, state->ev, state->cli,
913 &state->incoming_frag);
914 if (tevent_req_nomem(subreq, req)) {
917 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
920 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
921 struct ncacn_packet **pkt,
922 DATA_BLOB *reply_pdu)
924 struct rpc_api_pipe_state *state = tevent_req_data(
925 req, struct rpc_api_pipe_state);
928 if (tevent_req_is_nterror(req, &status)) {
932 /* return data to caller and assign it ownership of memory */
934 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
935 reply_pdu->length = state->reply_pdu.length;
936 state->reply_pdu.length = 0;
938 data_blob_free(&state->reply_pdu);
942 *pkt = talloc_steal(mem_ctx, state->pkt);
948 /*******************************************************************
949 Creates spnego auth bind.
950 ********************************************************************/
952 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
953 struct pipe_auth_data *auth,
954 DATA_BLOB *auth_info)
956 DATA_BLOB in_token = data_blob_null;
957 DATA_BLOB auth_token = data_blob_null;
960 /* Negotiate the initial auth token */
961 status = spnego_get_client_auth_token(mem_ctx,
962 auth->a_u.spnego_state,
963 &in_token, &auth_token);
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 krb5 auth bind.
989 ********************************************************************/
991 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
992 struct pipe_auth_data *auth,
993 DATA_BLOB *auth_info)
995 DATA_BLOB in_token = data_blob_null;
996 DATA_BLOB auth_token = data_blob_null;
999 /* Negotiate the initial auth token */
1000 status = gse_get_client_auth_token(mem_ctx,
1001 auth->a_u.gssapi_state,
1004 if (!NT_STATUS_IS_OK(status)) {
1008 status = dcerpc_push_dcerpc_auth(mem_ctx,
1011 0, /* auth_pad_length */
1012 1, /* auth_context_id */
1015 if (!NT_STATUS_IS_OK(status)) {
1016 data_blob_free(&auth_token);
1020 DEBUG(5, ("Created GSS Authentication Token:\n"));
1021 dump_data(5, auth_token.data, auth_token.length);
1023 data_blob_free(&auth_token);
1024 return NT_STATUS_OK;
1027 /*******************************************************************
1028 Creates SPNEGO NTLMSSP auth bind.
1029 ********************************************************************/
1031 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1032 enum dcerpc_AuthLevel auth_level,
1033 DATA_BLOB *auth_info)
1036 DATA_BLOB null_blob = data_blob_null;
1037 DATA_BLOB request = data_blob_null;
1038 DATA_BLOB spnego_msg = data_blob_null;
1039 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1041 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1042 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1046 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1047 data_blob_free(&request);
1051 /* Wrap this in SPNEGO. */
1052 spnego_msg = spnego_gen_negTokenInit(talloc_tos(), OIDs_ntlm, &request, NULL);
1054 data_blob_free(&request);
1056 status = dcerpc_push_dcerpc_auth(cli,
1057 DCERPC_AUTH_TYPE_SPNEGO,
1059 0, /* auth_pad_length */
1060 1, /* auth_context_id */
1064 if (!NT_STATUS_IS_OK(status)) {
1065 data_blob_free(&spnego_msg);
1069 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1070 dump_data(5, spnego_msg.data, spnego_msg.length);
1071 data_blob_free(&spnego_msg);
1073 return NT_STATUS_OK;
1076 /*******************************************************************
1077 Creates NTLMSSP auth bind.
1078 ********************************************************************/
1080 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1081 enum dcerpc_AuthLevel auth_level,
1082 DATA_BLOB *auth_info)
1085 DATA_BLOB null_blob = data_blob_null;
1086 DATA_BLOB request = data_blob_null;
1088 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1089 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1093 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1094 data_blob_free(&request);
1098 status = dcerpc_push_dcerpc_auth(cli,
1099 DCERPC_AUTH_TYPE_NTLMSSP,
1101 0, /* auth_pad_length */
1102 1, /* auth_context_id */
1105 if (!NT_STATUS_IS_OK(status)) {
1106 data_blob_free(&request);
1110 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1111 dump_data(5, request.data, request.length);
1113 return NT_STATUS_OK;
1116 /*******************************************************************
1117 Creates schannel auth bind.
1118 ********************************************************************/
1120 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1121 enum dcerpc_AuthLevel auth_level,
1122 DATA_BLOB *auth_info)
1125 struct NL_AUTH_MESSAGE r;
1126 DATA_BLOB schannel_blob;
1128 /* Use lp_workgroup() if domain not specified */
1130 if (!cli->auth->domain || !cli->auth->domain[0]) {
1131 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1132 if (cli->auth->domain == NULL) {
1133 return NT_STATUS_NO_MEMORY;
1138 * Now marshall the data into the auth parse_struct.
1141 r.MessageType = NL_NEGOTIATE_REQUEST;
1142 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1143 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1144 r.oem_netbios_domain.a = cli->auth->domain;
1145 r.oem_netbios_computer.a = global_myname();
1147 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1148 if (!NT_STATUS_IS_OK(status)) {
1152 status = dcerpc_push_dcerpc_auth(cli,
1153 DCERPC_AUTH_TYPE_SCHANNEL,
1155 0, /* auth_pad_length */
1156 1, /* auth_context_id */
1159 if (!NT_STATUS_IS_OK(status)) {
1163 return NT_STATUS_OK;
1166 /*******************************************************************
1167 Creates the internals of a DCE/RPC bind request or alter context PDU.
1168 ********************************************************************/
1170 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1171 enum dcerpc_pkt_type ptype,
1173 const struct ndr_syntax_id *abstract,
1174 const struct ndr_syntax_id *transfer,
1175 const DATA_BLOB *auth_info,
1178 uint16 auth_len = auth_info->length;
1180 union dcerpc_payload u;
1181 struct dcerpc_ctx_list ctx_list;
1184 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1187 ctx_list.context_id = 0;
1188 ctx_list.num_transfer_syntaxes = 1;
1189 ctx_list.abstract_syntax = *abstract;
1190 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1192 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1193 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1194 u.bind.assoc_group_id = 0x0;
1195 u.bind.num_contexts = 1;
1196 u.bind.ctx_list = &ctx_list;
1197 u.bind.auth_info = *auth_info;
1199 status = dcerpc_push_ncacn_packet(mem_ctx,
1201 DCERPC_PFC_FLAG_FIRST |
1202 DCERPC_PFC_FLAG_LAST,
1207 if (!NT_STATUS_IS_OK(status)) {
1208 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1212 return NT_STATUS_OK;
1215 /*******************************************************************
1216 Creates a DCE/RPC bind request.
1217 ********************************************************************/
1219 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1220 struct rpc_pipe_client *cli,
1221 struct pipe_auth_data *auth,
1223 const struct ndr_syntax_id *abstract,
1224 const struct ndr_syntax_id *transfer,
1227 DATA_BLOB auth_info = data_blob_null;
1228 NTSTATUS ret = NT_STATUS_OK;
1230 switch (auth->auth_type) {
1231 case DCERPC_AUTH_TYPE_SCHANNEL:
1232 ret = create_schannel_auth_rpc_bind_req(cli,
1235 if (!NT_STATUS_IS_OK(ret)) {
1240 case DCERPC_AUTH_TYPE_NTLMSSP:
1241 ret = create_ntlmssp_auth_rpc_bind_req(cli,
1244 if (!NT_STATUS_IS_OK(ret)) {
1249 case DCERPC_AUTH_TYPE_SPNEGO:
1250 switch (auth->spnego_type) {
1251 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1252 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli,
1257 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1258 ret = create_spnego_auth_bind_req(cli, auth,
1262 return NT_STATUS_INTERNAL_ERROR;
1264 if (!NT_STATUS_IS_OK(ret)) {
1269 case DCERPC_AUTH_TYPE_KRB5:
1270 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_info);
1271 if (!NT_STATUS_IS_OK(ret)) {
1276 case DCERPC_AUTH_TYPE_NONE:
1280 /* "Can't" happen. */
1281 return NT_STATUS_INVALID_INFO_CLASS;
1284 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1294 /*******************************************************************
1295 Calculate how much data we're going to send in this packet, also
1296 work out any sign/seal padding length.
1297 ********************************************************************/
1299 static NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli,
1301 uint32_t *data_to_send,
1302 uint16_t *p_frag_len,
1303 uint16_t *p_auth_len,
1304 uint32_t *p_ss_padding)
1306 uint32_t data_space, data_len;
1308 struct gse_context *gse_ctx;
1309 enum dcerpc_AuthType auth_type;
1313 switch (cli->auth->auth_level) {
1314 case DCERPC_AUTH_LEVEL_NONE:
1315 case DCERPC_AUTH_LEVEL_CONNECT:
1316 case DCERPC_AUTH_LEVEL_PACKET:
1317 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1318 data_len = MIN(data_space, data_left);
1321 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1322 *data_to_send = data_len;
1323 return NT_STATUS_OK;
1325 case DCERPC_AUTH_LEVEL_INTEGRITY:
1326 case DCERPC_AUTH_LEVEL_PRIVACY:
1327 max_len = cli->max_xmit_frag
1328 - DCERPC_REQUEST_LENGTH
1329 - DCERPC_AUTH_TRAILER_LENGTH;
1331 /* Treat the same for all authenticated rpc requests. */
1332 switch(cli->auth->auth_type) {
1333 case DCERPC_AUTH_TYPE_SPNEGO:
1334 switch (cli->auth->spnego_type) {
1335 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1336 *p_auth_len = NTLMSSP_SIG_SIZE;
1338 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1339 status = spnego_get_negotiated_mech(
1340 cli->auth->a_u.spnego_state,
1341 &auth_type, &auth_ctx);
1342 if (!NT_STATUS_IS_OK(status)) {
1345 gse_ctx = talloc_get_type(auth_ctx,
1346 struct gse_context);
1348 return NT_STATUS_INVALID_PARAMETER;
1350 *p_auth_len = gse_get_signature_length(gse_ctx,
1351 (cli->auth->auth_level ==
1352 DCERPC_AUTH_LEVEL_PRIVACY),
1356 return NT_STATUS_INVALID_PARAMETER;
1359 case DCERPC_AUTH_TYPE_NTLMSSP:
1360 *p_auth_len = NTLMSSP_SIG_SIZE;
1362 case DCERPC_AUTH_TYPE_SCHANNEL:
1363 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1365 case DCERPC_AUTH_TYPE_KRB5:
1366 *p_auth_len = gse_get_signature_length(
1367 cli->auth->a_u.gssapi_state,
1368 (cli->auth->auth_level ==
1369 DCERPC_AUTH_LEVEL_PRIVACY),
1373 return NT_STATUS_INVALID_PARAMETER;
1376 data_space = max_len - *p_auth_len;
1378 data_len = MIN(data_space, data_left);
1380 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1381 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1383 *p_frag_len = DCERPC_REQUEST_LENGTH
1384 + data_len + *p_ss_padding
1385 + DCERPC_AUTH_TRAILER_LENGTH
1387 *data_to_send = data_len;
1388 return NT_STATUS_OK;
1394 return NT_STATUS_INVALID_PARAMETER;
1397 /*******************************************************************
1399 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1400 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1401 and deals with signing/sealing details.
1402 ********************************************************************/
1404 struct rpc_api_pipe_req_state {
1405 struct event_context *ev;
1406 struct rpc_pipe_client *cli;
1409 DATA_BLOB *req_data;
1410 uint32_t req_data_sent;
1412 DATA_BLOB reply_pdu;
1415 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1416 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1417 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1418 bool *is_last_frag);
1420 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1421 struct event_context *ev,
1422 struct rpc_pipe_client *cli,
1424 DATA_BLOB *req_data)
1426 struct tevent_req *req, *subreq;
1427 struct rpc_api_pipe_req_state *state;
1431 req = tevent_req_create(mem_ctx, &state,
1432 struct rpc_api_pipe_req_state);
1438 state->op_num = op_num;
1439 state->req_data = req_data;
1440 state->req_data_sent = 0;
1441 state->call_id = get_rpc_call_id();
1442 state->reply_pdu = data_blob_null;
1443 state->rpc_out = data_blob_null;
1445 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1446 + RPC_MAX_SIGN_SIZE) {
1447 /* Server is screwed up ! */
1448 status = NT_STATUS_INVALID_PARAMETER;
1452 status = prepare_next_frag(state, &is_last_frag);
1453 if (!NT_STATUS_IS_OK(status)) {
1458 subreq = rpc_api_pipe_send(state, ev, state->cli,
1460 DCERPC_PKT_RESPONSE);
1461 if (subreq == NULL) {
1464 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1466 subreq = rpc_write_send(state, ev, cli->transport,
1467 state->rpc_out.data,
1468 state->rpc_out.length);
1469 if (subreq == NULL) {
1472 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1478 tevent_req_nterror(req, status);
1479 return tevent_req_post(req, ev);
1485 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1488 uint32_t data_sent_thistime;
1495 union dcerpc_payload u;
1497 data_left = state->req_data->length - state->req_data_sent;
1499 status = calculate_data_len_tosend(state->cli, data_left,
1500 &data_sent_thistime,
1501 &frag_len, &auth_len,
1503 if (!NT_STATUS_IS_OK(status)) {
1507 if (state->req_data_sent == 0) {
1508 flags = DCERPC_PFC_FLAG_FIRST;
1511 if (data_sent_thistime == data_left) {
1512 flags |= DCERPC_PFC_FLAG_LAST;
1515 data_blob_free(&state->rpc_out);
1517 ZERO_STRUCT(u.request);
1519 u.request.alloc_hint = state->req_data->length;
1520 u.request.context_id = 0;
1521 u.request.opnum = state->op_num;
1523 status = dcerpc_push_ncacn_packet(state,
1530 if (!NT_STATUS_IS_OK(status)) {
1534 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1535 * compute it right for requests because the auth trailer is missing
1537 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1539 /* Copy in the data. */
1540 if (!data_blob_append(NULL, &state->rpc_out,
1541 state->req_data->data + state->req_data_sent,
1542 data_sent_thistime)) {
1543 return NT_STATUS_NO_MEMORY;
1546 switch (state->cli->auth->auth_level) {
1547 case DCERPC_AUTH_LEVEL_NONE:
1548 case DCERPC_AUTH_LEVEL_CONNECT:
1549 case DCERPC_AUTH_LEVEL_PACKET:
1551 case DCERPC_AUTH_LEVEL_INTEGRITY:
1552 case DCERPC_AUTH_LEVEL_PRIVACY:
1553 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1555 if (!NT_STATUS_IS_OK(status)) {
1560 return NT_STATUS_INVALID_PARAMETER;
1563 state->req_data_sent += data_sent_thistime;
1564 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1569 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1571 struct tevent_req *req = tevent_req_callback_data(
1572 subreq, struct tevent_req);
1573 struct rpc_api_pipe_req_state *state = tevent_req_data(
1574 req, struct rpc_api_pipe_req_state);
1578 status = rpc_write_recv(subreq);
1579 TALLOC_FREE(subreq);
1580 if (!NT_STATUS_IS_OK(status)) {
1581 tevent_req_nterror(req, status);
1585 status = prepare_next_frag(state, &is_last_frag);
1586 if (!NT_STATUS_IS_OK(status)) {
1587 tevent_req_nterror(req, status);
1592 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1594 DCERPC_PKT_RESPONSE);
1595 if (tevent_req_nomem(subreq, req)) {
1598 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1600 subreq = rpc_write_send(state, state->ev,
1601 state->cli->transport,
1602 state->rpc_out.data,
1603 state->rpc_out.length);
1604 if (tevent_req_nomem(subreq, req)) {
1607 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1612 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1614 struct tevent_req *req = tevent_req_callback_data(
1615 subreq, struct tevent_req);
1616 struct rpc_api_pipe_req_state *state = tevent_req_data(
1617 req, struct rpc_api_pipe_req_state);
1620 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1621 TALLOC_FREE(subreq);
1622 if (!NT_STATUS_IS_OK(status)) {
1623 tevent_req_nterror(req, status);
1626 tevent_req_done(req);
1629 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1630 DATA_BLOB *reply_pdu)
1632 struct rpc_api_pipe_req_state *state = tevent_req_data(
1633 req, struct rpc_api_pipe_req_state);
1636 if (tevent_req_is_nterror(req, &status)) {
1638 * We always have to initialize to reply pdu, even if there is
1639 * none. The rpccli_* caller routines expect this.
1641 *reply_pdu = data_blob_null;
1645 /* return data to caller and assign it ownership of memory */
1646 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1647 reply_pdu->length = state->reply_pdu.length;
1648 state->reply_pdu.length = 0;
1650 return NT_STATUS_OK;
1654 /****************************************************************************
1655 Set the handle state.
1656 ****************************************************************************/
1658 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1659 const char *pipe_name, uint16 device_state)
1661 bool state_set = False;
1663 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1664 char *rparam = NULL;
1666 uint32 rparam_len, rdata_len;
1668 if (pipe_name == NULL)
1671 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1672 cli->fnum, pipe_name, device_state));
1674 /* create parameters: device state */
1675 SSVAL(param, 0, device_state);
1677 /* create setup parameters. */
1679 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1681 /* send the data on \PIPE\ */
1682 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1683 setup, 2, 0, /* setup, length, max */
1684 param, 2, 0, /* param, length, max */
1685 NULL, 0, 1024, /* data, length, max */
1686 &rparam, &rparam_len, /* return param, length */
1687 &rdata, &rdata_len)) /* return data, length */
1689 DEBUG(5, ("Set Handle state: return OK\n"));
1700 /****************************************************************************
1701 Check the rpc bind acknowledge response.
1702 ****************************************************************************/
1704 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1705 const struct ndr_syntax_id *transfer)
1707 struct dcerpc_ack_ctx ctx;
1709 if (r->secondary_address_size == 0) {
1710 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1713 if (r->num_results < 1 || !r->ctx_list) {
1717 ctx = r->ctx_list[0];
1719 /* check the transfer syntax */
1720 if ((ctx.syntax.if_version != transfer->if_version) ||
1721 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1722 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1726 if (r->num_results != 0x1 || ctx.result != 0) {
1727 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1728 r->num_results, ctx.reason));
1731 DEBUG(5,("check_bind_response: accepted!\n"));
1735 /*******************************************************************
1736 Creates a DCE/RPC bind authentication response.
1737 This is the packet that is sent back to the server once we
1738 have received a BIND-ACK, to finish the third leg of
1739 the authentication handshake.
1740 ********************************************************************/
1742 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1743 struct rpc_pipe_client *cli,
1745 enum dcerpc_AuthType auth_type,
1746 enum dcerpc_AuthLevel auth_level,
1747 DATA_BLOB *pauth_blob,
1751 union dcerpc_payload u;
1755 status = dcerpc_push_dcerpc_auth(mem_ctx,
1758 0, /* auth_pad_length */
1759 1, /* auth_context_id */
1761 &u.auth3.auth_info);
1762 if (!NT_STATUS_IS_OK(status)) {
1766 status = dcerpc_push_ncacn_packet(mem_ctx,
1768 DCERPC_PFC_FLAG_FIRST |
1769 DCERPC_PFC_FLAG_LAST,
1774 data_blob_free(&u.auth3.auth_info);
1775 if (!NT_STATUS_IS_OK(status)) {
1776 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1780 return NT_STATUS_OK;
1783 /*******************************************************************
1784 Creates a DCE/RPC bind alter context authentication request which
1785 may contain a spnego auth blobl
1786 ********************************************************************/
1788 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1789 enum dcerpc_AuthType auth_type,
1790 enum dcerpc_AuthLevel auth_level,
1792 const struct ndr_syntax_id *abstract,
1793 const struct ndr_syntax_id *transfer,
1794 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1797 DATA_BLOB auth_info;
1800 status = dcerpc_push_dcerpc_auth(mem_ctx,
1803 0, /* auth_pad_length */
1804 1, /* auth_context_id */
1807 if (!NT_STATUS_IS_OK(status)) {
1811 status = create_bind_or_alt_ctx_internal(mem_ctx,
1818 data_blob_free(&auth_info);
1822 /****************************************************************************
1824 ****************************************************************************/
1826 struct rpc_pipe_bind_state {
1827 struct event_context *ev;
1828 struct rpc_pipe_client *cli;
1830 uint32_t rpc_call_id;
1833 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1834 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1835 struct rpc_pipe_bind_state *state,
1836 DATA_BLOB *credentials);
1837 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1838 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1839 struct rpc_pipe_bind_state *state,
1840 DATA_BLOB *credentials);
1841 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1842 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1843 struct rpc_pipe_bind_state *state,
1844 DATA_BLOB *credentials);
1845 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1846 struct rpc_pipe_bind_state *state,
1847 DATA_BLOB *credentials);
1849 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1850 struct event_context *ev,
1851 struct rpc_pipe_client *cli,
1852 struct pipe_auth_data *auth)
1854 struct tevent_req *req, *subreq;
1855 struct rpc_pipe_bind_state *state;
1858 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1863 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1864 rpccli_pipe_txt(talloc_tos(), cli),
1865 (unsigned int)auth->auth_type,
1866 (unsigned int)auth->spnego_type,
1867 (unsigned int)auth->auth_level ));
1871 state->rpc_call_id = get_rpc_call_id();
1872 state->rpc_out = data_blob_null;
1874 cli->auth = talloc_move(cli, &auth);
1876 /* Marshall the outgoing data. */
1877 status = create_rpc_bind_req(state, cli,
1880 &cli->abstract_syntax,
1881 &cli->transfer_syntax,
1884 if (!NT_STATUS_IS_OK(status)) {
1888 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1889 DCERPC_PKT_BIND_ACK);
1890 if (subreq == NULL) {
1893 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1897 tevent_req_nterror(req, status);
1898 return tevent_req_post(req, ev);
1904 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1906 struct tevent_req *req = tevent_req_callback_data(
1907 subreq, struct tevent_req);
1908 struct rpc_pipe_bind_state *state = tevent_req_data(
1909 req, struct rpc_pipe_bind_state);
1910 struct pipe_auth_data *pauth = state->cli->auth;
1911 DATA_BLOB reply_pdu;
1912 struct ncacn_packet *pkt;
1913 struct dcerpc_auth auth;
1914 DATA_BLOB auth_token = data_blob_null;
1917 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1918 TALLOC_FREE(subreq);
1919 if (!NT_STATUS_IS_OK(status)) {
1920 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1921 rpccli_pipe_txt(talloc_tos(), state->cli),
1922 nt_errstr(status)));
1923 tevent_req_nterror(req, status);
1927 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1928 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1929 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1933 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1934 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1936 switch(state->cli->auth->auth_type) {
1938 case DCERPC_AUTH_TYPE_NONE:
1939 case DCERPC_AUTH_TYPE_SCHANNEL:
1940 /* Bind complete. */
1941 tevent_req_done(req);
1944 case DCERPC_AUTH_TYPE_NTLMSSP:
1945 case DCERPC_AUTH_TYPE_SPNEGO:
1946 case DCERPC_AUTH_TYPE_KRB5:
1947 /* Paranoid lenght checks */
1948 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1949 + pkt->auth_length) {
1950 tevent_req_nterror(req,
1951 NT_STATUS_INFO_LENGTH_MISMATCH);
1954 /* get auth credentials */
1955 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1956 &pkt->u.bind_ack.auth_info,
1958 if (!NT_STATUS_IS_OK(status)) {
1959 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1960 nt_errstr(status)));
1961 tevent_req_nterror(req, status);
1971 * For authenticated binds we may need to do 3 or 4 leg binds.
1974 switch(state->cli->auth->auth_type) {
1976 case DCERPC_AUTH_TYPE_NONE:
1977 case DCERPC_AUTH_TYPE_SCHANNEL:
1978 /* Bind complete. */
1979 tevent_req_done(req);
1982 case DCERPC_AUTH_TYPE_NTLMSSP:
1983 /* Need to send AUTH3 packet - no reply. */
1984 status = rpc_finish_auth3_bind_send(req, state,
1988 case DCERPC_AUTH_TYPE_SPNEGO:
1989 switch (pauth->spnego_type) {
1990 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1991 /* Need to send alter context request and reply. */
1992 status = rpc_finish_spnego_ntlmssp_bind_send(req,
1993 state, &auth.credentials);
1996 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1997 status = spnego_get_client_auth_token(state,
1998 pauth->a_u.spnego_state,
2001 if (!NT_STATUS_IS_OK(status)) {
2004 if (auth_token.length == 0) {
2005 /* Bind complete. */
2006 tevent_req_done(req);
2009 if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
2010 status = rpc_bind_next_send(req, state,
2013 status = rpc_bind_finish_send(req, state,
2018 status = NT_STATUS_INTERNAL_ERROR;
2022 case DCERPC_AUTH_TYPE_KRB5:
2023 status = gse_get_client_auth_token(state,
2024 pauth->a_u.gssapi_state,
2027 if (!NT_STATUS_IS_OK(status)) {
2031 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
2032 status = rpc_bind_next_send(req, state, &auth_token);
2034 status = rpc_bind_finish_send(req, state, &auth_token);
2042 if (!NT_STATUS_IS_OK(status)) {
2043 tevent_req_nterror(req, status);
2048 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
2049 (unsigned int)state->cli->auth->auth_type,
2050 (unsigned int)state->cli->auth->spnego_type));
2051 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2054 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2055 struct rpc_pipe_bind_state *state,
2056 DATA_BLOB *credentials)
2058 struct pipe_auth_data *auth = state->cli->auth;
2059 DATA_BLOB client_reply = data_blob_null;
2060 struct tevent_req *subreq;
2063 /* TODO - check auth_type/auth_level match. */
2065 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2066 *credentials, &client_reply);
2068 if (!NT_STATUS_IS_OK(status)) {
2069 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2070 "blob failed: %s.\n", nt_errstr(status)));
2074 data_blob_free(&state->rpc_out);
2076 status = create_rpc_bind_auth3(state, state->cli,
2082 data_blob_free(&client_reply);
2084 if (!NT_STATUS_IS_OK(status)) {
2088 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2089 state->rpc_out.data, state->rpc_out.length);
2090 if (subreq == NULL) {
2091 return NT_STATUS_NO_MEMORY;
2093 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2094 return NT_STATUS_OK;
2097 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2099 struct tevent_req *req = tevent_req_callback_data(
2100 subreq, struct tevent_req);
2103 status = rpc_write_recv(subreq);
2104 TALLOC_FREE(subreq);
2105 if (!NT_STATUS_IS_OK(status)) {
2106 tevent_req_nterror(req, status);
2109 tevent_req_done(req);
2112 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2113 struct rpc_pipe_bind_state *state,
2114 DATA_BLOB *credentials)
2116 struct pipe_auth_data *auth = state->cli->auth;
2117 DATA_BLOB server_ntlm_response = data_blob_null;
2118 DATA_BLOB client_reply = data_blob_null;
2119 DATA_BLOB tmp_blob = data_blob_null;
2120 struct tevent_req *subreq;
2124 * The server might give us back two challenges - tmp_blob is for the
2127 if (!spnego_parse_challenge(state, *credentials,
2128 &server_ntlm_response,
2130 data_blob_free(&server_ntlm_response);
2131 data_blob_free(&tmp_blob);
2132 return NT_STATUS_INVALID_PARAMETER;
2135 /* We're finished with the server spnego response and the tmp_blob. */
2136 data_blob_free(&tmp_blob);
2138 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2139 server_ntlm_response, &client_reply);
2141 /* Finished with the server_ntlm response */
2142 data_blob_free(&server_ntlm_response);
2144 if (!NT_STATUS_IS_OK(status)) {
2145 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2146 "using server blob failed.\n"));
2147 data_blob_free(&client_reply);
2151 /* SPNEGO wrap the client reply. */
2152 tmp_blob = spnego_gen_auth(state, client_reply);
2153 data_blob_free(&client_reply);
2154 client_reply = tmp_blob;
2155 tmp_blob = data_blob_null;
2157 /* Now prepare the alter context pdu. */
2158 data_blob_free(&state->rpc_out);
2160 status = create_rpc_alter_context(state,
2164 &state->cli->abstract_syntax,
2165 &state->cli->transfer_syntax,
2168 data_blob_free(&client_reply);
2170 if (!NT_STATUS_IS_OK(status)) {
2174 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2175 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2176 if (subreq == NULL) {
2177 return NT_STATUS_NO_MEMORY;
2179 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2180 return NT_STATUS_OK;
2183 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2185 struct tevent_req *req = tevent_req_callback_data(
2186 subreq, struct tevent_req);
2187 struct rpc_pipe_bind_state *state = tevent_req_data(
2188 req, struct rpc_pipe_bind_state);
2189 DATA_BLOB tmp_blob = data_blob_null;
2190 struct ncacn_packet *pkt;
2191 struct dcerpc_auth auth;
2194 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2195 TALLOC_FREE(subreq);
2196 if (!NT_STATUS_IS_OK(status)) {
2197 tevent_req_nterror(req, status);
2201 status = dcerpc_pull_dcerpc_auth(pkt,
2202 &pkt->u.alter_resp.auth_info,
2204 if (!NT_STATUS_IS_OK(status)) {
2205 tevent_req_nterror(req, status);
2209 /* Check we got a valid auth response. */
2210 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2212 OID_NTLMSSP, &tmp_blob)) {
2213 data_blob_free(&tmp_blob);
2214 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2218 data_blob_free(&tmp_blob);
2220 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2221 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2222 tevent_req_done(req);
2225 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2226 struct rpc_pipe_bind_state *state,
2227 DATA_BLOB *auth_token)
2229 struct pipe_auth_data *auth = state->cli->auth;
2230 struct tevent_req *subreq;
2233 /* Now prepare the alter context pdu. */
2234 data_blob_free(&state->rpc_out);
2236 status = create_rpc_alter_context(state,
2240 &state->cli->abstract_syntax,
2241 &state->cli->transfer_syntax,
2244 if (!NT_STATUS_IS_OK(status)) {
2248 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2249 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2250 if (subreq == NULL) {
2251 return NT_STATUS_NO_MEMORY;
2253 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2254 return NT_STATUS_OK;
2257 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2258 struct rpc_pipe_bind_state *state,
2259 DATA_BLOB *auth_token)
2261 struct pipe_auth_data *auth = state->cli->auth;
2262 struct tevent_req *subreq;
2265 /* Now prepare the auth3 context pdu. */
2266 data_blob_free(&state->rpc_out);
2268 status = create_rpc_bind_auth3(state, state->cli,
2274 if (!NT_STATUS_IS_OK(status)) {
2278 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2279 state->rpc_out.data, state->rpc_out.length);
2280 if (subreq == NULL) {
2281 return NT_STATUS_NO_MEMORY;
2283 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2284 return NT_STATUS_OK;
2287 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2289 return tevent_req_simple_recv_ntstatus(req);
2292 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2293 struct pipe_auth_data *auth)
2295 TALLOC_CTX *frame = talloc_stackframe();
2296 struct event_context *ev;
2297 struct tevent_req *req;
2298 NTSTATUS status = NT_STATUS_OK;
2300 ev = event_context_init(frame);
2302 status = NT_STATUS_NO_MEMORY;
2306 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2308 status = NT_STATUS_NO_MEMORY;
2312 if (!tevent_req_poll(req, ev)) {
2313 status = map_nt_error_from_unix(errno);
2317 status = rpc_pipe_bind_recv(req);
2323 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2325 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2326 unsigned int timeout)
2330 if (rpc_cli->transport == NULL) {
2331 return RPCCLI_DEFAULT_TIMEOUT;
2334 if (rpc_cli->transport->set_timeout == NULL) {
2335 return RPCCLI_DEFAULT_TIMEOUT;
2338 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2340 return RPCCLI_DEFAULT_TIMEOUT;
2346 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2348 if (rpc_cli == NULL) {
2352 if (rpc_cli->transport == NULL) {
2356 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2359 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2361 struct cli_state *cli;
2363 if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP)
2364 || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO
2365 && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2366 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2370 cli = rpc_pipe_np_smb_conn(rpc_cli);
2374 E_md4hash(cli->password ? cli->password : "", nt_hash);
2378 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2379 struct pipe_auth_data **presult)
2381 struct pipe_auth_data *result;
2383 result = talloc(mem_ctx, struct pipe_auth_data);
2384 if (result == NULL) {
2385 return NT_STATUS_NO_MEMORY;
2388 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2389 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2390 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2392 result->user_name = talloc_strdup(result, "");
2393 result->domain = talloc_strdup(result, "");
2394 if ((result->user_name == NULL) || (result->domain == NULL)) {
2395 TALLOC_FREE(result);
2396 return NT_STATUS_NO_MEMORY;
2400 return NT_STATUS_OK;
2403 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2405 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2409 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2410 enum dcerpc_AuthType auth_type,
2411 enum pipe_auth_type_spnego spnego_type,
2412 enum dcerpc_AuthLevel auth_level,
2414 const char *username,
2415 const char *password,
2416 struct pipe_auth_data **presult)
2418 struct pipe_auth_data *result;
2421 result = talloc(mem_ctx, struct pipe_auth_data);
2422 if (result == NULL) {
2423 return NT_STATUS_NO_MEMORY;
2426 result->auth_type = auth_type;
2427 result->spnego_type = spnego_type;
2428 result->auth_level = auth_level;
2430 result->user_name = talloc_strdup(result, username);
2431 result->domain = talloc_strdup(result, domain);
2432 if ((result->user_name == NULL) || (result->domain == NULL)) {
2433 status = NT_STATUS_NO_MEMORY;
2437 status = auth_ntlmssp_client_start(NULL,
2440 lp_client_ntlmv2_auth(),
2441 &result->a_u.auth_ntlmssp_state);
2442 if (!NT_STATUS_IS_OK(status)) {
2446 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2448 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2450 if (!NT_STATUS_IS_OK(status)) {
2454 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2456 if (!NT_STATUS_IS_OK(status)) {
2460 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2462 if (!NT_STATUS_IS_OK(status)) {
2467 * Turn off sign+seal to allow selected auth level to turn it back on.
2469 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2470 ~(NTLMSSP_NEGOTIATE_SIGN |
2471 NTLMSSP_NEGOTIATE_SEAL));
2473 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2474 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2475 NTLMSSP_NEGOTIATE_SIGN);
2476 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2477 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2478 NTLMSSP_NEGOTIATE_SEAL |
2479 NTLMSSP_NEGOTIATE_SIGN);
2483 return NT_STATUS_OK;
2486 TALLOC_FREE(result);
2490 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2491 enum dcerpc_AuthLevel auth_level,
2492 struct netlogon_creds_CredentialState *creds,
2493 struct pipe_auth_data **presult)
2495 struct pipe_auth_data *result;
2497 result = talloc(mem_ctx, struct pipe_auth_data);
2498 if (result == NULL) {
2499 return NT_STATUS_NO_MEMORY;
2502 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2503 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2504 result->auth_level = auth_level;
2506 result->user_name = talloc_strdup(result, "");
2507 result->domain = talloc_strdup(result, domain);
2508 if ((result->user_name == NULL) || (result->domain == NULL)) {
2512 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2513 if (result->a_u.schannel_auth == NULL) {
2517 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2518 result->a_u.schannel_auth->seq_num = 0;
2519 result->a_u.schannel_auth->initiator = true;
2520 result->a_u.schannel_auth->creds = creds;
2523 return NT_STATUS_OK;
2526 TALLOC_FREE(result);
2527 return NT_STATUS_NO_MEMORY;
2531 * Create an rpc pipe client struct, connecting to a tcp port.
2533 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2535 const struct ndr_syntax_id *abstract_syntax,
2536 struct rpc_pipe_client **presult)
2538 struct rpc_pipe_client *result;
2539 struct sockaddr_storage addr;
2543 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2544 if (result == NULL) {
2545 return NT_STATUS_NO_MEMORY;
2548 result->abstract_syntax = *abstract_syntax;
2549 result->transfer_syntax = ndr_transfer_syntax;
2550 result->dispatch = cli_do_rpc_ndr;
2551 result->dispatch_send = cli_do_rpc_ndr_send;
2552 result->dispatch_recv = cli_do_rpc_ndr_recv;
2554 result->desthost = talloc_strdup(result, host);
2555 result->srv_name_slash = talloc_asprintf_strupper_m(
2556 result, "\\\\%s", result->desthost);
2557 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2558 status = NT_STATUS_NO_MEMORY;
2562 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2563 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2565 if (!resolve_name(host, &addr, 0, false)) {
2566 status = NT_STATUS_NOT_FOUND;
2570 status = open_socket_out(&addr, port, 60, &fd);
2571 if (!NT_STATUS_IS_OK(status)) {
2574 set_socket_options(fd, lp_socket_options());
2576 status = rpc_transport_sock_init(result, fd, &result->transport);
2577 if (!NT_STATUS_IS_OK(status)) {
2582 result->transport->transport = NCACN_IP_TCP;
2585 return NT_STATUS_OK;
2588 TALLOC_FREE(result);
2593 * Determine the tcp port on which a dcerpc interface is listening
2594 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2597 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2598 const struct ndr_syntax_id *abstract_syntax,
2602 struct rpc_pipe_client *epm_pipe = NULL;
2603 struct pipe_auth_data *auth = NULL;
2604 struct dcerpc_binding *map_binding = NULL;
2605 struct dcerpc_binding *res_binding = NULL;
2606 struct epm_twr_t *map_tower = NULL;
2607 struct epm_twr_t *res_towers = NULL;
2608 struct policy_handle *entry_handle = NULL;
2609 uint32_t num_towers = 0;
2610 uint32_t max_towers = 1;
2611 struct epm_twr_p_t towers;
2612 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2614 if (pport == NULL) {
2615 status = NT_STATUS_INVALID_PARAMETER;
2619 /* open the connection to the endpoint mapper */
2620 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2621 &ndr_table_epmapper.syntax_id,
2624 if (!NT_STATUS_IS_OK(status)) {
2628 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2629 if (!NT_STATUS_IS_OK(status)) {
2633 status = rpc_pipe_bind(epm_pipe, auth);
2634 if (!NT_STATUS_IS_OK(status)) {
2638 /* create tower for asking the epmapper */
2640 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2641 if (map_binding == NULL) {
2642 status = NT_STATUS_NO_MEMORY;
2646 map_binding->transport = NCACN_IP_TCP;
2647 map_binding->object = *abstract_syntax;
2648 map_binding->host = host; /* needed? */
2649 map_binding->endpoint = "0"; /* correct? needed? */
2651 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2652 if (map_tower == NULL) {
2653 status = NT_STATUS_NO_MEMORY;
2657 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2658 &(map_tower->tower));
2659 if (!NT_STATUS_IS_OK(status)) {
2663 /* allocate further parameters for the epm_Map call */
2665 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2666 if (res_towers == NULL) {
2667 status = NT_STATUS_NO_MEMORY;
2670 towers.twr = res_towers;
2672 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2673 if (entry_handle == NULL) {
2674 status = NT_STATUS_NO_MEMORY;
2678 /* ask the endpoint mapper for the port */
2680 status = rpccli_epm_Map(epm_pipe,
2682 CONST_DISCARD(struct GUID *,
2683 &(abstract_syntax->uuid)),
2690 if (!NT_STATUS_IS_OK(status)) {
2694 if (num_towers != 1) {
2695 status = NT_STATUS_UNSUCCESSFUL;
2699 /* extract the port from the answer */
2701 status = dcerpc_binding_from_tower(tmp_ctx,
2702 &(towers.twr->tower),
2704 if (!NT_STATUS_IS_OK(status)) {
2708 /* are further checks here necessary? */
2709 if (res_binding->transport != NCACN_IP_TCP) {
2710 status = NT_STATUS_UNSUCCESSFUL;
2714 *pport = (uint16_t)atoi(res_binding->endpoint);
2717 TALLOC_FREE(tmp_ctx);
2722 * Create a rpc pipe client struct, connecting to a host via tcp.
2723 * The port is determined by asking the endpoint mapper on the given
2726 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2727 const struct ndr_syntax_id *abstract_syntax,
2728 struct rpc_pipe_client **presult)
2733 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2734 if (!NT_STATUS_IS_OK(status)) {
2738 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2739 abstract_syntax, presult);
2742 /********************************************************************
2743 Create a rpc pipe client struct, connecting to a unix domain socket
2744 ********************************************************************/
2745 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2746 const struct ndr_syntax_id *abstract_syntax,
2747 struct rpc_pipe_client **presult)
2749 struct rpc_pipe_client *result;
2750 struct sockaddr_un addr;
2754 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2755 if (result == NULL) {
2756 return NT_STATUS_NO_MEMORY;
2759 result->abstract_syntax = *abstract_syntax;
2760 result->transfer_syntax = ndr_transfer_syntax;
2761 result->dispatch = cli_do_rpc_ndr;
2762 result->dispatch_send = cli_do_rpc_ndr_send;
2763 result->dispatch_recv = cli_do_rpc_ndr_recv;
2765 result->desthost = get_myname(result);
2766 result->srv_name_slash = talloc_asprintf_strupper_m(
2767 result, "\\\\%s", result->desthost);
2768 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2769 status = NT_STATUS_NO_MEMORY;
2773 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2774 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2776 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2778 status = map_nt_error_from_unix(errno);
2783 addr.sun_family = AF_UNIX;
2784 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2786 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2787 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2790 return map_nt_error_from_unix(errno);
2793 status = rpc_transport_sock_init(result, fd, &result->transport);
2794 if (!NT_STATUS_IS_OK(status)) {
2799 result->transport->transport = NCALRPC;
2802 return NT_STATUS_OK;
2805 TALLOC_FREE(result);
2809 struct rpc_pipe_client_np_ref {
2810 struct cli_state *cli;
2811 struct rpc_pipe_client *pipe;
2814 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2816 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2820 /****************************************************************************
2821 Open a named pipe over SMB to a remote server.
2823 * CAVEAT CALLER OF THIS FUNCTION:
2824 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2825 * so be sure that this function is called AFTER any structure (vs pointer)
2826 * assignment of the cli. In particular, libsmbclient does structure
2827 * assignments of cli, which invalidates the data in the returned
2828 * rpc_pipe_client if this function is called before the structure assignment
2831 ****************************************************************************/
2833 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2834 const struct ndr_syntax_id *abstract_syntax,
2835 struct rpc_pipe_client **presult)
2837 struct rpc_pipe_client *result;
2839 struct rpc_pipe_client_np_ref *np_ref;
2841 /* sanity check to protect against crashes */
2844 return NT_STATUS_INVALID_HANDLE;
2847 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2848 if (result == NULL) {
2849 return NT_STATUS_NO_MEMORY;
2852 result->abstract_syntax = *abstract_syntax;
2853 result->transfer_syntax = ndr_transfer_syntax;
2854 result->dispatch = cli_do_rpc_ndr;
2855 result->dispatch_send = cli_do_rpc_ndr_send;
2856 result->dispatch_recv = cli_do_rpc_ndr_recv;
2857 result->desthost = talloc_strdup(result, cli->desthost);
2858 result->srv_name_slash = talloc_asprintf_strupper_m(
2859 result, "\\\\%s", result->desthost);
2861 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2862 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2864 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2865 TALLOC_FREE(result);
2866 return NT_STATUS_NO_MEMORY;
2869 status = rpc_transport_np_init(result, cli, abstract_syntax,
2870 &result->transport);
2871 if (!NT_STATUS_IS_OK(status)) {
2872 TALLOC_FREE(result);
2876 result->transport->transport = NCACN_NP;
2878 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2879 if (np_ref == NULL) {
2880 TALLOC_FREE(result);
2881 return NT_STATUS_NO_MEMORY;
2884 np_ref->pipe = result;
2886 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2887 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2890 return NT_STATUS_OK;
2893 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2894 struct rpc_cli_smbd_conn *conn,
2895 const struct ndr_syntax_id *syntax,
2896 struct rpc_pipe_client **presult)
2898 struct rpc_pipe_client *result;
2899 struct pipe_auth_data *auth;
2902 result = talloc(mem_ctx, struct rpc_pipe_client);
2903 if (result == NULL) {
2904 return NT_STATUS_NO_MEMORY;
2906 result->abstract_syntax = *syntax;
2907 result->transfer_syntax = ndr_transfer_syntax;
2908 result->dispatch = cli_do_rpc_ndr;
2909 result->dispatch_send = cli_do_rpc_ndr_send;
2910 result->dispatch_recv = cli_do_rpc_ndr_recv;
2911 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2912 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2914 result->desthost = talloc_strdup(result, global_myname());
2915 result->srv_name_slash = talloc_asprintf_strupper_m(
2916 result, "\\\\%s", global_myname());
2917 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2918 TALLOC_FREE(result);
2919 return NT_STATUS_NO_MEMORY;
2922 status = rpc_transport_smbd_init(result, conn, syntax,
2923 &result->transport);
2924 if (!NT_STATUS_IS_OK(status)) {
2925 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2926 nt_errstr(status)));
2927 TALLOC_FREE(result);
2931 status = rpccli_anon_bind_data(result, &auth);
2932 if (!NT_STATUS_IS_OK(status)) {
2933 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2934 nt_errstr(status)));
2935 TALLOC_FREE(result);
2939 status = rpc_pipe_bind(result, auth);
2940 if (!NT_STATUS_IS_OK(status)) {
2941 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2942 TALLOC_FREE(result);
2946 result->transport->transport = NCACN_INTERNAL;
2949 return NT_STATUS_OK;
2952 /****************************************************************************
2953 Open a pipe to a remote server.
2954 ****************************************************************************/
2956 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2957 enum dcerpc_transport_t transport,
2958 const struct ndr_syntax_id *interface,
2959 struct rpc_pipe_client **presult)
2961 switch (transport) {
2963 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2966 return rpc_pipe_open_np(cli, interface, presult);
2968 return NT_STATUS_NOT_IMPLEMENTED;
2972 /****************************************************************************
2973 Open a named pipe to an SMB server and bind anonymously.
2974 ****************************************************************************/
2976 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2977 enum dcerpc_transport_t transport,
2978 const struct ndr_syntax_id *interface,
2979 struct rpc_pipe_client **presult)
2981 struct rpc_pipe_client *result;
2982 struct pipe_auth_data *auth;
2985 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2986 if (!NT_STATUS_IS_OK(status)) {
2990 status = rpccli_anon_bind_data(result, &auth);
2991 if (!NT_STATUS_IS_OK(status)) {
2992 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2993 nt_errstr(status)));
2994 TALLOC_FREE(result);
2999 * This is a bit of an abstraction violation due to the fact that an
3000 * anonymous bind on an authenticated SMB inherits the user/domain
3001 * from the enclosing SMB creds
3004 TALLOC_FREE(auth->user_name);
3005 TALLOC_FREE(auth->domain);
3007 auth->user_name = talloc_strdup(auth, cli->user_name);
3008 auth->domain = talloc_strdup(auth, cli->domain);
3009 auth->user_session_key = data_blob_talloc(auth,
3010 cli->user_session_key.data,
3011 cli->user_session_key.length);
3013 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3014 TALLOC_FREE(result);
3015 return NT_STATUS_NO_MEMORY;
3018 status = rpc_pipe_bind(result, auth);
3019 if (!NT_STATUS_IS_OK(status)) {
3021 if (ndr_syntax_id_equal(interface,
3022 &ndr_table_dssetup.syntax_id)) {
3023 /* non AD domains just don't have this pipe, avoid
3024 * level 0 statement in that case - gd */
3027 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3028 "%s failed with error %s\n",
3029 get_pipe_name_from_syntax(talloc_tos(), interface),
3030 nt_errstr(status) ));
3031 TALLOC_FREE(result);
3035 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3036 "%s and bound anonymously.\n",
3037 get_pipe_name_from_syntax(talloc_tos(), interface),
3041 return NT_STATUS_OK;
3044 /****************************************************************************
3045 ****************************************************************************/
3047 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3048 const struct ndr_syntax_id *interface,
3049 struct rpc_pipe_client **presult)
3051 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3052 interface, presult);
3055 /****************************************************************************
3056 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3057 ****************************************************************************/
3059 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3060 const struct ndr_syntax_id *interface,
3061 enum dcerpc_transport_t transport,
3063 enum dcerpc_AuthLevel auth_level,
3065 const char *username,
3066 const char *password,
3067 struct rpc_pipe_client **presult)
3069 struct rpc_pipe_client *result;
3070 struct pipe_auth_data *auth;
3071 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
3072 enum pipe_auth_type_spnego spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
3075 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3076 if (!NT_STATUS_IS_OK(status)) {
3081 auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3082 spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
3085 status = rpccli_ntlmssp_bind_data(result,
3086 auth_type, spnego_type, auth_level,
3087 domain, username, password,
3089 if (!NT_STATUS_IS_OK(status)) {
3090 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3091 nt_errstr(status)));
3095 status = rpc_pipe_bind(result, auth);
3096 if (!NT_STATUS_IS_OK(status)) {
3097 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3098 nt_errstr(status) ));
3102 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3103 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3104 get_pipe_name_from_syntax(talloc_tos(), interface),
3105 cli->desthost, domain, username ));
3108 return NT_STATUS_OK;
3112 TALLOC_FREE(result);
3116 /****************************************************************************
3118 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3119 ****************************************************************************/
3121 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3122 const struct ndr_syntax_id *interface,
3123 enum dcerpc_transport_t transport,
3124 enum dcerpc_AuthLevel auth_level,
3126 const char *username,
3127 const char *password,
3128 struct rpc_pipe_client **presult)
3130 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3141 /****************************************************************************
3143 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3144 ****************************************************************************/
3146 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3147 const struct ndr_syntax_id *interface,
3148 enum dcerpc_transport_t transport,
3149 enum dcerpc_AuthLevel auth_level,
3151 const char *username,
3152 const char *password,
3153 struct rpc_pipe_client **presult)
3155 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3166 /****************************************************************************
3167 Get a the schannel session key out of an already opened netlogon pipe.
3168 ****************************************************************************/
3169 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3170 struct cli_state *cli,
3174 enum netr_SchannelType sec_chan_type = 0;
3175 unsigned char machine_pwd[16];
3176 const char *machine_account;
3179 /* Get the machine account credentials from secrets.tdb. */
3180 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3183 DEBUG(0, ("get_schannel_session_key: could not fetch "
3184 "trust account password for domain '%s'\n",
3186 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3189 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3190 cli->desthost, /* server name */
3191 domain, /* domain */
3192 global_myname(), /* client name */
3193 machine_account, /* machine account name */
3198 if (!NT_STATUS_IS_OK(status)) {
3199 DEBUG(3, ("get_schannel_session_key_common: "
3200 "rpccli_netlogon_setup_creds failed with result %s "
3201 "to server %s, domain %s, machine account %s.\n",
3202 nt_errstr(status), cli->desthost, domain,
3207 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3208 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3210 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3213 return NT_STATUS_OK;;
3216 /****************************************************************************
3217 Open a netlogon pipe and get the schannel session key.
3218 Now exposed to external callers.
3219 ****************************************************************************/
3222 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3225 struct rpc_pipe_client **presult)
3227 struct rpc_pipe_client *netlogon_pipe = NULL;
3230 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3232 if (!NT_STATUS_IS_OK(status)) {
3236 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3238 if (!NT_STATUS_IS_OK(status)) {
3239 TALLOC_FREE(netlogon_pipe);
3243 *presult = netlogon_pipe;
3244 return NT_STATUS_OK;
3247 /****************************************************************************
3249 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3250 using session_key. sign and seal.
3252 The *pdc will be stolen onto this new pipe
3253 ****************************************************************************/
3255 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3256 const struct ndr_syntax_id *interface,
3257 enum dcerpc_transport_t transport,
3258 enum dcerpc_AuthLevel auth_level,
3260 struct netlogon_creds_CredentialState **pdc,
3261 struct rpc_pipe_client **presult)
3263 struct rpc_pipe_client *result;
3264 struct pipe_auth_data *auth;
3267 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3268 if (!NT_STATUS_IS_OK(status)) {
3272 status = rpccli_schannel_bind_data(result, domain, auth_level,
3274 if (!NT_STATUS_IS_OK(status)) {
3275 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3276 nt_errstr(status)));
3277 TALLOC_FREE(result);
3281 status = rpc_pipe_bind(result, auth);
3282 if (!NT_STATUS_IS_OK(status)) {
3283 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3284 "cli_rpc_pipe_bind failed with error %s\n",
3285 nt_errstr(status) ));
3286 TALLOC_FREE(result);
3291 * The credentials on a new netlogon pipe are the ones we are passed
3292 * in - reference them in
3294 result->dc = talloc_move(result, pdc);
3296 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3297 "for domain %s and bound using schannel.\n",
3298 get_pipe_name_from_syntax(talloc_tos(), interface),
3299 cli->desthost, domain ));
3302 return NT_STATUS_OK;
3305 /****************************************************************************
3306 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3307 Fetch the session key ourselves using a temporary netlogon pipe. This
3308 version uses an ntlmssp auth bound netlogon pipe to get the key.
3309 ****************************************************************************/
3311 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3313 const char *username,
3314 const char *password,
3316 struct rpc_pipe_client **presult)
3318 struct rpc_pipe_client *netlogon_pipe = NULL;
3321 status = cli_rpc_pipe_open_spnego_ntlmssp(
3322 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3323 DCERPC_AUTH_LEVEL_PRIVACY,
3324 domain, username, password, &netlogon_pipe);
3325 if (!NT_STATUS_IS_OK(status)) {
3329 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3331 if (!NT_STATUS_IS_OK(status)) {
3332 TALLOC_FREE(netlogon_pipe);
3336 *presult = netlogon_pipe;
3337 return NT_STATUS_OK;
3340 /****************************************************************************
3341 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3342 Fetch the session key ourselves using a temporary netlogon pipe. This version
3343 uses an ntlmssp bind to get the session key.
3344 ****************************************************************************/
3346 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3347 const struct ndr_syntax_id *interface,
3348 enum dcerpc_transport_t transport,
3349 enum dcerpc_AuthLevel auth_level,
3351 const char *username,
3352 const char *password,
3353 struct rpc_pipe_client **presult)
3355 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3356 struct rpc_pipe_client *netlogon_pipe = NULL;
3357 struct rpc_pipe_client *result = NULL;
3360 status = get_schannel_session_key_auth_ntlmssp(
3361 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3362 if (!NT_STATUS_IS_OK(status)) {
3363 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3364 "key from server %s for domain %s.\n",
3365 cli->desthost, domain ));
3369 status = cli_rpc_pipe_open_schannel_with_key(
3370 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3373 /* Now we've bound using the session key we can close the netlog pipe. */
3374 TALLOC_FREE(netlogon_pipe);
3376 if (NT_STATUS_IS_OK(status)) {
3382 /****************************************************************************
3383 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3384 Fetch the session key ourselves using a temporary netlogon pipe.
3385 ****************************************************************************/
3387 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3388 const struct ndr_syntax_id *interface,
3389 enum dcerpc_transport_t transport,
3390 enum dcerpc_AuthLevel auth_level,
3392 struct rpc_pipe_client **presult)
3394 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3395 struct rpc_pipe_client *netlogon_pipe = NULL;
3396 struct rpc_pipe_client *result = NULL;
3399 status = get_schannel_session_key(cli, domain, &neg_flags,
3401 if (!NT_STATUS_IS_OK(status)) {
3402 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3403 "key from server %s for domain %s.\n",
3404 cli->desthost, domain ));
3408 status = cli_rpc_pipe_open_schannel_with_key(
3409 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3412 /* Now we've bound using the session key we can close the netlog pipe. */
3413 TALLOC_FREE(netlogon_pipe);
3415 if (NT_STATUS_IS_OK(status)) {
3422 /****************************************************************************
3423 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3424 The idea is this can be called with service_princ, username and password all
3425 NULL so long as the caller has a TGT.
3426 ****************************************************************************/
3428 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3429 const struct ndr_syntax_id *interface,
3430 enum dcerpc_transport_t transport,
3431 enum dcerpc_AuthLevel auth_level,
3433 const char *username,
3434 const char *password,
3435 struct rpc_pipe_client **presult)
3437 struct rpc_pipe_client *result;
3438 struct pipe_auth_data *auth;
3441 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3442 if (!NT_STATUS_IS_OK(status)) {
3446 auth = talloc(result, struct pipe_auth_data);
3448 status = NT_STATUS_NO_MEMORY;
3451 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3452 auth->auth_level = auth_level;
3457 auth->user_name = talloc_strdup(auth, username);
3458 if (!auth->user_name) {
3459 status = NT_STATUS_NO_MEMORY;
3463 /* Fixme, should we fetch/set the Realm ? */
3464 auth->domain = talloc_strdup(auth, "");
3465 if (!auth->domain) {
3466 status = NT_STATUS_NO_MEMORY;
3470 status = gse_init_client(auth, auth->auth_type, auth->auth_level,
3471 NULL, server, "cifs", username, password,
3472 GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3474 if (!NT_STATUS_IS_OK(status)) {
3475 DEBUG(0, ("gse_init_client returned %s\n",
3476 nt_errstr(status)));
3480 status = rpc_pipe_bind(result, auth);
3481 if (!NT_STATUS_IS_OK(status)) {
3482 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3483 nt_errstr(status)));
3488 return NT_STATUS_OK;
3491 TALLOC_FREE(result);
3495 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3496 const struct ndr_syntax_id *interface,
3497 enum dcerpc_transport_t transport,
3498 enum dcerpc_AuthLevel auth_level,
3500 const char *username,
3501 const char *password,
3502 struct rpc_pipe_client **presult)
3504 struct rpc_pipe_client *result;
3505 struct pipe_auth_data *auth;
3508 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3509 if (!NT_STATUS_IS_OK(status)) {
3513 auth = talloc(result, struct pipe_auth_data);
3515 status = NT_STATUS_NO_MEMORY;
3518 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3519 auth->auth_level = auth_level;
3521 auth->spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
3526 auth->user_name = talloc_strdup(auth, username);
3527 if (!auth->user_name) {
3528 status = NT_STATUS_NO_MEMORY;
3532 /* Fixme, should we fetch/set the Realm ? */
3533 auth->domain = talloc_strdup(auth, "");
3534 if (!auth->domain) {
3535 status = NT_STATUS_NO_MEMORY;
3539 status = spnego_gssapi_init_client(auth, auth->auth_level,
3540 NULL, server, "cifs",
3543 &auth->a_u.spnego_state);
3544 if (!NT_STATUS_IS_OK(status)) {
3545 DEBUG(0, ("spnego_init_client returned %s\n",
3546 nt_errstr(status)));
3550 status = rpc_pipe_bind(result, auth);
3551 if (!NT_STATUS_IS_OK(status)) {
3552 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3553 nt_errstr(status)));
3558 return NT_STATUS_OK;
3561 TALLOC_FREE(result);
3565 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3566 struct rpc_pipe_client *cli,
3567 DATA_BLOB *session_key)
3569 struct pipe_auth_data *a = cli->auth;
3572 if (!session_key || !cli) {
3573 return NT_STATUS_INVALID_PARAMETER;
3577 return NT_STATUS_INVALID_PARAMETER;
3580 switch (cli->auth->auth_type) {
3581 case DCERPC_AUTH_TYPE_SCHANNEL:
3582 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3585 case DCERPC_AUTH_TYPE_SPNEGO:
3586 switch (cli->auth->spnego_type) {
3587 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3588 sk = auth_ntlmssp_get_session_key(
3589 a->a_u.auth_ntlmssp_state);
3591 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3592 sk = gse_get_session_key(a->a_u.gssapi_state);
3595 return NT_STATUS_NO_USER_SESSION_KEY;
3598 case DCERPC_AUTH_TYPE_NTLMSSP:
3599 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3601 case DCERPC_AUTH_TYPE_KRB5:
3602 sk = gse_get_session_key(a->a_u.gssapi_state);
3604 case DCERPC_AUTH_TYPE_NONE:
3605 sk = data_blob_const(a->user_session_key.data,
3606 a->user_session_key.length);
3609 return NT_STATUS_NO_USER_SESSION_KEY;
3612 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3613 return NT_STATUS_OK;