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;
1309 switch (cli->auth->auth_level) {
1310 case DCERPC_AUTH_LEVEL_NONE:
1311 case DCERPC_AUTH_LEVEL_CONNECT:
1312 case DCERPC_AUTH_LEVEL_PACKET:
1313 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1314 data_len = MIN(data_space, data_left);
1317 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1318 *data_to_send = data_len;
1319 return NT_STATUS_OK;
1321 case DCERPC_AUTH_LEVEL_INTEGRITY:
1322 case DCERPC_AUTH_LEVEL_PRIVACY:
1323 max_len = cli->max_xmit_frag
1324 - DCERPC_REQUEST_LENGTH
1325 - DCERPC_AUTH_TRAILER_LENGTH;
1327 /* Treat the same for all authenticated rpc requests. */
1328 switch(cli->auth->auth_type) {
1329 case DCERPC_AUTH_TYPE_SPNEGO:
1330 switch (cli->auth->spnego_type) {
1331 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1332 *p_auth_len = NTLMSSP_SIG_SIZE;
1334 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1335 *p_auth_len = 0; /* TODO */
1338 return NT_STATUS_INVALID_PARAMETER;
1340 case DCERPC_AUTH_TYPE_NTLMSSP:
1341 *p_auth_len = NTLMSSP_SIG_SIZE;
1343 case DCERPC_AUTH_TYPE_SCHANNEL:
1344 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1346 case DCERPC_AUTH_TYPE_KRB5:
1347 *p_auth_len = gse_get_signature_length(
1348 cli->auth->a_u.gssapi_state,
1349 (cli->auth->auth_level ==
1350 DCERPC_AUTH_LEVEL_PRIVACY),
1354 return NT_STATUS_INVALID_PARAMETER;
1357 data_space = max_len - *p_auth_len;
1359 data_len = MIN(data_space, data_left);
1361 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1362 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1364 *p_frag_len = DCERPC_REQUEST_LENGTH
1365 + data_len + *p_ss_padding
1366 + DCERPC_AUTH_TRAILER_LENGTH
1368 *data_to_send = data_len;
1369 return NT_STATUS_OK;
1375 return NT_STATUS_INVALID_PARAMETER;
1378 /*******************************************************************
1380 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1381 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1382 and deals with signing/sealing details.
1383 ********************************************************************/
1385 struct rpc_api_pipe_req_state {
1386 struct event_context *ev;
1387 struct rpc_pipe_client *cli;
1390 DATA_BLOB *req_data;
1391 uint32_t req_data_sent;
1393 DATA_BLOB reply_pdu;
1396 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1397 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1398 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1399 bool *is_last_frag);
1401 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1402 struct event_context *ev,
1403 struct rpc_pipe_client *cli,
1405 DATA_BLOB *req_data)
1407 struct tevent_req *req, *subreq;
1408 struct rpc_api_pipe_req_state *state;
1412 req = tevent_req_create(mem_ctx, &state,
1413 struct rpc_api_pipe_req_state);
1419 state->op_num = op_num;
1420 state->req_data = req_data;
1421 state->req_data_sent = 0;
1422 state->call_id = get_rpc_call_id();
1423 state->reply_pdu = data_blob_null;
1424 state->rpc_out = data_blob_null;
1426 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1427 + RPC_MAX_SIGN_SIZE) {
1428 /* Server is screwed up ! */
1429 status = NT_STATUS_INVALID_PARAMETER;
1433 status = prepare_next_frag(state, &is_last_frag);
1434 if (!NT_STATUS_IS_OK(status)) {
1439 subreq = rpc_api_pipe_send(state, ev, state->cli,
1441 DCERPC_PKT_RESPONSE);
1442 if (subreq == NULL) {
1445 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1447 subreq = rpc_write_send(state, ev, cli->transport,
1448 state->rpc_out.data,
1449 state->rpc_out.length);
1450 if (subreq == NULL) {
1453 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1459 tevent_req_nterror(req, status);
1460 return tevent_req_post(req, ev);
1466 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1469 uint32_t data_sent_thistime;
1476 union dcerpc_payload u;
1478 data_left = state->req_data->length - state->req_data_sent;
1480 status = calculate_data_len_tosend(state->cli, data_left,
1481 &data_sent_thistime,
1482 &frag_len, &auth_len,
1484 if (!NT_STATUS_IS_OK(status)) {
1488 if (state->req_data_sent == 0) {
1489 flags = DCERPC_PFC_FLAG_FIRST;
1492 if (data_sent_thistime == data_left) {
1493 flags |= DCERPC_PFC_FLAG_LAST;
1496 data_blob_free(&state->rpc_out);
1498 ZERO_STRUCT(u.request);
1500 u.request.alloc_hint = state->req_data->length;
1501 u.request.context_id = 0;
1502 u.request.opnum = state->op_num;
1504 status = dcerpc_push_ncacn_packet(state,
1511 if (!NT_STATUS_IS_OK(status)) {
1515 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1516 * compute it right for requests because the auth trailer is missing
1518 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1520 /* Copy in the data. */
1521 if (!data_blob_append(NULL, &state->rpc_out,
1522 state->req_data->data + state->req_data_sent,
1523 data_sent_thistime)) {
1524 return NT_STATUS_NO_MEMORY;
1527 switch (state->cli->auth->auth_level) {
1528 case DCERPC_AUTH_LEVEL_NONE:
1529 case DCERPC_AUTH_LEVEL_CONNECT:
1530 case DCERPC_AUTH_LEVEL_PACKET:
1532 case DCERPC_AUTH_LEVEL_INTEGRITY:
1533 case DCERPC_AUTH_LEVEL_PRIVACY:
1534 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1536 if (!NT_STATUS_IS_OK(status)) {
1541 return NT_STATUS_INVALID_PARAMETER;
1544 state->req_data_sent += data_sent_thistime;
1545 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1550 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1552 struct tevent_req *req = tevent_req_callback_data(
1553 subreq, struct tevent_req);
1554 struct rpc_api_pipe_req_state *state = tevent_req_data(
1555 req, struct rpc_api_pipe_req_state);
1559 status = rpc_write_recv(subreq);
1560 TALLOC_FREE(subreq);
1561 if (!NT_STATUS_IS_OK(status)) {
1562 tevent_req_nterror(req, status);
1566 status = prepare_next_frag(state, &is_last_frag);
1567 if (!NT_STATUS_IS_OK(status)) {
1568 tevent_req_nterror(req, status);
1573 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1575 DCERPC_PKT_RESPONSE);
1576 if (tevent_req_nomem(subreq, req)) {
1579 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1581 subreq = rpc_write_send(state, state->ev,
1582 state->cli->transport,
1583 state->rpc_out.data,
1584 state->rpc_out.length);
1585 if (tevent_req_nomem(subreq, req)) {
1588 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1593 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1595 struct tevent_req *req = tevent_req_callback_data(
1596 subreq, struct tevent_req);
1597 struct rpc_api_pipe_req_state *state = tevent_req_data(
1598 req, struct rpc_api_pipe_req_state);
1601 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1602 TALLOC_FREE(subreq);
1603 if (!NT_STATUS_IS_OK(status)) {
1604 tevent_req_nterror(req, status);
1607 tevent_req_done(req);
1610 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1611 DATA_BLOB *reply_pdu)
1613 struct rpc_api_pipe_req_state *state = tevent_req_data(
1614 req, struct rpc_api_pipe_req_state);
1617 if (tevent_req_is_nterror(req, &status)) {
1619 * We always have to initialize to reply pdu, even if there is
1620 * none. The rpccli_* caller routines expect this.
1622 *reply_pdu = data_blob_null;
1626 /* return data to caller and assign it ownership of memory */
1627 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1628 reply_pdu->length = state->reply_pdu.length;
1629 state->reply_pdu.length = 0;
1631 return NT_STATUS_OK;
1635 /****************************************************************************
1636 Set the handle state.
1637 ****************************************************************************/
1639 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1640 const char *pipe_name, uint16 device_state)
1642 bool state_set = False;
1644 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1645 char *rparam = NULL;
1647 uint32 rparam_len, rdata_len;
1649 if (pipe_name == NULL)
1652 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1653 cli->fnum, pipe_name, device_state));
1655 /* create parameters: device state */
1656 SSVAL(param, 0, device_state);
1658 /* create setup parameters. */
1660 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1662 /* send the data on \PIPE\ */
1663 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1664 setup, 2, 0, /* setup, length, max */
1665 param, 2, 0, /* param, length, max */
1666 NULL, 0, 1024, /* data, length, max */
1667 &rparam, &rparam_len, /* return param, length */
1668 &rdata, &rdata_len)) /* return data, length */
1670 DEBUG(5, ("Set Handle state: return OK\n"));
1681 /****************************************************************************
1682 Check the rpc bind acknowledge response.
1683 ****************************************************************************/
1685 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1686 const struct ndr_syntax_id *transfer)
1688 struct dcerpc_ack_ctx ctx;
1690 if (r->secondary_address_size == 0) {
1691 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1694 if (r->num_results < 1 || !r->ctx_list) {
1698 ctx = r->ctx_list[0];
1700 /* check the transfer syntax */
1701 if ((ctx.syntax.if_version != transfer->if_version) ||
1702 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1703 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1707 if (r->num_results != 0x1 || ctx.result != 0) {
1708 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1709 r->num_results, ctx.reason));
1712 DEBUG(5,("check_bind_response: accepted!\n"));
1716 /*******************************************************************
1717 Creates a DCE/RPC bind authentication response.
1718 This is the packet that is sent back to the server once we
1719 have received a BIND-ACK, to finish the third leg of
1720 the authentication handshake.
1721 ********************************************************************/
1723 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1724 struct rpc_pipe_client *cli,
1726 enum dcerpc_AuthType auth_type,
1727 enum dcerpc_AuthLevel auth_level,
1728 DATA_BLOB *pauth_blob,
1732 union dcerpc_payload u;
1736 status = dcerpc_push_dcerpc_auth(mem_ctx,
1739 0, /* auth_pad_length */
1740 1, /* auth_context_id */
1742 &u.auth3.auth_info);
1743 if (!NT_STATUS_IS_OK(status)) {
1747 status = dcerpc_push_ncacn_packet(mem_ctx,
1749 DCERPC_PFC_FLAG_FIRST |
1750 DCERPC_PFC_FLAG_LAST,
1755 data_blob_free(&u.auth3.auth_info);
1756 if (!NT_STATUS_IS_OK(status)) {
1757 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1761 return NT_STATUS_OK;
1764 /*******************************************************************
1765 Creates a DCE/RPC bind alter context authentication request which
1766 may contain a spnego auth blobl
1767 ********************************************************************/
1769 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1770 enum dcerpc_AuthType auth_type,
1771 enum dcerpc_AuthLevel auth_level,
1773 const struct ndr_syntax_id *abstract,
1774 const struct ndr_syntax_id *transfer,
1775 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1778 DATA_BLOB auth_info;
1781 status = dcerpc_push_dcerpc_auth(mem_ctx,
1784 0, /* auth_pad_length */
1785 1, /* auth_context_id */
1788 if (!NT_STATUS_IS_OK(status)) {
1792 status = create_bind_or_alt_ctx_internal(mem_ctx,
1799 data_blob_free(&auth_info);
1803 /****************************************************************************
1805 ****************************************************************************/
1807 struct rpc_pipe_bind_state {
1808 struct event_context *ev;
1809 struct rpc_pipe_client *cli;
1811 uint32_t rpc_call_id;
1814 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1815 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1816 struct rpc_pipe_bind_state *state,
1817 DATA_BLOB *credentials);
1818 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1819 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1820 struct rpc_pipe_bind_state *state,
1821 DATA_BLOB *credentials);
1822 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1823 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1824 struct rpc_pipe_bind_state *state,
1825 DATA_BLOB *credentials);
1826 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1827 struct rpc_pipe_bind_state *state,
1828 DATA_BLOB *credentials);
1830 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1831 struct event_context *ev,
1832 struct rpc_pipe_client *cli,
1833 struct pipe_auth_data *auth)
1835 struct tevent_req *req, *subreq;
1836 struct rpc_pipe_bind_state *state;
1839 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1844 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1845 rpccli_pipe_txt(talloc_tos(), cli),
1846 (unsigned int)auth->auth_type,
1847 (unsigned int)auth->spnego_type,
1848 (unsigned int)auth->auth_level ));
1852 state->rpc_call_id = get_rpc_call_id();
1853 state->rpc_out = data_blob_null;
1855 cli->auth = talloc_move(cli, &auth);
1857 /* Marshall the outgoing data. */
1858 status = create_rpc_bind_req(state, cli,
1861 &cli->abstract_syntax,
1862 &cli->transfer_syntax,
1865 if (!NT_STATUS_IS_OK(status)) {
1869 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1870 DCERPC_PKT_BIND_ACK);
1871 if (subreq == NULL) {
1874 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1878 tevent_req_nterror(req, status);
1879 return tevent_req_post(req, ev);
1885 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1887 struct tevent_req *req = tevent_req_callback_data(
1888 subreq, struct tevent_req);
1889 struct rpc_pipe_bind_state *state = tevent_req_data(
1890 req, struct rpc_pipe_bind_state);
1891 struct pipe_auth_data *pauth = state->cli->auth;
1892 DATA_BLOB reply_pdu;
1893 struct ncacn_packet *pkt;
1894 struct dcerpc_auth auth;
1895 DATA_BLOB auth_token = data_blob_null;
1898 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1899 TALLOC_FREE(subreq);
1900 if (!NT_STATUS_IS_OK(status)) {
1901 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1902 rpccli_pipe_txt(talloc_tos(), state->cli),
1903 nt_errstr(status)));
1904 tevent_req_nterror(req, status);
1908 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1909 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1910 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1914 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1915 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1917 switch(state->cli->auth->auth_type) {
1919 case DCERPC_AUTH_TYPE_NONE:
1920 case DCERPC_AUTH_TYPE_SCHANNEL:
1921 /* Bind complete. */
1922 tevent_req_done(req);
1925 case DCERPC_AUTH_TYPE_NTLMSSP:
1926 case DCERPC_AUTH_TYPE_SPNEGO:
1927 case DCERPC_AUTH_TYPE_KRB5:
1928 /* Paranoid lenght checks */
1929 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1930 + pkt->auth_length) {
1931 tevent_req_nterror(req,
1932 NT_STATUS_INFO_LENGTH_MISMATCH);
1935 /* get auth credentials */
1936 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1937 &pkt->u.bind_ack.auth_info,
1939 if (!NT_STATUS_IS_OK(status)) {
1940 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1941 nt_errstr(status)));
1942 tevent_req_nterror(req, status);
1952 * For authenticated binds we may need to do 3 or 4 leg binds.
1955 switch(state->cli->auth->auth_type) {
1957 case DCERPC_AUTH_TYPE_NONE:
1958 case DCERPC_AUTH_TYPE_SCHANNEL:
1959 /* Bind complete. */
1960 tevent_req_done(req);
1963 case DCERPC_AUTH_TYPE_NTLMSSP:
1964 /* Need to send AUTH3 packet - no reply. */
1965 status = rpc_finish_auth3_bind_send(req, state,
1969 case DCERPC_AUTH_TYPE_SPNEGO:
1970 switch (pauth->spnego_type) {
1971 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1972 /* Need to send alter context request and reply. */
1973 status = rpc_finish_spnego_ntlmssp_bind_send(req,
1974 state, &auth.credentials);
1977 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1978 status = spnego_get_client_auth_token(state,
1979 pauth->a_u.spnego_state,
1982 if (!NT_STATUS_IS_OK(status)) {
1985 if (auth_token.length == 0) {
1986 /* Bind complete. */
1987 tevent_req_done(req);
1990 if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
1991 status = rpc_bind_next_send(req, state,
1994 status = rpc_bind_finish_send(req, state,
1999 status = NT_STATUS_INTERNAL_ERROR;
2003 case DCERPC_AUTH_TYPE_KRB5:
2004 status = gse_get_client_auth_token(state,
2005 pauth->a_u.gssapi_state,
2008 if (!NT_STATUS_IS_OK(status)) {
2012 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
2013 status = rpc_bind_next_send(req, state, &auth_token);
2015 status = rpc_bind_finish_send(req, state, &auth_token);
2023 if (!NT_STATUS_IS_OK(status)) {
2024 tevent_req_nterror(req, status);
2029 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
2030 (unsigned int)state->cli->auth->auth_type,
2031 (unsigned int)state->cli->auth->spnego_type));
2032 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2035 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2036 struct rpc_pipe_bind_state *state,
2037 DATA_BLOB *credentials)
2039 struct pipe_auth_data *auth = state->cli->auth;
2040 DATA_BLOB client_reply = data_blob_null;
2041 struct tevent_req *subreq;
2044 /* TODO - check auth_type/auth_level match. */
2046 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2047 *credentials, &client_reply);
2049 if (!NT_STATUS_IS_OK(status)) {
2050 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2051 "blob failed: %s.\n", nt_errstr(status)));
2055 data_blob_free(&state->rpc_out);
2057 status = create_rpc_bind_auth3(state, state->cli,
2063 data_blob_free(&client_reply);
2065 if (!NT_STATUS_IS_OK(status)) {
2069 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2070 state->rpc_out.data, state->rpc_out.length);
2071 if (subreq == NULL) {
2072 return NT_STATUS_NO_MEMORY;
2074 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2075 return NT_STATUS_OK;
2078 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2080 struct tevent_req *req = tevent_req_callback_data(
2081 subreq, struct tevent_req);
2084 status = rpc_write_recv(subreq);
2085 TALLOC_FREE(subreq);
2086 if (!NT_STATUS_IS_OK(status)) {
2087 tevent_req_nterror(req, status);
2090 tevent_req_done(req);
2093 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2094 struct rpc_pipe_bind_state *state,
2095 DATA_BLOB *credentials)
2097 struct pipe_auth_data *auth = state->cli->auth;
2098 DATA_BLOB server_ntlm_response = data_blob_null;
2099 DATA_BLOB client_reply = data_blob_null;
2100 DATA_BLOB tmp_blob = data_blob_null;
2101 struct tevent_req *subreq;
2105 * The server might give us back two challenges - tmp_blob is for the
2108 if (!spnego_parse_challenge(state, *credentials,
2109 &server_ntlm_response,
2111 data_blob_free(&server_ntlm_response);
2112 data_blob_free(&tmp_blob);
2113 return NT_STATUS_INVALID_PARAMETER;
2116 /* We're finished with the server spnego response and the tmp_blob. */
2117 data_blob_free(&tmp_blob);
2119 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2120 server_ntlm_response, &client_reply);
2122 /* Finished with the server_ntlm response */
2123 data_blob_free(&server_ntlm_response);
2125 if (!NT_STATUS_IS_OK(status)) {
2126 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2127 "using server blob failed.\n"));
2128 data_blob_free(&client_reply);
2132 /* SPNEGO wrap the client reply. */
2133 tmp_blob = spnego_gen_auth(state, client_reply);
2134 data_blob_free(&client_reply);
2135 client_reply = tmp_blob;
2136 tmp_blob = data_blob_null;
2138 /* Now prepare the alter context pdu. */
2139 data_blob_free(&state->rpc_out);
2141 status = create_rpc_alter_context(state,
2145 &state->cli->abstract_syntax,
2146 &state->cli->transfer_syntax,
2149 data_blob_free(&client_reply);
2151 if (!NT_STATUS_IS_OK(status)) {
2155 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2156 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2157 if (subreq == NULL) {
2158 return NT_STATUS_NO_MEMORY;
2160 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2161 return NT_STATUS_OK;
2164 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2166 struct tevent_req *req = tevent_req_callback_data(
2167 subreq, struct tevent_req);
2168 struct rpc_pipe_bind_state *state = tevent_req_data(
2169 req, struct rpc_pipe_bind_state);
2170 DATA_BLOB tmp_blob = data_blob_null;
2171 struct ncacn_packet *pkt;
2172 struct dcerpc_auth auth;
2175 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2176 TALLOC_FREE(subreq);
2177 if (!NT_STATUS_IS_OK(status)) {
2178 tevent_req_nterror(req, status);
2182 status = dcerpc_pull_dcerpc_auth(pkt,
2183 &pkt->u.alter_resp.auth_info,
2185 if (!NT_STATUS_IS_OK(status)) {
2186 tevent_req_nterror(req, status);
2190 /* Check we got a valid auth response. */
2191 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2193 OID_NTLMSSP, &tmp_blob)) {
2194 data_blob_free(&tmp_blob);
2195 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2199 data_blob_free(&tmp_blob);
2201 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2202 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2203 tevent_req_done(req);
2206 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2207 struct rpc_pipe_bind_state *state,
2208 DATA_BLOB *auth_token)
2210 struct pipe_auth_data *auth = state->cli->auth;
2211 struct tevent_req *subreq;
2214 /* Now prepare the alter context pdu. */
2215 data_blob_free(&state->rpc_out);
2217 status = create_rpc_alter_context(state,
2221 &state->cli->abstract_syntax,
2222 &state->cli->transfer_syntax,
2225 if (!NT_STATUS_IS_OK(status)) {
2229 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2230 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2231 if (subreq == NULL) {
2232 return NT_STATUS_NO_MEMORY;
2234 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2235 return NT_STATUS_OK;
2238 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2239 struct rpc_pipe_bind_state *state,
2240 DATA_BLOB *auth_token)
2242 struct pipe_auth_data *auth = state->cli->auth;
2243 struct tevent_req *subreq;
2246 /* Now prepare the auth3 context pdu. */
2247 data_blob_free(&state->rpc_out);
2249 status = create_rpc_bind_auth3(state, state->cli,
2255 if (!NT_STATUS_IS_OK(status)) {
2259 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2260 state->rpc_out.data, state->rpc_out.length);
2261 if (subreq == NULL) {
2262 return NT_STATUS_NO_MEMORY;
2264 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2265 return NT_STATUS_OK;
2268 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2270 return tevent_req_simple_recv_ntstatus(req);
2273 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2274 struct pipe_auth_data *auth)
2276 TALLOC_CTX *frame = talloc_stackframe();
2277 struct event_context *ev;
2278 struct tevent_req *req;
2279 NTSTATUS status = NT_STATUS_OK;
2281 ev = event_context_init(frame);
2283 status = NT_STATUS_NO_MEMORY;
2287 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2289 status = NT_STATUS_NO_MEMORY;
2293 if (!tevent_req_poll(req, ev)) {
2294 status = map_nt_error_from_unix(errno);
2298 status = rpc_pipe_bind_recv(req);
2304 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2306 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2307 unsigned int timeout)
2311 if (rpc_cli->transport == NULL) {
2312 return RPCCLI_DEFAULT_TIMEOUT;
2315 if (rpc_cli->transport->set_timeout == NULL) {
2316 return RPCCLI_DEFAULT_TIMEOUT;
2319 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2321 return RPCCLI_DEFAULT_TIMEOUT;
2327 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2329 if (rpc_cli == NULL) {
2333 if (rpc_cli->transport == NULL) {
2337 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2340 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2342 struct cli_state *cli;
2344 if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP)
2345 || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO
2346 && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2347 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2351 cli = rpc_pipe_np_smb_conn(rpc_cli);
2355 E_md4hash(cli->password ? cli->password : "", nt_hash);
2359 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2360 struct pipe_auth_data **presult)
2362 struct pipe_auth_data *result;
2364 result = talloc(mem_ctx, struct pipe_auth_data);
2365 if (result == NULL) {
2366 return NT_STATUS_NO_MEMORY;
2369 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2370 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2371 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2373 result->user_name = talloc_strdup(result, "");
2374 result->domain = talloc_strdup(result, "");
2375 if ((result->user_name == NULL) || (result->domain == NULL)) {
2376 TALLOC_FREE(result);
2377 return NT_STATUS_NO_MEMORY;
2381 return NT_STATUS_OK;
2384 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2386 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2390 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2391 enum dcerpc_AuthType auth_type,
2392 enum pipe_auth_type_spnego spnego_type,
2393 enum dcerpc_AuthLevel auth_level,
2395 const char *username,
2396 const char *password,
2397 struct pipe_auth_data **presult)
2399 struct pipe_auth_data *result;
2402 result = talloc(mem_ctx, struct pipe_auth_data);
2403 if (result == NULL) {
2404 return NT_STATUS_NO_MEMORY;
2407 result->auth_type = auth_type;
2408 result->spnego_type = spnego_type;
2409 result->auth_level = auth_level;
2411 result->user_name = talloc_strdup(result, username);
2412 result->domain = talloc_strdup(result, domain);
2413 if ((result->user_name == NULL) || (result->domain == NULL)) {
2414 status = NT_STATUS_NO_MEMORY;
2418 status = auth_ntlmssp_client_start(NULL,
2421 lp_client_ntlmv2_auth(),
2422 &result->a_u.auth_ntlmssp_state);
2423 if (!NT_STATUS_IS_OK(status)) {
2427 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2429 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2431 if (!NT_STATUS_IS_OK(status)) {
2435 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2437 if (!NT_STATUS_IS_OK(status)) {
2441 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2443 if (!NT_STATUS_IS_OK(status)) {
2448 * Turn off sign+seal to allow selected auth level to turn it back on.
2450 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2451 ~(NTLMSSP_NEGOTIATE_SIGN |
2452 NTLMSSP_NEGOTIATE_SEAL));
2454 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2455 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2456 NTLMSSP_NEGOTIATE_SIGN);
2457 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2458 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2459 NTLMSSP_NEGOTIATE_SEAL |
2460 NTLMSSP_NEGOTIATE_SIGN);
2464 return NT_STATUS_OK;
2467 TALLOC_FREE(result);
2471 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2472 enum dcerpc_AuthLevel auth_level,
2473 struct netlogon_creds_CredentialState *creds,
2474 struct pipe_auth_data **presult)
2476 struct pipe_auth_data *result;
2478 result = talloc(mem_ctx, struct pipe_auth_data);
2479 if (result == NULL) {
2480 return NT_STATUS_NO_MEMORY;
2483 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2484 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2485 result->auth_level = auth_level;
2487 result->user_name = talloc_strdup(result, "");
2488 result->domain = talloc_strdup(result, domain);
2489 if ((result->user_name == NULL) || (result->domain == NULL)) {
2493 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2494 if (result->a_u.schannel_auth == NULL) {
2498 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2499 result->a_u.schannel_auth->seq_num = 0;
2500 result->a_u.schannel_auth->initiator = true;
2501 result->a_u.schannel_auth->creds = creds;
2504 return NT_STATUS_OK;
2507 TALLOC_FREE(result);
2508 return NT_STATUS_NO_MEMORY;
2512 * Create an rpc pipe client struct, connecting to a tcp port.
2514 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2516 const struct ndr_syntax_id *abstract_syntax,
2517 struct rpc_pipe_client **presult)
2519 struct rpc_pipe_client *result;
2520 struct sockaddr_storage addr;
2524 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2525 if (result == NULL) {
2526 return NT_STATUS_NO_MEMORY;
2529 result->abstract_syntax = *abstract_syntax;
2530 result->transfer_syntax = ndr_transfer_syntax;
2531 result->dispatch = cli_do_rpc_ndr;
2532 result->dispatch_send = cli_do_rpc_ndr_send;
2533 result->dispatch_recv = cli_do_rpc_ndr_recv;
2535 result->desthost = talloc_strdup(result, host);
2536 result->srv_name_slash = talloc_asprintf_strupper_m(
2537 result, "\\\\%s", result->desthost);
2538 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2539 status = NT_STATUS_NO_MEMORY;
2543 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2544 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2546 if (!resolve_name(host, &addr, 0, false)) {
2547 status = NT_STATUS_NOT_FOUND;
2551 status = open_socket_out(&addr, port, 60, &fd);
2552 if (!NT_STATUS_IS_OK(status)) {
2555 set_socket_options(fd, lp_socket_options());
2557 status = rpc_transport_sock_init(result, fd, &result->transport);
2558 if (!NT_STATUS_IS_OK(status)) {
2563 result->transport->transport = NCACN_IP_TCP;
2566 return NT_STATUS_OK;
2569 TALLOC_FREE(result);
2574 * Determine the tcp port on which a dcerpc interface is listening
2575 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2578 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2579 const struct ndr_syntax_id *abstract_syntax,
2583 struct rpc_pipe_client *epm_pipe = NULL;
2584 struct pipe_auth_data *auth = NULL;
2585 struct dcerpc_binding *map_binding = NULL;
2586 struct dcerpc_binding *res_binding = NULL;
2587 struct epm_twr_t *map_tower = NULL;
2588 struct epm_twr_t *res_towers = NULL;
2589 struct policy_handle *entry_handle = NULL;
2590 uint32_t num_towers = 0;
2591 uint32_t max_towers = 1;
2592 struct epm_twr_p_t towers;
2593 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2595 if (pport == NULL) {
2596 status = NT_STATUS_INVALID_PARAMETER;
2600 /* open the connection to the endpoint mapper */
2601 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2602 &ndr_table_epmapper.syntax_id,
2605 if (!NT_STATUS_IS_OK(status)) {
2609 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2610 if (!NT_STATUS_IS_OK(status)) {
2614 status = rpc_pipe_bind(epm_pipe, auth);
2615 if (!NT_STATUS_IS_OK(status)) {
2619 /* create tower for asking the epmapper */
2621 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2622 if (map_binding == NULL) {
2623 status = NT_STATUS_NO_MEMORY;
2627 map_binding->transport = NCACN_IP_TCP;
2628 map_binding->object = *abstract_syntax;
2629 map_binding->host = host; /* needed? */
2630 map_binding->endpoint = "0"; /* correct? needed? */
2632 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2633 if (map_tower == NULL) {
2634 status = NT_STATUS_NO_MEMORY;
2638 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2639 &(map_tower->tower));
2640 if (!NT_STATUS_IS_OK(status)) {
2644 /* allocate further parameters for the epm_Map call */
2646 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2647 if (res_towers == NULL) {
2648 status = NT_STATUS_NO_MEMORY;
2651 towers.twr = res_towers;
2653 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2654 if (entry_handle == NULL) {
2655 status = NT_STATUS_NO_MEMORY;
2659 /* ask the endpoint mapper for the port */
2661 status = rpccli_epm_Map(epm_pipe,
2663 CONST_DISCARD(struct GUID *,
2664 &(abstract_syntax->uuid)),
2671 if (!NT_STATUS_IS_OK(status)) {
2675 if (num_towers != 1) {
2676 status = NT_STATUS_UNSUCCESSFUL;
2680 /* extract the port from the answer */
2682 status = dcerpc_binding_from_tower(tmp_ctx,
2683 &(towers.twr->tower),
2685 if (!NT_STATUS_IS_OK(status)) {
2689 /* are further checks here necessary? */
2690 if (res_binding->transport != NCACN_IP_TCP) {
2691 status = NT_STATUS_UNSUCCESSFUL;
2695 *pport = (uint16_t)atoi(res_binding->endpoint);
2698 TALLOC_FREE(tmp_ctx);
2703 * Create a rpc pipe client struct, connecting to a host via tcp.
2704 * The port is determined by asking the endpoint mapper on the given
2707 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2708 const struct ndr_syntax_id *abstract_syntax,
2709 struct rpc_pipe_client **presult)
2714 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2715 if (!NT_STATUS_IS_OK(status)) {
2719 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2720 abstract_syntax, presult);
2723 /********************************************************************
2724 Create a rpc pipe client struct, connecting to a unix domain socket
2725 ********************************************************************/
2726 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2727 const struct ndr_syntax_id *abstract_syntax,
2728 struct rpc_pipe_client **presult)
2730 struct rpc_pipe_client *result;
2731 struct sockaddr_un addr;
2735 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2736 if (result == NULL) {
2737 return NT_STATUS_NO_MEMORY;
2740 result->abstract_syntax = *abstract_syntax;
2741 result->transfer_syntax = ndr_transfer_syntax;
2742 result->dispatch = cli_do_rpc_ndr;
2743 result->dispatch_send = cli_do_rpc_ndr_send;
2744 result->dispatch_recv = cli_do_rpc_ndr_recv;
2746 result->desthost = get_myname(result);
2747 result->srv_name_slash = talloc_asprintf_strupper_m(
2748 result, "\\\\%s", result->desthost);
2749 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2750 status = NT_STATUS_NO_MEMORY;
2754 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2755 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2757 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2759 status = map_nt_error_from_unix(errno);
2764 addr.sun_family = AF_UNIX;
2765 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2767 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2768 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2771 return map_nt_error_from_unix(errno);
2774 status = rpc_transport_sock_init(result, fd, &result->transport);
2775 if (!NT_STATUS_IS_OK(status)) {
2780 result->transport->transport = NCALRPC;
2783 return NT_STATUS_OK;
2786 TALLOC_FREE(result);
2790 struct rpc_pipe_client_np_ref {
2791 struct cli_state *cli;
2792 struct rpc_pipe_client *pipe;
2795 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2797 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2801 /****************************************************************************
2802 Open a named pipe over SMB to a remote server.
2804 * CAVEAT CALLER OF THIS FUNCTION:
2805 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2806 * so be sure that this function is called AFTER any structure (vs pointer)
2807 * assignment of the cli. In particular, libsmbclient does structure
2808 * assignments of cli, which invalidates the data in the returned
2809 * rpc_pipe_client if this function is called before the structure assignment
2812 ****************************************************************************/
2814 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2815 const struct ndr_syntax_id *abstract_syntax,
2816 struct rpc_pipe_client **presult)
2818 struct rpc_pipe_client *result;
2820 struct rpc_pipe_client_np_ref *np_ref;
2822 /* sanity check to protect against crashes */
2825 return NT_STATUS_INVALID_HANDLE;
2828 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2829 if (result == NULL) {
2830 return NT_STATUS_NO_MEMORY;
2833 result->abstract_syntax = *abstract_syntax;
2834 result->transfer_syntax = ndr_transfer_syntax;
2835 result->dispatch = cli_do_rpc_ndr;
2836 result->dispatch_send = cli_do_rpc_ndr_send;
2837 result->dispatch_recv = cli_do_rpc_ndr_recv;
2838 result->desthost = talloc_strdup(result, cli->desthost);
2839 result->srv_name_slash = talloc_asprintf_strupper_m(
2840 result, "\\\\%s", result->desthost);
2842 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2843 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2845 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2846 TALLOC_FREE(result);
2847 return NT_STATUS_NO_MEMORY;
2850 status = rpc_transport_np_init(result, cli, abstract_syntax,
2851 &result->transport);
2852 if (!NT_STATUS_IS_OK(status)) {
2853 TALLOC_FREE(result);
2857 result->transport->transport = NCACN_NP;
2859 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2860 if (np_ref == NULL) {
2861 TALLOC_FREE(result);
2862 return NT_STATUS_NO_MEMORY;
2865 np_ref->pipe = result;
2867 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2868 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2871 return NT_STATUS_OK;
2874 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2875 struct rpc_cli_smbd_conn *conn,
2876 const struct ndr_syntax_id *syntax,
2877 struct rpc_pipe_client **presult)
2879 struct rpc_pipe_client *result;
2880 struct pipe_auth_data *auth;
2883 result = talloc(mem_ctx, struct rpc_pipe_client);
2884 if (result == NULL) {
2885 return NT_STATUS_NO_MEMORY;
2887 result->abstract_syntax = *syntax;
2888 result->transfer_syntax = ndr_transfer_syntax;
2889 result->dispatch = cli_do_rpc_ndr;
2890 result->dispatch_send = cli_do_rpc_ndr_send;
2891 result->dispatch_recv = cli_do_rpc_ndr_recv;
2892 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2893 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2895 result->desthost = talloc_strdup(result, global_myname());
2896 result->srv_name_slash = talloc_asprintf_strupper_m(
2897 result, "\\\\%s", global_myname());
2898 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2899 TALLOC_FREE(result);
2900 return NT_STATUS_NO_MEMORY;
2903 status = rpc_transport_smbd_init(result, conn, syntax,
2904 &result->transport);
2905 if (!NT_STATUS_IS_OK(status)) {
2906 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2907 nt_errstr(status)));
2908 TALLOC_FREE(result);
2912 status = rpccli_anon_bind_data(result, &auth);
2913 if (!NT_STATUS_IS_OK(status)) {
2914 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2915 nt_errstr(status)));
2916 TALLOC_FREE(result);
2920 status = rpc_pipe_bind(result, auth);
2921 if (!NT_STATUS_IS_OK(status)) {
2922 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2923 TALLOC_FREE(result);
2927 result->transport->transport = NCACN_INTERNAL;
2930 return NT_STATUS_OK;
2933 /****************************************************************************
2934 Open a pipe to a remote server.
2935 ****************************************************************************/
2937 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2938 enum dcerpc_transport_t transport,
2939 const struct ndr_syntax_id *interface,
2940 struct rpc_pipe_client **presult)
2942 switch (transport) {
2944 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2947 return rpc_pipe_open_np(cli, interface, presult);
2949 return NT_STATUS_NOT_IMPLEMENTED;
2953 /****************************************************************************
2954 Open a named pipe to an SMB server and bind anonymously.
2955 ****************************************************************************/
2957 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2958 enum dcerpc_transport_t transport,
2959 const struct ndr_syntax_id *interface,
2960 struct rpc_pipe_client **presult)
2962 struct rpc_pipe_client *result;
2963 struct pipe_auth_data *auth;
2966 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2967 if (!NT_STATUS_IS_OK(status)) {
2971 status = rpccli_anon_bind_data(result, &auth);
2972 if (!NT_STATUS_IS_OK(status)) {
2973 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2974 nt_errstr(status)));
2975 TALLOC_FREE(result);
2980 * This is a bit of an abstraction violation due to the fact that an
2981 * anonymous bind on an authenticated SMB inherits the user/domain
2982 * from the enclosing SMB creds
2985 TALLOC_FREE(auth->user_name);
2986 TALLOC_FREE(auth->domain);
2988 auth->user_name = talloc_strdup(auth, cli->user_name);
2989 auth->domain = talloc_strdup(auth, cli->domain);
2990 auth->user_session_key = data_blob_talloc(auth,
2991 cli->user_session_key.data,
2992 cli->user_session_key.length);
2994 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2995 TALLOC_FREE(result);
2996 return NT_STATUS_NO_MEMORY;
2999 status = rpc_pipe_bind(result, auth);
3000 if (!NT_STATUS_IS_OK(status)) {
3002 if (ndr_syntax_id_equal(interface,
3003 &ndr_table_dssetup.syntax_id)) {
3004 /* non AD domains just don't have this pipe, avoid
3005 * level 0 statement in that case - gd */
3008 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3009 "%s failed with error %s\n",
3010 get_pipe_name_from_syntax(talloc_tos(), interface),
3011 nt_errstr(status) ));
3012 TALLOC_FREE(result);
3016 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3017 "%s and bound anonymously.\n",
3018 get_pipe_name_from_syntax(talloc_tos(), interface),
3022 return NT_STATUS_OK;
3025 /****************************************************************************
3026 ****************************************************************************/
3028 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3029 const struct ndr_syntax_id *interface,
3030 struct rpc_pipe_client **presult)
3032 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3033 interface, presult);
3036 /****************************************************************************
3037 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3038 ****************************************************************************/
3040 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3041 const struct ndr_syntax_id *interface,
3042 enum dcerpc_transport_t transport,
3044 enum dcerpc_AuthLevel auth_level,
3046 const char *username,
3047 const char *password,
3048 struct rpc_pipe_client **presult)
3050 struct rpc_pipe_client *result;
3051 struct pipe_auth_data *auth;
3052 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
3053 enum pipe_auth_type_spnego spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
3056 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3057 if (!NT_STATUS_IS_OK(status)) {
3062 auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3063 spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
3066 status = rpccli_ntlmssp_bind_data(result,
3067 auth_type, spnego_type, auth_level,
3068 domain, username, password,
3070 if (!NT_STATUS_IS_OK(status)) {
3071 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3072 nt_errstr(status)));
3076 status = rpc_pipe_bind(result, auth);
3077 if (!NT_STATUS_IS_OK(status)) {
3078 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3079 nt_errstr(status) ));
3083 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3084 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3085 get_pipe_name_from_syntax(talloc_tos(), interface),
3086 cli->desthost, domain, username ));
3089 return NT_STATUS_OK;
3093 TALLOC_FREE(result);
3097 /****************************************************************************
3099 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3100 ****************************************************************************/
3102 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3103 const struct ndr_syntax_id *interface,
3104 enum dcerpc_transport_t transport,
3105 enum dcerpc_AuthLevel auth_level,
3107 const char *username,
3108 const char *password,
3109 struct rpc_pipe_client **presult)
3111 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3122 /****************************************************************************
3124 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3125 ****************************************************************************/
3127 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3128 const struct ndr_syntax_id *interface,
3129 enum dcerpc_transport_t transport,
3130 enum dcerpc_AuthLevel auth_level,
3132 const char *username,
3133 const char *password,
3134 struct rpc_pipe_client **presult)
3136 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3147 /****************************************************************************
3148 Get a the schannel session key out of an already opened netlogon pipe.
3149 ****************************************************************************/
3150 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3151 struct cli_state *cli,
3155 enum netr_SchannelType sec_chan_type = 0;
3156 unsigned char machine_pwd[16];
3157 const char *machine_account;
3160 /* Get the machine account credentials from secrets.tdb. */
3161 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3164 DEBUG(0, ("get_schannel_session_key: could not fetch "
3165 "trust account password for domain '%s'\n",
3167 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3170 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3171 cli->desthost, /* server name */
3172 domain, /* domain */
3173 global_myname(), /* client name */
3174 machine_account, /* machine account name */
3179 if (!NT_STATUS_IS_OK(status)) {
3180 DEBUG(3, ("get_schannel_session_key_common: "
3181 "rpccli_netlogon_setup_creds failed with result %s "
3182 "to server %s, domain %s, machine account %s.\n",
3183 nt_errstr(status), cli->desthost, domain,
3188 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3189 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3191 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3194 return NT_STATUS_OK;;
3197 /****************************************************************************
3198 Open a netlogon pipe and get the schannel session key.
3199 Now exposed to external callers.
3200 ****************************************************************************/
3203 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3206 struct rpc_pipe_client **presult)
3208 struct rpc_pipe_client *netlogon_pipe = NULL;
3211 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3213 if (!NT_STATUS_IS_OK(status)) {
3217 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3219 if (!NT_STATUS_IS_OK(status)) {
3220 TALLOC_FREE(netlogon_pipe);
3224 *presult = netlogon_pipe;
3225 return NT_STATUS_OK;
3228 /****************************************************************************
3230 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3231 using session_key. sign and seal.
3233 The *pdc will be stolen onto this new pipe
3234 ****************************************************************************/
3236 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3237 const struct ndr_syntax_id *interface,
3238 enum dcerpc_transport_t transport,
3239 enum dcerpc_AuthLevel auth_level,
3241 struct netlogon_creds_CredentialState **pdc,
3242 struct rpc_pipe_client **presult)
3244 struct rpc_pipe_client *result;
3245 struct pipe_auth_data *auth;
3248 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3249 if (!NT_STATUS_IS_OK(status)) {
3253 status = rpccli_schannel_bind_data(result, domain, auth_level,
3255 if (!NT_STATUS_IS_OK(status)) {
3256 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3257 nt_errstr(status)));
3258 TALLOC_FREE(result);
3262 status = rpc_pipe_bind(result, auth);
3263 if (!NT_STATUS_IS_OK(status)) {
3264 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3265 "cli_rpc_pipe_bind failed with error %s\n",
3266 nt_errstr(status) ));
3267 TALLOC_FREE(result);
3272 * The credentials on a new netlogon pipe are the ones we are passed
3273 * in - reference them in
3275 result->dc = talloc_move(result, pdc);
3277 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3278 "for domain %s and bound using schannel.\n",
3279 get_pipe_name_from_syntax(talloc_tos(), interface),
3280 cli->desthost, domain ));
3283 return NT_STATUS_OK;
3286 /****************************************************************************
3287 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3288 Fetch the session key ourselves using a temporary netlogon pipe. This
3289 version uses an ntlmssp auth bound netlogon pipe to get the key.
3290 ****************************************************************************/
3292 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3294 const char *username,
3295 const char *password,
3297 struct rpc_pipe_client **presult)
3299 struct rpc_pipe_client *netlogon_pipe = NULL;
3302 status = cli_rpc_pipe_open_spnego_ntlmssp(
3303 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3304 DCERPC_AUTH_LEVEL_PRIVACY,
3305 domain, username, password, &netlogon_pipe);
3306 if (!NT_STATUS_IS_OK(status)) {
3310 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3312 if (!NT_STATUS_IS_OK(status)) {
3313 TALLOC_FREE(netlogon_pipe);
3317 *presult = netlogon_pipe;
3318 return NT_STATUS_OK;
3321 /****************************************************************************
3322 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3323 Fetch the session key ourselves using a temporary netlogon pipe. This version
3324 uses an ntlmssp bind to get the session key.
3325 ****************************************************************************/
3327 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3328 const struct ndr_syntax_id *interface,
3329 enum dcerpc_transport_t transport,
3330 enum dcerpc_AuthLevel auth_level,
3332 const char *username,
3333 const char *password,
3334 struct rpc_pipe_client **presult)
3336 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3337 struct rpc_pipe_client *netlogon_pipe = NULL;
3338 struct rpc_pipe_client *result = NULL;
3341 status = get_schannel_session_key_auth_ntlmssp(
3342 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3343 if (!NT_STATUS_IS_OK(status)) {
3344 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3345 "key from server %s for domain %s.\n",
3346 cli->desthost, domain ));
3350 status = cli_rpc_pipe_open_schannel_with_key(
3351 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3354 /* Now we've bound using the session key we can close the netlog pipe. */
3355 TALLOC_FREE(netlogon_pipe);
3357 if (NT_STATUS_IS_OK(status)) {
3363 /****************************************************************************
3364 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3365 Fetch the session key ourselves using a temporary netlogon pipe.
3366 ****************************************************************************/
3368 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3369 const struct ndr_syntax_id *interface,
3370 enum dcerpc_transport_t transport,
3371 enum dcerpc_AuthLevel auth_level,
3373 struct rpc_pipe_client **presult)
3375 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3376 struct rpc_pipe_client *netlogon_pipe = NULL;
3377 struct rpc_pipe_client *result = NULL;
3380 status = get_schannel_session_key(cli, domain, &neg_flags,
3382 if (!NT_STATUS_IS_OK(status)) {
3383 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3384 "key from server %s for domain %s.\n",
3385 cli->desthost, domain ));
3389 status = cli_rpc_pipe_open_schannel_with_key(
3390 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3393 /* Now we've bound using the session key we can close the netlog pipe. */
3394 TALLOC_FREE(netlogon_pipe);
3396 if (NT_STATUS_IS_OK(status)) {
3403 /****************************************************************************
3404 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3405 The idea is this can be called with service_princ, username and password all
3406 NULL so long as the caller has a TGT.
3407 ****************************************************************************/
3409 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3410 const struct ndr_syntax_id *interface,
3411 enum dcerpc_transport_t transport,
3412 enum dcerpc_AuthLevel auth_level,
3414 const char *username,
3415 const char *password,
3416 struct rpc_pipe_client **presult)
3418 struct rpc_pipe_client *result;
3419 struct pipe_auth_data *auth;
3422 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3423 if (!NT_STATUS_IS_OK(status)) {
3427 auth = talloc(result, struct pipe_auth_data);
3429 status = NT_STATUS_NO_MEMORY;
3432 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3433 auth->auth_level = auth_level;
3438 auth->user_name = talloc_strdup(auth, username);
3439 if (!auth->user_name) {
3440 status = NT_STATUS_NO_MEMORY;
3444 /* Fixme, should we fetch/set the Realm ? */
3445 auth->domain = talloc_strdup(auth, "");
3446 if (!auth->domain) {
3447 status = NT_STATUS_NO_MEMORY;
3451 status = gse_init_client(auth, auth->auth_type, auth->auth_level,
3452 NULL, server, "cifs", username, password,
3453 GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3455 if (!NT_STATUS_IS_OK(status)) {
3456 DEBUG(0, ("gse_init_client returned %s\n",
3457 nt_errstr(status)));
3461 status = rpc_pipe_bind(result, auth);
3462 if (!NT_STATUS_IS_OK(status)) {
3463 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3464 nt_errstr(status)));
3469 return NT_STATUS_OK;
3472 TALLOC_FREE(result);
3476 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3477 const struct ndr_syntax_id *interface,
3478 enum dcerpc_transport_t transport,
3479 enum dcerpc_AuthLevel auth_level,
3481 const char *username,
3482 const char *password,
3483 struct rpc_pipe_client **presult)
3485 struct rpc_pipe_client *result;
3486 struct pipe_auth_data *auth;
3489 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3490 if (!NT_STATUS_IS_OK(status)) {
3494 auth = talloc(result, struct pipe_auth_data);
3496 status = NT_STATUS_NO_MEMORY;
3499 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3500 auth->auth_level = auth_level;
3502 auth->spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
3507 auth->user_name = talloc_strdup(auth, username);
3508 if (!auth->user_name) {
3509 status = NT_STATUS_NO_MEMORY;
3513 /* Fixme, should we fetch/set the Realm ? */
3514 auth->domain = talloc_strdup(auth, "");
3515 if (!auth->domain) {
3516 status = NT_STATUS_NO_MEMORY;
3520 status = spnego_gssapi_init_client(auth, auth->auth_level,
3521 NULL, server, "cifs",
3524 &auth->a_u.spnego_state);
3525 if (!NT_STATUS_IS_OK(status)) {
3526 DEBUG(0, ("spnego_init_client returned %s\n",
3527 nt_errstr(status)));
3531 status = rpc_pipe_bind(result, auth);
3532 if (!NT_STATUS_IS_OK(status)) {
3533 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3534 nt_errstr(status)));
3539 return NT_STATUS_OK;
3542 TALLOC_FREE(result);
3546 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3547 struct rpc_pipe_client *cli,
3548 DATA_BLOB *session_key)
3550 struct pipe_auth_data *a = cli->auth;
3553 if (!session_key || !cli) {
3554 return NT_STATUS_INVALID_PARAMETER;
3558 return NT_STATUS_INVALID_PARAMETER;
3561 switch (cli->auth->auth_type) {
3562 case DCERPC_AUTH_TYPE_SCHANNEL:
3563 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3566 case DCERPC_AUTH_TYPE_SPNEGO:
3567 switch (cli->auth->spnego_type) {
3568 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3569 sk = auth_ntlmssp_get_session_key(
3570 a->a_u.auth_ntlmssp_state);
3572 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3573 sk = gse_get_session_key(a->a_u.gssapi_state);
3576 return NT_STATUS_NO_USER_SESSION_KEY;
3579 case DCERPC_AUTH_TYPE_NTLMSSP:
3580 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3582 case DCERPC_AUTH_TYPE_KRB5:
3583 sk = gse_get_session_key(a->a_u.gssapi_state);
3585 case DCERPC_AUTH_TYPE_NONE:
3586 sk = data_blob_const(a->user_session_key.data,
3587 a->user_session_key.length);
3590 return NT_STATUS_NO_USER_SESSION_KEY;
3593 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3594 return NT_STATUS_OK;