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 ret = create_spnego_auth_bind_req(cli, auth, &auth_info);
1251 if (!NT_STATUS_IS_OK(ret)) {
1256 case DCERPC_AUTH_TYPE_KRB5:
1257 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_info);
1258 if (!NT_STATUS_IS_OK(ret)) {
1263 case DCERPC_AUTH_TYPE_NONE:
1267 /* "Can't" happen. */
1268 return NT_STATUS_INVALID_INFO_CLASS;
1271 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1281 /*******************************************************************
1282 Calculate how much data we're going to send in this packet, also
1283 work out any sign/seal padding length.
1284 ********************************************************************/
1286 static NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli,
1288 uint32_t *data_to_send,
1289 uint16_t *p_frag_len,
1290 uint16_t *p_auth_len,
1291 uint32_t *p_ss_padding)
1293 uint32_t data_space, data_len;
1295 struct gse_context *gse_ctx;
1296 enum dcerpc_AuthType auth_type;
1300 switch (cli->auth->auth_level) {
1301 case DCERPC_AUTH_LEVEL_NONE:
1302 case DCERPC_AUTH_LEVEL_CONNECT:
1303 case DCERPC_AUTH_LEVEL_PACKET:
1304 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1305 data_len = MIN(data_space, data_left);
1308 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1309 *data_to_send = data_len;
1310 return NT_STATUS_OK;
1312 case DCERPC_AUTH_LEVEL_INTEGRITY:
1313 case DCERPC_AUTH_LEVEL_PRIVACY:
1314 max_len = cli->max_xmit_frag
1315 - DCERPC_REQUEST_LENGTH
1316 - DCERPC_AUTH_TRAILER_LENGTH;
1318 /* Treat the same for all authenticated rpc requests. */
1319 switch(cli->auth->auth_type) {
1320 case DCERPC_AUTH_TYPE_SPNEGO:
1321 status = spnego_get_negotiated_mech(
1322 cli->auth->a_u.spnego_state,
1323 &auth_type, &auth_ctx);
1324 if (!NT_STATUS_IS_OK(status)) {
1327 switch (auth_type) {
1328 case DCERPC_AUTH_TYPE_NTLMSSP:
1329 *p_auth_len = NTLMSSP_SIG_SIZE;
1331 case DCERPC_AUTH_TYPE_KRB5:
1332 gse_ctx = talloc_get_type(auth_ctx,
1333 struct gse_context);
1335 return NT_STATUS_INVALID_PARAMETER;
1337 *p_auth_len = gse_get_signature_length(gse_ctx,
1338 (cli->auth->auth_level ==
1339 DCERPC_AUTH_LEVEL_PRIVACY),
1343 return NT_STATUS_INVALID_PARAMETER;
1346 case DCERPC_AUTH_TYPE_NTLMSSP:
1347 *p_auth_len = NTLMSSP_SIG_SIZE;
1349 case DCERPC_AUTH_TYPE_SCHANNEL:
1350 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1352 case DCERPC_AUTH_TYPE_KRB5:
1353 *p_auth_len = gse_get_signature_length(
1354 cli->auth->a_u.gssapi_state,
1355 (cli->auth->auth_level ==
1356 DCERPC_AUTH_LEVEL_PRIVACY),
1360 return NT_STATUS_INVALID_PARAMETER;
1363 data_space = max_len - *p_auth_len;
1365 data_len = MIN(data_space, data_left);
1367 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1368 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1370 *p_frag_len = DCERPC_REQUEST_LENGTH
1371 + data_len + *p_ss_padding
1372 + DCERPC_AUTH_TRAILER_LENGTH
1374 *data_to_send = data_len;
1375 return NT_STATUS_OK;
1381 return NT_STATUS_INVALID_PARAMETER;
1384 /*******************************************************************
1386 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1387 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1388 and deals with signing/sealing details.
1389 ********************************************************************/
1391 struct rpc_api_pipe_req_state {
1392 struct event_context *ev;
1393 struct rpc_pipe_client *cli;
1396 DATA_BLOB *req_data;
1397 uint32_t req_data_sent;
1399 DATA_BLOB reply_pdu;
1402 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1403 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1404 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1405 bool *is_last_frag);
1407 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1408 struct event_context *ev,
1409 struct rpc_pipe_client *cli,
1411 DATA_BLOB *req_data)
1413 struct tevent_req *req, *subreq;
1414 struct rpc_api_pipe_req_state *state;
1418 req = tevent_req_create(mem_ctx, &state,
1419 struct rpc_api_pipe_req_state);
1425 state->op_num = op_num;
1426 state->req_data = req_data;
1427 state->req_data_sent = 0;
1428 state->call_id = get_rpc_call_id();
1429 state->reply_pdu = data_blob_null;
1430 state->rpc_out = data_blob_null;
1432 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1433 + RPC_MAX_SIGN_SIZE) {
1434 /* Server is screwed up ! */
1435 status = NT_STATUS_INVALID_PARAMETER;
1439 status = prepare_next_frag(state, &is_last_frag);
1440 if (!NT_STATUS_IS_OK(status)) {
1445 subreq = rpc_api_pipe_send(state, ev, state->cli,
1447 DCERPC_PKT_RESPONSE);
1448 if (subreq == NULL) {
1451 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1453 subreq = rpc_write_send(state, ev, cli->transport,
1454 state->rpc_out.data,
1455 state->rpc_out.length);
1456 if (subreq == NULL) {
1459 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1465 tevent_req_nterror(req, status);
1466 return tevent_req_post(req, ev);
1472 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1475 uint32_t data_sent_thistime;
1482 union dcerpc_payload u;
1484 data_left = state->req_data->length - state->req_data_sent;
1486 status = calculate_data_len_tosend(state->cli, data_left,
1487 &data_sent_thistime,
1488 &frag_len, &auth_len,
1490 if (!NT_STATUS_IS_OK(status)) {
1494 if (state->req_data_sent == 0) {
1495 flags = DCERPC_PFC_FLAG_FIRST;
1498 if (data_sent_thistime == data_left) {
1499 flags |= DCERPC_PFC_FLAG_LAST;
1502 data_blob_free(&state->rpc_out);
1504 ZERO_STRUCT(u.request);
1506 u.request.alloc_hint = state->req_data->length;
1507 u.request.context_id = 0;
1508 u.request.opnum = state->op_num;
1510 status = dcerpc_push_ncacn_packet(state,
1517 if (!NT_STATUS_IS_OK(status)) {
1521 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1522 * compute it right for requests because the auth trailer is missing
1524 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1526 /* Copy in the data. */
1527 if (!data_blob_append(NULL, &state->rpc_out,
1528 state->req_data->data + state->req_data_sent,
1529 data_sent_thistime)) {
1530 return NT_STATUS_NO_MEMORY;
1533 switch (state->cli->auth->auth_level) {
1534 case DCERPC_AUTH_LEVEL_NONE:
1535 case DCERPC_AUTH_LEVEL_CONNECT:
1536 case DCERPC_AUTH_LEVEL_PACKET:
1538 case DCERPC_AUTH_LEVEL_INTEGRITY:
1539 case DCERPC_AUTH_LEVEL_PRIVACY:
1540 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1542 if (!NT_STATUS_IS_OK(status)) {
1547 return NT_STATUS_INVALID_PARAMETER;
1550 state->req_data_sent += data_sent_thistime;
1551 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1556 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1558 struct tevent_req *req = tevent_req_callback_data(
1559 subreq, struct tevent_req);
1560 struct rpc_api_pipe_req_state *state = tevent_req_data(
1561 req, struct rpc_api_pipe_req_state);
1565 status = rpc_write_recv(subreq);
1566 TALLOC_FREE(subreq);
1567 if (!NT_STATUS_IS_OK(status)) {
1568 tevent_req_nterror(req, status);
1572 status = prepare_next_frag(state, &is_last_frag);
1573 if (!NT_STATUS_IS_OK(status)) {
1574 tevent_req_nterror(req, status);
1579 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1581 DCERPC_PKT_RESPONSE);
1582 if (tevent_req_nomem(subreq, req)) {
1585 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1587 subreq = rpc_write_send(state, state->ev,
1588 state->cli->transport,
1589 state->rpc_out.data,
1590 state->rpc_out.length);
1591 if (tevent_req_nomem(subreq, req)) {
1594 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1599 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1601 struct tevent_req *req = tevent_req_callback_data(
1602 subreq, struct tevent_req);
1603 struct rpc_api_pipe_req_state *state = tevent_req_data(
1604 req, struct rpc_api_pipe_req_state);
1607 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1608 TALLOC_FREE(subreq);
1609 if (!NT_STATUS_IS_OK(status)) {
1610 tevent_req_nterror(req, status);
1613 tevent_req_done(req);
1616 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1617 DATA_BLOB *reply_pdu)
1619 struct rpc_api_pipe_req_state *state = tevent_req_data(
1620 req, struct rpc_api_pipe_req_state);
1623 if (tevent_req_is_nterror(req, &status)) {
1625 * We always have to initialize to reply pdu, even if there is
1626 * none. The rpccli_* caller routines expect this.
1628 *reply_pdu = data_blob_null;
1632 /* return data to caller and assign it ownership of memory */
1633 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1634 reply_pdu->length = state->reply_pdu.length;
1635 state->reply_pdu.length = 0;
1637 return NT_STATUS_OK;
1641 /****************************************************************************
1642 Set the handle state.
1643 ****************************************************************************/
1645 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1646 const char *pipe_name, uint16 device_state)
1648 bool state_set = False;
1650 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1651 char *rparam = NULL;
1653 uint32 rparam_len, rdata_len;
1655 if (pipe_name == NULL)
1658 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1659 cli->fnum, pipe_name, device_state));
1661 /* create parameters: device state */
1662 SSVAL(param, 0, device_state);
1664 /* create setup parameters. */
1666 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1668 /* send the data on \PIPE\ */
1669 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1670 setup, 2, 0, /* setup, length, max */
1671 param, 2, 0, /* param, length, max */
1672 NULL, 0, 1024, /* data, length, max */
1673 &rparam, &rparam_len, /* return param, length */
1674 &rdata, &rdata_len)) /* return data, length */
1676 DEBUG(5, ("Set Handle state: return OK\n"));
1687 /****************************************************************************
1688 Check the rpc bind acknowledge response.
1689 ****************************************************************************/
1691 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1692 const struct ndr_syntax_id *transfer)
1694 struct dcerpc_ack_ctx ctx;
1696 if (r->secondary_address_size == 0) {
1697 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1700 if (r->num_results < 1 || !r->ctx_list) {
1704 ctx = r->ctx_list[0];
1706 /* check the transfer syntax */
1707 if ((ctx.syntax.if_version != transfer->if_version) ||
1708 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1709 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1713 if (r->num_results != 0x1 || ctx.result != 0) {
1714 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1715 r->num_results, ctx.reason));
1718 DEBUG(5,("check_bind_response: accepted!\n"));
1722 /*******************************************************************
1723 Creates a DCE/RPC bind authentication response.
1724 This is the packet that is sent back to the server once we
1725 have received a BIND-ACK, to finish the third leg of
1726 the authentication handshake.
1727 ********************************************************************/
1729 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1730 struct rpc_pipe_client *cli,
1732 enum dcerpc_AuthType auth_type,
1733 enum dcerpc_AuthLevel auth_level,
1734 DATA_BLOB *pauth_blob,
1738 union dcerpc_payload u;
1742 status = dcerpc_push_dcerpc_auth(mem_ctx,
1745 0, /* auth_pad_length */
1746 1, /* auth_context_id */
1748 &u.auth3.auth_info);
1749 if (!NT_STATUS_IS_OK(status)) {
1753 status = dcerpc_push_ncacn_packet(mem_ctx,
1755 DCERPC_PFC_FLAG_FIRST |
1756 DCERPC_PFC_FLAG_LAST,
1761 data_blob_free(&u.auth3.auth_info);
1762 if (!NT_STATUS_IS_OK(status)) {
1763 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1767 return NT_STATUS_OK;
1770 /*******************************************************************
1771 Creates a DCE/RPC bind alter context authentication request which
1772 may contain a spnego auth blobl
1773 ********************************************************************/
1775 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1776 enum dcerpc_AuthType auth_type,
1777 enum dcerpc_AuthLevel auth_level,
1779 const struct ndr_syntax_id *abstract,
1780 const struct ndr_syntax_id *transfer,
1781 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1784 DATA_BLOB auth_info;
1787 status = dcerpc_push_dcerpc_auth(mem_ctx,
1790 0, /* auth_pad_length */
1791 1, /* auth_context_id */
1794 if (!NT_STATUS_IS_OK(status)) {
1798 status = create_bind_or_alt_ctx_internal(mem_ctx,
1805 data_blob_free(&auth_info);
1809 /****************************************************************************
1811 ****************************************************************************/
1813 struct rpc_pipe_bind_state {
1814 struct event_context *ev;
1815 struct rpc_pipe_client *cli;
1817 uint32_t rpc_call_id;
1820 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1821 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1822 struct rpc_pipe_bind_state *state,
1823 DATA_BLOB *credentials);
1824 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1825 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1826 struct rpc_pipe_bind_state *state,
1827 DATA_BLOB *credentials);
1828 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1829 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1830 struct rpc_pipe_bind_state *state,
1831 DATA_BLOB *credentials);
1832 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1833 struct rpc_pipe_bind_state *state,
1834 DATA_BLOB *credentials);
1836 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1837 struct event_context *ev,
1838 struct rpc_pipe_client *cli,
1839 struct pipe_auth_data *auth)
1841 struct tevent_req *req, *subreq;
1842 struct rpc_pipe_bind_state *state;
1845 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1850 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1851 rpccli_pipe_txt(talloc_tos(), cli),
1852 (unsigned int)auth->auth_type,
1853 (unsigned int)auth->spnego_type,
1854 (unsigned int)auth->auth_level ));
1858 state->rpc_call_id = get_rpc_call_id();
1859 state->rpc_out = data_blob_null;
1861 cli->auth = talloc_move(cli, &auth);
1863 /* Marshall the outgoing data. */
1864 status = create_rpc_bind_req(state, cli,
1867 &cli->abstract_syntax,
1868 &cli->transfer_syntax,
1871 if (!NT_STATUS_IS_OK(status)) {
1875 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1876 DCERPC_PKT_BIND_ACK);
1877 if (subreq == NULL) {
1880 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1884 tevent_req_nterror(req, status);
1885 return tevent_req_post(req, ev);
1891 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1893 struct tevent_req *req = tevent_req_callback_data(
1894 subreq, struct tevent_req);
1895 struct rpc_pipe_bind_state *state = tevent_req_data(
1896 req, struct rpc_pipe_bind_state);
1897 struct pipe_auth_data *pauth = state->cli->auth;
1898 DATA_BLOB reply_pdu;
1899 struct ncacn_packet *pkt;
1900 struct dcerpc_auth auth;
1901 DATA_BLOB auth_token = data_blob_null;
1904 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1905 TALLOC_FREE(subreq);
1906 if (!NT_STATUS_IS_OK(status)) {
1907 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1908 rpccli_pipe_txt(talloc_tos(), state->cli),
1909 nt_errstr(status)));
1910 tevent_req_nterror(req, status);
1914 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1915 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1916 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1920 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1921 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1923 switch(state->cli->auth->auth_type) {
1925 case DCERPC_AUTH_TYPE_NONE:
1926 case DCERPC_AUTH_TYPE_SCHANNEL:
1927 /* Bind complete. */
1928 tevent_req_done(req);
1931 case DCERPC_AUTH_TYPE_NTLMSSP:
1932 case DCERPC_AUTH_TYPE_SPNEGO:
1933 case DCERPC_AUTH_TYPE_KRB5:
1934 /* Paranoid lenght checks */
1935 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1936 + pkt->auth_length) {
1937 tevent_req_nterror(req,
1938 NT_STATUS_INFO_LENGTH_MISMATCH);
1941 /* get auth credentials */
1942 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1943 &pkt->u.bind_ack.auth_info,
1945 if (!NT_STATUS_IS_OK(status)) {
1946 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1947 nt_errstr(status)));
1948 tevent_req_nterror(req, status);
1958 * For authenticated binds we may need to do 3 or 4 leg binds.
1961 switch(state->cli->auth->auth_type) {
1963 case DCERPC_AUTH_TYPE_NONE:
1964 case DCERPC_AUTH_TYPE_SCHANNEL:
1965 /* Bind complete. */
1966 tevent_req_done(req);
1969 case DCERPC_AUTH_TYPE_NTLMSSP:
1970 /* Need to send AUTH3 packet - no reply. */
1971 status = rpc_finish_auth3_bind_send(req, state,
1975 case DCERPC_AUTH_TYPE_SPNEGO:
1976 status = spnego_get_client_auth_token(state,
1977 pauth->a_u.spnego_state,
1980 if (!NT_STATUS_IS_OK(status)) {
1983 if (auth_token.length == 0) {
1984 /* Bind complete. */
1985 tevent_req_done(req);
1988 if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
1989 status = rpc_bind_next_send(req, state,
1992 status = rpc_bind_finish_send(req, state,
1997 case DCERPC_AUTH_TYPE_KRB5:
1998 status = gse_get_client_auth_token(state,
1999 pauth->a_u.gssapi_state,
2002 if (!NT_STATUS_IS_OK(status)) {
2006 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
2007 status = rpc_bind_next_send(req, state, &auth_token);
2009 status = rpc_bind_finish_send(req, state, &auth_token);
2017 if (!NT_STATUS_IS_OK(status)) {
2018 tevent_req_nterror(req, status);
2023 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
2024 (unsigned int)state->cli->auth->auth_type,
2025 (unsigned int)state->cli->auth->spnego_type));
2026 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2029 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2030 struct rpc_pipe_bind_state *state,
2031 DATA_BLOB *credentials)
2033 struct pipe_auth_data *auth = state->cli->auth;
2034 DATA_BLOB client_reply = data_blob_null;
2035 struct tevent_req *subreq;
2038 /* TODO - check auth_type/auth_level match. */
2040 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2041 *credentials, &client_reply);
2043 if (!NT_STATUS_IS_OK(status)) {
2044 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2045 "blob failed: %s.\n", nt_errstr(status)));
2049 data_blob_free(&state->rpc_out);
2051 status = create_rpc_bind_auth3(state, state->cli,
2057 data_blob_free(&client_reply);
2059 if (!NT_STATUS_IS_OK(status)) {
2063 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2064 state->rpc_out.data, state->rpc_out.length);
2065 if (subreq == NULL) {
2066 return NT_STATUS_NO_MEMORY;
2068 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2069 return NT_STATUS_OK;
2072 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2074 struct tevent_req *req = tevent_req_callback_data(
2075 subreq, struct tevent_req);
2078 status = rpc_write_recv(subreq);
2079 TALLOC_FREE(subreq);
2080 if (!NT_STATUS_IS_OK(status)) {
2081 tevent_req_nterror(req, status);
2084 tevent_req_done(req);
2087 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2088 struct rpc_pipe_bind_state *state,
2089 DATA_BLOB *credentials)
2091 struct pipe_auth_data *auth = state->cli->auth;
2092 DATA_BLOB server_ntlm_response = data_blob_null;
2093 DATA_BLOB client_reply = data_blob_null;
2094 DATA_BLOB tmp_blob = data_blob_null;
2095 struct tevent_req *subreq;
2099 * The server might give us back two challenges - tmp_blob is for the
2102 if (!spnego_parse_challenge(state, *credentials,
2103 &server_ntlm_response,
2105 data_blob_free(&server_ntlm_response);
2106 data_blob_free(&tmp_blob);
2107 return NT_STATUS_INVALID_PARAMETER;
2110 /* We're finished with the server spnego response and the tmp_blob. */
2111 data_blob_free(&tmp_blob);
2113 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2114 server_ntlm_response, &client_reply);
2116 /* Finished with the server_ntlm response */
2117 data_blob_free(&server_ntlm_response);
2119 if (!NT_STATUS_IS_OK(status)) {
2120 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2121 "using server blob failed.\n"));
2122 data_blob_free(&client_reply);
2126 /* SPNEGO wrap the client reply. */
2127 tmp_blob = spnego_gen_auth(state, client_reply);
2128 data_blob_free(&client_reply);
2129 client_reply = tmp_blob;
2130 tmp_blob = data_blob_null;
2132 /* Now prepare the alter context pdu. */
2133 data_blob_free(&state->rpc_out);
2135 status = create_rpc_alter_context(state,
2139 &state->cli->abstract_syntax,
2140 &state->cli->transfer_syntax,
2143 data_blob_free(&client_reply);
2145 if (!NT_STATUS_IS_OK(status)) {
2149 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2150 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2151 if (subreq == NULL) {
2152 return NT_STATUS_NO_MEMORY;
2154 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2155 return NT_STATUS_OK;
2158 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2160 struct tevent_req *req = tevent_req_callback_data(
2161 subreq, struct tevent_req);
2162 struct rpc_pipe_bind_state *state = tevent_req_data(
2163 req, struct rpc_pipe_bind_state);
2164 DATA_BLOB tmp_blob = data_blob_null;
2165 struct ncacn_packet *pkt;
2166 struct dcerpc_auth auth;
2169 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2170 TALLOC_FREE(subreq);
2171 if (!NT_STATUS_IS_OK(status)) {
2172 tevent_req_nterror(req, status);
2176 status = dcerpc_pull_dcerpc_auth(pkt,
2177 &pkt->u.alter_resp.auth_info,
2179 if (!NT_STATUS_IS_OK(status)) {
2180 tevent_req_nterror(req, status);
2184 /* Check we got a valid auth response. */
2185 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2187 OID_NTLMSSP, &tmp_blob)) {
2188 data_blob_free(&tmp_blob);
2189 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2193 data_blob_free(&tmp_blob);
2195 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2196 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2197 tevent_req_done(req);
2200 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2201 struct rpc_pipe_bind_state *state,
2202 DATA_BLOB *auth_token)
2204 struct pipe_auth_data *auth = state->cli->auth;
2205 struct tevent_req *subreq;
2208 /* Now prepare the alter context pdu. */
2209 data_blob_free(&state->rpc_out);
2211 status = create_rpc_alter_context(state,
2215 &state->cli->abstract_syntax,
2216 &state->cli->transfer_syntax,
2219 if (!NT_STATUS_IS_OK(status)) {
2223 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2224 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2225 if (subreq == NULL) {
2226 return NT_STATUS_NO_MEMORY;
2228 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2229 return NT_STATUS_OK;
2232 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2233 struct rpc_pipe_bind_state *state,
2234 DATA_BLOB *auth_token)
2236 struct pipe_auth_data *auth = state->cli->auth;
2237 struct tevent_req *subreq;
2240 /* Now prepare the auth3 context pdu. */
2241 data_blob_free(&state->rpc_out);
2243 status = create_rpc_bind_auth3(state, state->cli,
2249 if (!NT_STATUS_IS_OK(status)) {
2253 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2254 state->rpc_out.data, state->rpc_out.length);
2255 if (subreq == NULL) {
2256 return NT_STATUS_NO_MEMORY;
2258 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2259 return NT_STATUS_OK;
2262 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2264 return tevent_req_simple_recv_ntstatus(req);
2267 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2268 struct pipe_auth_data *auth)
2270 TALLOC_CTX *frame = talloc_stackframe();
2271 struct event_context *ev;
2272 struct tevent_req *req;
2273 NTSTATUS status = NT_STATUS_OK;
2275 ev = event_context_init(frame);
2277 status = NT_STATUS_NO_MEMORY;
2281 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2283 status = NT_STATUS_NO_MEMORY;
2287 if (!tevent_req_poll(req, ev)) {
2288 status = map_nt_error_from_unix(errno);
2292 status = rpc_pipe_bind_recv(req);
2298 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2300 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2301 unsigned int timeout)
2305 if (rpc_cli->transport == NULL) {
2306 return RPCCLI_DEFAULT_TIMEOUT;
2309 if (rpc_cli->transport->set_timeout == NULL) {
2310 return RPCCLI_DEFAULT_TIMEOUT;
2313 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2315 return RPCCLI_DEFAULT_TIMEOUT;
2321 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2323 if (rpc_cli == NULL) {
2327 if (rpc_cli->transport == NULL) {
2331 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2334 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2336 struct auth_ntlmssp_state *a = NULL;
2337 struct cli_state *cli;
2339 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2340 a = rpc_cli->auth->a_u.auth_ntlmssp_state;
2341 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2342 enum dcerpc_AuthType auth_type;
2346 status = spnego_get_negotiated_mech(
2347 rpc_cli->auth->a_u.spnego_state,
2348 &auth_type, &auth_ctx);
2349 if (!NT_STATUS_IS_OK(status)) {
2353 if (auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2354 a = talloc_get_type(auth_ctx,
2355 struct auth_ntlmssp_state);
2360 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2364 cli = rpc_pipe_np_smb_conn(rpc_cli);
2368 E_md4hash(cli->password ? cli->password : "", nt_hash);
2372 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2373 struct pipe_auth_data **presult)
2375 struct pipe_auth_data *result;
2377 result = talloc(mem_ctx, struct pipe_auth_data);
2378 if (result == NULL) {
2379 return NT_STATUS_NO_MEMORY;
2382 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2383 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2384 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2386 result->user_name = talloc_strdup(result, "");
2387 result->domain = talloc_strdup(result, "");
2388 if ((result->user_name == NULL) || (result->domain == NULL)) {
2389 TALLOC_FREE(result);
2390 return NT_STATUS_NO_MEMORY;
2394 return NT_STATUS_OK;
2397 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2399 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2403 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2404 enum dcerpc_AuthType auth_type,
2405 enum dcerpc_AuthLevel auth_level,
2407 const char *username,
2408 const char *password,
2409 struct pipe_auth_data **presult)
2411 struct pipe_auth_data *result;
2414 result = talloc(mem_ctx, struct pipe_auth_data);
2415 if (result == NULL) {
2416 return NT_STATUS_NO_MEMORY;
2419 result->auth_type = auth_type;
2420 result->auth_level = auth_level;
2422 result->user_name = talloc_strdup(result, username);
2423 result->domain = talloc_strdup(result, domain);
2424 if ((result->user_name == NULL) || (result->domain == NULL)) {
2425 status = NT_STATUS_NO_MEMORY;
2429 status = auth_ntlmssp_client_start(NULL,
2432 lp_client_ntlmv2_auth(),
2433 &result->a_u.auth_ntlmssp_state);
2434 if (!NT_STATUS_IS_OK(status)) {
2438 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2440 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2442 if (!NT_STATUS_IS_OK(status)) {
2446 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2448 if (!NT_STATUS_IS_OK(status)) {
2452 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2454 if (!NT_STATUS_IS_OK(status)) {
2459 * Turn off sign+seal to allow selected auth level to turn it back on.
2461 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2462 ~(NTLMSSP_NEGOTIATE_SIGN |
2463 NTLMSSP_NEGOTIATE_SEAL));
2465 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2466 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2467 NTLMSSP_NEGOTIATE_SIGN);
2468 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2469 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2470 NTLMSSP_NEGOTIATE_SEAL |
2471 NTLMSSP_NEGOTIATE_SIGN);
2475 return NT_STATUS_OK;
2478 TALLOC_FREE(result);
2482 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2483 enum dcerpc_AuthLevel auth_level,
2484 struct netlogon_creds_CredentialState *creds,
2485 struct pipe_auth_data **presult)
2487 struct pipe_auth_data *result;
2489 result = talloc(mem_ctx, struct pipe_auth_data);
2490 if (result == NULL) {
2491 return NT_STATUS_NO_MEMORY;
2494 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2495 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2496 result->auth_level = auth_level;
2498 result->user_name = talloc_strdup(result, "");
2499 result->domain = talloc_strdup(result, domain);
2500 if ((result->user_name == NULL) || (result->domain == NULL)) {
2504 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2505 if (result->a_u.schannel_auth == NULL) {
2509 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2510 result->a_u.schannel_auth->seq_num = 0;
2511 result->a_u.schannel_auth->initiator = true;
2512 result->a_u.schannel_auth->creds = creds;
2515 return NT_STATUS_OK;
2518 TALLOC_FREE(result);
2519 return NT_STATUS_NO_MEMORY;
2523 * Create an rpc pipe client struct, connecting to a tcp port.
2525 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2527 const struct ndr_syntax_id *abstract_syntax,
2528 struct rpc_pipe_client **presult)
2530 struct rpc_pipe_client *result;
2531 struct sockaddr_storage addr;
2535 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2536 if (result == NULL) {
2537 return NT_STATUS_NO_MEMORY;
2540 result->abstract_syntax = *abstract_syntax;
2541 result->transfer_syntax = ndr_transfer_syntax;
2542 result->dispatch = cli_do_rpc_ndr;
2543 result->dispatch_send = cli_do_rpc_ndr_send;
2544 result->dispatch_recv = cli_do_rpc_ndr_recv;
2546 result->desthost = talloc_strdup(result, host);
2547 result->srv_name_slash = talloc_asprintf_strupper_m(
2548 result, "\\\\%s", result->desthost);
2549 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2550 status = NT_STATUS_NO_MEMORY;
2554 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2555 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2557 if (!resolve_name(host, &addr, 0, false)) {
2558 status = NT_STATUS_NOT_FOUND;
2562 status = open_socket_out(&addr, port, 60, &fd);
2563 if (!NT_STATUS_IS_OK(status)) {
2566 set_socket_options(fd, lp_socket_options());
2568 status = rpc_transport_sock_init(result, fd, &result->transport);
2569 if (!NT_STATUS_IS_OK(status)) {
2574 result->transport->transport = NCACN_IP_TCP;
2577 return NT_STATUS_OK;
2580 TALLOC_FREE(result);
2585 * Determine the tcp port on which a dcerpc interface is listening
2586 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2589 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2590 const struct ndr_syntax_id *abstract_syntax,
2594 struct rpc_pipe_client *epm_pipe = NULL;
2595 struct pipe_auth_data *auth = NULL;
2596 struct dcerpc_binding *map_binding = NULL;
2597 struct dcerpc_binding *res_binding = NULL;
2598 struct epm_twr_t *map_tower = NULL;
2599 struct epm_twr_t *res_towers = NULL;
2600 struct policy_handle *entry_handle = NULL;
2601 uint32_t num_towers = 0;
2602 uint32_t max_towers = 1;
2603 struct epm_twr_p_t towers;
2604 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2606 if (pport == NULL) {
2607 status = NT_STATUS_INVALID_PARAMETER;
2611 /* open the connection to the endpoint mapper */
2612 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2613 &ndr_table_epmapper.syntax_id,
2616 if (!NT_STATUS_IS_OK(status)) {
2620 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2621 if (!NT_STATUS_IS_OK(status)) {
2625 status = rpc_pipe_bind(epm_pipe, auth);
2626 if (!NT_STATUS_IS_OK(status)) {
2630 /* create tower for asking the epmapper */
2632 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2633 if (map_binding == NULL) {
2634 status = NT_STATUS_NO_MEMORY;
2638 map_binding->transport = NCACN_IP_TCP;
2639 map_binding->object = *abstract_syntax;
2640 map_binding->host = host; /* needed? */
2641 map_binding->endpoint = "0"; /* correct? needed? */
2643 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2644 if (map_tower == NULL) {
2645 status = NT_STATUS_NO_MEMORY;
2649 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2650 &(map_tower->tower));
2651 if (!NT_STATUS_IS_OK(status)) {
2655 /* allocate further parameters for the epm_Map call */
2657 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2658 if (res_towers == NULL) {
2659 status = NT_STATUS_NO_MEMORY;
2662 towers.twr = res_towers;
2664 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2665 if (entry_handle == NULL) {
2666 status = NT_STATUS_NO_MEMORY;
2670 /* ask the endpoint mapper for the port */
2672 status = rpccli_epm_Map(epm_pipe,
2674 CONST_DISCARD(struct GUID *,
2675 &(abstract_syntax->uuid)),
2682 if (!NT_STATUS_IS_OK(status)) {
2686 if (num_towers != 1) {
2687 status = NT_STATUS_UNSUCCESSFUL;
2691 /* extract the port from the answer */
2693 status = dcerpc_binding_from_tower(tmp_ctx,
2694 &(towers.twr->tower),
2696 if (!NT_STATUS_IS_OK(status)) {
2700 /* are further checks here necessary? */
2701 if (res_binding->transport != NCACN_IP_TCP) {
2702 status = NT_STATUS_UNSUCCESSFUL;
2706 *pport = (uint16_t)atoi(res_binding->endpoint);
2709 TALLOC_FREE(tmp_ctx);
2714 * Create a rpc pipe client struct, connecting to a host via tcp.
2715 * The port is determined by asking the endpoint mapper on the given
2718 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2719 const struct ndr_syntax_id *abstract_syntax,
2720 struct rpc_pipe_client **presult)
2725 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2726 if (!NT_STATUS_IS_OK(status)) {
2730 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2731 abstract_syntax, presult);
2734 /********************************************************************
2735 Create a rpc pipe client struct, connecting to a unix domain socket
2736 ********************************************************************/
2737 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2738 const struct ndr_syntax_id *abstract_syntax,
2739 struct rpc_pipe_client **presult)
2741 struct rpc_pipe_client *result;
2742 struct sockaddr_un addr;
2746 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2747 if (result == NULL) {
2748 return NT_STATUS_NO_MEMORY;
2751 result->abstract_syntax = *abstract_syntax;
2752 result->transfer_syntax = ndr_transfer_syntax;
2753 result->dispatch = cli_do_rpc_ndr;
2754 result->dispatch_send = cli_do_rpc_ndr_send;
2755 result->dispatch_recv = cli_do_rpc_ndr_recv;
2757 result->desthost = get_myname(result);
2758 result->srv_name_slash = talloc_asprintf_strupper_m(
2759 result, "\\\\%s", result->desthost);
2760 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2761 status = NT_STATUS_NO_MEMORY;
2765 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2766 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2768 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2770 status = map_nt_error_from_unix(errno);
2775 addr.sun_family = AF_UNIX;
2776 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2778 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2779 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2782 return map_nt_error_from_unix(errno);
2785 status = rpc_transport_sock_init(result, fd, &result->transport);
2786 if (!NT_STATUS_IS_OK(status)) {
2791 result->transport->transport = NCALRPC;
2794 return NT_STATUS_OK;
2797 TALLOC_FREE(result);
2801 struct rpc_pipe_client_np_ref {
2802 struct cli_state *cli;
2803 struct rpc_pipe_client *pipe;
2806 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2808 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2812 /****************************************************************************
2813 Open a named pipe over SMB to a remote server.
2815 * CAVEAT CALLER OF THIS FUNCTION:
2816 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2817 * so be sure that this function is called AFTER any structure (vs pointer)
2818 * assignment of the cli. In particular, libsmbclient does structure
2819 * assignments of cli, which invalidates the data in the returned
2820 * rpc_pipe_client if this function is called before the structure assignment
2823 ****************************************************************************/
2825 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2826 const struct ndr_syntax_id *abstract_syntax,
2827 struct rpc_pipe_client **presult)
2829 struct rpc_pipe_client *result;
2831 struct rpc_pipe_client_np_ref *np_ref;
2833 /* sanity check to protect against crashes */
2836 return NT_STATUS_INVALID_HANDLE;
2839 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2840 if (result == NULL) {
2841 return NT_STATUS_NO_MEMORY;
2844 result->abstract_syntax = *abstract_syntax;
2845 result->transfer_syntax = ndr_transfer_syntax;
2846 result->dispatch = cli_do_rpc_ndr;
2847 result->dispatch_send = cli_do_rpc_ndr_send;
2848 result->dispatch_recv = cli_do_rpc_ndr_recv;
2849 result->desthost = talloc_strdup(result, cli->desthost);
2850 result->srv_name_slash = talloc_asprintf_strupper_m(
2851 result, "\\\\%s", result->desthost);
2853 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2854 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2856 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2857 TALLOC_FREE(result);
2858 return NT_STATUS_NO_MEMORY;
2861 status = rpc_transport_np_init(result, cli, abstract_syntax,
2862 &result->transport);
2863 if (!NT_STATUS_IS_OK(status)) {
2864 TALLOC_FREE(result);
2868 result->transport->transport = NCACN_NP;
2870 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2871 if (np_ref == NULL) {
2872 TALLOC_FREE(result);
2873 return NT_STATUS_NO_MEMORY;
2876 np_ref->pipe = result;
2878 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2879 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2882 return NT_STATUS_OK;
2885 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2886 struct rpc_cli_smbd_conn *conn,
2887 const struct ndr_syntax_id *syntax,
2888 struct rpc_pipe_client **presult)
2890 struct rpc_pipe_client *result;
2891 struct pipe_auth_data *auth;
2894 result = talloc(mem_ctx, struct rpc_pipe_client);
2895 if (result == NULL) {
2896 return NT_STATUS_NO_MEMORY;
2898 result->abstract_syntax = *syntax;
2899 result->transfer_syntax = ndr_transfer_syntax;
2900 result->dispatch = cli_do_rpc_ndr;
2901 result->dispatch_send = cli_do_rpc_ndr_send;
2902 result->dispatch_recv = cli_do_rpc_ndr_recv;
2903 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2904 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2906 result->desthost = talloc_strdup(result, global_myname());
2907 result->srv_name_slash = talloc_asprintf_strupper_m(
2908 result, "\\\\%s", global_myname());
2909 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2910 TALLOC_FREE(result);
2911 return NT_STATUS_NO_MEMORY;
2914 status = rpc_transport_smbd_init(result, conn, syntax,
2915 &result->transport);
2916 if (!NT_STATUS_IS_OK(status)) {
2917 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2918 nt_errstr(status)));
2919 TALLOC_FREE(result);
2923 status = rpccli_anon_bind_data(result, &auth);
2924 if (!NT_STATUS_IS_OK(status)) {
2925 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2926 nt_errstr(status)));
2927 TALLOC_FREE(result);
2931 status = rpc_pipe_bind(result, auth);
2932 if (!NT_STATUS_IS_OK(status)) {
2933 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2934 TALLOC_FREE(result);
2938 result->transport->transport = NCACN_INTERNAL;
2941 return NT_STATUS_OK;
2944 /****************************************************************************
2945 Open a pipe to a remote server.
2946 ****************************************************************************/
2948 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2949 enum dcerpc_transport_t transport,
2950 const struct ndr_syntax_id *interface,
2951 struct rpc_pipe_client **presult)
2953 switch (transport) {
2955 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2958 return rpc_pipe_open_np(cli, interface, presult);
2960 return NT_STATUS_NOT_IMPLEMENTED;
2964 /****************************************************************************
2965 Open a named pipe to an SMB server and bind anonymously.
2966 ****************************************************************************/
2968 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2969 enum dcerpc_transport_t transport,
2970 const struct ndr_syntax_id *interface,
2971 struct rpc_pipe_client **presult)
2973 struct rpc_pipe_client *result;
2974 struct pipe_auth_data *auth;
2977 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2978 if (!NT_STATUS_IS_OK(status)) {
2982 status = rpccli_anon_bind_data(result, &auth);
2983 if (!NT_STATUS_IS_OK(status)) {
2984 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2985 nt_errstr(status)));
2986 TALLOC_FREE(result);
2991 * This is a bit of an abstraction violation due to the fact that an
2992 * anonymous bind on an authenticated SMB inherits the user/domain
2993 * from the enclosing SMB creds
2996 TALLOC_FREE(auth->user_name);
2997 TALLOC_FREE(auth->domain);
2999 auth->user_name = talloc_strdup(auth, cli->user_name);
3000 auth->domain = talloc_strdup(auth, cli->domain);
3001 auth->user_session_key = data_blob_talloc(auth,
3002 cli->user_session_key.data,
3003 cli->user_session_key.length);
3005 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3006 TALLOC_FREE(result);
3007 return NT_STATUS_NO_MEMORY;
3010 status = rpc_pipe_bind(result, auth);
3011 if (!NT_STATUS_IS_OK(status)) {
3013 if (ndr_syntax_id_equal(interface,
3014 &ndr_table_dssetup.syntax_id)) {
3015 /* non AD domains just don't have this pipe, avoid
3016 * level 0 statement in that case - gd */
3019 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3020 "%s failed with error %s\n",
3021 get_pipe_name_from_syntax(talloc_tos(), interface),
3022 nt_errstr(status) ));
3023 TALLOC_FREE(result);
3027 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3028 "%s and bound anonymously.\n",
3029 get_pipe_name_from_syntax(talloc_tos(), interface),
3033 return NT_STATUS_OK;
3036 /****************************************************************************
3037 ****************************************************************************/
3039 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3040 const struct ndr_syntax_id *interface,
3041 struct rpc_pipe_client **presult)
3043 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3044 interface, presult);
3047 /****************************************************************************
3048 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3049 ****************************************************************************/
3051 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3052 const struct ndr_syntax_id *interface,
3053 enum dcerpc_transport_t transport,
3054 enum dcerpc_AuthLevel auth_level,
3056 const char *username,
3057 const char *password,
3058 struct rpc_pipe_client **presult)
3060 struct rpc_pipe_client *result;
3061 struct pipe_auth_data *auth;
3062 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
3065 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3066 if (!NT_STATUS_IS_OK(status)) {
3070 status = rpccli_ntlmssp_bind_data(result,
3071 auth_type, auth_level,
3072 domain, username, password,
3074 if (!NT_STATUS_IS_OK(status)) {
3075 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3076 nt_errstr(status)));
3080 status = rpc_pipe_bind(result, auth);
3081 if (!NT_STATUS_IS_OK(status)) {
3082 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3083 nt_errstr(status) ));
3087 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3088 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3089 get_pipe_name_from_syntax(talloc_tos(), interface),
3090 cli->desthost, domain, username ));
3093 return NT_STATUS_OK;
3097 TALLOC_FREE(result);
3101 /****************************************************************************
3102 Get a the schannel session key out of an already opened netlogon pipe.
3103 ****************************************************************************/
3104 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3105 struct cli_state *cli,
3109 enum netr_SchannelType sec_chan_type = 0;
3110 unsigned char machine_pwd[16];
3111 const char *machine_account;
3114 /* Get the machine account credentials from secrets.tdb. */
3115 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3118 DEBUG(0, ("get_schannel_session_key: could not fetch "
3119 "trust account password for domain '%s'\n",
3121 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3124 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3125 cli->desthost, /* server name */
3126 domain, /* domain */
3127 global_myname(), /* client name */
3128 machine_account, /* machine account name */
3133 if (!NT_STATUS_IS_OK(status)) {
3134 DEBUG(3, ("get_schannel_session_key_common: "
3135 "rpccli_netlogon_setup_creds failed with result %s "
3136 "to server %s, domain %s, machine account %s.\n",
3137 nt_errstr(status), cli->desthost, domain,
3142 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3143 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3145 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3148 return NT_STATUS_OK;;
3151 /****************************************************************************
3152 Open a netlogon pipe and get the schannel session key.
3153 Now exposed to external callers.
3154 ****************************************************************************/
3157 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3160 struct rpc_pipe_client **presult)
3162 struct rpc_pipe_client *netlogon_pipe = NULL;
3165 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3167 if (!NT_STATUS_IS_OK(status)) {
3171 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3173 if (!NT_STATUS_IS_OK(status)) {
3174 TALLOC_FREE(netlogon_pipe);
3178 *presult = netlogon_pipe;
3179 return NT_STATUS_OK;
3182 /****************************************************************************
3184 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3185 using session_key. sign and seal.
3187 The *pdc will be stolen onto this new pipe
3188 ****************************************************************************/
3190 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3191 const struct ndr_syntax_id *interface,
3192 enum dcerpc_transport_t transport,
3193 enum dcerpc_AuthLevel auth_level,
3195 struct netlogon_creds_CredentialState **pdc,
3196 struct rpc_pipe_client **presult)
3198 struct rpc_pipe_client *result;
3199 struct pipe_auth_data *auth;
3202 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3203 if (!NT_STATUS_IS_OK(status)) {
3207 status = rpccli_schannel_bind_data(result, domain, auth_level,
3209 if (!NT_STATUS_IS_OK(status)) {
3210 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3211 nt_errstr(status)));
3212 TALLOC_FREE(result);
3216 status = rpc_pipe_bind(result, auth);
3217 if (!NT_STATUS_IS_OK(status)) {
3218 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3219 "cli_rpc_pipe_bind failed with error %s\n",
3220 nt_errstr(status) ));
3221 TALLOC_FREE(result);
3226 * The credentials on a new netlogon pipe are the ones we are passed
3227 * in - reference them in
3229 result->dc = talloc_move(result, pdc);
3231 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3232 "for domain %s and bound using schannel.\n",
3233 get_pipe_name_from_syntax(talloc_tos(), interface),
3234 cli->desthost, domain ));
3237 return NT_STATUS_OK;
3240 /****************************************************************************
3241 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3242 Fetch the session key ourselves using a temporary netlogon pipe. This
3243 version uses an ntlmssp auth bound netlogon pipe to get the key.
3244 ****************************************************************************/
3246 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3248 const char *username,
3249 const char *password,
3251 struct rpc_pipe_client **presult)
3253 struct rpc_pipe_client *netlogon_pipe = NULL;
3256 status = cli_rpc_pipe_open_spnego_ntlmssp(
3257 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3258 DCERPC_AUTH_LEVEL_PRIVACY,
3259 domain, username, password, &netlogon_pipe);
3260 if (!NT_STATUS_IS_OK(status)) {
3264 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3266 if (!NT_STATUS_IS_OK(status)) {
3267 TALLOC_FREE(netlogon_pipe);
3271 *presult = netlogon_pipe;
3272 return NT_STATUS_OK;
3275 /****************************************************************************
3276 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3277 Fetch the session key ourselves using a temporary netlogon pipe. This version
3278 uses an ntlmssp bind to get the session key.
3279 ****************************************************************************/
3281 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3282 const struct ndr_syntax_id *interface,
3283 enum dcerpc_transport_t transport,
3284 enum dcerpc_AuthLevel auth_level,
3286 const char *username,
3287 const char *password,
3288 struct rpc_pipe_client **presult)
3290 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3291 struct rpc_pipe_client *netlogon_pipe = NULL;
3292 struct rpc_pipe_client *result = NULL;
3295 status = get_schannel_session_key_auth_ntlmssp(
3296 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3297 if (!NT_STATUS_IS_OK(status)) {
3298 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3299 "key from server %s for domain %s.\n",
3300 cli->desthost, domain ));
3304 status = cli_rpc_pipe_open_schannel_with_key(
3305 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3308 /* Now we've bound using the session key we can close the netlog pipe. */
3309 TALLOC_FREE(netlogon_pipe);
3311 if (NT_STATUS_IS_OK(status)) {
3317 /****************************************************************************
3318 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3319 Fetch the session key ourselves using a temporary netlogon pipe.
3320 ****************************************************************************/
3322 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3323 const struct ndr_syntax_id *interface,
3324 enum dcerpc_transport_t transport,
3325 enum dcerpc_AuthLevel auth_level,
3327 struct rpc_pipe_client **presult)
3329 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3330 struct rpc_pipe_client *netlogon_pipe = NULL;
3331 struct rpc_pipe_client *result = NULL;
3334 status = get_schannel_session_key(cli, domain, &neg_flags,
3336 if (!NT_STATUS_IS_OK(status)) {
3337 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3338 "key from server %s for domain %s.\n",
3339 cli->desthost, domain ));
3343 status = cli_rpc_pipe_open_schannel_with_key(
3344 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3347 /* Now we've bound using the session key we can close the netlog pipe. */
3348 TALLOC_FREE(netlogon_pipe);
3350 if (NT_STATUS_IS_OK(status)) {
3357 /****************************************************************************
3358 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3359 The idea is this can be called with service_princ, username and password all
3360 NULL so long as the caller has a TGT.
3361 ****************************************************************************/
3363 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3364 const struct ndr_syntax_id *interface,
3365 enum dcerpc_transport_t transport,
3366 enum dcerpc_AuthLevel auth_level,
3368 const char *username,
3369 const char *password,
3370 struct rpc_pipe_client **presult)
3372 struct rpc_pipe_client *result;
3373 struct pipe_auth_data *auth;
3376 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3377 if (!NT_STATUS_IS_OK(status)) {
3381 auth = talloc(result, struct pipe_auth_data);
3383 status = NT_STATUS_NO_MEMORY;
3386 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3387 auth->auth_level = auth_level;
3392 auth->user_name = talloc_strdup(auth, username);
3393 if (!auth->user_name) {
3394 status = NT_STATUS_NO_MEMORY;
3398 /* Fixme, should we fetch/set the Realm ? */
3399 auth->domain = talloc_strdup(auth, "");
3400 if (!auth->domain) {
3401 status = NT_STATUS_NO_MEMORY;
3405 status = gse_init_client(auth, auth->auth_type, auth->auth_level,
3406 NULL, server, "cifs", username, password,
3407 GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3409 if (!NT_STATUS_IS_OK(status)) {
3410 DEBUG(0, ("gse_init_client returned %s\n",
3411 nt_errstr(status)));
3415 status = rpc_pipe_bind(result, auth);
3416 if (!NT_STATUS_IS_OK(status)) {
3417 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3418 nt_errstr(status)));
3423 return NT_STATUS_OK;
3426 TALLOC_FREE(result);
3430 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3431 const struct ndr_syntax_id *interface,
3432 enum dcerpc_transport_t transport,
3433 enum dcerpc_AuthLevel auth_level,
3435 const char *username,
3436 const char *password,
3437 struct rpc_pipe_client **presult)
3439 struct rpc_pipe_client *result;
3440 struct pipe_auth_data *auth;
3443 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3444 if (!NT_STATUS_IS_OK(status)) {
3448 auth = talloc(result, struct pipe_auth_data);
3450 status = NT_STATUS_NO_MEMORY;
3453 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3454 auth->auth_level = auth_level;
3456 auth->spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
3461 auth->user_name = talloc_strdup(auth, username);
3462 if (!auth->user_name) {
3463 status = NT_STATUS_NO_MEMORY;
3467 /* Fixme, should we fetch/set the Realm ? */
3468 auth->domain = talloc_strdup(auth, "");
3469 if (!auth->domain) {
3470 status = NT_STATUS_NO_MEMORY;
3474 status = spnego_gssapi_init_client(auth, auth->auth_level,
3475 NULL, server, "cifs",
3478 &auth->a_u.spnego_state);
3479 if (!NT_STATUS_IS_OK(status)) {
3480 DEBUG(0, ("spnego_init_client returned %s\n",
3481 nt_errstr(status)));
3485 status = rpc_pipe_bind(result, auth);
3486 if (!NT_STATUS_IS_OK(status)) {
3487 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3488 nt_errstr(status)));
3493 return NT_STATUS_OK;
3496 TALLOC_FREE(result);
3500 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3501 const struct ndr_syntax_id *interface,
3502 enum dcerpc_transport_t transport,
3503 enum dcerpc_AuthLevel auth_level,
3505 const char *username,
3506 const char *password,
3507 struct rpc_pipe_client **presult)
3509 struct rpc_pipe_client *result;
3510 struct pipe_auth_data *auth;
3513 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3514 if (!NT_STATUS_IS_OK(status)) {
3518 auth = talloc(result, struct pipe_auth_data);
3520 status = NT_STATUS_NO_MEMORY;
3523 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3524 auth->auth_level = auth_level;
3529 auth->user_name = talloc_strdup(auth, username);
3530 if (!auth->user_name) {
3531 status = NT_STATUS_NO_MEMORY;
3538 auth->domain = talloc_strdup(auth, domain);
3539 if (!auth->domain) {
3540 status = NT_STATUS_NO_MEMORY;
3544 status = spnego_ntlmssp_init_client(auth, auth->auth_level,
3545 domain, username, password,
3546 &auth->a_u.spnego_state);
3547 if (!NT_STATUS_IS_OK(status)) {
3548 DEBUG(0, ("spnego_init_client returned %s\n",
3549 nt_errstr(status)));
3553 status = rpc_pipe_bind(result, auth);
3554 if (!NT_STATUS_IS_OK(status)) {
3555 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3556 nt_errstr(status)));
3561 return NT_STATUS_OK;
3564 TALLOC_FREE(result);
3568 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3569 struct rpc_pipe_client *cli,
3570 DATA_BLOB *session_key)
3572 struct pipe_auth_data *a = cli->auth;
3575 if (!session_key || !cli) {
3576 return NT_STATUS_INVALID_PARAMETER;
3580 return NT_STATUS_INVALID_PARAMETER;
3583 switch (cli->auth->auth_type) {
3584 case DCERPC_AUTH_TYPE_SCHANNEL:
3585 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3588 case DCERPC_AUTH_TYPE_SPNEGO:
3589 sk = spnego_get_session_key(a->a_u.spnego_state);
3590 if (sk.length == 0) {
3591 return NT_STATUS_NO_USER_SESSION_KEY;
3594 case DCERPC_AUTH_TYPE_NTLMSSP:
3595 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3597 case DCERPC_AUTH_TYPE_KRB5:
3598 sk = gse_get_session_key(a->a_u.gssapi_state);
3600 case DCERPC_AUTH_TYPE_NONE:
3601 sk = data_blob_const(a->user_session_key.data,
3602 a->user_session_key.length);
3605 return NT_STATUS_NO_USER_SESSION_KEY;
3608 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3609 return NT_STATUS_OK;