2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client routines
4 * Largely rewritten by Jeremy Allison 2005.
5 * Heavily modified by Simo Sorce 2010.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/cli_epmapper.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
24 #include "../librpc/gen_ndr/ndr_dssetup.h"
25 #include "../librpc/gen_ndr/ndr_netlogon.h"
26 #include "../libcli/auth/schannel.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../libcli/auth/ntlmssp.h"
30 #include "ntlmssp_wrap.h"
31 #include "rpc_client/cli_netlogon.h"
32 #include "librpc/gen_ndr/ndr_dcerpc.h"
33 #include "librpc/rpc/dcerpc.h"
34 #include "librpc/rpc/dcerpc_gssapi.h"
35 #include "librpc/rpc/dcerpc_spnego.h"
38 #define DBGC_CLASS DBGC_RPC_CLI
40 /********************************************************************
41 Pipe description for a DEBUG
42 ********************************************************************/
43 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
44 struct rpc_pipe_client *cli)
46 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
53 /********************************************************************
55 ********************************************************************/
57 static uint32 get_rpc_call_id(void)
59 static uint32 call_id = 0;
63 /*******************************************************************
64 Use SMBreadX to get rest of one fragment's worth of rpc data.
65 Reads the whole size or give an error message
66 ********************************************************************/
68 struct rpc_read_state {
69 struct event_context *ev;
70 struct rpc_cli_transport *transport;
76 static void rpc_read_done(struct tevent_req *subreq);
78 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
79 struct event_context *ev,
80 struct rpc_cli_transport *transport,
81 uint8_t *data, size_t size)
83 struct tevent_req *req, *subreq;
84 struct rpc_read_state *state;
86 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
91 state->transport = transport;
96 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
98 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
100 if (subreq == NULL) {
103 tevent_req_set_callback(subreq, rpc_read_done, req);
111 static void rpc_read_done(struct tevent_req *subreq)
113 struct tevent_req *req = tevent_req_callback_data(
114 subreq, struct tevent_req);
115 struct rpc_read_state *state = tevent_req_data(
116 req, struct rpc_read_state);
120 status = state->transport->read_recv(subreq, &received);
122 if (!NT_STATUS_IS_OK(status)) {
123 tevent_req_nterror(req, status);
127 state->num_read += received;
128 if (state->num_read == state->size) {
129 tevent_req_done(req);
133 subreq = state->transport->read_send(state, state->ev,
134 state->data + state->num_read,
135 state->size - state->num_read,
136 state->transport->priv);
137 if (tevent_req_nomem(subreq, req)) {
140 tevent_req_set_callback(subreq, rpc_read_done, req);
143 static NTSTATUS rpc_read_recv(struct tevent_req *req)
145 return tevent_req_simple_recv_ntstatus(req);
148 struct rpc_write_state {
149 struct event_context *ev;
150 struct rpc_cli_transport *transport;
156 static void rpc_write_done(struct tevent_req *subreq);
158 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
159 struct event_context *ev,
160 struct rpc_cli_transport *transport,
161 const uint8_t *data, size_t size)
163 struct tevent_req *req, *subreq;
164 struct rpc_write_state *state;
166 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
171 state->transport = transport;
174 state->num_written = 0;
176 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
178 subreq = transport->write_send(state, ev, data, size, transport->priv);
179 if (subreq == NULL) {
182 tevent_req_set_callback(subreq, rpc_write_done, req);
189 static void rpc_write_done(struct tevent_req *subreq)
191 struct tevent_req *req = tevent_req_callback_data(
192 subreq, struct tevent_req);
193 struct rpc_write_state *state = tevent_req_data(
194 req, struct rpc_write_state);
198 status = state->transport->write_recv(subreq, &written);
200 if (!NT_STATUS_IS_OK(status)) {
201 tevent_req_nterror(req, status);
205 state->num_written += written;
207 if (state->num_written == state->size) {
208 tevent_req_done(req);
212 subreq = state->transport->write_send(state, state->ev,
213 state->data + state->num_written,
214 state->size - state->num_written,
215 state->transport->priv);
216 if (tevent_req_nomem(subreq, req)) {
219 tevent_req_set_callback(subreq, rpc_write_done, req);
222 static NTSTATUS rpc_write_recv(struct tevent_req *req)
224 return tevent_req_simple_recv_ntstatus(req);
228 /****************************************************************************
229 Try and get a PDU's worth of data from current_pdu. If not, then read more
231 ****************************************************************************/
233 struct get_complete_frag_state {
234 struct event_context *ev;
235 struct rpc_pipe_client *cli;
240 static void get_complete_frag_got_header(struct tevent_req *subreq);
241 static void get_complete_frag_got_rest(struct tevent_req *subreq);
243 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
244 struct event_context *ev,
245 struct rpc_pipe_client *cli,
248 struct tevent_req *req, *subreq;
249 struct get_complete_frag_state *state;
253 req = tevent_req_create(mem_ctx, &state,
254 struct get_complete_frag_state);
260 state->frag_len = RPC_HEADER_LEN;
263 received = pdu->length;
264 if (received < RPC_HEADER_LEN) {
265 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
266 status = NT_STATUS_NO_MEMORY;
269 subreq = rpc_read_send(state, state->ev,
270 state->cli->transport,
271 pdu->data + received,
272 RPC_HEADER_LEN - received);
273 if (subreq == NULL) {
274 status = NT_STATUS_NO_MEMORY;
277 tevent_req_set_callback(subreq, get_complete_frag_got_header,
282 state->frag_len = dcerpc_get_frag_length(pdu);
285 * Ensure we have frag_len bytes of data.
287 if (received < state->frag_len) {
288 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
289 status = NT_STATUS_NO_MEMORY;
292 subreq = rpc_read_send(state, state->ev,
293 state->cli->transport,
294 pdu->data + received,
295 state->frag_len - received);
296 if (subreq == NULL) {
297 status = NT_STATUS_NO_MEMORY;
300 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
305 status = NT_STATUS_OK;
307 if (NT_STATUS_IS_OK(status)) {
308 tevent_req_done(req);
310 tevent_req_nterror(req, status);
312 return tevent_req_post(req, ev);
315 static void get_complete_frag_got_header(struct tevent_req *subreq)
317 struct tevent_req *req = tevent_req_callback_data(
318 subreq, struct tevent_req);
319 struct get_complete_frag_state *state = tevent_req_data(
320 req, struct get_complete_frag_state);
323 status = rpc_read_recv(subreq);
325 if (!NT_STATUS_IS_OK(status)) {
326 tevent_req_nterror(req, status);
330 state->frag_len = dcerpc_get_frag_length(state->pdu);
332 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
333 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
338 * We're here in this piece of code because we've read exactly
339 * RPC_HEADER_LEN bytes into state->pdu.
342 subreq = rpc_read_send(state, state->ev, state->cli->transport,
343 state->pdu->data + RPC_HEADER_LEN,
344 state->frag_len - RPC_HEADER_LEN);
345 if (tevent_req_nomem(subreq, req)) {
348 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
351 static void get_complete_frag_got_rest(struct tevent_req *subreq)
353 struct tevent_req *req = tevent_req_callback_data(
354 subreq, struct tevent_req);
357 status = rpc_read_recv(subreq);
359 if (!NT_STATUS_IS_OK(status)) {
360 tevent_req_nterror(req, status);
363 tevent_req_done(req);
366 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
368 return tevent_req_simple_recv_ntstatus(req);
371 /****************************************************************************
372 Do basic authentication checks on an incoming pdu.
373 ****************************************************************************/
375 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
376 struct rpc_pipe_client *cli,
377 struct ncacn_packet *pkt,
379 uint8_t expected_pkt_type,
381 DATA_BLOB *reply_pdu)
383 struct dcerpc_response *r;
384 NTSTATUS ret = NT_STATUS_OK;
388 * Point the return values at the real data including the RPC
389 * header. Just in case the caller wants it.
393 /* Ensure we have the correct type. */
394 switch (pkt->ptype) {
395 case DCERPC_PKT_ALTER_RESP:
396 case DCERPC_PKT_BIND_ACK:
398 /* Client code never receives this kind of packets */
402 case DCERPC_PKT_RESPONSE:
404 r = &pkt->u.response;
406 /* Here's where we deal with incoming sign/seal. */
407 ret = dcerpc_check_auth(cli->auth, pkt,
408 &r->stub_and_verifier,
409 DCERPC_RESPONSE_LENGTH,
411 if (!NT_STATUS_IS_OK(ret)) {
415 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
416 return NT_STATUS_BUFFER_TOO_SMALL;
419 /* Point the return values at the NDR data. */
420 rdata->data = r->stub_and_verifier.data;
422 if (pkt->auth_length) {
423 /* We've already done integer wrap tests in
424 * dcerpc_check_auth(). */
425 rdata->length = r->stub_and_verifier.length
427 - DCERPC_AUTH_TRAILER_LENGTH
430 rdata->length = r->stub_and_verifier.length;
433 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
434 (long unsigned int)pdu->length,
435 (long unsigned int)rdata->length,
436 (unsigned int)pad_len));
439 * If this is the first reply, and the allocation hint is
440 * reasonable, try and set up the reply_pdu DATA_BLOB to the
444 if ((reply_pdu->length == 0) &&
445 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
446 if (!data_blob_realloc(mem_ctx, reply_pdu,
448 DEBUG(0, ("reply alloc hint %d too "
449 "large to allocate\n",
450 (int)r->alloc_hint));
451 return NT_STATUS_NO_MEMORY;
457 case DCERPC_PKT_BIND_NAK:
458 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
459 rpccli_pipe_txt(talloc_tos(), cli)));
460 /* Use this for now... */
461 return NT_STATUS_NETWORK_ACCESS_DENIED;
463 case DCERPC_PKT_FAULT:
465 DEBUG(1, (__location__ ": RPC fault code %s received "
467 dcerpc_errstr(talloc_tos(),
468 pkt->u.fault.status),
469 rpccli_pipe_txt(talloc_tos(), cli)));
471 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
472 return NT_STATUS_UNSUCCESSFUL;
474 return NT_STATUS(pkt->u.fault.status);
478 DEBUG(0, (__location__ "Unknown packet type %u received "
480 (unsigned int)pkt->ptype,
481 rpccli_pipe_txt(talloc_tos(), cli)));
482 return NT_STATUS_INVALID_INFO_CLASS;
485 if (pkt->ptype != expected_pkt_type) {
486 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
487 "RPC packet type - %u, not %u\n",
488 rpccli_pipe_txt(talloc_tos(), cli),
489 pkt->ptype, expected_pkt_type));
490 return NT_STATUS_INVALID_INFO_CLASS;
493 /* Do this just before return - we don't want to modify any rpc header
494 data before now as we may have needed to do cryptographic actions on
497 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
498 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
499 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
500 "fragment first/last ON.\n"));
501 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
507 /****************************************************************************
508 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
509 ****************************************************************************/
511 struct cli_api_pipe_state {
512 struct event_context *ev;
513 struct rpc_cli_transport *transport;
518 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
519 static void cli_api_pipe_write_done(struct tevent_req *subreq);
520 static void cli_api_pipe_read_done(struct tevent_req *subreq);
522 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
523 struct event_context *ev,
524 struct rpc_cli_transport *transport,
525 uint8_t *data, size_t data_len,
526 uint32_t max_rdata_len)
528 struct tevent_req *req, *subreq;
529 struct cli_api_pipe_state *state;
532 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
537 state->transport = transport;
539 if (max_rdata_len < RPC_HEADER_LEN) {
541 * For a RPC reply we always need at least RPC_HEADER_LEN
542 * bytes. We check this here because we will receive
543 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
545 status = NT_STATUS_INVALID_PARAMETER;
549 if (transport->trans_send != NULL) {
550 subreq = transport->trans_send(state, ev, data, data_len,
551 max_rdata_len, transport->priv);
552 if (subreq == NULL) {
555 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
560 * If the transport does not provide a "trans" routine, i.e. for
561 * example the ncacn_ip_tcp transport, do the write/read step here.
564 subreq = rpc_write_send(state, ev, transport, data, data_len);
565 if (subreq == NULL) {
568 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
572 tevent_req_nterror(req, status);
573 return tevent_req_post(req, ev);
579 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
581 struct tevent_req *req = tevent_req_callback_data(
582 subreq, struct tevent_req);
583 struct cli_api_pipe_state *state = tevent_req_data(
584 req, struct cli_api_pipe_state);
587 status = state->transport->trans_recv(subreq, state, &state->rdata,
590 if (!NT_STATUS_IS_OK(status)) {
591 tevent_req_nterror(req, status);
594 tevent_req_done(req);
597 static void cli_api_pipe_write_done(struct tevent_req *subreq)
599 struct tevent_req *req = tevent_req_callback_data(
600 subreq, struct tevent_req);
601 struct cli_api_pipe_state *state = tevent_req_data(
602 req, struct cli_api_pipe_state);
605 status = rpc_write_recv(subreq);
607 if (!NT_STATUS_IS_OK(status)) {
608 tevent_req_nterror(req, status);
612 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
613 if (tevent_req_nomem(state->rdata, req)) {
618 * We don't need to use rpc_read_send here, the upper layer will cope
619 * with a short read, transport->trans_send could also return less
620 * than state->max_rdata_len.
622 subreq = state->transport->read_send(state, state->ev, state->rdata,
624 state->transport->priv);
625 if (tevent_req_nomem(subreq, req)) {
628 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
631 static void cli_api_pipe_read_done(struct tevent_req *subreq)
633 struct tevent_req *req = tevent_req_callback_data(
634 subreq, struct tevent_req);
635 struct cli_api_pipe_state *state = tevent_req_data(
636 req, struct cli_api_pipe_state);
640 status = state->transport->read_recv(subreq, &received);
642 if (!NT_STATUS_IS_OK(status)) {
643 tevent_req_nterror(req, status);
646 state->rdata_len = received;
647 tevent_req_done(req);
650 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
651 uint8_t **prdata, uint32_t *prdata_len)
653 struct cli_api_pipe_state *state = tevent_req_data(
654 req, struct cli_api_pipe_state);
657 if (tevent_req_is_nterror(req, &status)) {
661 *prdata = talloc_move(mem_ctx, &state->rdata);
662 *prdata_len = state->rdata_len;
666 /****************************************************************************
667 Send data on an rpc pipe via trans. The data must be the last
668 pdu fragment of an NDR data stream.
670 Receive response data from an rpc pipe, which may be large...
672 Read the first fragment: unfortunately have to use SMBtrans for the first
673 bit, then SMBreadX for subsequent bits.
675 If first fragment received also wasn't the last fragment, continue
676 getting fragments until we _do_ receive the last fragment.
678 Request/Response PDU's look like the following...
680 |<------------------PDU len----------------------------------------------->|
681 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
683 +------------+-----------------+-------------+---------------+-------------+
684 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
685 +------------+-----------------+-------------+---------------+-------------+
687 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
688 signing & sealing being negotiated.
690 ****************************************************************************/
692 struct rpc_api_pipe_state {
693 struct event_context *ev;
694 struct rpc_pipe_client *cli;
695 uint8_t expected_pkt_type;
697 DATA_BLOB incoming_frag;
698 struct ncacn_packet *pkt;
702 size_t reply_pdu_offset;
706 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
707 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
709 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
710 struct event_context *ev,
711 struct rpc_pipe_client *cli,
712 DATA_BLOB *data, /* Outgoing PDU */
713 uint8_t expected_pkt_type)
715 struct tevent_req *req, *subreq;
716 struct rpc_api_pipe_state *state;
717 uint16_t max_recv_frag;
720 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
726 state->expected_pkt_type = expected_pkt_type;
727 state->incoming_frag = data_blob_null;
728 state->reply_pdu = data_blob_null;
729 state->reply_pdu_offset = 0;
730 state->endianess = DCERPC_DREP_LE;
733 * Ensure we're not sending too much.
735 if (data->length > cli->max_xmit_frag) {
736 status = NT_STATUS_INVALID_PARAMETER;
740 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
742 /* get the header first, then fetch the rest once we have
743 * the frag_length available */
744 max_recv_frag = RPC_HEADER_LEN;
746 subreq = cli_api_pipe_send(state, ev, cli->transport,
747 data->data, data->length, max_recv_frag);
748 if (subreq == NULL) {
751 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
755 tevent_req_nterror(req, status);
756 return tevent_req_post(req, ev);
762 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
764 struct tevent_req *req = tevent_req_callback_data(
765 subreq, struct tevent_req);
766 struct rpc_api_pipe_state *state = tevent_req_data(
767 req, struct rpc_api_pipe_state);
769 uint8_t *rdata = NULL;
770 uint32_t rdata_len = 0;
772 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
774 if (!NT_STATUS_IS_OK(status)) {
775 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
776 tevent_req_nterror(req, status);
781 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
782 rpccli_pipe_txt(talloc_tos(), state->cli)));
783 tevent_req_done(req);
788 * Move data on state->incoming_frag.
790 state->incoming_frag.data = talloc_move(state, &rdata);
791 state->incoming_frag.length = rdata_len;
792 if (!state->incoming_frag.data) {
793 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
797 /* Ensure we have enough data for a pdu. */
798 subreq = get_complete_frag_send(state, state->ev, state->cli,
799 &state->incoming_frag);
800 if (tevent_req_nomem(subreq, req)) {
803 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
806 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
808 struct tevent_req *req = tevent_req_callback_data(
809 subreq, struct tevent_req);
810 struct rpc_api_pipe_state *state = tevent_req_data(
811 req, struct rpc_api_pipe_state);
813 DATA_BLOB rdata = data_blob_null;
815 status = get_complete_frag_recv(subreq);
817 if (!NT_STATUS_IS_OK(status)) {
818 DEBUG(5, ("get_complete_frag failed: %s\n",
820 tevent_req_nterror(req, status);
824 state->pkt = talloc(state, struct ncacn_packet);
826 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
830 status = dcerpc_pull_ncacn_packet(state,
831 &state->incoming_frag,
834 if (!NT_STATUS_IS_OK(status)) {
835 tevent_req_nterror(req, status);
839 if (state->incoming_frag.length != state->pkt->frag_length) {
840 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
841 (unsigned int)state->incoming_frag.length,
842 (unsigned int)state->pkt->frag_length));
843 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
847 status = cli_pipe_validate_current_pdu(state,
848 state->cli, state->pkt,
849 &state->incoming_frag,
850 state->expected_pkt_type,
854 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
855 (unsigned)state->incoming_frag.length,
856 (unsigned)state->reply_pdu_offset,
859 if (!NT_STATUS_IS_OK(status)) {
860 tevent_req_nterror(req, status);
864 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
865 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
867 * Set the data type correctly for big-endian data on the
870 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
872 rpccli_pipe_txt(talloc_tos(), state->cli)));
873 state->endianess = 0x00; /* BIG ENDIAN */
876 * Check endianness on subsequent packets.
878 if (state->endianess != state->pkt->drep[0]) {
879 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
881 state->endianess?"little":"big",
882 state->pkt->drep[0]?"little":"big"));
883 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
887 /* Now copy the data portion out of the pdu into rbuf. */
888 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
889 if (!data_blob_realloc(NULL, &state->reply_pdu,
890 state->reply_pdu_offset + rdata.length)) {
891 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
896 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
897 rdata.data, rdata.length);
898 state->reply_pdu_offset += rdata.length;
900 /* reset state->incoming_frag, there is no need to free it,
901 * it will be reallocated to the right size the next time
903 state->incoming_frag.length = 0;
905 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
906 /* make sure the pdu length is right now that we
907 * have all the data available (alloc hint may
908 * have allocated more than was actually used) */
909 state->reply_pdu.length = state->reply_pdu_offset;
910 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
911 rpccli_pipe_txt(talloc_tos(), state->cli),
912 (unsigned)state->reply_pdu.length));
913 tevent_req_done(req);
917 subreq = get_complete_frag_send(state, state->ev, state->cli,
918 &state->incoming_frag);
919 if (tevent_req_nomem(subreq, req)) {
922 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
925 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
926 struct ncacn_packet **pkt,
927 DATA_BLOB *reply_pdu)
929 struct rpc_api_pipe_state *state = tevent_req_data(
930 req, struct rpc_api_pipe_state);
933 if (tevent_req_is_nterror(req, &status)) {
937 /* return data to caller and assign it ownership of memory */
939 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
940 reply_pdu->length = state->reply_pdu.length;
941 state->reply_pdu.length = 0;
943 data_blob_free(&state->reply_pdu);
947 *pkt = talloc_steal(mem_ctx, state->pkt);
953 /*******************************************************************
954 Creates spnego auth bind.
955 ********************************************************************/
957 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
958 struct pipe_auth_data *auth,
959 DATA_BLOB *auth_token)
961 DATA_BLOB in_token = data_blob_null;
964 /* Negotiate the initial auth token */
965 status = spnego_get_client_auth_token(mem_ctx,
966 auth->a_u.spnego_state,
967 &in_token, auth_token);
968 if (!NT_STATUS_IS_OK(status)) {
972 DEBUG(5, ("Created GSS Authentication Token:\n"));
973 dump_data(5, auth_token->data, auth_token->length);
978 /*******************************************************************
979 Creates krb5 auth bind.
980 ********************************************************************/
982 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
983 struct pipe_auth_data *auth,
984 DATA_BLOB *auth_token)
986 DATA_BLOB in_token = data_blob_null;
989 /* Negotiate the initial auth token */
990 status = gse_get_client_auth_token(mem_ctx,
991 auth->a_u.gssapi_state,
994 if (!NT_STATUS_IS_OK(status)) {
998 DEBUG(5, ("Created GSS Authentication Token:\n"));
999 dump_data(5, auth_token->data, auth_token->length);
1001 return NT_STATUS_OK;
1004 /*******************************************************************
1005 Creates NTLMSSP auth bind.
1006 ********************************************************************/
1008 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1009 DATA_BLOB *auth_token)
1012 DATA_BLOB null_blob = data_blob_null;
1014 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1015 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1016 null_blob, auth_token);
1018 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1019 data_blob_free(auth_token);
1023 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1024 dump_data(5, auth_token->data, auth_token->length);
1026 return NT_STATUS_OK;
1029 /*******************************************************************
1030 Creates schannel auth bind.
1031 ********************************************************************/
1033 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1034 DATA_BLOB *auth_token)
1037 struct NL_AUTH_MESSAGE r;
1039 /* Use lp_workgroup() if domain not specified */
1041 if (!cli->auth->domain || !cli->auth->domain[0]) {
1042 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1043 if (cli->auth->domain == NULL) {
1044 return NT_STATUS_NO_MEMORY;
1049 * Now marshall the data into the auth parse_struct.
1052 r.MessageType = NL_NEGOTIATE_REQUEST;
1053 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1054 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1055 r.oem_netbios_domain.a = cli->auth->domain;
1056 r.oem_netbios_computer.a = global_myname();
1058 status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1059 if (!NT_STATUS_IS_OK(status)) {
1063 return NT_STATUS_OK;
1066 /*******************************************************************
1067 Creates the internals of a DCE/RPC bind request or alter context PDU.
1068 ********************************************************************/
1070 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1071 enum dcerpc_pkt_type ptype,
1073 const struct ndr_syntax_id *abstract,
1074 const struct ndr_syntax_id *transfer,
1075 const DATA_BLOB *auth_info,
1078 uint16 auth_len = auth_info->length;
1080 union dcerpc_payload u;
1081 struct dcerpc_ctx_list ctx_list;
1084 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1087 ctx_list.context_id = 0;
1088 ctx_list.num_transfer_syntaxes = 1;
1089 ctx_list.abstract_syntax = *abstract;
1090 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1092 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1093 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1094 u.bind.assoc_group_id = 0x0;
1095 u.bind.num_contexts = 1;
1096 u.bind.ctx_list = &ctx_list;
1097 u.bind.auth_info = *auth_info;
1099 status = dcerpc_push_ncacn_packet(mem_ctx,
1101 DCERPC_PFC_FLAG_FIRST |
1102 DCERPC_PFC_FLAG_LAST,
1107 if (!NT_STATUS_IS_OK(status)) {
1108 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1112 return NT_STATUS_OK;
1115 /*******************************************************************
1116 Creates a DCE/RPC bind request.
1117 ********************************************************************/
1119 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1120 struct rpc_pipe_client *cli,
1121 struct pipe_auth_data *auth,
1123 const struct ndr_syntax_id *abstract,
1124 const struct ndr_syntax_id *transfer,
1127 DATA_BLOB auth_token = data_blob_null;
1128 DATA_BLOB auth_info = data_blob_null;
1129 NTSTATUS ret = NT_STATUS_OK;
1131 switch (auth->auth_type) {
1132 case DCERPC_AUTH_TYPE_SCHANNEL:
1133 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1134 if (!NT_STATUS_IS_OK(ret)) {
1139 case DCERPC_AUTH_TYPE_NTLMSSP:
1140 ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token);
1141 if (!NT_STATUS_IS_OK(ret)) {
1146 case DCERPC_AUTH_TYPE_SPNEGO:
1147 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1148 if (!NT_STATUS_IS_OK(ret)) {
1153 case DCERPC_AUTH_TYPE_KRB5:
1154 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
1155 if (!NT_STATUS_IS_OK(ret)) {
1160 case DCERPC_AUTH_TYPE_NONE:
1164 /* "Can't" happen. */
1165 return NT_STATUS_INVALID_INFO_CLASS;
1168 if (auth_token.length != 0) {
1169 ret = dcerpc_push_dcerpc_auth(cli,
1172 0, /* auth_pad_length */
1173 1, /* auth_context_id */
1176 if (!NT_STATUS_IS_OK(ret)) {
1179 data_blob_free(&auth_token);
1182 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1192 /*******************************************************************
1194 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1195 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1196 and deals with signing/sealing details.
1197 ********************************************************************/
1199 struct rpc_api_pipe_req_state {
1200 struct event_context *ev;
1201 struct rpc_pipe_client *cli;
1204 DATA_BLOB *req_data;
1205 uint32_t req_data_sent;
1207 DATA_BLOB reply_pdu;
1210 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1211 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1212 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1213 bool *is_last_frag);
1215 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1216 struct event_context *ev,
1217 struct rpc_pipe_client *cli,
1219 DATA_BLOB *req_data)
1221 struct tevent_req *req, *subreq;
1222 struct rpc_api_pipe_req_state *state;
1226 req = tevent_req_create(mem_ctx, &state,
1227 struct rpc_api_pipe_req_state);
1233 state->op_num = op_num;
1234 state->req_data = req_data;
1235 state->req_data_sent = 0;
1236 state->call_id = get_rpc_call_id();
1237 state->reply_pdu = data_blob_null;
1238 state->rpc_out = data_blob_null;
1240 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1241 + RPC_MAX_SIGN_SIZE) {
1242 /* Server is screwed up ! */
1243 status = NT_STATUS_INVALID_PARAMETER;
1247 status = prepare_next_frag(state, &is_last_frag);
1248 if (!NT_STATUS_IS_OK(status)) {
1253 subreq = rpc_api_pipe_send(state, ev, state->cli,
1255 DCERPC_PKT_RESPONSE);
1256 if (subreq == NULL) {
1259 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1261 subreq = rpc_write_send(state, ev, cli->transport,
1262 state->rpc_out.data,
1263 state->rpc_out.length);
1264 if (subreq == NULL) {
1267 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1273 tevent_req_nterror(req, status);
1274 return tevent_req_post(req, ev);
1280 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1283 size_t data_sent_thistime;
1290 union dcerpc_payload u;
1292 data_left = state->req_data->length - state->req_data_sent;
1294 status = dcerpc_guess_sizes(state->cli->auth,
1295 DCERPC_REQUEST_LENGTH, data_left,
1296 state->cli->max_xmit_frag,
1297 CLIENT_NDR_PADDING_SIZE,
1298 &data_sent_thistime,
1299 &frag_len, &auth_len, &pad_len);
1300 if (!NT_STATUS_IS_OK(status)) {
1304 if (state->req_data_sent == 0) {
1305 flags = DCERPC_PFC_FLAG_FIRST;
1308 if (data_sent_thistime == data_left) {
1309 flags |= DCERPC_PFC_FLAG_LAST;
1312 data_blob_free(&state->rpc_out);
1314 ZERO_STRUCT(u.request);
1316 u.request.alloc_hint = state->req_data->length;
1317 u.request.context_id = 0;
1318 u.request.opnum = state->op_num;
1320 status = dcerpc_push_ncacn_packet(state,
1327 if (!NT_STATUS_IS_OK(status)) {
1331 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1332 * compute it right for requests because the auth trailer is missing
1334 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1336 /* Copy in the data. */
1337 if (!data_blob_append(NULL, &state->rpc_out,
1338 state->req_data->data + state->req_data_sent,
1339 data_sent_thistime)) {
1340 return NT_STATUS_NO_MEMORY;
1343 switch (state->cli->auth->auth_level) {
1344 case DCERPC_AUTH_LEVEL_NONE:
1345 case DCERPC_AUTH_LEVEL_CONNECT:
1346 case DCERPC_AUTH_LEVEL_PACKET:
1348 case DCERPC_AUTH_LEVEL_INTEGRITY:
1349 case DCERPC_AUTH_LEVEL_PRIVACY:
1350 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1352 if (!NT_STATUS_IS_OK(status)) {
1357 return NT_STATUS_INVALID_PARAMETER;
1360 state->req_data_sent += data_sent_thistime;
1361 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1366 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1368 struct tevent_req *req = tevent_req_callback_data(
1369 subreq, struct tevent_req);
1370 struct rpc_api_pipe_req_state *state = tevent_req_data(
1371 req, struct rpc_api_pipe_req_state);
1375 status = rpc_write_recv(subreq);
1376 TALLOC_FREE(subreq);
1377 if (!NT_STATUS_IS_OK(status)) {
1378 tevent_req_nterror(req, status);
1382 status = prepare_next_frag(state, &is_last_frag);
1383 if (!NT_STATUS_IS_OK(status)) {
1384 tevent_req_nterror(req, status);
1389 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1391 DCERPC_PKT_RESPONSE);
1392 if (tevent_req_nomem(subreq, req)) {
1395 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1397 subreq = rpc_write_send(state, state->ev,
1398 state->cli->transport,
1399 state->rpc_out.data,
1400 state->rpc_out.length);
1401 if (tevent_req_nomem(subreq, req)) {
1404 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1409 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1411 struct tevent_req *req = tevent_req_callback_data(
1412 subreq, struct tevent_req);
1413 struct rpc_api_pipe_req_state *state = tevent_req_data(
1414 req, struct rpc_api_pipe_req_state);
1417 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1418 TALLOC_FREE(subreq);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 tevent_req_nterror(req, status);
1423 tevent_req_done(req);
1426 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1427 DATA_BLOB *reply_pdu)
1429 struct rpc_api_pipe_req_state *state = tevent_req_data(
1430 req, struct rpc_api_pipe_req_state);
1433 if (tevent_req_is_nterror(req, &status)) {
1435 * We always have to initialize to reply pdu, even if there is
1436 * none. The rpccli_* caller routines expect this.
1438 *reply_pdu = data_blob_null;
1442 /* return data to caller and assign it ownership of memory */
1443 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1444 reply_pdu->length = state->reply_pdu.length;
1445 state->reply_pdu.length = 0;
1447 return NT_STATUS_OK;
1451 /****************************************************************************
1452 Set the handle state.
1453 ****************************************************************************/
1455 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1456 const char *pipe_name, uint16 device_state)
1458 bool state_set = False;
1460 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1461 char *rparam = NULL;
1463 uint32 rparam_len, rdata_len;
1465 if (pipe_name == NULL)
1468 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1469 cli->fnum, pipe_name, device_state));
1471 /* create parameters: device state */
1472 SSVAL(param, 0, device_state);
1474 /* create setup parameters. */
1476 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1478 /* send the data on \PIPE\ */
1479 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1480 setup, 2, 0, /* setup, length, max */
1481 param, 2, 0, /* param, length, max */
1482 NULL, 0, 1024, /* data, length, max */
1483 &rparam, &rparam_len, /* return param, length */
1484 &rdata, &rdata_len)) /* return data, length */
1486 DEBUG(5, ("Set Handle state: return OK\n"));
1497 /****************************************************************************
1498 Check the rpc bind acknowledge response.
1499 ****************************************************************************/
1501 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1502 const struct ndr_syntax_id *transfer)
1504 struct dcerpc_ack_ctx ctx;
1506 if (r->secondary_address_size == 0) {
1507 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1510 if (r->num_results < 1 || !r->ctx_list) {
1514 ctx = r->ctx_list[0];
1516 /* check the transfer syntax */
1517 if ((ctx.syntax.if_version != transfer->if_version) ||
1518 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1519 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1523 if (r->num_results != 0x1 || ctx.result != 0) {
1524 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1525 r->num_results, ctx.reason));
1528 DEBUG(5,("check_bind_response: accepted!\n"));
1532 /*******************************************************************
1533 Creates a DCE/RPC bind authentication response.
1534 This is the packet that is sent back to the server once we
1535 have received a BIND-ACK, to finish the third leg of
1536 the authentication handshake.
1537 ********************************************************************/
1539 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1540 struct rpc_pipe_client *cli,
1542 enum dcerpc_AuthType auth_type,
1543 enum dcerpc_AuthLevel auth_level,
1544 DATA_BLOB *pauth_blob,
1548 union dcerpc_payload u;
1552 status = dcerpc_push_dcerpc_auth(mem_ctx,
1555 0, /* auth_pad_length */
1556 1, /* auth_context_id */
1558 &u.auth3.auth_info);
1559 if (!NT_STATUS_IS_OK(status)) {
1563 status = dcerpc_push_ncacn_packet(mem_ctx,
1565 DCERPC_PFC_FLAG_FIRST |
1566 DCERPC_PFC_FLAG_LAST,
1571 data_blob_free(&u.auth3.auth_info);
1572 if (!NT_STATUS_IS_OK(status)) {
1573 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1577 return NT_STATUS_OK;
1580 /*******************************************************************
1581 Creates a DCE/RPC bind alter context authentication request which
1582 may contain a spnego auth blobl
1583 ********************************************************************/
1585 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1586 enum dcerpc_AuthType auth_type,
1587 enum dcerpc_AuthLevel auth_level,
1589 const struct ndr_syntax_id *abstract,
1590 const struct ndr_syntax_id *transfer,
1591 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1594 DATA_BLOB auth_info;
1597 status = dcerpc_push_dcerpc_auth(mem_ctx,
1600 0, /* auth_pad_length */
1601 1, /* auth_context_id */
1604 if (!NT_STATUS_IS_OK(status)) {
1608 status = create_bind_or_alt_ctx_internal(mem_ctx,
1615 data_blob_free(&auth_info);
1619 /****************************************************************************
1621 ****************************************************************************/
1623 struct rpc_pipe_bind_state {
1624 struct event_context *ev;
1625 struct rpc_pipe_client *cli;
1627 uint32_t rpc_call_id;
1630 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1631 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1632 struct rpc_pipe_bind_state *state,
1633 DATA_BLOB *credentials);
1634 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1635 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1636 struct rpc_pipe_bind_state *state,
1637 DATA_BLOB *credentials);
1638 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1639 struct rpc_pipe_bind_state *state,
1640 DATA_BLOB *credentials);
1642 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1643 struct event_context *ev,
1644 struct rpc_pipe_client *cli,
1645 struct pipe_auth_data *auth)
1647 struct tevent_req *req, *subreq;
1648 struct rpc_pipe_bind_state *state;
1651 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1656 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1657 rpccli_pipe_txt(talloc_tos(), cli),
1658 (unsigned int)auth->auth_type,
1659 (unsigned int)auth->spnego_type,
1660 (unsigned int)auth->auth_level ));
1664 state->rpc_call_id = get_rpc_call_id();
1665 state->rpc_out = data_blob_null;
1667 cli->auth = talloc_move(cli, &auth);
1669 /* Marshall the outgoing data. */
1670 status = create_rpc_bind_req(state, cli,
1673 &cli->abstract_syntax,
1674 &cli->transfer_syntax,
1677 if (!NT_STATUS_IS_OK(status)) {
1681 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1682 DCERPC_PKT_BIND_ACK);
1683 if (subreq == NULL) {
1686 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1690 tevent_req_nterror(req, status);
1691 return tevent_req_post(req, ev);
1697 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1699 struct tevent_req *req = tevent_req_callback_data(
1700 subreq, struct tevent_req);
1701 struct rpc_pipe_bind_state *state = tevent_req_data(
1702 req, struct rpc_pipe_bind_state);
1703 struct pipe_auth_data *pauth = state->cli->auth;
1704 DATA_BLOB reply_pdu;
1705 struct ncacn_packet *pkt;
1706 struct dcerpc_auth auth;
1707 DATA_BLOB auth_token = data_blob_null;
1710 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1711 TALLOC_FREE(subreq);
1712 if (!NT_STATUS_IS_OK(status)) {
1713 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1714 rpccli_pipe_txt(talloc_tos(), state->cli),
1715 nt_errstr(status)));
1716 tevent_req_nterror(req, status);
1720 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1721 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1722 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1726 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1727 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1729 switch(state->cli->auth->auth_type) {
1731 case DCERPC_AUTH_TYPE_NONE:
1732 case DCERPC_AUTH_TYPE_SCHANNEL:
1733 /* Bind complete. */
1734 tevent_req_done(req);
1737 case DCERPC_AUTH_TYPE_NTLMSSP:
1738 case DCERPC_AUTH_TYPE_SPNEGO:
1739 case DCERPC_AUTH_TYPE_KRB5:
1740 /* Paranoid lenght checks */
1741 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1742 + pkt->auth_length) {
1743 tevent_req_nterror(req,
1744 NT_STATUS_INFO_LENGTH_MISMATCH);
1747 /* get auth credentials */
1748 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1749 &pkt->u.bind_ack.auth_info,
1751 if (!NT_STATUS_IS_OK(status)) {
1752 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1753 nt_errstr(status)));
1754 tevent_req_nterror(req, status);
1764 * For authenticated binds we may need to do 3 or 4 leg binds.
1767 switch(state->cli->auth->auth_type) {
1769 case DCERPC_AUTH_TYPE_NONE:
1770 case DCERPC_AUTH_TYPE_SCHANNEL:
1771 /* Bind complete. */
1772 tevent_req_done(req);
1775 case DCERPC_AUTH_TYPE_NTLMSSP:
1776 /* Need to send AUTH3 packet - no reply. */
1777 status = rpc_finish_auth3_bind_send(req, state,
1781 case DCERPC_AUTH_TYPE_SPNEGO:
1782 status = spnego_get_client_auth_token(state,
1783 pauth->a_u.spnego_state,
1786 if (!NT_STATUS_IS_OK(status)) {
1789 if (auth_token.length == 0) {
1790 /* Bind complete. */
1791 tevent_req_done(req);
1794 if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
1795 status = rpc_bind_next_send(req, state,
1798 status = rpc_bind_finish_send(req, state,
1803 case DCERPC_AUTH_TYPE_KRB5:
1804 status = gse_get_client_auth_token(state,
1805 pauth->a_u.gssapi_state,
1808 if (!NT_STATUS_IS_OK(status)) {
1812 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
1813 status = rpc_bind_next_send(req, state, &auth_token);
1815 status = rpc_bind_finish_send(req, state, &auth_token);
1823 if (!NT_STATUS_IS_OK(status)) {
1824 tevent_req_nterror(req, status);
1829 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
1830 (unsigned int)state->cli->auth->auth_type,
1831 (unsigned int)state->cli->auth->spnego_type));
1832 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1835 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1836 struct rpc_pipe_bind_state *state,
1837 DATA_BLOB *credentials)
1839 struct pipe_auth_data *auth = state->cli->auth;
1840 DATA_BLOB client_reply = data_blob_null;
1841 struct tevent_req *subreq;
1844 /* TODO - check auth_type/auth_level match. */
1846 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
1847 *credentials, &client_reply);
1849 if (!NT_STATUS_IS_OK(status)) {
1850 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
1851 "blob failed: %s.\n", nt_errstr(status)));
1855 data_blob_free(&state->rpc_out);
1857 status = create_rpc_bind_auth3(state, state->cli,
1863 data_blob_free(&client_reply);
1865 if (!NT_STATUS_IS_OK(status)) {
1869 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1870 state->rpc_out.data, state->rpc_out.length);
1871 if (subreq == NULL) {
1872 return NT_STATUS_NO_MEMORY;
1874 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
1875 return NT_STATUS_OK;
1878 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
1880 struct tevent_req *req = tevent_req_callback_data(
1881 subreq, struct tevent_req);
1884 status = rpc_write_recv(subreq);
1885 TALLOC_FREE(subreq);
1886 if (!NT_STATUS_IS_OK(status)) {
1887 tevent_req_nterror(req, status);
1890 tevent_req_done(req);
1893 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1894 struct rpc_pipe_bind_state *state,
1895 DATA_BLOB *auth_token)
1897 struct pipe_auth_data *auth = state->cli->auth;
1898 struct tevent_req *subreq;
1901 /* Now prepare the alter context pdu. */
1902 data_blob_free(&state->rpc_out);
1904 status = create_rpc_alter_context(state,
1908 &state->cli->abstract_syntax,
1909 &state->cli->transfer_syntax,
1912 if (!NT_STATUS_IS_OK(status)) {
1916 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1917 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1918 if (subreq == NULL) {
1919 return NT_STATUS_NO_MEMORY;
1921 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1922 return NT_STATUS_OK;
1925 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1926 struct rpc_pipe_bind_state *state,
1927 DATA_BLOB *auth_token)
1929 struct pipe_auth_data *auth = state->cli->auth;
1930 struct tevent_req *subreq;
1933 /* Now prepare the auth3 context pdu. */
1934 data_blob_free(&state->rpc_out);
1936 status = create_rpc_bind_auth3(state, state->cli,
1942 if (!NT_STATUS_IS_OK(status)) {
1946 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1947 state->rpc_out.data, state->rpc_out.length);
1948 if (subreq == NULL) {
1949 return NT_STATUS_NO_MEMORY;
1951 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
1952 return NT_STATUS_OK;
1955 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1957 return tevent_req_simple_recv_ntstatus(req);
1960 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1961 struct pipe_auth_data *auth)
1963 TALLOC_CTX *frame = talloc_stackframe();
1964 struct event_context *ev;
1965 struct tevent_req *req;
1966 NTSTATUS status = NT_STATUS_OK;
1968 ev = event_context_init(frame);
1970 status = NT_STATUS_NO_MEMORY;
1974 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1976 status = NT_STATUS_NO_MEMORY;
1980 if (!tevent_req_poll(req, ev)) {
1981 status = map_nt_error_from_unix(errno);
1985 status = rpc_pipe_bind_recv(req);
1991 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1993 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1994 unsigned int timeout)
1998 if (rpc_cli->transport == NULL) {
1999 return RPCCLI_DEFAULT_TIMEOUT;
2002 if (rpc_cli->transport->set_timeout == NULL) {
2003 return RPCCLI_DEFAULT_TIMEOUT;
2006 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2008 return RPCCLI_DEFAULT_TIMEOUT;
2014 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2016 if (rpc_cli == NULL) {
2020 if (rpc_cli->transport == NULL) {
2024 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2027 struct rpccli_bh_state {
2028 struct rpc_pipe_client *rpc_cli;
2031 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2033 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2034 struct rpccli_bh_state);
2036 return rpccli_is_connected(hs->rpc_cli);
2039 struct rpccli_bh_raw_call_state {
2045 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2047 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2048 struct tevent_context *ev,
2049 struct dcerpc_binding_handle *h,
2050 const struct GUID *object,
2053 const uint8_t *in_data,
2056 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2057 struct rpccli_bh_state);
2058 struct tevent_req *req;
2059 struct rpccli_bh_raw_call_state *state;
2061 struct tevent_req *subreq;
2063 req = tevent_req_create(mem_ctx, &state,
2064 struct rpccli_bh_raw_call_state);
2068 state->in_data.data = discard_const_p(uint8_t, in_data);
2069 state->in_data.length = in_length;
2071 ok = rpccli_bh_is_connected(h);
2073 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2074 return tevent_req_post(req, ev);
2077 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2078 opnum, &state->in_data);
2079 if (tevent_req_nomem(subreq, req)) {
2080 return tevent_req_post(req, ev);
2082 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2087 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2089 struct tevent_req *req =
2090 tevent_req_callback_data(subreq,
2092 struct rpccli_bh_raw_call_state *state =
2093 tevent_req_data(req,
2094 struct rpccli_bh_raw_call_state);
2097 state->out_flags = 0;
2099 /* TODO: support bigendian responses */
2101 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2102 TALLOC_FREE(subreq);
2103 if (!NT_STATUS_IS_OK(status)) {
2104 tevent_req_nterror(req, status);
2108 tevent_req_done(req);
2111 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2112 TALLOC_CTX *mem_ctx,
2115 uint32_t *out_flags)
2117 struct rpccli_bh_raw_call_state *state =
2118 tevent_req_data(req,
2119 struct rpccli_bh_raw_call_state);
2122 if (tevent_req_is_nterror(req, &status)) {
2123 tevent_req_received(req);
2127 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2128 *out_length = state->out_data.length;
2129 *out_flags = state->out_flags;
2130 tevent_req_received(req);
2131 return NT_STATUS_OK;
2134 struct rpccli_bh_disconnect_state {
2138 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2139 struct tevent_context *ev,
2140 struct dcerpc_binding_handle *h)
2142 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2143 struct rpccli_bh_state);
2144 struct tevent_req *req;
2145 struct rpccli_bh_disconnect_state *state;
2148 req = tevent_req_create(mem_ctx, &state,
2149 struct rpccli_bh_disconnect_state);
2154 ok = rpccli_bh_is_connected(h);
2156 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2157 return tevent_req_post(req, ev);
2161 * TODO: do a real async disconnect ...
2163 * For now the caller needs to free rpc_cli
2167 tevent_req_done(req);
2168 return tevent_req_post(req, ev);
2171 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2175 if (tevent_req_is_nterror(req, &status)) {
2176 tevent_req_received(req);
2180 tevent_req_received(req);
2181 return NT_STATUS_OK;
2184 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2189 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2191 const void *_struct_ptr,
2192 const struct ndr_interface_call *call)
2194 void *struct_ptr = discard_const(_struct_ptr);
2196 if (DEBUGLEVEL < 10) {
2200 if (ndr_flags & NDR_IN) {
2201 ndr_print_function_debug(call->ndr_print,
2206 if (ndr_flags & NDR_OUT) {
2207 ndr_print_function_debug(call->ndr_print,
2214 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2216 .is_connected = rpccli_bh_is_connected,
2217 .raw_call_send = rpccli_bh_raw_call_send,
2218 .raw_call_recv = rpccli_bh_raw_call_recv,
2219 .disconnect_send = rpccli_bh_disconnect_send,
2220 .disconnect_recv = rpccli_bh_disconnect_recv,
2222 .ref_alloc = rpccli_bh_ref_alloc,
2223 .do_ndr_print = rpccli_bh_do_ndr_print,
2226 /* initialise a rpc_pipe_client binding handle */
2227 static struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2229 struct dcerpc_binding_handle *h;
2230 struct rpccli_bh_state *hs;
2232 h = dcerpc_binding_handle_create(c,
2237 struct rpccli_bh_state,
2247 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2249 struct auth_ntlmssp_state *a = NULL;
2250 struct cli_state *cli;
2252 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2253 a = rpc_cli->auth->a_u.auth_ntlmssp_state;
2254 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2255 enum dcerpc_AuthType auth_type;
2259 status = spnego_get_negotiated_mech(
2260 rpc_cli->auth->a_u.spnego_state,
2261 &auth_type, &auth_ctx);
2262 if (!NT_STATUS_IS_OK(status)) {
2266 if (auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2267 a = talloc_get_type(auth_ctx,
2268 struct auth_ntlmssp_state);
2273 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2277 cli = rpc_pipe_np_smb_conn(rpc_cli);
2281 E_md4hash(cli->password ? cli->password : "", nt_hash);
2285 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2286 struct pipe_auth_data **presult)
2288 struct pipe_auth_data *result;
2290 result = talloc(mem_ctx, struct pipe_auth_data);
2291 if (result == NULL) {
2292 return NT_STATUS_NO_MEMORY;
2295 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2296 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2297 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2299 result->user_name = talloc_strdup(result, "");
2300 result->domain = talloc_strdup(result, "");
2301 if ((result->user_name == NULL) || (result->domain == NULL)) {
2302 TALLOC_FREE(result);
2303 return NT_STATUS_NO_MEMORY;
2307 return NT_STATUS_OK;
2310 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2312 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2316 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2317 enum dcerpc_AuthType auth_type,
2318 enum dcerpc_AuthLevel auth_level,
2320 const char *username,
2321 const char *password,
2322 struct pipe_auth_data **presult)
2324 struct pipe_auth_data *result;
2327 result = talloc(mem_ctx, struct pipe_auth_data);
2328 if (result == NULL) {
2329 return NT_STATUS_NO_MEMORY;
2332 result->auth_type = auth_type;
2333 result->auth_level = auth_level;
2335 result->user_name = talloc_strdup(result, username);
2336 result->domain = talloc_strdup(result, domain);
2337 if ((result->user_name == NULL) || (result->domain == NULL)) {
2338 status = NT_STATUS_NO_MEMORY;
2342 status = auth_ntlmssp_client_start(NULL,
2345 lp_client_ntlmv2_auth(),
2346 &result->a_u.auth_ntlmssp_state);
2347 if (!NT_STATUS_IS_OK(status)) {
2351 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2353 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2355 if (!NT_STATUS_IS_OK(status)) {
2359 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2361 if (!NT_STATUS_IS_OK(status)) {
2365 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2367 if (!NT_STATUS_IS_OK(status)) {
2372 * Turn off sign+seal to allow selected auth level to turn it back on.
2374 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2375 ~(NTLMSSP_NEGOTIATE_SIGN |
2376 NTLMSSP_NEGOTIATE_SEAL));
2378 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2379 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2380 NTLMSSP_NEGOTIATE_SIGN);
2381 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2382 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2383 NTLMSSP_NEGOTIATE_SEAL |
2384 NTLMSSP_NEGOTIATE_SIGN);
2388 return NT_STATUS_OK;
2391 TALLOC_FREE(result);
2395 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2396 enum dcerpc_AuthLevel auth_level,
2397 struct netlogon_creds_CredentialState *creds,
2398 struct pipe_auth_data **presult)
2400 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 = DCERPC_AUTH_TYPE_SCHANNEL;
2408 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2409 result->auth_level = auth_level;
2411 result->user_name = talloc_strdup(result, "");
2412 result->domain = talloc_strdup(result, domain);
2413 if ((result->user_name == NULL) || (result->domain == NULL)) {
2417 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2418 if (result->a_u.schannel_auth == NULL) {
2422 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2423 result->a_u.schannel_auth->seq_num = 0;
2424 result->a_u.schannel_auth->initiator = true;
2425 result->a_u.schannel_auth->creds = creds;
2428 return NT_STATUS_OK;
2431 TALLOC_FREE(result);
2432 return NT_STATUS_NO_MEMORY;
2436 * Create an rpc pipe client struct, connecting to a tcp port.
2438 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2440 const struct ndr_syntax_id *abstract_syntax,
2441 struct rpc_pipe_client **presult)
2443 struct rpc_pipe_client *result;
2444 struct sockaddr_storage addr;
2448 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2449 if (result == NULL) {
2450 return NT_STATUS_NO_MEMORY;
2453 result->abstract_syntax = *abstract_syntax;
2454 result->transfer_syntax = ndr_transfer_syntax;
2456 result->desthost = talloc_strdup(result, host);
2457 result->srv_name_slash = talloc_asprintf_strupper_m(
2458 result, "\\\\%s", result->desthost);
2459 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2460 status = NT_STATUS_NO_MEMORY;
2464 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2465 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2467 if (!resolve_name(host, &addr, 0, false)) {
2468 status = NT_STATUS_NOT_FOUND;
2472 status = open_socket_out(&addr, port, 60, &fd);
2473 if (!NT_STATUS_IS_OK(status)) {
2476 set_socket_options(fd, lp_socket_options());
2478 status = rpc_transport_sock_init(result, fd, &result->transport);
2479 if (!NT_STATUS_IS_OK(status)) {
2484 result->transport->transport = NCACN_IP_TCP;
2486 result->binding_handle = rpccli_bh_create(result);
2487 if (result->binding_handle == NULL) {
2488 TALLOC_FREE(result);
2489 return NT_STATUS_NO_MEMORY;
2493 return NT_STATUS_OK;
2496 TALLOC_FREE(result);
2501 * Determine the tcp port on which a dcerpc interface is listening
2502 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2505 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2506 const struct ndr_syntax_id *abstract_syntax,
2510 struct rpc_pipe_client *epm_pipe = NULL;
2511 struct pipe_auth_data *auth = NULL;
2512 struct dcerpc_binding *map_binding = NULL;
2513 struct dcerpc_binding *res_binding = NULL;
2514 struct epm_twr_t *map_tower = NULL;
2515 struct epm_twr_t *res_towers = NULL;
2516 struct policy_handle *entry_handle = NULL;
2517 uint32_t num_towers = 0;
2518 uint32_t max_towers = 1;
2519 struct epm_twr_p_t towers;
2520 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2522 if (pport == NULL) {
2523 status = NT_STATUS_INVALID_PARAMETER;
2527 /* open the connection to the endpoint mapper */
2528 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2529 &ndr_table_epmapper.syntax_id,
2532 if (!NT_STATUS_IS_OK(status)) {
2536 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2537 if (!NT_STATUS_IS_OK(status)) {
2541 status = rpc_pipe_bind(epm_pipe, auth);
2542 if (!NT_STATUS_IS_OK(status)) {
2546 /* create tower for asking the epmapper */
2548 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2549 if (map_binding == NULL) {
2550 status = NT_STATUS_NO_MEMORY;
2554 map_binding->transport = NCACN_IP_TCP;
2555 map_binding->object = *abstract_syntax;
2556 map_binding->host = host; /* needed? */
2557 map_binding->endpoint = "0"; /* correct? needed? */
2559 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2560 if (map_tower == NULL) {
2561 status = NT_STATUS_NO_MEMORY;
2565 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2566 &(map_tower->tower));
2567 if (!NT_STATUS_IS_OK(status)) {
2571 /* allocate further parameters for the epm_Map call */
2573 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2574 if (res_towers == NULL) {
2575 status = NT_STATUS_NO_MEMORY;
2578 towers.twr = res_towers;
2580 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2581 if (entry_handle == NULL) {
2582 status = NT_STATUS_NO_MEMORY;
2586 /* ask the endpoint mapper for the port */
2588 status = rpccli_epm_Map(epm_pipe,
2590 CONST_DISCARD(struct GUID *,
2591 &(abstract_syntax->uuid)),
2598 if (!NT_STATUS_IS_OK(status)) {
2602 if (num_towers != 1) {
2603 status = NT_STATUS_UNSUCCESSFUL;
2607 /* extract the port from the answer */
2609 status = dcerpc_binding_from_tower(tmp_ctx,
2610 &(towers.twr->tower),
2612 if (!NT_STATUS_IS_OK(status)) {
2616 /* are further checks here necessary? */
2617 if (res_binding->transport != NCACN_IP_TCP) {
2618 status = NT_STATUS_UNSUCCESSFUL;
2622 *pport = (uint16_t)atoi(res_binding->endpoint);
2625 TALLOC_FREE(tmp_ctx);
2630 * Create a rpc pipe client struct, connecting to a host via tcp.
2631 * The port is determined by asking the endpoint mapper on the given
2634 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2635 const struct ndr_syntax_id *abstract_syntax,
2636 struct rpc_pipe_client **presult)
2641 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2642 if (!NT_STATUS_IS_OK(status)) {
2646 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2647 abstract_syntax, presult);
2650 /********************************************************************
2651 Create a rpc pipe client struct, connecting to a unix domain socket
2652 ********************************************************************/
2653 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2654 const struct ndr_syntax_id *abstract_syntax,
2655 struct rpc_pipe_client **presult)
2657 struct rpc_pipe_client *result;
2658 struct sockaddr_un addr;
2662 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2663 if (result == NULL) {
2664 return NT_STATUS_NO_MEMORY;
2667 result->abstract_syntax = *abstract_syntax;
2668 result->transfer_syntax = ndr_transfer_syntax;
2670 result->desthost = get_myname(result);
2671 result->srv_name_slash = talloc_asprintf_strupper_m(
2672 result, "\\\\%s", result->desthost);
2673 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2674 status = NT_STATUS_NO_MEMORY;
2678 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2679 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2681 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2683 status = map_nt_error_from_unix(errno);
2688 addr.sun_family = AF_UNIX;
2689 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2691 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2692 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2695 return map_nt_error_from_unix(errno);
2698 status = rpc_transport_sock_init(result, fd, &result->transport);
2699 if (!NT_STATUS_IS_OK(status)) {
2704 result->transport->transport = NCALRPC;
2706 result->binding_handle = rpccli_bh_create(result);
2707 if (result->binding_handle == NULL) {
2708 TALLOC_FREE(result);
2709 return NT_STATUS_NO_MEMORY;
2713 return NT_STATUS_OK;
2716 TALLOC_FREE(result);
2720 struct rpc_pipe_client_np_ref {
2721 struct cli_state *cli;
2722 struct rpc_pipe_client *pipe;
2725 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2727 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2731 /****************************************************************************
2732 Open a named pipe over SMB to a remote server.
2734 * CAVEAT CALLER OF THIS FUNCTION:
2735 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2736 * so be sure that this function is called AFTER any structure (vs pointer)
2737 * assignment of the cli. In particular, libsmbclient does structure
2738 * assignments of cli, which invalidates the data in the returned
2739 * rpc_pipe_client if this function is called before the structure assignment
2742 ****************************************************************************/
2744 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2745 const struct ndr_syntax_id *abstract_syntax,
2746 struct rpc_pipe_client **presult)
2748 struct rpc_pipe_client *result;
2750 struct rpc_pipe_client_np_ref *np_ref;
2752 /* sanity check to protect against crashes */
2755 return NT_STATUS_INVALID_HANDLE;
2758 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2759 if (result == NULL) {
2760 return NT_STATUS_NO_MEMORY;
2763 result->abstract_syntax = *abstract_syntax;
2764 result->transfer_syntax = ndr_transfer_syntax;
2765 result->desthost = talloc_strdup(result, cli->desthost);
2766 result->srv_name_slash = talloc_asprintf_strupper_m(
2767 result, "\\\\%s", result->desthost);
2769 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2770 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2772 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2773 TALLOC_FREE(result);
2774 return NT_STATUS_NO_MEMORY;
2777 status = rpc_transport_np_init(result, cli, abstract_syntax,
2778 &result->transport);
2779 if (!NT_STATUS_IS_OK(status)) {
2780 TALLOC_FREE(result);
2784 result->transport->transport = NCACN_NP;
2786 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2787 if (np_ref == NULL) {
2788 TALLOC_FREE(result);
2789 return NT_STATUS_NO_MEMORY;
2792 np_ref->pipe = result;
2794 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2795 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2797 result->binding_handle = rpccli_bh_create(result);
2798 if (result->binding_handle == NULL) {
2799 TALLOC_FREE(result);
2800 return NT_STATUS_NO_MEMORY;
2804 return NT_STATUS_OK;
2807 /****************************************************************************
2808 Open a pipe to a remote server.
2809 ****************************************************************************/
2811 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2812 enum dcerpc_transport_t transport,
2813 const struct ndr_syntax_id *interface,
2814 struct rpc_pipe_client **presult)
2816 switch (transport) {
2818 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2821 return rpc_pipe_open_np(cli, interface, presult);
2823 return NT_STATUS_NOT_IMPLEMENTED;
2827 /****************************************************************************
2828 Open a named pipe to an SMB server and bind anonymously.
2829 ****************************************************************************/
2831 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2832 enum dcerpc_transport_t transport,
2833 const struct ndr_syntax_id *interface,
2834 struct rpc_pipe_client **presult)
2836 struct rpc_pipe_client *result;
2837 struct pipe_auth_data *auth;
2840 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2841 if (!NT_STATUS_IS_OK(status)) {
2845 status = rpccli_anon_bind_data(result, &auth);
2846 if (!NT_STATUS_IS_OK(status)) {
2847 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2848 nt_errstr(status)));
2849 TALLOC_FREE(result);
2854 * This is a bit of an abstraction violation due to the fact that an
2855 * anonymous bind on an authenticated SMB inherits the user/domain
2856 * from the enclosing SMB creds
2859 TALLOC_FREE(auth->user_name);
2860 TALLOC_FREE(auth->domain);
2862 auth->user_name = talloc_strdup(auth, cli->user_name);
2863 auth->domain = talloc_strdup(auth, cli->domain);
2864 auth->user_session_key = data_blob_talloc(auth,
2865 cli->user_session_key.data,
2866 cli->user_session_key.length);
2868 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2869 TALLOC_FREE(result);
2870 return NT_STATUS_NO_MEMORY;
2873 status = rpc_pipe_bind(result, auth);
2874 if (!NT_STATUS_IS_OK(status)) {
2876 if (ndr_syntax_id_equal(interface,
2877 &ndr_table_dssetup.syntax_id)) {
2878 /* non AD domains just don't have this pipe, avoid
2879 * level 0 statement in that case - gd */
2882 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2883 "%s failed with error %s\n",
2884 get_pipe_name_from_syntax(talloc_tos(), interface),
2885 nt_errstr(status) ));
2886 TALLOC_FREE(result);
2890 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2891 "%s and bound anonymously.\n",
2892 get_pipe_name_from_syntax(talloc_tos(), interface),
2896 return NT_STATUS_OK;
2899 /****************************************************************************
2900 ****************************************************************************/
2902 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2903 const struct ndr_syntax_id *interface,
2904 struct rpc_pipe_client **presult)
2906 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2907 interface, presult);
2910 /****************************************************************************
2911 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2912 ****************************************************************************/
2914 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2915 const struct ndr_syntax_id *interface,
2916 enum dcerpc_transport_t transport,
2917 enum dcerpc_AuthLevel auth_level,
2919 const char *username,
2920 const char *password,
2921 struct rpc_pipe_client **presult)
2923 struct rpc_pipe_client *result;
2924 struct pipe_auth_data *auth = NULL;
2925 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2928 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2929 if (!NT_STATUS_IS_OK(status)) {
2933 status = rpccli_ntlmssp_bind_data(result,
2934 auth_type, auth_level,
2935 domain, username, password,
2937 if (!NT_STATUS_IS_OK(status)) {
2938 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2939 nt_errstr(status)));
2943 status = rpc_pipe_bind(result, auth);
2944 if (!NT_STATUS_IS_OK(status)) {
2945 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2946 nt_errstr(status) ));
2950 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2951 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2952 get_pipe_name_from_syntax(talloc_tos(), interface),
2953 cli->desthost, domain, username ));
2956 return NT_STATUS_OK;
2960 TALLOC_FREE(result);
2964 /****************************************************************************
2965 Get a the schannel session key out of an already opened netlogon pipe.
2966 ****************************************************************************/
2967 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2968 struct cli_state *cli,
2972 enum netr_SchannelType sec_chan_type = 0;
2973 unsigned char machine_pwd[16];
2974 const char *machine_account;
2977 /* Get the machine account credentials from secrets.tdb. */
2978 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2981 DEBUG(0, ("get_schannel_session_key: could not fetch "
2982 "trust account password for domain '%s'\n",
2984 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2987 status = rpccli_netlogon_setup_creds(netlogon_pipe,
2988 cli->desthost, /* server name */
2989 domain, /* domain */
2990 global_myname(), /* client name */
2991 machine_account, /* machine account name */
2996 if (!NT_STATUS_IS_OK(status)) {
2997 DEBUG(3, ("get_schannel_session_key_common: "
2998 "rpccli_netlogon_setup_creds failed with result %s "
2999 "to server %s, domain %s, machine account %s.\n",
3000 nt_errstr(status), cli->desthost, domain,
3005 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3006 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3008 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3011 return NT_STATUS_OK;;
3014 /****************************************************************************
3015 Open a netlogon pipe and get the schannel session key.
3016 Now exposed to external callers.
3017 ****************************************************************************/
3020 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3023 struct rpc_pipe_client **presult)
3025 struct rpc_pipe_client *netlogon_pipe = NULL;
3028 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3030 if (!NT_STATUS_IS_OK(status)) {
3034 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3036 if (!NT_STATUS_IS_OK(status)) {
3037 TALLOC_FREE(netlogon_pipe);
3041 *presult = netlogon_pipe;
3042 return NT_STATUS_OK;
3045 /****************************************************************************
3047 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3048 using session_key. sign and seal.
3050 The *pdc will be stolen onto this new pipe
3051 ****************************************************************************/
3053 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3054 const struct ndr_syntax_id *interface,
3055 enum dcerpc_transport_t transport,
3056 enum dcerpc_AuthLevel auth_level,
3058 struct netlogon_creds_CredentialState **pdc,
3059 struct rpc_pipe_client **presult)
3061 struct rpc_pipe_client *result;
3062 struct pipe_auth_data *auth;
3065 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3066 if (!NT_STATUS_IS_OK(status)) {
3070 status = rpccli_schannel_bind_data(result, domain, auth_level,
3072 if (!NT_STATUS_IS_OK(status)) {
3073 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3074 nt_errstr(status)));
3075 TALLOC_FREE(result);
3079 status = rpc_pipe_bind(result, auth);
3080 if (!NT_STATUS_IS_OK(status)) {
3081 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3082 "cli_rpc_pipe_bind failed with error %s\n",
3083 nt_errstr(status) ));
3084 TALLOC_FREE(result);
3089 * The credentials on a new netlogon pipe are the ones we are passed
3090 * in - reference them in
3092 result->dc = talloc_move(result, pdc);
3094 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3095 "for domain %s and bound using schannel.\n",
3096 get_pipe_name_from_syntax(talloc_tos(), interface),
3097 cli->desthost, domain ));
3100 return NT_STATUS_OK;
3103 /****************************************************************************
3104 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3105 Fetch the session key ourselves using a temporary netlogon pipe. This
3106 version uses an ntlmssp auth bound netlogon pipe to get the key.
3107 ****************************************************************************/
3109 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3111 const char *username,
3112 const char *password,
3114 struct rpc_pipe_client **presult)
3116 struct rpc_pipe_client *netlogon_pipe = NULL;
3119 status = cli_rpc_pipe_open_spnego_ntlmssp(
3120 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3121 DCERPC_AUTH_LEVEL_PRIVACY,
3122 domain, username, password, &netlogon_pipe);
3123 if (!NT_STATUS_IS_OK(status)) {
3127 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3129 if (!NT_STATUS_IS_OK(status)) {
3130 TALLOC_FREE(netlogon_pipe);
3134 *presult = netlogon_pipe;
3135 return NT_STATUS_OK;
3138 /****************************************************************************
3139 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3140 Fetch the session key ourselves using a temporary netlogon pipe. This version
3141 uses an ntlmssp bind to get the session key.
3142 ****************************************************************************/
3144 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3145 const struct ndr_syntax_id *interface,
3146 enum dcerpc_transport_t transport,
3147 enum dcerpc_AuthLevel auth_level,
3149 const char *username,
3150 const char *password,
3151 struct rpc_pipe_client **presult)
3153 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3154 struct rpc_pipe_client *netlogon_pipe = NULL;
3155 struct rpc_pipe_client *result = NULL;
3158 status = get_schannel_session_key_auth_ntlmssp(
3159 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3160 if (!NT_STATUS_IS_OK(status)) {
3161 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3162 "key from server %s for domain %s.\n",
3163 cli->desthost, domain ));
3167 status = cli_rpc_pipe_open_schannel_with_key(
3168 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3171 /* Now we've bound using the session key we can close the netlog pipe. */
3172 TALLOC_FREE(netlogon_pipe);
3174 if (NT_STATUS_IS_OK(status)) {
3180 /****************************************************************************
3181 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3182 Fetch the session key ourselves using a temporary netlogon pipe.
3183 ****************************************************************************/
3185 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3186 const struct ndr_syntax_id *interface,
3187 enum dcerpc_transport_t transport,
3188 enum dcerpc_AuthLevel auth_level,
3190 struct rpc_pipe_client **presult)
3192 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3193 struct rpc_pipe_client *netlogon_pipe = NULL;
3194 struct rpc_pipe_client *result = NULL;
3197 status = get_schannel_session_key(cli, domain, &neg_flags,
3199 if (!NT_STATUS_IS_OK(status)) {
3200 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3201 "key from server %s for domain %s.\n",
3202 cli->desthost, domain ));
3206 status = cli_rpc_pipe_open_schannel_with_key(
3207 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3210 /* Now we've bound using the session key we can close the netlog pipe. */
3211 TALLOC_FREE(netlogon_pipe);
3213 if (NT_STATUS_IS_OK(status)) {
3220 /****************************************************************************
3221 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3222 The idea is this can be called with service_princ, username and password all
3223 NULL so long as the caller has a TGT.
3224 ****************************************************************************/
3226 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3227 const struct ndr_syntax_id *interface,
3228 enum dcerpc_transport_t transport,
3229 enum dcerpc_AuthLevel auth_level,
3231 const char *username,
3232 const char *password,
3233 struct rpc_pipe_client **presult)
3235 struct rpc_pipe_client *result;
3236 struct pipe_auth_data *auth;
3239 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3240 if (!NT_STATUS_IS_OK(status)) {
3244 auth = talloc(result, struct pipe_auth_data);
3246 status = NT_STATUS_NO_MEMORY;
3249 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3250 auth->auth_level = auth_level;
3255 auth->user_name = talloc_strdup(auth, username);
3256 if (!auth->user_name) {
3257 status = NT_STATUS_NO_MEMORY;
3261 /* Fixme, should we fetch/set the Realm ? */
3262 auth->domain = talloc_strdup(auth, "");
3263 if (!auth->domain) {
3264 status = NT_STATUS_NO_MEMORY;
3268 status = gse_init_client(auth, auth->auth_type, auth->auth_level,
3269 NULL, server, "cifs", username, password,
3270 GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3272 if (!NT_STATUS_IS_OK(status)) {
3273 DEBUG(0, ("gse_init_client returned %s\n",
3274 nt_errstr(status)));
3278 status = rpc_pipe_bind(result, auth);
3279 if (!NT_STATUS_IS_OK(status)) {
3280 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3281 nt_errstr(status)));
3286 return NT_STATUS_OK;
3289 TALLOC_FREE(result);
3293 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3294 const struct ndr_syntax_id *interface,
3295 enum dcerpc_transport_t transport,
3296 enum dcerpc_AuthLevel auth_level,
3298 const char *username,
3299 const char *password,
3300 struct rpc_pipe_client **presult)
3302 struct rpc_pipe_client *result;
3303 struct pipe_auth_data *auth;
3306 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3307 if (!NT_STATUS_IS_OK(status)) {
3311 auth = talloc(result, struct pipe_auth_data);
3313 status = NT_STATUS_NO_MEMORY;
3316 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3317 auth->auth_level = auth_level;
3319 auth->spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
3324 auth->user_name = talloc_strdup(auth, username);
3325 if (!auth->user_name) {
3326 status = NT_STATUS_NO_MEMORY;
3330 /* Fixme, should we fetch/set the Realm ? */
3331 auth->domain = talloc_strdup(auth, "");
3332 if (!auth->domain) {
3333 status = NT_STATUS_NO_MEMORY;
3337 status = spnego_gssapi_init_client(auth, auth->auth_level,
3338 NULL, server, "cifs",
3341 &auth->a_u.spnego_state);
3342 if (!NT_STATUS_IS_OK(status)) {
3343 DEBUG(0, ("spnego_init_client returned %s\n",
3344 nt_errstr(status)));
3348 status = rpc_pipe_bind(result, auth);
3349 if (!NT_STATUS_IS_OK(status)) {
3350 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3351 nt_errstr(status)));
3356 return NT_STATUS_OK;
3359 TALLOC_FREE(result);
3363 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3364 const struct ndr_syntax_id *interface,
3365 enum dcerpc_transport_t transport,
3366 enum dcerpc_AuthLevel auth_level,
3368 const char *username,
3369 const char *password,
3370 struct rpc_pipe_client **presult)
3372 struct rpc_pipe_client *result;
3373 struct pipe_auth_data *auth;
3376 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3377 if (!NT_STATUS_IS_OK(status)) {
3381 auth = talloc(result, struct pipe_auth_data);
3383 status = NT_STATUS_NO_MEMORY;
3386 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3387 auth->auth_level = auth_level;
3392 auth->user_name = talloc_strdup(auth, username);
3393 if (!auth->user_name) {
3394 status = NT_STATUS_NO_MEMORY;
3401 auth->domain = talloc_strdup(auth, domain);
3402 if (!auth->domain) {
3403 status = NT_STATUS_NO_MEMORY;
3407 status = spnego_ntlmssp_init_client(auth, auth->auth_level,
3408 domain, username, password,
3409 &auth->a_u.spnego_state);
3410 if (!NT_STATUS_IS_OK(status)) {
3411 DEBUG(0, ("spnego_init_client returned %s\n",
3412 nt_errstr(status)));
3416 status = rpc_pipe_bind(result, auth);
3417 if (!NT_STATUS_IS_OK(status)) {
3418 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3419 nt_errstr(status)));
3424 return NT_STATUS_OK;
3427 TALLOC_FREE(result);
3431 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3432 struct rpc_pipe_client *cli,
3433 DATA_BLOB *session_key)
3435 struct pipe_auth_data *a = cli->auth;
3436 DATA_BLOB sk = data_blob_null;
3439 if (!session_key || !cli) {
3440 return NT_STATUS_INVALID_PARAMETER;
3444 return NT_STATUS_INVALID_PARAMETER;
3447 switch (cli->auth->auth_type) {
3448 case DCERPC_AUTH_TYPE_SCHANNEL:
3449 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3453 case DCERPC_AUTH_TYPE_SPNEGO:
3454 sk = spnego_get_session_key(mem_ctx, a->a_u.spnego_state);
3457 case DCERPC_AUTH_TYPE_NTLMSSP:
3458 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3461 case DCERPC_AUTH_TYPE_KRB5:
3462 sk = gse_get_session_key(mem_ctx, a->a_u.gssapi_state);
3465 case DCERPC_AUTH_TYPE_NONE:
3466 sk = data_blob_const(a->user_session_key.data,
3467 a->user_session_key.length);
3475 return NT_STATUS_NO_USER_SESSION_KEY;
3479 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3484 return NT_STATUS_OK;