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 NTLMSSP auth bind.
1029 ********************************************************************/
1031 static NTSTATUS create_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;
1039 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1040 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1044 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1045 data_blob_free(&request);
1049 status = dcerpc_push_dcerpc_auth(cli,
1050 DCERPC_AUTH_TYPE_NTLMSSP,
1052 0, /* auth_pad_length */
1053 1, /* auth_context_id */
1056 if (!NT_STATUS_IS_OK(status)) {
1057 data_blob_free(&request);
1061 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1062 dump_data(5, request.data, request.length);
1064 return NT_STATUS_OK;
1067 /*******************************************************************
1068 Creates schannel auth bind.
1069 ********************************************************************/
1071 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1072 enum dcerpc_AuthLevel auth_level,
1073 DATA_BLOB *auth_info)
1076 struct NL_AUTH_MESSAGE r;
1077 DATA_BLOB schannel_blob;
1079 /* Use lp_workgroup() if domain not specified */
1081 if (!cli->auth->domain || !cli->auth->domain[0]) {
1082 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1083 if (cli->auth->domain == NULL) {
1084 return NT_STATUS_NO_MEMORY;
1089 * Now marshall the data into the auth parse_struct.
1092 r.MessageType = NL_NEGOTIATE_REQUEST;
1093 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1094 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1095 r.oem_netbios_domain.a = cli->auth->domain;
1096 r.oem_netbios_computer.a = global_myname();
1098 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1099 if (!NT_STATUS_IS_OK(status)) {
1103 status = dcerpc_push_dcerpc_auth(cli,
1104 DCERPC_AUTH_TYPE_SCHANNEL,
1106 0, /* auth_pad_length */
1107 1, /* auth_context_id */
1110 if (!NT_STATUS_IS_OK(status)) {
1114 return NT_STATUS_OK;
1117 /*******************************************************************
1118 Creates the internals of a DCE/RPC bind request or alter context PDU.
1119 ********************************************************************/
1121 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1122 enum dcerpc_pkt_type ptype,
1124 const struct ndr_syntax_id *abstract,
1125 const struct ndr_syntax_id *transfer,
1126 const DATA_BLOB *auth_info,
1129 uint16 auth_len = auth_info->length;
1131 union dcerpc_payload u;
1132 struct dcerpc_ctx_list ctx_list;
1135 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1138 ctx_list.context_id = 0;
1139 ctx_list.num_transfer_syntaxes = 1;
1140 ctx_list.abstract_syntax = *abstract;
1141 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1143 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1144 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1145 u.bind.assoc_group_id = 0x0;
1146 u.bind.num_contexts = 1;
1147 u.bind.ctx_list = &ctx_list;
1148 u.bind.auth_info = *auth_info;
1150 status = dcerpc_push_ncacn_packet(mem_ctx,
1152 DCERPC_PFC_FLAG_FIRST |
1153 DCERPC_PFC_FLAG_LAST,
1158 if (!NT_STATUS_IS_OK(status)) {
1159 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1163 return NT_STATUS_OK;
1166 /*******************************************************************
1167 Creates a DCE/RPC bind request.
1168 ********************************************************************/
1170 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1171 struct rpc_pipe_client *cli,
1172 struct pipe_auth_data *auth,
1174 const struct ndr_syntax_id *abstract,
1175 const struct ndr_syntax_id *transfer,
1178 DATA_BLOB auth_info = data_blob_null;
1179 NTSTATUS ret = NT_STATUS_OK;
1181 switch (auth->auth_type) {
1182 case DCERPC_AUTH_TYPE_SCHANNEL:
1183 ret = create_schannel_auth_rpc_bind_req(cli,
1186 if (!NT_STATUS_IS_OK(ret)) {
1191 case DCERPC_AUTH_TYPE_NTLMSSP:
1192 ret = create_ntlmssp_auth_rpc_bind_req(cli,
1195 if (!NT_STATUS_IS_OK(ret)) {
1200 case DCERPC_AUTH_TYPE_SPNEGO:
1201 ret = create_spnego_auth_bind_req(cli, auth, &auth_info);
1202 if (!NT_STATUS_IS_OK(ret)) {
1207 case DCERPC_AUTH_TYPE_KRB5:
1208 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_info);
1209 if (!NT_STATUS_IS_OK(ret)) {
1214 case DCERPC_AUTH_TYPE_NONE:
1218 /* "Can't" happen. */
1219 return NT_STATUS_INVALID_INFO_CLASS;
1222 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1232 /*******************************************************************
1233 Calculate how much data we're going to send in this packet, also
1234 work out any sign/seal padding length.
1235 ********************************************************************/
1237 static NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli,
1239 uint32_t *data_to_send,
1240 uint16_t *p_frag_len,
1241 uint16_t *p_auth_len,
1242 uint32_t *p_ss_padding)
1244 uint32_t data_space, data_len;
1246 struct gse_context *gse_ctx;
1247 enum dcerpc_AuthType auth_type;
1251 switch (cli->auth->auth_level) {
1252 case DCERPC_AUTH_LEVEL_NONE:
1253 case DCERPC_AUTH_LEVEL_CONNECT:
1254 case DCERPC_AUTH_LEVEL_PACKET:
1255 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1256 data_len = MIN(data_space, data_left);
1259 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1260 *data_to_send = data_len;
1261 return NT_STATUS_OK;
1263 case DCERPC_AUTH_LEVEL_INTEGRITY:
1264 case DCERPC_AUTH_LEVEL_PRIVACY:
1265 max_len = cli->max_xmit_frag
1266 - DCERPC_REQUEST_LENGTH
1267 - DCERPC_AUTH_TRAILER_LENGTH;
1269 /* Treat the same for all authenticated rpc requests. */
1270 switch(cli->auth->auth_type) {
1271 case DCERPC_AUTH_TYPE_SPNEGO:
1272 status = spnego_get_negotiated_mech(
1273 cli->auth->a_u.spnego_state,
1274 &auth_type, &auth_ctx);
1275 if (!NT_STATUS_IS_OK(status)) {
1278 switch (auth_type) {
1279 case DCERPC_AUTH_TYPE_NTLMSSP:
1280 *p_auth_len = NTLMSSP_SIG_SIZE;
1282 case DCERPC_AUTH_TYPE_KRB5:
1283 gse_ctx = talloc_get_type(auth_ctx,
1284 struct gse_context);
1286 return NT_STATUS_INVALID_PARAMETER;
1288 *p_auth_len = gse_get_signature_length(gse_ctx,
1289 (cli->auth->auth_level ==
1290 DCERPC_AUTH_LEVEL_PRIVACY),
1294 return NT_STATUS_INVALID_PARAMETER;
1297 case DCERPC_AUTH_TYPE_NTLMSSP:
1298 *p_auth_len = NTLMSSP_SIG_SIZE;
1300 case DCERPC_AUTH_TYPE_SCHANNEL:
1301 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1303 case DCERPC_AUTH_TYPE_KRB5:
1304 *p_auth_len = gse_get_signature_length(
1305 cli->auth->a_u.gssapi_state,
1306 (cli->auth->auth_level ==
1307 DCERPC_AUTH_LEVEL_PRIVACY),
1311 return NT_STATUS_INVALID_PARAMETER;
1314 data_space = max_len - *p_auth_len;
1316 data_len = MIN(data_space, data_left);
1318 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1319 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1321 *p_frag_len = DCERPC_REQUEST_LENGTH
1322 + data_len + *p_ss_padding
1323 + DCERPC_AUTH_TRAILER_LENGTH
1325 *data_to_send = data_len;
1326 return NT_STATUS_OK;
1332 return NT_STATUS_INVALID_PARAMETER;
1335 /*******************************************************************
1337 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1338 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1339 and deals with signing/sealing details.
1340 ********************************************************************/
1342 struct rpc_api_pipe_req_state {
1343 struct event_context *ev;
1344 struct rpc_pipe_client *cli;
1347 DATA_BLOB *req_data;
1348 uint32_t req_data_sent;
1350 DATA_BLOB reply_pdu;
1353 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1354 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1355 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1356 bool *is_last_frag);
1358 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1359 struct event_context *ev,
1360 struct rpc_pipe_client *cli,
1362 DATA_BLOB *req_data)
1364 struct tevent_req *req, *subreq;
1365 struct rpc_api_pipe_req_state *state;
1369 req = tevent_req_create(mem_ctx, &state,
1370 struct rpc_api_pipe_req_state);
1376 state->op_num = op_num;
1377 state->req_data = req_data;
1378 state->req_data_sent = 0;
1379 state->call_id = get_rpc_call_id();
1380 state->reply_pdu = data_blob_null;
1381 state->rpc_out = data_blob_null;
1383 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1384 + RPC_MAX_SIGN_SIZE) {
1385 /* Server is screwed up ! */
1386 status = NT_STATUS_INVALID_PARAMETER;
1390 status = prepare_next_frag(state, &is_last_frag);
1391 if (!NT_STATUS_IS_OK(status)) {
1396 subreq = rpc_api_pipe_send(state, ev, state->cli,
1398 DCERPC_PKT_RESPONSE);
1399 if (subreq == NULL) {
1402 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1404 subreq = rpc_write_send(state, ev, cli->transport,
1405 state->rpc_out.data,
1406 state->rpc_out.length);
1407 if (subreq == NULL) {
1410 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1416 tevent_req_nterror(req, status);
1417 return tevent_req_post(req, ev);
1423 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1426 uint32_t data_sent_thistime;
1433 union dcerpc_payload u;
1435 data_left = state->req_data->length - state->req_data_sent;
1437 status = calculate_data_len_tosend(state->cli, data_left,
1438 &data_sent_thistime,
1439 &frag_len, &auth_len,
1441 if (!NT_STATUS_IS_OK(status)) {
1445 if (state->req_data_sent == 0) {
1446 flags = DCERPC_PFC_FLAG_FIRST;
1449 if (data_sent_thistime == data_left) {
1450 flags |= DCERPC_PFC_FLAG_LAST;
1453 data_blob_free(&state->rpc_out);
1455 ZERO_STRUCT(u.request);
1457 u.request.alloc_hint = state->req_data->length;
1458 u.request.context_id = 0;
1459 u.request.opnum = state->op_num;
1461 status = dcerpc_push_ncacn_packet(state,
1468 if (!NT_STATUS_IS_OK(status)) {
1472 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1473 * compute it right for requests because the auth trailer is missing
1475 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1477 /* Copy in the data. */
1478 if (!data_blob_append(NULL, &state->rpc_out,
1479 state->req_data->data + state->req_data_sent,
1480 data_sent_thistime)) {
1481 return NT_STATUS_NO_MEMORY;
1484 switch (state->cli->auth->auth_level) {
1485 case DCERPC_AUTH_LEVEL_NONE:
1486 case DCERPC_AUTH_LEVEL_CONNECT:
1487 case DCERPC_AUTH_LEVEL_PACKET:
1489 case DCERPC_AUTH_LEVEL_INTEGRITY:
1490 case DCERPC_AUTH_LEVEL_PRIVACY:
1491 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1493 if (!NT_STATUS_IS_OK(status)) {
1498 return NT_STATUS_INVALID_PARAMETER;
1501 state->req_data_sent += data_sent_thistime;
1502 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1507 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1509 struct tevent_req *req = tevent_req_callback_data(
1510 subreq, struct tevent_req);
1511 struct rpc_api_pipe_req_state *state = tevent_req_data(
1512 req, struct rpc_api_pipe_req_state);
1516 status = rpc_write_recv(subreq);
1517 TALLOC_FREE(subreq);
1518 if (!NT_STATUS_IS_OK(status)) {
1519 tevent_req_nterror(req, status);
1523 status = prepare_next_frag(state, &is_last_frag);
1524 if (!NT_STATUS_IS_OK(status)) {
1525 tevent_req_nterror(req, status);
1530 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1532 DCERPC_PKT_RESPONSE);
1533 if (tevent_req_nomem(subreq, req)) {
1536 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1538 subreq = rpc_write_send(state, state->ev,
1539 state->cli->transport,
1540 state->rpc_out.data,
1541 state->rpc_out.length);
1542 if (tevent_req_nomem(subreq, req)) {
1545 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1550 static void rpc_api_pipe_req_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);
1558 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1559 TALLOC_FREE(subreq);
1560 if (!NT_STATUS_IS_OK(status)) {
1561 tevent_req_nterror(req, status);
1564 tevent_req_done(req);
1567 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1568 DATA_BLOB *reply_pdu)
1570 struct rpc_api_pipe_req_state *state = tevent_req_data(
1571 req, struct rpc_api_pipe_req_state);
1574 if (tevent_req_is_nterror(req, &status)) {
1576 * We always have to initialize to reply pdu, even if there is
1577 * none. The rpccli_* caller routines expect this.
1579 *reply_pdu = data_blob_null;
1583 /* return data to caller and assign it ownership of memory */
1584 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1585 reply_pdu->length = state->reply_pdu.length;
1586 state->reply_pdu.length = 0;
1588 return NT_STATUS_OK;
1592 /****************************************************************************
1593 Set the handle state.
1594 ****************************************************************************/
1596 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1597 const char *pipe_name, uint16 device_state)
1599 bool state_set = False;
1601 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1602 char *rparam = NULL;
1604 uint32 rparam_len, rdata_len;
1606 if (pipe_name == NULL)
1609 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1610 cli->fnum, pipe_name, device_state));
1612 /* create parameters: device state */
1613 SSVAL(param, 0, device_state);
1615 /* create setup parameters. */
1617 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1619 /* send the data on \PIPE\ */
1620 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1621 setup, 2, 0, /* setup, length, max */
1622 param, 2, 0, /* param, length, max */
1623 NULL, 0, 1024, /* data, length, max */
1624 &rparam, &rparam_len, /* return param, length */
1625 &rdata, &rdata_len)) /* return data, length */
1627 DEBUG(5, ("Set Handle state: return OK\n"));
1638 /****************************************************************************
1639 Check the rpc bind acknowledge response.
1640 ****************************************************************************/
1642 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1643 const struct ndr_syntax_id *transfer)
1645 struct dcerpc_ack_ctx ctx;
1647 if (r->secondary_address_size == 0) {
1648 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1651 if (r->num_results < 1 || !r->ctx_list) {
1655 ctx = r->ctx_list[0];
1657 /* check the transfer syntax */
1658 if ((ctx.syntax.if_version != transfer->if_version) ||
1659 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1660 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1664 if (r->num_results != 0x1 || ctx.result != 0) {
1665 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1666 r->num_results, ctx.reason));
1669 DEBUG(5,("check_bind_response: accepted!\n"));
1673 /*******************************************************************
1674 Creates a DCE/RPC bind authentication response.
1675 This is the packet that is sent back to the server once we
1676 have received a BIND-ACK, to finish the third leg of
1677 the authentication handshake.
1678 ********************************************************************/
1680 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1681 struct rpc_pipe_client *cli,
1683 enum dcerpc_AuthType auth_type,
1684 enum dcerpc_AuthLevel auth_level,
1685 DATA_BLOB *pauth_blob,
1689 union dcerpc_payload u;
1693 status = dcerpc_push_dcerpc_auth(mem_ctx,
1696 0, /* auth_pad_length */
1697 1, /* auth_context_id */
1699 &u.auth3.auth_info);
1700 if (!NT_STATUS_IS_OK(status)) {
1704 status = dcerpc_push_ncacn_packet(mem_ctx,
1706 DCERPC_PFC_FLAG_FIRST |
1707 DCERPC_PFC_FLAG_LAST,
1712 data_blob_free(&u.auth3.auth_info);
1713 if (!NT_STATUS_IS_OK(status)) {
1714 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1718 return NT_STATUS_OK;
1721 /*******************************************************************
1722 Creates a DCE/RPC bind alter context authentication request which
1723 may contain a spnego auth blobl
1724 ********************************************************************/
1726 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1727 enum dcerpc_AuthType auth_type,
1728 enum dcerpc_AuthLevel auth_level,
1730 const struct ndr_syntax_id *abstract,
1731 const struct ndr_syntax_id *transfer,
1732 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1735 DATA_BLOB auth_info;
1738 status = dcerpc_push_dcerpc_auth(mem_ctx,
1741 0, /* auth_pad_length */
1742 1, /* auth_context_id */
1745 if (!NT_STATUS_IS_OK(status)) {
1749 status = create_bind_or_alt_ctx_internal(mem_ctx,
1756 data_blob_free(&auth_info);
1760 /****************************************************************************
1762 ****************************************************************************/
1764 struct rpc_pipe_bind_state {
1765 struct event_context *ev;
1766 struct rpc_pipe_client *cli;
1768 uint32_t rpc_call_id;
1771 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1772 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1773 struct rpc_pipe_bind_state *state,
1774 DATA_BLOB *credentials);
1775 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1776 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1777 struct rpc_pipe_bind_state *state,
1778 DATA_BLOB *credentials);
1779 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1780 struct rpc_pipe_bind_state *state,
1781 DATA_BLOB *credentials);
1783 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1784 struct event_context *ev,
1785 struct rpc_pipe_client *cli,
1786 struct pipe_auth_data *auth)
1788 struct tevent_req *req, *subreq;
1789 struct rpc_pipe_bind_state *state;
1792 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1797 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1798 rpccli_pipe_txt(talloc_tos(), cli),
1799 (unsigned int)auth->auth_type,
1800 (unsigned int)auth->spnego_type,
1801 (unsigned int)auth->auth_level ));
1805 state->rpc_call_id = get_rpc_call_id();
1806 state->rpc_out = data_blob_null;
1808 cli->auth = talloc_move(cli, &auth);
1810 /* Marshall the outgoing data. */
1811 status = create_rpc_bind_req(state, cli,
1814 &cli->abstract_syntax,
1815 &cli->transfer_syntax,
1818 if (!NT_STATUS_IS_OK(status)) {
1822 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1823 DCERPC_PKT_BIND_ACK);
1824 if (subreq == NULL) {
1827 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1831 tevent_req_nterror(req, status);
1832 return tevent_req_post(req, ev);
1838 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1840 struct tevent_req *req = tevent_req_callback_data(
1841 subreq, struct tevent_req);
1842 struct rpc_pipe_bind_state *state = tevent_req_data(
1843 req, struct rpc_pipe_bind_state);
1844 struct pipe_auth_data *pauth = state->cli->auth;
1845 DATA_BLOB reply_pdu;
1846 struct ncacn_packet *pkt;
1847 struct dcerpc_auth auth;
1848 DATA_BLOB auth_token = data_blob_null;
1851 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1852 TALLOC_FREE(subreq);
1853 if (!NT_STATUS_IS_OK(status)) {
1854 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1855 rpccli_pipe_txt(talloc_tos(), state->cli),
1856 nt_errstr(status)));
1857 tevent_req_nterror(req, status);
1861 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1862 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1863 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1867 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1868 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1870 switch(state->cli->auth->auth_type) {
1872 case DCERPC_AUTH_TYPE_NONE:
1873 case DCERPC_AUTH_TYPE_SCHANNEL:
1874 /* Bind complete. */
1875 tevent_req_done(req);
1878 case DCERPC_AUTH_TYPE_NTLMSSP:
1879 case DCERPC_AUTH_TYPE_SPNEGO:
1880 case DCERPC_AUTH_TYPE_KRB5:
1881 /* Paranoid lenght checks */
1882 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1883 + pkt->auth_length) {
1884 tevent_req_nterror(req,
1885 NT_STATUS_INFO_LENGTH_MISMATCH);
1888 /* get auth credentials */
1889 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1890 &pkt->u.bind_ack.auth_info,
1892 if (!NT_STATUS_IS_OK(status)) {
1893 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1894 nt_errstr(status)));
1895 tevent_req_nterror(req, status);
1905 * For authenticated binds we may need to do 3 or 4 leg binds.
1908 switch(state->cli->auth->auth_type) {
1910 case DCERPC_AUTH_TYPE_NONE:
1911 case DCERPC_AUTH_TYPE_SCHANNEL:
1912 /* Bind complete. */
1913 tevent_req_done(req);
1916 case DCERPC_AUTH_TYPE_NTLMSSP:
1917 /* Need to send AUTH3 packet - no reply. */
1918 status = rpc_finish_auth3_bind_send(req, state,
1922 case DCERPC_AUTH_TYPE_SPNEGO:
1923 status = spnego_get_client_auth_token(state,
1924 pauth->a_u.spnego_state,
1927 if (!NT_STATUS_IS_OK(status)) {
1930 if (auth_token.length == 0) {
1931 /* Bind complete. */
1932 tevent_req_done(req);
1935 if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
1936 status = rpc_bind_next_send(req, state,
1939 status = rpc_bind_finish_send(req, state,
1944 case DCERPC_AUTH_TYPE_KRB5:
1945 status = gse_get_client_auth_token(state,
1946 pauth->a_u.gssapi_state,
1949 if (!NT_STATUS_IS_OK(status)) {
1953 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
1954 status = rpc_bind_next_send(req, state, &auth_token);
1956 status = rpc_bind_finish_send(req, state, &auth_token);
1964 if (!NT_STATUS_IS_OK(status)) {
1965 tevent_req_nterror(req, status);
1970 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
1971 (unsigned int)state->cli->auth->auth_type,
1972 (unsigned int)state->cli->auth->spnego_type));
1973 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1976 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1977 struct rpc_pipe_bind_state *state,
1978 DATA_BLOB *credentials)
1980 struct pipe_auth_data *auth = state->cli->auth;
1981 DATA_BLOB client_reply = data_blob_null;
1982 struct tevent_req *subreq;
1985 /* TODO - check auth_type/auth_level match. */
1987 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
1988 *credentials, &client_reply);
1990 if (!NT_STATUS_IS_OK(status)) {
1991 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
1992 "blob failed: %s.\n", nt_errstr(status)));
1996 data_blob_free(&state->rpc_out);
1998 status = create_rpc_bind_auth3(state, state->cli,
2004 data_blob_free(&client_reply);
2006 if (!NT_STATUS_IS_OK(status)) {
2010 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2011 state->rpc_out.data, state->rpc_out.length);
2012 if (subreq == NULL) {
2013 return NT_STATUS_NO_MEMORY;
2015 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2016 return NT_STATUS_OK;
2019 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2021 struct tevent_req *req = tevent_req_callback_data(
2022 subreq, struct tevent_req);
2025 status = rpc_write_recv(subreq);
2026 TALLOC_FREE(subreq);
2027 if (!NT_STATUS_IS_OK(status)) {
2028 tevent_req_nterror(req, status);
2031 tevent_req_done(req);
2034 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2035 struct rpc_pipe_bind_state *state,
2036 DATA_BLOB *auth_token)
2038 struct pipe_auth_data *auth = state->cli->auth;
2039 struct tevent_req *subreq;
2042 /* Now prepare the alter context pdu. */
2043 data_blob_free(&state->rpc_out);
2045 status = create_rpc_alter_context(state,
2049 &state->cli->abstract_syntax,
2050 &state->cli->transfer_syntax,
2053 if (!NT_STATUS_IS_OK(status)) {
2057 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2058 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2059 if (subreq == NULL) {
2060 return NT_STATUS_NO_MEMORY;
2062 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2063 return NT_STATUS_OK;
2066 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2067 struct rpc_pipe_bind_state *state,
2068 DATA_BLOB *auth_token)
2070 struct pipe_auth_data *auth = state->cli->auth;
2071 struct tevent_req *subreq;
2074 /* Now prepare the auth3 context pdu. */
2075 data_blob_free(&state->rpc_out);
2077 status = create_rpc_bind_auth3(state, state->cli,
2083 if (!NT_STATUS_IS_OK(status)) {
2087 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2088 state->rpc_out.data, state->rpc_out.length);
2089 if (subreq == NULL) {
2090 return NT_STATUS_NO_MEMORY;
2092 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2093 return NT_STATUS_OK;
2096 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2098 return tevent_req_simple_recv_ntstatus(req);
2101 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2102 struct pipe_auth_data *auth)
2104 TALLOC_CTX *frame = talloc_stackframe();
2105 struct event_context *ev;
2106 struct tevent_req *req;
2107 NTSTATUS status = NT_STATUS_OK;
2109 ev = event_context_init(frame);
2111 status = NT_STATUS_NO_MEMORY;
2115 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2117 status = NT_STATUS_NO_MEMORY;
2121 if (!tevent_req_poll(req, ev)) {
2122 status = map_nt_error_from_unix(errno);
2126 status = rpc_pipe_bind_recv(req);
2132 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2134 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2135 unsigned int timeout)
2139 if (rpc_cli->transport == NULL) {
2140 return RPCCLI_DEFAULT_TIMEOUT;
2143 if (rpc_cli->transport->set_timeout == NULL) {
2144 return RPCCLI_DEFAULT_TIMEOUT;
2147 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2149 return RPCCLI_DEFAULT_TIMEOUT;
2155 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2157 if (rpc_cli == NULL) {
2161 if (rpc_cli->transport == NULL) {
2165 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2168 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2170 struct auth_ntlmssp_state *a = NULL;
2171 struct cli_state *cli;
2173 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2174 a = rpc_cli->auth->a_u.auth_ntlmssp_state;
2175 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2176 enum dcerpc_AuthType auth_type;
2180 status = spnego_get_negotiated_mech(
2181 rpc_cli->auth->a_u.spnego_state,
2182 &auth_type, &auth_ctx);
2183 if (!NT_STATUS_IS_OK(status)) {
2187 if (auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2188 a = talloc_get_type(auth_ctx,
2189 struct auth_ntlmssp_state);
2194 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2198 cli = rpc_pipe_np_smb_conn(rpc_cli);
2202 E_md4hash(cli->password ? cli->password : "", nt_hash);
2206 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2207 struct pipe_auth_data **presult)
2209 struct pipe_auth_data *result;
2211 result = talloc(mem_ctx, struct pipe_auth_data);
2212 if (result == NULL) {
2213 return NT_STATUS_NO_MEMORY;
2216 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2217 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2218 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2220 result->user_name = talloc_strdup(result, "");
2221 result->domain = talloc_strdup(result, "");
2222 if ((result->user_name == NULL) || (result->domain == NULL)) {
2223 TALLOC_FREE(result);
2224 return NT_STATUS_NO_MEMORY;
2228 return NT_STATUS_OK;
2231 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2233 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2237 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2238 enum dcerpc_AuthType auth_type,
2239 enum dcerpc_AuthLevel auth_level,
2241 const char *username,
2242 const char *password,
2243 struct pipe_auth_data **presult)
2245 struct pipe_auth_data *result;
2248 result = talloc(mem_ctx, struct pipe_auth_data);
2249 if (result == NULL) {
2250 return NT_STATUS_NO_MEMORY;
2253 result->auth_type = auth_type;
2254 result->auth_level = auth_level;
2256 result->user_name = talloc_strdup(result, username);
2257 result->domain = talloc_strdup(result, domain);
2258 if ((result->user_name == NULL) || (result->domain == NULL)) {
2259 status = NT_STATUS_NO_MEMORY;
2263 status = auth_ntlmssp_client_start(NULL,
2266 lp_client_ntlmv2_auth(),
2267 &result->a_u.auth_ntlmssp_state);
2268 if (!NT_STATUS_IS_OK(status)) {
2272 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2274 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2276 if (!NT_STATUS_IS_OK(status)) {
2280 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2282 if (!NT_STATUS_IS_OK(status)) {
2286 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2288 if (!NT_STATUS_IS_OK(status)) {
2293 * Turn off sign+seal to allow selected auth level to turn it back on.
2295 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2296 ~(NTLMSSP_NEGOTIATE_SIGN |
2297 NTLMSSP_NEGOTIATE_SEAL));
2299 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2300 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2301 NTLMSSP_NEGOTIATE_SIGN);
2302 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2303 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2304 NTLMSSP_NEGOTIATE_SEAL |
2305 NTLMSSP_NEGOTIATE_SIGN);
2309 return NT_STATUS_OK;
2312 TALLOC_FREE(result);
2316 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2317 enum dcerpc_AuthLevel auth_level,
2318 struct netlogon_creds_CredentialState *creds,
2319 struct pipe_auth_data **presult)
2321 struct pipe_auth_data *result;
2323 result = talloc(mem_ctx, struct pipe_auth_data);
2324 if (result == NULL) {
2325 return NT_STATUS_NO_MEMORY;
2328 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2329 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2330 result->auth_level = auth_level;
2332 result->user_name = talloc_strdup(result, "");
2333 result->domain = talloc_strdup(result, domain);
2334 if ((result->user_name == NULL) || (result->domain == NULL)) {
2338 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2339 if (result->a_u.schannel_auth == NULL) {
2343 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2344 result->a_u.schannel_auth->seq_num = 0;
2345 result->a_u.schannel_auth->initiator = true;
2346 result->a_u.schannel_auth->creds = creds;
2349 return NT_STATUS_OK;
2352 TALLOC_FREE(result);
2353 return NT_STATUS_NO_MEMORY;
2357 * Create an rpc pipe client struct, connecting to a tcp port.
2359 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2361 const struct ndr_syntax_id *abstract_syntax,
2362 struct rpc_pipe_client **presult)
2364 struct rpc_pipe_client *result;
2365 struct sockaddr_storage addr;
2369 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2370 if (result == NULL) {
2371 return NT_STATUS_NO_MEMORY;
2374 result->abstract_syntax = *abstract_syntax;
2375 result->transfer_syntax = ndr_transfer_syntax;
2376 result->dispatch = cli_do_rpc_ndr;
2377 result->dispatch_send = cli_do_rpc_ndr_send;
2378 result->dispatch_recv = cli_do_rpc_ndr_recv;
2380 result->desthost = talloc_strdup(result, host);
2381 result->srv_name_slash = talloc_asprintf_strupper_m(
2382 result, "\\\\%s", result->desthost);
2383 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2384 status = NT_STATUS_NO_MEMORY;
2388 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2389 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2391 if (!resolve_name(host, &addr, 0, false)) {
2392 status = NT_STATUS_NOT_FOUND;
2396 status = open_socket_out(&addr, port, 60, &fd);
2397 if (!NT_STATUS_IS_OK(status)) {
2400 set_socket_options(fd, lp_socket_options());
2402 status = rpc_transport_sock_init(result, fd, &result->transport);
2403 if (!NT_STATUS_IS_OK(status)) {
2408 result->transport->transport = NCACN_IP_TCP;
2411 return NT_STATUS_OK;
2414 TALLOC_FREE(result);
2419 * Determine the tcp port on which a dcerpc interface is listening
2420 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2423 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2424 const struct ndr_syntax_id *abstract_syntax,
2428 struct rpc_pipe_client *epm_pipe = NULL;
2429 struct pipe_auth_data *auth = NULL;
2430 struct dcerpc_binding *map_binding = NULL;
2431 struct dcerpc_binding *res_binding = NULL;
2432 struct epm_twr_t *map_tower = NULL;
2433 struct epm_twr_t *res_towers = NULL;
2434 struct policy_handle *entry_handle = NULL;
2435 uint32_t num_towers = 0;
2436 uint32_t max_towers = 1;
2437 struct epm_twr_p_t towers;
2438 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2440 if (pport == NULL) {
2441 status = NT_STATUS_INVALID_PARAMETER;
2445 /* open the connection to the endpoint mapper */
2446 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2447 &ndr_table_epmapper.syntax_id,
2450 if (!NT_STATUS_IS_OK(status)) {
2454 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2455 if (!NT_STATUS_IS_OK(status)) {
2459 status = rpc_pipe_bind(epm_pipe, auth);
2460 if (!NT_STATUS_IS_OK(status)) {
2464 /* create tower for asking the epmapper */
2466 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2467 if (map_binding == NULL) {
2468 status = NT_STATUS_NO_MEMORY;
2472 map_binding->transport = NCACN_IP_TCP;
2473 map_binding->object = *abstract_syntax;
2474 map_binding->host = host; /* needed? */
2475 map_binding->endpoint = "0"; /* correct? needed? */
2477 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2478 if (map_tower == NULL) {
2479 status = NT_STATUS_NO_MEMORY;
2483 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2484 &(map_tower->tower));
2485 if (!NT_STATUS_IS_OK(status)) {
2489 /* allocate further parameters for the epm_Map call */
2491 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2492 if (res_towers == NULL) {
2493 status = NT_STATUS_NO_MEMORY;
2496 towers.twr = res_towers;
2498 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2499 if (entry_handle == NULL) {
2500 status = NT_STATUS_NO_MEMORY;
2504 /* ask the endpoint mapper for the port */
2506 status = rpccli_epm_Map(epm_pipe,
2508 CONST_DISCARD(struct GUID *,
2509 &(abstract_syntax->uuid)),
2516 if (!NT_STATUS_IS_OK(status)) {
2520 if (num_towers != 1) {
2521 status = NT_STATUS_UNSUCCESSFUL;
2525 /* extract the port from the answer */
2527 status = dcerpc_binding_from_tower(tmp_ctx,
2528 &(towers.twr->tower),
2530 if (!NT_STATUS_IS_OK(status)) {
2534 /* are further checks here necessary? */
2535 if (res_binding->transport != NCACN_IP_TCP) {
2536 status = NT_STATUS_UNSUCCESSFUL;
2540 *pport = (uint16_t)atoi(res_binding->endpoint);
2543 TALLOC_FREE(tmp_ctx);
2548 * Create a rpc pipe client struct, connecting to a host via tcp.
2549 * The port is determined by asking the endpoint mapper on the given
2552 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2553 const struct ndr_syntax_id *abstract_syntax,
2554 struct rpc_pipe_client **presult)
2559 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2560 if (!NT_STATUS_IS_OK(status)) {
2564 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2565 abstract_syntax, presult);
2568 /********************************************************************
2569 Create a rpc pipe client struct, connecting to a unix domain socket
2570 ********************************************************************/
2571 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2572 const struct ndr_syntax_id *abstract_syntax,
2573 struct rpc_pipe_client **presult)
2575 struct rpc_pipe_client *result;
2576 struct sockaddr_un addr;
2580 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2581 if (result == NULL) {
2582 return NT_STATUS_NO_MEMORY;
2585 result->abstract_syntax = *abstract_syntax;
2586 result->transfer_syntax = ndr_transfer_syntax;
2587 result->dispatch = cli_do_rpc_ndr;
2588 result->dispatch_send = cli_do_rpc_ndr_send;
2589 result->dispatch_recv = cli_do_rpc_ndr_recv;
2591 result->desthost = get_myname(result);
2592 result->srv_name_slash = talloc_asprintf_strupper_m(
2593 result, "\\\\%s", result->desthost);
2594 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2595 status = NT_STATUS_NO_MEMORY;
2599 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2600 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2602 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2604 status = map_nt_error_from_unix(errno);
2609 addr.sun_family = AF_UNIX;
2610 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2612 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2613 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2616 return map_nt_error_from_unix(errno);
2619 status = rpc_transport_sock_init(result, fd, &result->transport);
2620 if (!NT_STATUS_IS_OK(status)) {
2625 result->transport->transport = NCALRPC;
2628 return NT_STATUS_OK;
2631 TALLOC_FREE(result);
2635 struct rpc_pipe_client_np_ref {
2636 struct cli_state *cli;
2637 struct rpc_pipe_client *pipe;
2640 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2642 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2646 /****************************************************************************
2647 Open a named pipe over SMB to a remote server.
2649 * CAVEAT CALLER OF THIS FUNCTION:
2650 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2651 * so be sure that this function is called AFTER any structure (vs pointer)
2652 * assignment of the cli. In particular, libsmbclient does structure
2653 * assignments of cli, which invalidates the data in the returned
2654 * rpc_pipe_client if this function is called before the structure assignment
2657 ****************************************************************************/
2659 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2660 const struct ndr_syntax_id *abstract_syntax,
2661 struct rpc_pipe_client **presult)
2663 struct rpc_pipe_client *result;
2665 struct rpc_pipe_client_np_ref *np_ref;
2667 /* sanity check to protect against crashes */
2670 return NT_STATUS_INVALID_HANDLE;
2673 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2674 if (result == NULL) {
2675 return NT_STATUS_NO_MEMORY;
2678 result->abstract_syntax = *abstract_syntax;
2679 result->transfer_syntax = ndr_transfer_syntax;
2680 result->dispatch = cli_do_rpc_ndr;
2681 result->dispatch_send = cli_do_rpc_ndr_send;
2682 result->dispatch_recv = cli_do_rpc_ndr_recv;
2683 result->desthost = talloc_strdup(result, cli->desthost);
2684 result->srv_name_slash = talloc_asprintf_strupper_m(
2685 result, "\\\\%s", result->desthost);
2687 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2688 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2690 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2691 TALLOC_FREE(result);
2692 return NT_STATUS_NO_MEMORY;
2695 status = rpc_transport_np_init(result, cli, abstract_syntax,
2696 &result->transport);
2697 if (!NT_STATUS_IS_OK(status)) {
2698 TALLOC_FREE(result);
2702 result->transport->transport = NCACN_NP;
2704 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2705 if (np_ref == NULL) {
2706 TALLOC_FREE(result);
2707 return NT_STATUS_NO_MEMORY;
2710 np_ref->pipe = result;
2712 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2713 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2716 return NT_STATUS_OK;
2719 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2720 struct rpc_cli_smbd_conn *conn,
2721 const struct ndr_syntax_id *syntax,
2722 struct rpc_pipe_client **presult)
2724 struct rpc_pipe_client *result;
2725 struct pipe_auth_data *auth;
2728 result = talloc(mem_ctx, struct rpc_pipe_client);
2729 if (result == NULL) {
2730 return NT_STATUS_NO_MEMORY;
2732 result->abstract_syntax = *syntax;
2733 result->transfer_syntax = ndr_transfer_syntax;
2734 result->dispatch = cli_do_rpc_ndr;
2735 result->dispatch_send = cli_do_rpc_ndr_send;
2736 result->dispatch_recv = cli_do_rpc_ndr_recv;
2737 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2738 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2740 result->desthost = talloc_strdup(result, global_myname());
2741 result->srv_name_slash = talloc_asprintf_strupper_m(
2742 result, "\\\\%s", global_myname());
2743 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2744 TALLOC_FREE(result);
2745 return NT_STATUS_NO_MEMORY;
2748 status = rpc_transport_smbd_init(result, conn, syntax,
2749 &result->transport);
2750 if (!NT_STATUS_IS_OK(status)) {
2751 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2752 nt_errstr(status)));
2753 TALLOC_FREE(result);
2757 status = rpccli_anon_bind_data(result, &auth);
2758 if (!NT_STATUS_IS_OK(status)) {
2759 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2760 nt_errstr(status)));
2761 TALLOC_FREE(result);
2765 status = rpc_pipe_bind(result, auth);
2766 if (!NT_STATUS_IS_OK(status)) {
2767 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2768 TALLOC_FREE(result);
2772 result->transport->transport = NCACN_INTERNAL;
2775 return NT_STATUS_OK;
2778 /****************************************************************************
2779 Open a pipe to a remote server.
2780 ****************************************************************************/
2782 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2783 enum dcerpc_transport_t transport,
2784 const struct ndr_syntax_id *interface,
2785 struct rpc_pipe_client **presult)
2787 switch (transport) {
2789 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2792 return rpc_pipe_open_np(cli, interface, presult);
2794 return NT_STATUS_NOT_IMPLEMENTED;
2798 /****************************************************************************
2799 Open a named pipe to an SMB server and bind anonymously.
2800 ****************************************************************************/
2802 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2803 enum dcerpc_transport_t transport,
2804 const struct ndr_syntax_id *interface,
2805 struct rpc_pipe_client **presult)
2807 struct rpc_pipe_client *result;
2808 struct pipe_auth_data *auth;
2811 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2812 if (!NT_STATUS_IS_OK(status)) {
2816 status = rpccli_anon_bind_data(result, &auth);
2817 if (!NT_STATUS_IS_OK(status)) {
2818 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2819 nt_errstr(status)));
2820 TALLOC_FREE(result);
2825 * This is a bit of an abstraction violation due to the fact that an
2826 * anonymous bind on an authenticated SMB inherits the user/domain
2827 * from the enclosing SMB creds
2830 TALLOC_FREE(auth->user_name);
2831 TALLOC_FREE(auth->domain);
2833 auth->user_name = talloc_strdup(auth, cli->user_name);
2834 auth->domain = talloc_strdup(auth, cli->domain);
2835 auth->user_session_key = data_blob_talloc(auth,
2836 cli->user_session_key.data,
2837 cli->user_session_key.length);
2839 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2840 TALLOC_FREE(result);
2841 return NT_STATUS_NO_MEMORY;
2844 status = rpc_pipe_bind(result, auth);
2845 if (!NT_STATUS_IS_OK(status)) {
2847 if (ndr_syntax_id_equal(interface,
2848 &ndr_table_dssetup.syntax_id)) {
2849 /* non AD domains just don't have this pipe, avoid
2850 * level 0 statement in that case - gd */
2853 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2854 "%s failed with error %s\n",
2855 get_pipe_name_from_syntax(talloc_tos(), interface),
2856 nt_errstr(status) ));
2857 TALLOC_FREE(result);
2861 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2862 "%s and bound anonymously.\n",
2863 get_pipe_name_from_syntax(talloc_tos(), interface),
2867 return NT_STATUS_OK;
2870 /****************************************************************************
2871 ****************************************************************************/
2873 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2874 const struct ndr_syntax_id *interface,
2875 struct rpc_pipe_client **presult)
2877 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2878 interface, presult);
2881 /****************************************************************************
2882 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2883 ****************************************************************************/
2885 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2886 const struct ndr_syntax_id *interface,
2887 enum dcerpc_transport_t transport,
2888 enum dcerpc_AuthLevel auth_level,
2890 const char *username,
2891 const char *password,
2892 struct rpc_pipe_client **presult)
2894 struct rpc_pipe_client *result;
2895 struct pipe_auth_data *auth;
2896 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2899 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2900 if (!NT_STATUS_IS_OK(status)) {
2904 status = rpccli_ntlmssp_bind_data(result,
2905 auth_type, auth_level,
2906 domain, username, password,
2908 if (!NT_STATUS_IS_OK(status)) {
2909 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2910 nt_errstr(status)));
2914 status = rpc_pipe_bind(result, auth);
2915 if (!NT_STATUS_IS_OK(status)) {
2916 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2917 nt_errstr(status) ));
2921 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2922 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2923 get_pipe_name_from_syntax(talloc_tos(), interface),
2924 cli->desthost, domain, username ));
2927 return NT_STATUS_OK;
2931 TALLOC_FREE(result);
2935 /****************************************************************************
2936 Get a the schannel session key out of an already opened netlogon pipe.
2937 ****************************************************************************/
2938 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2939 struct cli_state *cli,
2943 enum netr_SchannelType sec_chan_type = 0;
2944 unsigned char machine_pwd[16];
2945 const char *machine_account;
2948 /* Get the machine account credentials from secrets.tdb. */
2949 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2952 DEBUG(0, ("get_schannel_session_key: could not fetch "
2953 "trust account password for domain '%s'\n",
2955 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2958 status = rpccli_netlogon_setup_creds(netlogon_pipe,
2959 cli->desthost, /* server name */
2960 domain, /* domain */
2961 global_myname(), /* client name */
2962 machine_account, /* machine account name */
2967 if (!NT_STATUS_IS_OK(status)) {
2968 DEBUG(3, ("get_schannel_session_key_common: "
2969 "rpccli_netlogon_setup_creds failed with result %s "
2970 "to server %s, domain %s, machine account %s.\n",
2971 nt_errstr(status), cli->desthost, domain,
2976 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2977 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2979 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2982 return NT_STATUS_OK;;
2985 /****************************************************************************
2986 Open a netlogon pipe and get the schannel session key.
2987 Now exposed to external callers.
2988 ****************************************************************************/
2991 NTSTATUS get_schannel_session_key(struct cli_state *cli,
2994 struct rpc_pipe_client **presult)
2996 struct rpc_pipe_client *netlogon_pipe = NULL;
2999 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3001 if (!NT_STATUS_IS_OK(status)) {
3005 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3007 if (!NT_STATUS_IS_OK(status)) {
3008 TALLOC_FREE(netlogon_pipe);
3012 *presult = netlogon_pipe;
3013 return NT_STATUS_OK;
3016 /****************************************************************************
3018 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3019 using session_key. sign and seal.
3021 The *pdc will be stolen onto this new pipe
3022 ****************************************************************************/
3024 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3025 const struct ndr_syntax_id *interface,
3026 enum dcerpc_transport_t transport,
3027 enum dcerpc_AuthLevel auth_level,
3029 struct netlogon_creds_CredentialState **pdc,
3030 struct rpc_pipe_client **presult)
3032 struct rpc_pipe_client *result;
3033 struct pipe_auth_data *auth;
3036 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3037 if (!NT_STATUS_IS_OK(status)) {
3041 status = rpccli_schannel_bind_data(result, domain, auth_level,
3043 if (!NT_STATUS_IS_OK(status)) {
3044 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3045 nt_errstr(status)));
3046 TALLOC_FREE(result);
3050 status = rpc_pipe_bind(result, auth);
3051 if (!NT_STATUS_IS_OK(status)) {
3052 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3053 "cli_rpc_pipe_bind failed with error %s\n",
3054 nt_errstr(status) ));
3055 TALLOC_FREE(result);
3060 * The credentials on a new netlogon pipe are the ones we are passed
3061 * in - reference them in
3063 result->dc = talloc_move(result, pdc);
3065 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3066 "for domain %s and bound using schannel.\n",
3067 get_pipe_name_from_syntax(talloc_tos(), interface),
3068 cli->desthost, domain ));
3071 return NT_STATUS_OK;
3074 /****************************************************************************
3075 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3076 Fetch the session key ourselves using a temporary netlogon pipe. This
3077 version uses an ntlmssp auth bound netlogon pipe to get the key.
3078 ****************************************************************************/
3080 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3082 const char *username,
3083 const char *password,
3085 struct rpc_pipe_client **presult)
3087 struct rpc_pipe_client *netlogon_pipe = NULL;
3090 status = cli_rpc_pipe_open_spnego_ntlmssp(
3091 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3092 DCERPC_AUTH_LEVEL_PRIVACY,
3093 domain, username, password, &netlogon_pipe);
3094 if (!NT_STATUS_IS_OK(status)) {
3098 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3100 if (!NT_STATUS_IS_OK(status)) {
3101 TALLOC_FREE(netlogon_pipe);
3105 *presult = netlogon_pipe;
3106 return NT_STATUS_OK;
3109 /****************************************************************************
3110 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3111 Fetch the session key ourselves using a temporary netlogon pipe. This version
3112 uses an ntlmssp bind to get the session key.
3113 ****************************************************************************/
3115 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3116 const struct ndr_syntax_id *interface,
3117 enum dcerpc_transport_t transport,
3118 enum dcerpc_AuthLevel auth_level,
3120 const char *username,
3121 const char *password,
3122 struct rpc_pipe_client **presult)
3124 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3125 struct rpc_pipe_client *netlogon_pipe = NULL;
3126 struct rpc_pipe_client *result = NULL;
3129 status = get_schannel_session_key_auth_ntlmssp(
3130 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3131 if (!NT_STATUS_IS_OK(status)) {
3132 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3133 "key from server %s for domain %s.\n",
3134 cli->desthost, domain ));
3138 status = cli_rpc_pipe_open_schannel_with_key(
3139 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3142 /* Now we've bound using the session key we can close the netlog pipe. */
3143 TALLOC_FREE(netlogon_pipe);
3145 if (NT_STATUS_IS_OK(status)) {
3151 /****************************************************************************
3152 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3153 Fetch the session key ourselves using a temporary netlogon pipe.
3154 ****************************************************************************/
3156 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3157 const struct ndr_syntax_id *interface,
3158 enum dcerpc_transport_t transport,
3159 enum dcerpc_AuthLevel auth_level,
3161 struct rpc_pipe_client **presult)
3163 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3164 struct rpc_pipe_client *netlogon_pipe = NULL;
3165 struct rpc_pipe_client *result = NULL;
3168 status = get_schannel_session_key(cli, domain, &neg_flags,
3170 if (!NT_STATUS_IS_OK(status)) {
3171 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3172 "key from server %s for domain %s.\n",
3173 cli->desthost, domain ));
3177 status = cli_rpc_pipe_open_schannel_with_key(
3178 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3181 /* Now we've bound using the session key we can close the netlog pipe. */
3182 TALLOC_FREE(netlogon_pipe);
3184 if (NT_STATUS_IS_OK(status)) {
3191 /****************************************************************************
3192 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3193 The idea is this can be called with service_princ, username and password all
3194 NULL so long as the caller has a TGT.
3195 ****************************************************************************/
3197 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3198 const struct ndr_syntax_id *interface,
3199 enum dcerpc_transport_t transport,
3200 enum dcerpc_AuthLevel auth_level,
3202 const char *username,
3203 const char *password,
3204 struct rpc_pipe_client **presult)
3206 struct rpc_pipe_client *result;
3207 struct pipe_auth_data *auth;
3210 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3211 if (!NT_STATUS_IS_OK(status)) {
3215 auth = talloc(result, struct pipe_auth_data);
3217 status = NT_STATUS_NO_MEMORY;
3220 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3221 auth->auth_level = auth_level;
3226 auth->user_name = talloc_strdup(auth, username);
3227 if (!auth->user_name) {
3228 status = NT_STATUS_NO_MEMORY;
3232 /* Fixme, should we fetch/set the Realm ? */
3233 auth->domain = talloc_strdup(auth, "");
3234 if (!auth->domain) {
3235 status = NT_STATUS_NO_MEMORY;
3239 status = gse_init_client(auth, auth->auth_type, auth->auth_level,
3240 NULL, server, "cifs", username, password,
3241 GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3243 if (!NT_STATUS_IS_OK(status)) {
3244 DEBUG(0, ("gse_init_client returned %s\n",
3245 nt_errstr(status)));
3249 status = rpc_pipe_bind(result, auth);
3250 if (!NT_STATUS_IS_OK(status)) {
3251 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3252 nt_errstr(status)));
3257 return NT_STATUS_OK;
3260 TALLOC_FREE(result);
3264 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3265 const struct ndr_syntax_id *interface,
3266 enum dcerpc_transport_t transport,
3267 enum dcerpc_AuthLevel auth_level,
3269 const char *username,
3270 const char *password,
3271 struct rpc_pipe_client **presult)
3273 struct rpc_pipe_client *result;
3274 struct pipe_auth_data *auth;
3277 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3278 if (!NT_STATUS_IS_OK(status)) {
3282 auth = talloc(result, struct pipe_auth_data);
3284 status = NT_STATUS_NO_MEMORY;
3287 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3288 auth->auth_level = auth_level;
3290 auth->spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
3295 auth->user_name = talloc_strdup(auth, username);
3296 if (!auth->user_name) {
3297 status = NT_STATUS_NO_MEMORY;
3301 /* Fixme, should we fetch/set the Realm ? */
3302 auth->domain = talloc_strdup(auth, "");
3303 if (!auth->domain) {
3304 status = NT_STATUS_NO_MEMORY;
3308 status = spnego_gssapi_init_client(auth, auth->auth_level,
3309 NULL, server, "cifs",
3312 &auth->a_u.spnego_state);
3313 if (!NT_STATUS_IS_OK(status)) {
3314 DEBUG(0, ("spnego_init_client returned %s\n",
3315 nt_errstr(status)));
3319 status = rpc_pipe_bind(result, auth);
3320 if (!NT_STATUS_IS_OK(status)) {
3321 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3322 nt_errstr(status)));
3327 return NT_STATUS_OK;
3330 TALLOC_FREE(result);
3334 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3335 const struct ndr_syntax_id *interface,
3336 enum dcerpc_transport_t transport,
3337 enum dcerpc_AuthLevel auth_level,
3339 const char *username,
3340 const char *password,
3341 struct rpc_pipe_client **presult)
3343 struct rpc_pipe_client *result;
3344 struct pipe_auth_data *auth;
3347 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3348 if (!NT_STATUS_IS_OK(status)) {
3352 auth = talloc(result, struct pipe_auth_data);
3354 status = NT_STATUS_NO_MEMORY;
3357 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3358 auth->auth_level = auth_level;
3363 auth->user_name = talloc_strdup(auth, username);
3364 if (!auth->user_name) {
3365 status = NT_STATUS_NO_MEMORY;
3372 auth->domain = talloc_strdup(auth, domain);
3373 if (!auth->domain) {
3374 status = NT_STATUS_NO_MEMORY;
3378 status = spnego_ntlmssp_init_client(auth, auth->auth_level,
3379 domain, username, password,
3380 &auth->a_u.spnego_state);
3381 if (!NT_STATUS_IS_OK(status)) {
3382 DEBUG(0, ("spnego_init_client returned %s\n",
3383 nt_errstr(status)));
3387 status = rpc_pipe_bind(result, auth);
3388 if (!NT_STATUS_IS_OK(status)) {
3389 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3390 nt_errstr(status)));
3395 return NT_STATUS_OK;
3398 TALLOC_FREE(result);
3402 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3403 struct rpc_pipe_client *cli,
3404 DATA_BLOB *session_key)
3406 struct pipe_auth_data *a = cli->auth;
3409 if (!session_key || !cli) {
3410 return NT_STATUS_INVALID_PARAMETER;
3414 return NT_STATUS_INVALID_PARAMETER;
3417 switch (cli->auth->auth_type) {
3418 case DCERPC_AUTH_TYPE_SCHANNEL:
3419 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3422 case DCERPC_AUTH_TYPE_SPNEGO:
3423 sk = spnego_get_session_key(a->a_u.spnego_state);
3424 if (sk.length == 0) {
3425 return NT_STATUS_NO_USER_SESSION_KEY;
3428 case DCERPC_AUTH_TYPE_NTLMSSP:
3429 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3431 case DCERPC_AUTH_TYPE_KRB5:
3432 sk = gse_get_session_key(a->a_u.gssapi_state);
3434 case DCERPC_AUTH_TYPE_NONE:
3435 sk = data_blob_const(a->user_session_key.data,
3436 a->user_session_key.length);
3439 return NT_STATUS_NO_USER_SESSION_KEY;
3442 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3443 return NT_STATUS_OK;