2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client routines
4 * Largely rewritten by Jeremy Allison 2005.
5 * Heavily modified by Simo Sorce 2010.
6 * Copyright Andrew Bartlett 2011.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "../lib/util/tevent_ntstatus.h"
24 #include "librpc/gen_ndr/ndr_epmapper_c.h"
25 #include "../librpc/gen_ndr/ndr_schannel.h"
26 #include "../librpc/gen_ndr/ndr_dssetup.h"
27 #include "../libcli/auth/schannel.h"
28 #include "../libcli/auth/spnego.h"
29 #include "../auth/ntlmssp/ntlmssp.h"
30 #include "auth_generic.h"
31 #include "librpc/gen_ndr/ndr_dcerpc.h"
32 #include "librpc/gen_ndr/ndr_netlogon_c.h"
33 #include "librpc/rpc/dcerpc.h"
36 #include "libsmb/libsmb.h"
37 #include "auth/gensec/gensec.h"
38 #include "auth/credentials/credentials.h"
39 #include "../libcli/smb/smbXcli_base.h"
42 #define DBGC_CLASS DBGC_RPC_CLI
44 /********************************************************************
45 Pipe description for a DEBUG
46 ********************************************************************/
47 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
48 struct rpc_pipe_client
*cli
)
50 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
57 /********************************************************************
59 ********************************************************************/
61 static uint32
get_rpc_call_id(void)
63 static uint32 call_id
= 0;
67 /*******************************************************************
68 Use SMBreadX to get rest of one fragment's worth of rpc data.
69 Reads the whole size or give an error message
70 ********************************************************************/
72 struct rpc_read_state
{
73 struct event_context
*ev
;
74 struct rpc_cli_transport
*transport
;
80 static void rpc_read_done(struct tevent_req
*subreq
);
82 static struct tevent_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
83 struct event_context
*ev
,
84 struct rpc_cli_transport
*transport
,
85 uint8_t *data
, size_t size
)
87 struct tevent_req
*req
, *subreq
;
88 struct rpc_read_state
*state
;
90 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_read_state
);
95 state
->transport
= transport
;
100 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size
));
102 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
104 if (subreq
== NULL
) {
107 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
115 static void rpc_read_done(struct tevent_req
*subreq
)
117 struct tevent_req
*req
= tevent_req_callback_data(
118 subreq
, struct tevent_req
);
119 struct rpc_read_state
*state
= tevent_req_data(
120 req
, struct rpc_read_state
);
124 status
= state
->transport
->read_recv(subreq
, &received
);
126 if (!NT_STATUS_IS_OK(status
)) {
127 tevent_req_nterror(req
, status
);
131 state
->num_read
+= received
;
132 if (state
->num_read
== state
->size
) {
133 tevent_req_done(req
);
137 subreq
= state
->transport
->read_send(state
, state
->ev
,
138 state
->data
+ state
->num_read
,
139 state
->size
- state
->num_read
,
140 state
->transport
->priv
);
141 if (tevent_req_nomem(subreq
, req
)) {
144 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
147 static NTSTATUS
rpc_read_recv(struct tevent_req
*req
)
149 return tevent_req_simple_recv_ntstatus(req
);
152 struct rpc_write_state
{
153 struct event_context
*ev
;
154 struct rpc_cli_transport
*transport
;
160 static void rpc_write_done(struct tevent_req
*subreq
);
162 static struct tevent_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
163 struct event_context
*ev
,
164 struct rpc_cli_transport
*transport
,
165 const uint8_t *data
, size_t size
)
167 struct tevent_req
*req
, *subreq
;
168 struct rpc_write_state
*state
;
170 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_write_state
);
175 state
->transport
= transport
;
178 state
->num_written
= 0;
180 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size
));
182 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
183 if (subreq
== NULL
) {
186 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
193 static void rpc_write_done(struct tevent_req
*subreq
)
195 struct tevent_req
*req
= tevent_req_callback_data(
196 subreq
, struct tevent_req
);
197 struct rpc_write_state
*state
= tevent_req_data(
198 req
, struct rpc_write_state
);
202 status
= state
->transport
->write_recv(subreq
, &written
);
204 if (!NT_STATUS_IS_OK(status
)) {
205 tevent_req_nterror(req
, status
);
209 state
->num_written
+= written
;
211 if (state
->num_written
== state
->size
) {
212 tevent_req_done(req
);
216 subreq
= state
->transport
->write_send(state
, state
->ev
,
217 state
->data
+ state
->num_written
,
218 state
->size
- state
->num_written
,
219 state
->transport
->priv
);
220 if (tevent_req_nomem(subreq
, req
)) {
223 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
226 static NTSTATUS
rpc_write_recv(struct tevent_req
*req
)
228 return tevent_req_simple_recv_ntstatus(req
);
232 /****************************************************************************
233 Try and get a PDU's worth of data from current_pdu. If not, then read more
235 ****************************************************************************/
237 struct get_complete_frag_state
{
238 struct event_context
*ev
;
239 struct rpc_pipe_client
*cli
;
244 static void get_complete_frag_got_header(struct tevent_req
*subreq
);
245 static void get_complete_frag_got_rest(struct tevent_req
*subreq
);
247 static struct tevent_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
248 struct event_context
*ev
,
249 struct rpc_pipe_client
*cli
,
252 struct tevent_req
*req
, *subreq
;
253 struct get_complete_frag_state
*state
;
257 req
= tevent_req_create(mem_ctx
, &state
,
258 struct get_complete_frag_state
);
264 state
->frag_len
= RPC_HEADER_LEN
;
267 received
= pdu
->length
;
268 if (received
< RPC_HEADER_LEN
) {
269 if (!data_blob_realloc(mem_ctx
, pdu
, RPC_HEADER_LEN
)) {
270 status
= NT_STATUS_NO_MEMORY
;
273 subreq
= rpc_read_send(state
, state
->ev
,
274 state
->cli
->transport
,
275 pdu
->data
+ received
,
276 RPC_HEADER_LEN
- received
);
277 if (subreq
== NULL
) {
278 status
= NT_STATUS_NO_MEMORY
;
281 tevent_req_set_callback(subreq
, get_complete_frag_got_header
,
286 state
->frag_len
= dcerpc_get_frag_length(pdu
);
287 if (state
->frag_len
< RPC_HEADER_LEN
) {
288 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
289 return tevent_req_post(req
, ev
);
293 * Ensure we have frag_len bytes of data.
295 if (received
< state
->frag_len
) {
296 if (!data_blob_realloc(NULL
, pdu
, state
->frag_len
)) {
297 status
= NT_STATUS_NO_MEMORY
;
300 subreq
= rpc_read_send(state
, state
->ev
,
301 state
->cli
->transport
,
302 pdu
->data
+ received
,
303 state
->frag_len
- received
);
304 if (subreq
== NULL
) {
305 status
= NT_STATUS_NO_MEMORY
;
308 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
,
313 status
= NT_STATUS_OK
;
315 if (NT_STATUS_IS_OK(status
)) {
316 tevent_req_done(req
);
318 tevent_req_nterror(req
, status
);
320 return tevent_req_post(req
, ev
);
323 static void get_complete_frag_got_header(struct tevent_req
*subreq
)
325 struct tevent_req
*req
= tevent_req_callback_data(
326 subreq
, struct tevent_req
);
327 struct get_complete_frag_state
*state
= tevent_req_data(
328 req
, struct get_complete_frag_state
);
331 status
= rpc_read_recv(subreq
);
333 if (!NT_STATUS_IS_OK(status
)) {
334 tevent_req_nterror(req
, status
);
338 state
->frag_len
= dcerpc_get_frag_length(state
->pdu
);
339 if (state
->frag_len
< RPC_HEADER_LEN
) {
340 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
344 if (!data_blob_realloc(NULL
, state
->pdu
, state
->frag_len
)) {
345 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
350 * We're here in this piece of code because we've read exactly
351 * RPC_HEADER_LEN bytes into state->pdu.
354 subreq
= rpc_read_send(state
, state
->ev
, state
->cli
->transport
,
355 state
->pdu
->data
+ RPC_HEADER_LEN
,
356 state
->frag_len
- RPC_HEADER_LEN
);
357 if (tevent_req_nomem(subreq
, req
)) {
360 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
363 static void get_complete_frag_got_rest(struct tevent_req
*subreq
)
365 struct tevent_req
*req
= tevent_req_callback_data(
366 subreq
, struct tevent_req
);
369 status
= rpc_read_recv(subreq
);
371 if (!NT_STATUS_IS_OK(status
)) {
372 tevent_req_nterror(req
, status
);
375 tevent_req_done(req
);
378 static NTSTATUS
get_complete_frag_recv(struct tevent_req
*req
)
380 return tevent_req_simple_recv_ntstatus(req
);
383 /****************************************************************************
384 Do basic authentication checks on an incoming pdu.
385 ****************************************************************************/
387 static NTSTATUS
cli_pipe_validate_current_pdu(TALLOC_CTX
*mem_ctx
,
388 struct rpc_pipe_client
*cli
,
389 struct ncacn_packet
*pkt
,
391 uint8_t expected_pkt_type
,
393 DATA_BLOB
*reply_pdu
)
395 struct dcerpc_response
*r
;
396 NTSTATUS ret
= NT_STATUS_OK
;
400 * Point the return values at the real data including the RPC
401 * header. Just in case the caller wants it.
405 /* Ensure we have the correct type. */
406 switch (pkt
->ptype
) {
407 case DCERPC_PKT_ALTER_RESP
:
408 case DCERPC_PKT_BIND_ACK
:
410 /* Client code never receives this kind of packets */
414 case DCERPC_PKT_RESPONSE
:
416 r
= &pkt
->u
.response
;
418 /* Here's where we deal with incoming sign/seal. */
419 ret
= dcerpc_check_auth(cli
->auth
, pkt
,
420 &r
->stub_and_verifier
,
421 DCERPC_RESPONSE_LENGTH
,
423 if (!NT_STATUS_IS_OK(ret
)) {
427 if (pkt
->frag_length
< DCERPC_RESPONSE_LENGTH
+ pad_len
) {
428 return NT_STATUS_BUFFER_TOO_SMALL
;
431 /* Point the return values at the NDR data. */
432 rdata
->data
= r
->stub_and_verifier
.data
;
434 if (pkt
->auth_length
) {
435 /* We've already done integer wrap tests in
436 * dcerpc_check_auth(). */
437 rdata
->length
= r
->stub_and_verifier
.length
439 - DCERPC_AUTH_TRAILER_LENGTH
442 rdata
->length
= r
->stub_and_verifier
.length
;
445 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
446 (long unsigned int)pdu
->length
,
447 (long unsigned int)rdata
->length
,
448 (unsigned int)pad_len
));
451 * If this is the first reply, and the allocation hint is
452 * reasonable, try and set up the reply_pdu DATA_BLOB to the
456 if ((reply_pdu
->length
== 0) &&
457 r
->alloc_hint
&& (r
->alloc_hint
< 15*1024*1024)) {
458 if (!data_blob_realloc(mem_ctx
, reply_pdu
,
460 DEBUG(0, ("reply alloc hint %d too "
461 "large to allocate\n",
462 (int)r
->alloc_hint
));
463 return NT_STATUS_NO_MEMORY
;
469 case DCERPC_PKT_BIND_NAK
:
470 DEBUG(1, (__location__
": Bind NACK received from %s!\n",
471 rpccli_pipe_txt(talloc_tos(), cli
)));
472 /* Use this for now... */
473 return NT_STATUS_NETWORK_ACCESS_DENIED
;
475 case DCERPC_PKT_FAULT
:
477 DEBUG(1, (__location__
": RPC fault code %s received "
479 dcerpc_errstr(talloc_tos(),
480 pkt
->u
.fault
.status
),
481 rpccli_pipe_txt(talloc_tos(), cli
)));
483 return dcerpc_fault_to_nt_status(pkt
->u
.fault
.status
);
486 DEBUG(0, (__location__
"Unknown packet type %u received "
488 (unsigned int)pkt
->ptype
,
489 rpccli_pipe_txt(talloc_tos(), cli
)));
490 return NT_STATUS_INVALID_INFO_CLASS
;
493 if (pkt
->ptype
!= expected_pkt_type
) {
494 DEBUG(3, (__location__
": Connection to %s got an unexpected "
495 "RPC packet type - %u, not %u\n",
496 rpccli_pipe_txt(talloc_tos(), cli
),
497 pkt
->ptype
, expected_pkt_type
));
498 return NT_STATUS_INVALID_INFO_CLASS
;
501 /* Do this just before return - we don't want to modify any rpc header
502 data before now as we may have needed to do cryptographic actions on
505 if ((pkt
->ptype
== DCERPC_PKT_BIND_ACK
) &&
506 !(pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
507 DEBUG(5, (__location__
": bug in server (AS/U?), setting "
508 "fragment first/last ON.\n"));
509 pkt
->pfc_flags
|= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
515 /****************************************************************************
516 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
517 ****************************************************************************/
519 struct cli_api_pipe_state
{
520 struct event_context
*ev
;
521 struct rpc_cli_transport
*transport
;
526 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
);
527 static void cli_api_pipe_write_done(struct tevent_req
*subreq
);
528 static void cli_api_pipe_read_done(struct tevent_req
*subreq
);
530 static struct tevent_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
531 struct event_context
*ev
,
532 struct rpc_cli_transport
*transport
,
533 uint8_t *data
, size_t data_len
,
534 uint32_t max_rdata_len
)
536 struct tevent_req
*req
, *subreq
;
537 struct cli_api_pipe_state
*state
;
540 req
= tevent_req_create(mem_ctx
, &state
, struct cli_api_pipe_state
);
545 state
->transport
= transport
;
547 if (max_rdata_len
< RPC_HEADER_LEN
) {
549 * For a RPC reply we always need at least RPC_HEADER_LEN
550 * bytes. We check this here because we will receive
551 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
553 status
= NT_STATUS_INVALID_PARAMETER
;
557 if (transport
->trans_send
!= NULL
) {
558 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
559 max_rdata_len
, transport
->priv
);
560 if (subreq
== NULL
) {
563 tevent_req_set_callback(subreq
, cli_api_pipe_trans_done
, req
);
568 * If the transport does not provide a "trans" routine, i.e. for
569 * example the ncacn_ip_tcp transport, do the write/read step here.
572 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
573 if (subreq
== NULL
) {
576 tevent_req_set_callback(subreq
, cli_api_pipe_write_done
, req
);
580 tevent_req_nterror(req
, status
);
581 return tevent_req_post(req
, ev
);
587 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
)
589 struct tevent_req
*req
= tevent_req_callback_data(
590 subreq
, struct tevent_req
);
591 struct cli_api_pipe_state
*state
= tevent_req_data(
592 req
, struct cli_api_pipe_state
);
595 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
598 if (!NT_STATUS_IS_OK(status
)) {
599 tevent_req_nterror(req
, status
);
602 tevent_req_done(req
);
605 static void cli_api_pipe_write_done(struct tevent_req
*subreq
)
607 struct tevent_req
*req
= tevent_req_callback_data(
608 subreq
, struct tevent_req
);
609 struct cli_api_pipe_state
*state
= tevent_req_data(
610 req
, struct cli_api_pipe_state
);
613 status
= rpc_write_recv(subreq
);
615 if (!NT_STATUS_IS_OK(status
)) {
616 tevent_req_nterror(req
, status
);
620 state
->rdata
= talloc_array(state
, uint8_t, RPC_HEADER_LEN
);
621 if (tevent_req_nomem(state
->rdata
, req
)) {
626 * We don't need to use rpc_read_send here, the upper layer will cope
627 * with a short read, transport->trans_send could also return less
628 * than state->max_rdata_len.
630 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
632 state
->transport
->priv
);
633 if (tevent_req_nomem(subreq
, req
)) {
636 tevent_req_set_callback(subreq
, cli_api_pipe_read_done
, req
);
639 static void cli_api_pipe_read_done(struct tevent_req
*subreq
)
641 struct tevent_req
*req
= tevent_req_callback_data(
642 subreq
, struct tevent_req
);
643 struct cli_api_pipe_state
*state
= tevent_req_data(
644 req
, struct cli_api_pipe_state
);
648 status
= state
->transport
->read_recv(subreq
, &received
);
650 if (!NT_STATUS_IS_OK(status
)) {
651 tevent_req_nterror(req
, status
);
654 state
->rdata_len
= received
;
655 tevent_req_done(req
);
658 static NTSTATUS
cli_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
659 uint8_t **prdata
, uint32_t *prdata_len
)
661 struct cli_api_pipe_state
*state
= tevent_req_data(
662 req
, struct cli_api_pipe_state
);
665 if (tevent_req_is_nterror(req
, &status
)) {
669 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
670 *prdata_len
= state
->rdata_len
;
674 /****************************************************************************
675 Send data on an rpc pipe via trans. The data must be the last
676 pdu fragment of an NDR data stream.
678 Receive response data from an rpc pipe, which may be large...
680 Read the first fragment: unfortunately have to use SMBtrans for the first
681 bit, then SMBreadX for subsequent bits.
683 If first fragment received also wasn't the last fragment, continue
684 getting fragments until we _do_ receive the last fragment.
686 Request/Response PDU's look like the following...
688 |<------------------PDU len----------------------------------------------->|
689 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
691 +------------+-----------------+-------------+---------------+-------------+
692 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
693 +------------+-----------------+-------------+---------------+-------------+
695 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
696 signing & sealing being negotiated.
698 ****************************************************************************/
700 struct rpc_api_pipe_state
{
701 struct event_context
*ev
;
702 struct rpc_pipe_client
*cli
;
703 uint8_t expected_pkt_type
;
705 DATA_BLOB incoming_frag
;
706 struct ncacn_packet
*pkt
;
710 size_t reply_pdu_offset
;
714 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
);
715 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
);
716 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
);
718 static struct tevent_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
719 struct event_context
*ev
,
720 struct rpc_pipe_client
*cli
,
721 DATA_BLOB
*data
, /* Outgoing PDU */
722 uint8_t expected_pkt_type
)
724 struct tevent_req
*req
, *subreq
;
725 struct rpc_api_pipe_state
*state
;
726 uint16_t max_recv_frag
;
729 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_api_pipe_state
);
735 state
->expected_pkt_type
= expected_pkt_type
;
736 state
->incoming_frag
= data_blob_null
;
737 state
->reply_pdu
= data_blob_null
;
738 state
->reply_pdu_offset
= 0;
739 state
->endianess
= DCERPC_DREP_LE
;
742 * Ensure we're not sending too much.
744 if (data
->length
> cli
->max_xmit_frag
) {
745 status
= NT_STATUS_INVALID_PARAMETER
;
749 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli
)));
751 if (state
->expected_pkt_type
== DCERPC_PKT_AUTH3
) {
752 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
753 data
->data
, data
->length
);
754 if (subreq
== NULL
) {
757 tevent_req_set_callback(subreq
, rpc_api_pipe_auth3_done
, req
);
761 /* get the header first, then fetch the rest once we have
762 * the frag_length available */
763 max_recv_frag
= RPC_HEADER_LEN
;
765 subreq
= cli_api_pipe_send(state
, ev
, cli
->transport
,
766 data
->data
, data
->length
, max_recv_frag
);
767 if (subreq
== NULL
) {
770 tevent_req_set_callback(subreq
, rpc_api_pipe_trans_done
, req
);
774 tevent_req_nterror(req
, status
);
775 return tevent_req_post(req
, ev
);
781 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
)
783 struct tevent_req
*req
=
784 tevent_req_callback_data(subreq
,
788 status
= rpc_write_recv(subreq
);
790 if (!NT_STATUS_IS_OK(status
)) {
791 tevent_req_nterror(req
, status
);
795 tevent_req_done(req
);
798 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
)
800 struct tevent_req
*req
= tevent_req_callback_data(
801 subreq
, struct tevent_req
);
802 struct rpc_api_pipe_state
*state
= tevent_req_data(
803 req
, struct rpc_api_pipe_state
);
805 uint8_t *rdata
= NULL
;
806 uint32_t rdata_len
= 0;
808 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
810 if (!NT_STATUS_IS_OK(status
)) {
811 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
812 tevent_req_nterror(req
, status
);
817 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
818 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
819 tevent_req_done(req
);
824 * Move data on state->incoming_frag.
826 state
->incoming_frag
.data
= talloc_move(state
, &rdata
);
827 state
->incoming_frag
.length
= rdata_len
;
828 if (!state
->incoming_frag
.data
) {
829 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
833 /* Ensure we have enough data for a pdu. */
834 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
835 &state
->incoming_frag
);
836 if (tevent_req_nomem(subreq
, req
)) {
839 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
842 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
)
844 struct tevent_req
*req
= tevent_req_callback_data(
845 subreq
, struct tevent_req
);
846 struct rpc_api_pipe_state
*state
= tevent_req_data(
847 req
, struct rpc_api_pipe_state
);
849 DATA_BLOB rdata
= data_blob_null
;
851 status
= get_complete_frag_recv(subreq
);
853 if (!NT_STATUS_IS_OK(status
)) {
854 DEBUG(5, ("get_complete_frag failed: %s\n",
856 tevent_req_nterror(req
, status
);
860 state
->pkt
= talloc(state
, struct ncacn_packet
);
862 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
866 status
= dcerpc_pull_ncacn_packet(state
->pkt
,
867 &state
->incoming_frag
,
870 if (!NT_STATUS_IS_OK(status
)) {
871 tevent_req_nterror(req
, status
);
875 if (state
->incoming_frag
.length
!= state
->pkt
->frag_length
) {
876 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
877 (unsigned int)state
->incoming_frag
.length
,
878 (unsigned int)state
->pkt
->frag_length
));
879 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
883 status
= cli_pipe_validate_current_pdu(state
,
884 state
->cli
, state
->pkt
,
885 &state
->incoming_frag
,
886 state
->expected_pkt_type
,
890 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
891 (unsigned)state
->incoming_frag
.length
,
892 (unsigned)state
->reply_pdu_offset
,
895 if (!NT_STATUS_IS_OK(status
)) {
896 tevent_req_nterror(req
, status
);
900 if ((state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_FIRST
)
901 && (state
->pkt
->drep
[0] != DCERPC_DREP_LE
)) {
903 * Set the data type correctly for big-endian data on the
906 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
908 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
909 state
->endianess
= 0x00; /* BIG ENDIAN */
912 * Check endianness on subsequent packets.
914 if (state
->endianess
!= state
->pkt
->drep
[0]) {
915 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
917 state
->endianess
?"little":"big",
918 state
->pkt
->drep
[0]?"little":"big"));
919 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
923 /* Now copy the data portion out of the pdu into rbuf. */
924 if (state
->reply_pdu
.length
< state
->reply_pdu_offset
+ rdata
.length
) {
925 if (!data_blob_realloc(NULL
, &state
->reply_pdu
,
926 state
->reply_pdu_offset
+ rdata
.length
)) {
927 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
932 memcpy(state
->reply_pdu
.data
+ state
->reply_pdu_offset
,
933 rdata
.data
, rdata
.length
);
934 state
->reply_pdu_offset
+= rdata
.length
;
936 /* reset state->incoming_frag, there is no need to free it,
937 * it will be reallocated to the right size the next time
939 state
->incoming_frag
.length
= 0;
941 if (state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
) {
942 /* make sure the pdu length is right now that we
943 * have all the data available (alloc hint may
944 * have allocated more than was actually used) */
945 state
->reply_pdu
.length
= state
->reply_pdu_offset
;
946 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
947 rpccli_pipe_txt(talloc_tos(), state
->cli
),
948 (unsigned)state
->reply_pdu
.length
));
949 tevent_req_done(req
);
953 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
954 &state
->incoming_frag
);
955 if (tevent_req_nomem(subreq
, req
)) {
958 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
961 static NTSTATUS
rpc_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
962 struct ncacn_packet
**pkt
,
963 DATA_BLOB
*reply_pdu
)
965 struct rpc_api_pipe_state
*state
= tevent_req_data(
966 req
, struct rpc_api_pipe_state
);
969 if (tevent_req_is_nterror(req
, &status
)) {
973 /* return data to caller and assign it ownership of memory */
975 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
976 reply_pdu
->length
= state
->reply_pdu
.length
;
977 state
->reply_pdu
.length
= 0;
979 data_blob_free(&state
->reply_pdu
);
983 *pkt
= talloc_steal(mem_ctx
, state
->pkt
);
989 /*******************************************************************
990 Creates NTLMSSP auth bind.
991 ********************************************************************/
993 static NTSTATUS
create_generic_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
995 DATA_BLOB
*auth_token
)
997 struct gensec_security
*gensec_security
;
998 DATA_BLOB null_blob
= data_blob_null
;
1000 gensec_security
= talloc_get_type_abort(cli
->auth
->auth_ctx
,
1001 struct gensec_security
);
1003 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1004 return gensec_update(gensec_security
, mem_ctx
, NULL
, null_blob
, auth_token
);
1007 /*******************************************************************
1008 Creates schannel auth bind.
1009 ********************************************************************/
1011 static NTSTATUS
create_schannel_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1012 DATA_BLOB
*auth_token
)
1015 struct NL_AUTH_MESSAGE r
;
1017 /* Use lp_workgroup() if domain not specified */
1019 if (!cli
->auth
->domain
|| !cli
->auth
->domain
[0]) {
1020 cli
->auth
->domain
= talloc_strdup(cli
, lp_workgroup());
1021 if (cli
->auth
->domain
== NULL
) {
1022 return NT_STATUS_NO_MEMORY
;
1027 * Now marshall the data into the auth parse_struct.
1030 r
.MessageType
= NL_NEGOTIATE_REQUEST
;
1031 r
.Flags
= NL_FLAG_OEM_NETBIOS_DOMAIN_NAME
|
1032 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME
;
1033 r
.oem_netbios_domain
.a
= cli
->auth
->domain
;
1034 r
.oem_netbios_computer
.a
= lp_netbios_name();
1036 status
= dcerpc_push_schannel_bind(cli
, &r
, auth_token
);
1037 if (!NT_STATUS_IS_OK(status
)) {
1041 return NT_STATUS_OK
;
1044 /*******************************************************************
1045 Creates the internals of a DCE/RPC bind request or alter context PDU.
1046 ********************************************************************/
1048 static NTSTATUS
create_bind_or_alt_ctx_internal(TALLOC_CTX
*mem_ctx
,
1049 enum dcerpc_pkt_type ptype
,
1051 const struct ndr_syntax_id
*abstract
,
1052 const struct ndr_syntax_id
*transfer
,
1053 const DATA_BLOB
*auth_info
,
1056 uint16 auth_len
= auth_info
->length
;
1058 union dcerpc_payload u
;
1059 struct dcerpc_ctx_list ctx_list
;
1062 auth_len
-= DCERPC_AUTH_TRAILER_LENGTH
;
1065 ctx_list
.context_id
= 0;
1066 ctx_list
.num_transfer_syntaxes
= 1;
1067 ctx_list
.abstract_syntax
= *abstract
;
1068 ctx_list
.transfer_syntaxes
= (struct ndr_syntax_id
*)discard_const(transfer
);
1070 u
.bind
.max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
1071 u
.bind
.max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
1072 u
.bind
.assoc_group_id
= 0x0;
1073 u
.bind
.num_contexts
= 1;
1074 u
.bind
.ctx_list
= &ctx_list
;
1075 u
.bind
.auth_info
= *auth_info
;
1077 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1079 DCERPC_PFC_FLAG_FIRST
|
1080 DCERPC_PFC_FLAG_LAST
,
1085 if (!NT_STATUS_IS_OK(status
)) {
1086 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1090 return NT_STATUS_OK
;
1093 /*******************************************************************
1094 Creates a DCE/RPC bind request.
1095 ********************************************************************/
1097 static NTSTATUS
create_rpc_bind_req(TALLOC_CTX
*mem_ctx
,
1098 struct rpc_pipe_client
*cli
,
1099 struct pipe_auth_data
*auth
,
1101 const struct ndr_syntax_id
*abstract
,
1102 const struct ndr_syntax_id
*transfer
,
1105 DATA_BLOB auth_token
= data_blob_null
;
1106 DATA_BLOB auth_info
= data_blob_null
;
1107 NTSTATUS ret
= NT_STATUS_OK
;
1109 switch (auth
->auth_type
) {
1110 case DCERPC_AUTH_TYPE_SCHANNEL
:
1111 ret
= create_schannel_auth_rpc_bind_req(cli
, &auth_token
);
1112 if (!NT_STATUS_IS_OK(ret
)) {
1117 case DCERPC_AUTH_TYPE_NTLMSSP
:
1118 case DCERPC_AUTH_TYPE_KRB5
:
1119 case DCERPC_AUTH_TYPE_SPNEGO
:
1120 ret
= create_generic_auth_rpc_bind_req(cli
, mem_ctx
, &auth_token
);
1122 if (!NT_STATUS_IS_OK(ret
) &&
1123 !NT_STATUS_EQUAL(ret
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1128 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
:
1129 auth_token
= data_blob_talloc(mem_ctx
,
1130 "NCALRPC_AUTH_TOKEN",
1134 case DCERPC_AUTH_TYPE_NONE
:
1138 /* "Can't" happen. */
1139 return NT_STATUS_INVALID_INFO_CLASS
;
1142 if (auth_token
.length
!= 0) {
1143 ret
= dcerpc_push_dcerpc_auth(cli
,
1146 0, /* auth_pad_length */
1147 1, /* auth_context_id */
1150 if (!NT_STATUS_IS_OK(ret
)) {
1153 data_blob_free(&auth_token
);
1156 ret
= create_bind_or_alt_ctx_internal(mem_ctx
,
1166 /*******************************************************************
1168 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1169 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1170 and deals with signing/sealing details.
1171 ********************************************************************/
1173 struct rpc_api_pipe_req_state
{
1174 struct event_context
*ev
;
1175 struct rpc_pipe_client
*cli
;
1178 DATA_BLOB
*req_data
;
1179 uint32_t req_data_sent
;
1181 DATA_BLOB reply_pdu
;
1184 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
1185 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
1186 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1187 bool *is_last_frag
);
1189 struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
1190 struct event_context
*ev
,
1191 struct rpc_pipe_client
*cli
,
1193 DATA_BLOB
*req_data
)
1195 struct tevent_req
*req
, *subreq
;
1196 struct rpc_api_pipe_req_state
*state
;
1200 req
= tevent_req_create(mem_ctx
, &state
,
1201 struct rpc_api_pipe_req_state
);
1207 state
->op_num
= op_num
;
1208 state
->req_data
= req_data
;
1209 state
->req_data_sent
= 0;
1210 state
->call_id
= get_rpc_call_id();
1211 state
->reply_pdu
= data_blob_null
;
1212 state
->rpc_out
= data_blob_null
;
1214 if (cli
->max_xmit_frag
< DCERPC_REQUEST_LENGTH
1215 + RPC_MAX_SIGN_SIZE
) {
1216 /* Server is screwed up ! */
1217 status
= NT_STATUS_INVALID_PARAMETER
;
1221 status
= prepare_next_frag(state
, &is_last_frag
);
1222 if (!NT_STATUS_IS_OK(status
)) {
1227 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
1229 DCERPC_PKT_RESPONSE
);
1230 if (subreq
== NULL
) {
1233 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1235 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
1236 state
->rpc_out
.data
,
1237 state
->rpc_out
.length
);
1238 if (subreq
== NULL
) {
1241 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1247 tevent_req_nterror(req
, status
);
1248 return tevent_req_post(req
, ev
);
1254 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1257 size_t data_sent_thistime
;
1264 union dcerpc_payload u
;
1266 data_left
= state
->req_data
->length
- state
->req_data_sent
;
1268 status
= dcerpc_guess_sizes(state
->cli
->auth
,
1269 DCERPC_REQUEST_LENGTH
, data_left
,
1270 state
->cli
->max_xmit_frag
,
1271 CLIENT_NDR_PADDING_SIZE
,
1272 &data_sent_thistime
,
1273 &frag_len
, &auth_len
, &pad_len
);
1274 if (!NT_STATUS_IS_OK(status
)) {
1278 if (state
->req_data_sent
== 0) {
1279 flags
= DCERPC_PFC_FLAG_FIRST
;
1282 if (data_sent_thistime
== data_left
) {
1283 flags
|= DCERPC_PFC_FLAG_LAST
;
1286 data_blob_free(&state
->rpc_out
);
1288 ZERO_STRUCT(u
.request
);
1290 u
.request
.alloc_hint
= state
->req_data
->length
;
1291 u
.request
.context_id
= 0;
1292 u
.request
.opnum
= state
->op_num
;
1294 status
= dcerpc_push_ncacn_packet(state
,
1301 if (!NT_STATUS_IS_OK(status
)) {
1305 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1306 * compute it right for requests because the auth trailer is missing
1308 dcerpc_set_frag_length(&state
->rpc_out
, frag_len
);
1310 /* Copy in the data. */
1311 if (!data_blob_append(NULL
, &state
->rpc_out
,
1312 state
->req_data
->data
+ state
->req_data_sent
,
1313 data_sent_thistime
)) {
1314 return NT_STATUS_NO_MEMORY
;
1317 switch (state
->cli
->auth
->auth_level
) {
1318 case DCERPC_AUTH_LEVEL_NONE
:
1319 case DCERPC_AUTH_LEVEL_CONNECT
:
1320 case DCERPC_AUTH_LEVEL_PACKET
:
1322 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1323 case DCERPC_AUTH_LEVEL_PRIVACY
:
1324 status
= dcerpc_add_auth_footer(state
->cli
->auth
, pad_len
,
1326 if (!NT_STATUS_IS_OK(status
)) {
1331 return NT_STATUS_INVALID_PARAMETER
;
1334 state
->req_data_sent
+= data_sent_thistime
;
1335 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
1340 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
1342 struct tevent_req
*req
= tevent_req_callback_data(
1343 subreq
, struct tevent_req
);
1344 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1345 req
, struct rpc_api_pipe_req_state
);
1349 status
= rpc_write_recv(subreq
);
1350 TALLOC_FREE(subreq
);
1351 if (!NT_STATUS_IS_OK(status
)) {
1352 tevent_req_nterror(req
, status
);
1356 status
= prepare_next_frag(state
, &is_last_frag
);
1357 if (!NT_STATUS_IS_OK(status
)) {
1358 tevent_req_nterror(req
, status
);
1363 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
1365 DCERPC_PKT_RESPONSE
);
1366 if (tevent_req_nomem(subreq
, req
)) {
1369 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1371 subreq
= rpc_write_send(state
, state
->ev
,
1372 state
->cli
->transport
,
1373 state
->rpc_out
.data
,
1374 state
->rpc_out
.length
);
1375 if (tevent_req_nomem(subreq
, req
)) {
1378 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1383 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
1385 struct tevent_req
*req
= tevent_req_callback_data(
1386 subreq
, struct tevent_req
);
1387 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1388 req
, struct rpc_api_pipe_req_state
);
1391 status
= rpc_api_pipe_recv(subreq
, state
, NULL
, &state
->reply_pdu
);
1392 TALLOC_FREE(subreq
);
1393 if (!NT_STATUS_IS_OK(status
)) {
1394 tevent_req_nterror(req
, status
);
1397 tevent_req_done(req
);
1400 NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1401 DATA_BLOB
*reply_pdu
)
1403 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1404 req
, struct rpc_api_pipe_req_state
);
1407 if (tevent_req_is_nterror(req
, &status
)) {
1409 * We always have to initialize to reply pdu, even if there is
1410 * none. The rpccli_* caller routines expect this.
1412 *reply_pdu
= data_blob_null
;
1416 /* return data to caller and assign it ownership of memory */
1417 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1418 reply_pdu
->length
= state
->reply_pdu
.length
;
1419 state
->reply_pdu
.length
= 0;
1421 return NT_STATUS_OK
;
1424 /****************************************************************************
1425 Check the rpc bind acknowledge response.
1426 ****************************************************************************/
1428 static bool check_bind_response(const struct dcerpc_bind_ack
*r
,
1429 const struct ndr_syntax_id
*transfer
)
1431 struct dcerpc_ack_ctx ctx
;
1433 if (r
->secondary_address_size
== 0) {
1434 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1437 if (r
->num_results
< 1 || !r
->ctx_list
) {
1441 ctx
= r
->ctx_list
[0];
1443 /* check the transfer syntax */
1444 if ((ctx
.syntax
.if_version
!= transfer
->if_version
) ||
1445 (memcmp(&ctx
.syntax
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
1446 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1450 if (r
->num_results
!= 0x1 || ctx
.result
!= 0) {
1451 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1452 r
->num_results
, ctx
.reason
));
1455 DEBUG(5,("check_bind_response: accepted!\n"));
1459 /*******************************************************************
1460 Creates a DCE/RPC bind authentication response.
1461 This is the packet that is sent back to the server once we
1462 have received a BIND-ACK, to finish the third leg of
1463 the authentication handshake.
1464 ********************************************************************/
1466 static NTSTATUS
create_rpc_bind_auth3(TALLOC_CTX
*mem_ctx
,
1467 struct rpc_pipe_client
*cli
,
1469 enum dcerpc_AuthType auth_type
,
1470 enum dcerpc_AuthLevel auth_level
,
1471 DATA_BLOB
*pauth_blob
,
1475 union dcerpc_payload u
;
1479 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1482 0, /* auth_pad_length */
1483 1, /* auth_context_id */
1485 &u
.auth3
.auth_info
);
1486 if (!NT_STATUS_IS_OK(status
)) {
1490 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1492 DCERPC_PFC_FLAG_FIRST
|
1493 DCERPC_PFC_FLAG_LAST
,
1498 data_blob_free(&u
.auth3
.auth_info
);
1499 if (!NT_STATUS_IS_OK(status
)) {
1500 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1504 return NT_STATUS_OK
;
1507 /*******************************************************************
1508 Creates a DCE/RPC bind alter context authentication request which
1509 may contain a spnego auth blobl
1510 ********************************************************************/
1512 static NTSTATUS
create_rpc_alter_context(TALLOC_CTX
*mem_ctx
,
1513 enum dcerpc_AuthType auth_type
,
1514 enum dcerpc_AuthLevel auth_level
,
1516 const struct ndr_syntax_id
*abstract
,
1517 const struct ndr_syntax_id
*transfer
,
1518 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
1521 DATA_BLOB auth_info
;
1524 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1527 0, /* auth_pad_length */
1528 1, /* auth_context_id */
1531 if (!NT_STATUS_IS_OK(status
)) {
1535 status
= create_bind_or_alt_ctx_internal(mem_ctx
,
1542 data_blob_free(&auth_info
);
1546 /****************************************************************************
1548 ****************************************************************************/
1550 struct rpc_pipe_bind_state
{
1551 struct event_context
*ev
;
1552 struct rpc_pipe_client
*cli
;
1555 uint32_t rpc_call_id
;
1556 struct netr_Authenticator auth
;
1557 struct netr_Authenticator return_auth
;
1558 struct netlogon_creds_CredentialState
*creds
;
1559 union netr_Capabilities capabilities
;
1560 struct netr_LogonGetCapabilities r
;
1563 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
1564 static void rpc_pipe_bind_step_two_trigger(struct tevent_req
*req
);
1565 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
1566 struct rpc_pipe_bind_state
*state
,
1567 DATA_BLOB
*credentials
);
1568 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
1569 struct rpc_pipe_bind_state
*state
,
1570 DATA_BLOB
*credentials
);
1572 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
1573 struct event_context
*ev
,
1574 struct rpc_pipe_client
*cli
,
1575 struct pipe_auth_data
*auth
)
1577 struct tevent_req
*req
, *subreq
;
1578 struct rpc_pipe_bind_state
*state
;
1581 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
1586 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1587 rpccli_pipe_txt(talloc_tos(), cli
),
1588 (unsigned int)auth
->auth_type
,
1589 (unsigned int)auth
->auth_level
));
1593 state
->rpc_call_id
= get_rpc_call_id();
1595 cli
->auth
= talloc_move(cli
, &auth
);
1597 /* Marshall the outgoing data. */
1598 status
= create_rpc_bind_req(state
, cli
,
1601 &cli
->abstract_syntax
,
1602 &cli
->transfer_syntax
,
1605 if (!NT_STATUS_IS_OK(status
) &&
1606 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1610 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
1611 DCERPC_PKT_BIND_ACK
);
1612 if (subreq
== NULL
) {
1615 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
1619 tevent_req_nterror(req
, status
);
1620 return tevent_req_post(req
, ev
);
1626 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
1628 struct tevent_req
*req
= tevent_req_callback_data(
1629 subreq
, struct tevent_req
);
1630 struct rpc_pipe_bind_state
*state
= tevent_req_data(
1631 req
, struct rpc_pipe_bind_state
);
1632 struct pipe_auth_data
*pauth
= state
->cli
->auth
;
1633 struct gensec_security
*gensec_security
;
1634 struct ncacn_packet
*pkt
= NULL
;
1635 struct dcerpc_auth auth
;
1636 DATA_BLOB auth_token
= data_blob_null
;
1639 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, NULL
);
1640 TALLOC_FREE(subreq
);
1641 if (!NT_STATUS_IS_OK(status
)) {
1642 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1643 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1644 nt_errstr(status
)));
1645 tevent_req_nterror(req
, status
);
1650 tevent_req_done(req
);
1654 if (!check_bind_response(&pkt
->u
.bind_ack
, &state
->cli
->transfer_syntax
)) {
1655 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1656 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
1660 state
->cli
->max_xmit_frag
= pkt
->u
.bind_ack
.max_xmit_frag
;
1661 state
->cli
->max_recv_frag
= pkt
->u
.bind_ack
.max_recv_frag
;
1663 switch(pauth
->auth_type
) {
1665 case DCERPC_AUTH_TYPE_NONE
:
1666 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
:
1667 /* Bind complete. */
1668 tevent_req_done(req
);
1671 case DCERPC_AUTH_TYPE_SCHANNEL
:
1672 rpc_pipe_bind_step_two_trigger(req
);
1675 case DCERPC_AUTH_TYPE_NTLMSSP
:
1676 case DCERPC_AUTH_TYPE_SPNEGO
:
1677 case DCERPC_AUTH_TYPE_KRB5
:
1678 /* Paranoid lenght checks */
1679 if (pkt
->frag_length
< DCERPC_AUTH_TRAILER_LENGTH
1680 + pkt
->auth_length
) {
1681 tevent_req_nterror(req
,
1682 NT_STATUS_INFO_LENGTH_MISMATCH
);
1685 /* get auth credentials */
1686 status
= dcerpc_pull_dcerpc_auth(talloc_tos(),
1687 &pkt
->u
.bind_ack
.auth_info
,
1689 if (!NT_STATUS_IS_OK(status
)) {
1690 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1691 nt_errstr(status
)));
1692 tevent_req_nterror(req
, status
);
1702 * For authenticated binds we may need to do 3 or 4 leg binds.
1705 switch(pauth
->auth_type
) {
1707 case DCERPC_AUTH_TYPE_NONE
:
1708 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
:
1709 case DCERPC_AUTH_TYPE_SCHANNEL
:
1710 /* Bind complete. */
1711 tevent_req_done(req
);
1714 case DCERPC_AUTH_TYPE_NTLMSSP
:
1715 case DCERPC_AUTH_TYPE_KRB5
:
1716 case DCERPC_AUTH_TYPE_SPNEGO
:
1717 gensec_security
= talloc_get_type_abort(pauth
->auth_ctx
,
1718 struct gensec_security
);
1719 status
= gensec_update(gensec_security
, state
, NULL
,
1720 auth
.credentials
, &auth_token
);
1721 if (NT_STATUS_EQUAL(status
,
1722 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1723 status
= rpc_bind_next_send(req
, state
,
1725 } else if (NT_STATUS_IS_OK(status
)) {
1726 if (auth_token
.length
== 0) {
1727 /* Bind complete. */
1728 tevent_req_done(req
);
1731 status
= rpc_bind_finish_send(req
, state
,
1740 if (!NT_STATUS_IS_OK(status
)) {
1741 tevent_req_nterror(req
, status
);
1746 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1747 (unsigned int)state
->cli
->auth
->auth_type
));
1748 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
1751 static void rpc_pipe_bind_step_two_done(struct tevent_req
*subreq
);
1753 static void rpc_pipe_bind_step_two_trigger(struct tevent_req
*req
)
1755 struct rpc_pipe_bind_state
*state
=
1756 tevent_req_data(req
,
1757 struct rpc_pipe_bind_state
);
1758 struct dcerpc_binding_handle
*b
= state
->cli
->binding_handle
;
1759 struct schannel_state
*schannel_auth
=
1760 talloc_get_type_abort(state
->cli
->auth
->auth_ctx
,
1761 struct schannel_state
);
1762 struct tevent_req
*subreq
;
1764 if (schannel_auth
== NULL
||
1765 !ndr_syntax_id_equal(&state
->cli
->abstract_syntax
,
1766 &ndr_table_netlogon
.syntax_id
)) {
1767 tevent_req_done(req
);
1771 ZERO_STRUCT(state
->return_auth
);
1773 state
->creds
= netlogon_creds_copy(state
, schannel_auth
->creds
);
1774 if (state
->creds
== NULL
) {
1775 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1779 netlogon_creds_client_authenticator(state
->creds
, &state
->auth
);
1781 state
->r
.in
.server_name
= state
->cli
->srv_name_slash
;
1782 state
->r
.in
.computer_name
= state
->creds
->computer_name
;
1783 state
->r
.in
.credential
= &state
->auth
;
1784 state
->r
.in
.query_level
= 1;
1785 state
->r
.in
.return_authenticator
= &state
->return_auth
;
1787 state
->r
.out
.capabilities
= &state
->capabilities
;
1788 state
->r
.out
.return_authenticator
= &state
->return_auth
;
1790 subreq
= dcerpc_netr_LogonGetCapabilities_r_send(talloc_tos(),
1794 if (subreq
== NULL
) {
1795 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1799 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_two_done
, req
);
1803 static void rpc_pipe_bind_step_two_done(struct tevent_req
*subreq
)
1805 struct tevent_req
*req
=
1806 tevent_req_callback_data(subreq
,
1808 struct rpc_pipe_bind_state
*state
=
1809 tevent_req_data(req
,
1810 struct rpc_pipe_bind_state
);
1813 status
= dcerpc_netr_LogonGetCapabilities_r_recv(subreq
, talloc_tos());
1814 TALLOC_FREE(subreq
);
1815 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
1816 if (state
->cli
->dc
&& state
->cli
->dc
->negotiate_flags
&
1817 NETLOGON_NEG_SUPPORTS_AES
) {
1818 DEBUG(5, ("AES is not supported and the error was %s\n",
1819 nt_errstr(status
)));
1820 tevent_req_nterror(req
,
1821 NT_STATUS_INVALID_NETWORK_RESPONSE
);
1825 /* This is probably NT */
1826 DEBUG(5, ("We are checking against an NT - %s\n",
1827 nt_errstr(status
)));
1828 tevent_req_done(req
);
1830 } else if (!NT_STATUS_IS_OK(status
)) {
1831 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
1832 nt_errstr(status
)));
1833 tevent_req_nterror(req
, status
);
1837 if (NT_STATUS_EQUAL(state
->r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
)) {
1838 if (state
->creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
1839 /* This means AES isn't supported. */
1840 DEBUG(5, ("AES is not supported and the error was %s\n",
1841 nt_errstr(state
->r
.out
.result
)));
1842 tevent_req_nterror(req
,
1843 NT_STATUS_INVALID_NETWORK_RESPONSE
);
1847 /* This is probably an old Samba version */
1848 DEBUG(5, ("We are checking against an old Samba version - %s\n",
1849 nt_errstr(state
->r
.out
.result
)));
1850 tevent_req_done(req
);
1854 /* We need to check the credential state here, cause win2k3 and earlier
1855 * returns NT_STATUS_NOT_IMPLEMENTED */
1856 if (!netlogon_creds_client_check(state
->creds
,
1857 &state
->r
.out
.return_authenticator
->cred
)) {
1859 * Server replied with bad credential. Fail.
1861 DEBUG(0,("rpc_pipe_bind_step_two_done: server %s "
1862 "replied with bad credential\n",
1863 state
->cli
->desthost
));
1864 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1868 TALLOC_FREE(state
->cli
->dc
);
1869 state
->cli
->dc
= talloc_steal(state
->cli
, state
->creds
);
1871 if (!NT_STATUS_IS_OK(state
->r
.out
.result
)) {
1872 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
1873 nt_errstr(state
->r
.out
.result
)));
1874 tevent_req_nterror(req
, state
->r
.out
.result
);
1878 if (state
->creds
->negotiate_flags
!=
1879 state
->r
.out
.capabilities
->server_capabilities
) {
1880 DEBUG(0, ("The client capabilities don't match the server "
1881 "capabilities: local[0x%08X] remote[0x%08X]\n",
1882 state
->creds
->negotiate_flags
,
1883 state
->capabilities
.server_capabilities
));
1884 tevent_req_nterror(req
,
1885 NT_STATUS_INVALID_NETWORK_RESPONSE
);
1889 /* TODO: Add downgrade dectection. */
1891 tevent_req_done(req
);
1895 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
1896 struct rpc_pipe_bind_state
*state
,
1897 DATA_BLOB
*auth_token
)
1899 struct pipe_auth_data
*auth
= state
->cli
->auth
;
1900 struct tevent_req
*subreq
;
1903 /* Now prepare the alter context pdu. */
1904 data_blob_free(&state
->rpc_out
);
1906 status
= create_rpc_alter_context(state
,
1910 &state
->cli
->abstract_syntax
,
1911 &state
->cli
->transfer_syntax
,
1914 if (!NT_STATUS_IS_OK(status
)) {
1918 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
1919 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
);
1920 if (subreq
== NULL
) {
1921 return NT_STATUS_NO_MEMORY
;
1923 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
1924 return NT_STATUS_OK
;
1927 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
1928 struct rpc_pipe_bind_state
*state
,
1929 DATA_BLOB
*auth_token
)
1931 struct pipe_auth_data
*auth
= state
->cli
->auth
;
1932 struct tevent_req
*subreq
;
1935 state
->auth3
= true;
1937 /* Now prepare the auth3 context pdu. */
1938 data_blob_free(&state
->rpc_out
);
1940 status
= create_rpc_bind_auth3(state
, state
->cli
,
1946 if (!NT_STATUS_IS_OK(status
)) {
1950 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
1951 &state
->rpc_out
, DCERPC_PKT_AUTH3
);
1952 if (subreq
== NULL
) {
1953 return NT_STATUS_NO_MEMORY
;
1955 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
1956 return NT_STATUS_OK
;
1959 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
1961 return tevent_req_simple_recv_ntstatus(req
);
1964 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
1965 struct pipe_auth_data
*auth
)
1967 TALLOC_CTX
*frame
= talloc_stackframe();
1968 struct event_context
*ev
;
1969 struct tevent_req
*req
;
1970 NTSTATUS status
= NT_STATUS_OK
;
1972 ev
= event_context_init(frame
);
1974 status
= NT_STATUS_NO_MEMORY
;
1978 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
1980 status
= NT_STATUS_NO_MEMORY
;
1984 if (!tevent_req_poll(req
, ev
)) {
1985 status
= map_nt_error_from_unix(errno
);
1989 status
= rpc_pipe_bind_recv(req
);
1995 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1997 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
1998 unsigned int timeout
)
2002 if (rpc_cli
->transport
== NULL
) {
2003 return RPCCLI_DEFAULT_TIMEOUT
;
2006 if (rpc_cli
->transport
->set_timeout
== NULL
) {
2007 return RPCCLI_DEFAULT_TIMEOUT
;
2010 old
= rpc_cli
->transport
->set_timeout(rpc_cli
->transport
->priv
, timeout
);
2012 return RPCCLI_DEFAULT_TIMEOUT
;
2018 bool rpccli_is_connected(struct rpc_pipe_client
*rpc_cli
)
2020 if (rpc_cli
== NULL
) {
2024 if (rpc_cli
->transport
== NULL
) {
2028 return rpc_cli
->transport
->is_connected(rpc_cli
->transport
->priv
);
2031 struct rpccli_bh_state
{
2032 struct rpc_pipe_client
*rpc_cli
;
2035 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle
*h
)
2037 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2038 struct rpccli_bh_state
);
2040 return rpccli_is_connected(hs
->rpc_cli
);
2043 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle
*h
,
2046 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2047 struct rpccli_bh_state
);
2049 return rpccli_set_timeout(hs
->rpc_cli
, timeout
);
2052 struct rpccli_bh_raw_call_state
{
2058 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
);
2060 static struct tevent_req
*rpccli_bh_raw_call_send(TALLOC_CTX
*mem_ctx
,
2061 struct tevent_context
*ev
,
2062 struct dcerpc_binding_handle
*h
,
2063 const struct GUID
*object
,
2066 const uint8_t *in_data
,
2069 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2070 struct rpccli_bh_state
);
2071 struct tevent_req
*req
;
2072 struct rpccli_bh_raw_call_state
*state
;
2074 struct tevent_req
*subreq
;
2076 req
= tevent_req_create(mem_ctx
, &state
,
2077 struct rpccli_bh_raw_call_state
);
2081 state
->in_data
.data
= discard_const_p(uint8_t, in_data
);
2082 state
->in_data
.length
= in_length
;
2084 ok
= rpccli_bh_is_connected(h
);
2086 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2087 return tevent_req_post(req
, ev
);
2090 subreq
= rpc_api_pipe_req_send(state
, ev
, hs
->rpc_cli
,
2091 opnum
, &state
->in_data
);
2092 if (tevent_req_nomem(subreq
, req
)) {
2093 return tevent_req_post(req
, ev
);
2095 tevent_req_set_callback(subreq
, rpccli_bh_raw_call_done
, req
);
2100 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
)
2102 struct tevent_req
*req
=
2103 tevent_req_callback_data(subreq
,
2105 struct rpccli_bh_raw_call_state
*state
=
2106 tevent_req_data(req
,
2107 struct rpccli_bh_raw_call_state
);
2110 state
->out_flags
= 0;
2112 /* TODO: support bigendian responses */
2114 status
= rpc_api_pipe_req_recv(subreq
, state
, &state
->out_data
);
2115 TALLOC_FREE(subreq
);
2116 if (!NT_STATUS_IS_OK(status
)) {
2117 tevent_req_nterror(req
, status
);
2121 tevent_req_done(req
);
2124 static NTSTATUS
rpccli_bh_raw_call_recv(struct tevent_req
*req
,
2125 TALLOC_CTX
*mem_ctx
,
2128 uint32_t *out_flags
)
2130 struct rpccli_bh_raw_call_state
*state
=
2131 tevent_req_data(req
,
2132 struct rpccli_bh_raw_call_state
);
2135 if (tevent_req_is_nterror(req
, &status
)) {
2136 tevent_req_received(req
);
2140 *out_data
= talloc_move(mem_ctx
, &state
->out_data
.data
);
2141 *out_length
= state
->out_data
.length
;
2142 *out_flags
= state
->out_flags
;
2143 tevent_req_received(req
);
2144 return NT_STATUS_OK
;
2147 struct rpccli_bh_disconnect_state
{
2151 static struct tevent_req
*rpccli_bh_disconnect_send(TALLOC_CTX
*mem_ctx
,
2152 struct tevent_context
*ev
,
2153 struct dcerpc_binding_handle
*h
)
2155 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2156 struct rpccli_bh_state
);
2157 struct tevent_req
*req
;
2158 struct rpccli_bh_disconnect_state
*state
;
2161 req
= tevent_req_create(mem_ctx
, &state
,
2162 struct rpccli_bh_disconnect_state
);
2167 ok
= rpccli_bh_is_connected(h
);
2169 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2170 return tevent_req_post(req
, ev
);
2174 * TODO: do a real async disconnect ...
2176 * For now the caller needs to free rpc_cli
2180 tevent_req_done(req
);
2181 return tevent_req_post(req
, ev
);
2184 static NTSTATUS
rpccli_bh_disconnect_recv(struct tevent_req
*req
)
2188 if (tevent_req_is_nterror(req
, &status
)) {
2189 tevent_req_received(req
);
2193 tevent_req_received(req
);
2194 return NT_STATUS_OK
;
2197 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle
*h
)
2202 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle
*h
,
2204 const void *_struct_ptr
,
2205 const struct ndr_interface_call
*call
)
2207 void *struct_ptr
= discard_const(_struct_ptr
);
2209 if (DEBUGLEVEL
< 10) {
2213 if (ndr_flags
& NDR_IN
) {
2214 ndr_print_function_debug(call
->ndr_print
,
2219 if (ndr_flags
& NDR_OUT
) {
2220 ndr_print_function_debug(call
->ndr_print
,
2227 static const struct dcerpc_binding_handle_ops rpccli_bh_ops
= {
2229 .is_connected
= rpccli_bh_is_connected
,
2230 .set_timeout
= rpccli_bh_set_timeout
,
2231 .raw_call_send
= rpccli_bh_raw_call_send
,
2232 .raw_call_recv
= rpccli_bh_raw_call_recv
,
2233 .disconnect_send
= rpccli_bh_disconnect_send
,
2234 .disconnect_recv
= rpccli_bh_disconnect_recv
,
2236 .ref_alloc
= rpccli_bh_ref_alloc
,
2237 .do_ndr_print
= rpccli_bh_do_ndr_print
,
2240 /* initialise a rpc_pipe_client binding handle */
2241 struct dcerpc_binding_handle
*rpccli_bh_create(struct rpc_pipe_client
*c
)
2243 struct dcerpc_binding_handle
*h
;
2244 struct rpccli_bh_state
*hs
;
2246 h
= dcerpc_binding_handle_create(c
,
2251 struct rpccli_bh_state
,
2261 NTSTATUS
rpccli_ncalrpc_bind_data(TALLOC_CTX
*mem_ctx
,
2262 struct pipe_auth_data
**presult
)
2264 struct pipe_auth_data
*result
;
2266 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2267 if (result
== NULL
) {
2268 return NT_STATUS_NO_MEMORY
;
2271 result
->auth_type
= DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
;
2272 result
->auth_level
= DCERPC_AUTH_LEVEL_CONNECT
;
2274 result
->user_name
= talloc_strdup(result
, "");
2275 result
->domain
= talloc_strdup(result
, "");
2276 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2277 TALLOC_FREE(result
);
2278 return NT_STATUS_NO_MEMORY
;
2282 return NT_STATUS_OK
;
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
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
2298 result
->user_name
= talloc_strdup(result
, "");
2299 result
->domain
= talloc_strdup(result
, "");
2300 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2301 TALLOC_FREE(result
);
2302 return NT_STATUS_NO_MEMORY
;
2306 return NT_STATUS_OK
;
2309 static NTSTATUS
rpccli_generic_bind_data(TALLOC_CTX
*mem_ctx
,
2310 enum dcerpc_AuthType auth_type
,
2311 enum dcerpc_AuthLevel auth_level
,
2313 const char *target_service
,
2315 const char *username
,
2316 const char *password
,
2317 enum credentials_use_kerberos use_kerberos
,
2318 struct pipe_auth_data
**presult
)
2320 struct auth_generic_state
*auth_generic_ctx
;
2321 struct pipe_auth_data
*result
;
2324 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2325 if (result
== NULL
) {
2326 return NT_STATUS_NO_MEMORY
;
2329 result
->auth_type
= auth_type
;
2330 result
->auth_level
= auth_level
;
2332 result
->user_name
= talloc_strdup(result
, username
);
2333 result
->domain
= talloc_strdup(result
, domain
);
2334 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2335 status
= NT_STATUS_NO_MEMORY
;
2339 status
= auth_generic_client_prepare(result
,
2341 if (!NT_STATUS_IS_OK(status
)) {
2345 status
= auth_generic_set_username(auth_generic_ctx
, username
);
2346 if (!NT_STATUS_IS_OK(status
)) {
2350 status
= auth_generic_set_domain(auth_generic_ctx
, domain
);
2351 if (!NT_STATUS_IS_OK(status
)) {
2355 status
= auth_generic_set_password(auth_generic_ctx
, password
);
2356 if (!NT_STATUS_IS_OK(status
)) {
2360 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
2361 if (!NT_STATUS_IS_OK(status
)) {
2365 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
2366 if (!NT_STATUS_IS_OK(status
)) {
2370 cli_credentials_set_kerberos_state(auth_generic_ctx
->credentials
, use_kerberos
);
2372 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
2373 if (!NT_STATUS_IS_OK(status
)) {
2377 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2378 talloc_free(auth_generic_ctx
);
2380 return NT_STATUS_OK
;
2383 TALLOC_FREE(result
);
2387 NTSTATUS
rpccli_schannel_bind_data(TALLOC_CTX
*mem_ctx
, const char *domain
,
2388 enum dcerpc_AuthLevel auth_level
,
2389 struct netlogon_creds_CredentialState
*creds
,
2390 struct pipe_auth_data
**presult
)
2392 struct schannel_state
*schannel_auth
;
2393 struct pipe_auth_data
*result
;
2395 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2396 if (result
== NULL
) {
2397 return NT_STATUS_NO_MEMORY
;
2400 result
->auth_type
= DCERPC_AUTH_TYPE_SCHANNEL
;
2401 result
->auth_level
= auth_level
;
2403 result
->user_name
= talloc_strdup(result
, "");
2404 result
->domain
= talloc_strdup(result
, domain
);
2405 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2409 schannel_auth
= talloc_zero(result
, struct schannel_state
);
2410 if (schannel_auth
== NULL
) {
2414 schannel_auth
->state
= SCHANNEL_STATE_START
;
2415 schannel_auth
->initiator
= true;
2416 schannel_auth
->creds
= netlogon_creds_copy(result
, creds
);
2418 result
->auth_ctx
= schannel_auth
;
2420 return NT_STATUS_OK
;
2423 TALLOC_FREE(result
);
2424 return NT_STATUS_NO_MEMORY
;
2428 * Create an rpc pipe client struct, connecting to a tcp port.
2430 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
2431 const struct sockaddr_storage
*ss_addr
,
2433 const struct ndr_syntax_id
*abstract_syntax
,
2434 struct rpc_pipe_client
**presult
)
2436 struct rpc_pipe_client
*result
;
2437 struct sockaddr_storage addr
;
2441 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
2442 if (result
== NULL
) {
2443 return NT_STATUS_NO_MEMORY
;
2446 result
->abstract_syntax
= *abstract_syntax
;
2447 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2449 result
->desthost
= talloc_strdup(result
, host
);
2450 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2451 result
, "\\\\%s", result
->desthost
);
2452 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2453 status
= NT_STATUS_NO_MEMORY
;
2457 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2458 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
2460 if (ss_addr
== NULL
) {
2461 if (!resolve_name(host
, &addr
, NBT_NAME_SERVER
, false)) {
2462 status
= NT_STATUS_NOT_FOUND
;
2469 status
= open_socket_out(&addr
, port
, 60*1000, &fd
);
2470 if (!NT_STATUS_IS_OK(status
)) {
2473 set_socket_options(fd
, lp_socket_options());
2475 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
2476 if (!NT_STATUS_IS_OK(status
)) {
2481 result
->transport
->transport
= NCACN_IP_TCP
;
2483 result
->binding_handle
= rpccli_bh_create(result
);
2484 if (result
->binding_handle
== NULL
) {
2485 TALLOC_FREE(result
);
2486 return NT_STATUS_NO_MEMORY
;
2490 return NT_STATUS_OK
;
2493 TALLOC_FREE(result
);
2498 * Determine the tcp port on which a dcerpc interface is listening
2499 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2502 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
2503 const struct sockaddr_storage
*addr
,
2504 const struct ndr_syntax_id
*abstract_syntax
,
2508 struct rpc_pipe_client
*epm_pipe
= NULL
;
2509 struct dcerpc_binding_handle
*epm_handle
= NULL
;
2510 struct pipe_auth_data
*auth
= NULL
;
2511 struct dcerpc_binding
*map_binding
= NULL
;
2512 struct dcerpc_binding
*res_binding
= NULL
;
2513 struct epm_twr_t
*map_tower
= NULL
;
2514 struct epm_twr_t
*res_towers
= NULL
;
2515 struct policy_handle
*entry_handle
= NULL
;
2516 uint32_t num_towers
= 0;
2517 uint32_t max_towers
= 1;
2518 struct epm_twr_p_t towers
;
2519 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2520 uint32_t result
= 0;
2522 if (pport
== NULL
) {
2523 status
= NT_STATUS_INVALID_PARAMETER
;
2527 if (ndr_syntax_id_equal(abstract_syntax
,
2528 &ndr_table_epmapper
.syntax_id
)) {
2530 return NT_STATUS_OK
;
2533 /* open the connection to the endpoint mapper */
2534 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, addr
, 135,
2535 &ndr_table_epmapper
.syntax_id
,
2538 if (!NT_STATUS_IS_OK(status
)) {
2541 epm_handle
= epm_pipe
->binding_handle
;
2543 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
2544 if (!NT_STATUS_IS_OK(status
)) {
2548 status
= rpc_pipe_bind(epm_pipe
, auth
);
2549 if (!NT_STATUS_IS_OK(status
)) {
2553 /* create tower for asking the epmapper */
2555 map_binding
= talloc_zero(tmp_ctx
, struct dcerpc_binding
);
2556 if (map_binding
== NULL
) {
2557 status
= NT_STATUS_NO_MEMORY
;
2561 map_binding
->transport
= NCACN_IP_TCP
;
2562 map_binding
->object
= *abstract_syntax
;
2563 map_binding
->host
= host
; /* needed? */
2564 map_binding
->endpoint
= "0"; /* correct? needed? */
2566 map_tower
= talloc_zero(tmp_ctx
, struct epm_twr_t
);
2567 if (map_tower
== NULL
) {
2568 status
= NT_STATUS_NO_MEMORY
;
2572 status
= dcerpc_binding_build_tower(tmp_ctx
, map_binding
,
2573 &(map_tower
->tower
));
2574 if (!NT_STATUS_IS_OK(status
)) {
2578 /* allocate further parameters for the epm_Map call */
2580 res_towers
= talloc_array(tmp_ctx
, struct epm_twr_t
, max_towers
);
2581 if (res_towers
== NULL
) {
2582 status
= NT_STATUS_NO_MEMORY
;
2585 towers
.twr
= res_towers
;
2587 entry_handle
= talloc_zero(tmp_ctx
, struct policy_handle
);
2588 if (entry_handle
== NULL
) {
2589 status
= NT_STATUS_NO_MEMORY
;
2593 /* ask the endpoint mapper for the port */
2595 status
= dcerpc_epm_Map(epm_handle
,
2597 discard_const_p(struct GUID
,
2598 &(abstract_syntax
->uuid
)),
2606 if (!NT_STATUS_IS_OK(status
)) {
2610 if (result
!= EPMAPPER_STATUS_OK
) {
2611 status
= NT_STATUS_UNSUCCESSFUL
;
2615 if (num_towers
!= 1) {
2616 status
= NT_STATUS_UNSUCCESSFUL
;
2620 /* extract the port from the answer */
2622 status
= dcerpc_binding_from_tower(tmp_ctx
,
2623 &(towers
.twr
->tower
),
2625 if (!NT_STATUS_IS_OK(status
)) {
2629 /* are further checks here necessary? */
2630 if (res_binding
->transport
!= NCACN_IP_TCP
) {
2631 status
= NT_STATUS_UNSUCCESSFUL
;
2635 *pport
= (uint16_t)atoi(res_binding
->endpoint
);
2638 TALLOC_FREE(tmp_ctx
);
2643 * Create a rpc pipe client struct, connecting to a host via tcp.
2644 * The port is determined by asking the endpoint mapper on the given
2647 NTSTATUS
rpc_pipe_open_tcp(TALLOC_CTX
*mem_ctx
, const char *host
,
2648 const struct sockaddr_storage
*addr
,
2649 const struct ndr_syntax_id
*abstract_syntax
,
2650 struct rpc_pipe_client
**presult
)
2655 status
= rpc_pipe_get_tcp_port(host
, addr
, abstract_syntax
, &port
);
2656 if (!NT_STATUS_IS_OK(status
)) {
2660 return rpc_pipe_open_tcp_port(mem_ctx
, host
, addr
, port
,
2661 abstract_syntax
, presult
);
2664 /********************************************************************
2665 Create a rpc pipe client struct, connecting to a unix domain socket
2666 ********************************************************************/
2667 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
, const char *socket_path
,
2668 const struct ndr_syntax_id
*abstract_syntax
,
2669 struct rpc_pipe_client
**presult
)
2671 struct rpc_pipe_client
*result
;
2672 struct sockaddr_un addr
;
2677 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
2678 if (result
== NULL
) {
2679 return NT_STATUS_NO_MEMORY
;
2682 result
->abstract_syntax
= *abstract_syntax
;
2683 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2685 result
->desthost
= get_myname(result
);
2686 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2687 result
, "\\\\%s", result
->desthost
);
2688 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2689 status
= NT_STATUS_NO_MEMORY
;
2693 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2694 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
2696 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
2698 status
= map_nt_error_from_unix(errno
);
2703 addr
.sun_family
= AF_UNIX
;
2704 strlcpy(addr
.sun_path
, socket_path
, sizeof(addr
.sun_path
));
2705 salen
= sizeof(struct sockaddr_un
);
2707 if (connect(fd
, (struct sockaddr
*)(void *)&addr
, salen
) == -1) {
2708 DEBUG(0, ("connect(%s) failed: %s\n", socket_path
,
2711 return map_nt_error_from_unix(errno
);
2714 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
2715 if (!NT_STATUS_IS_OK(status
)) {
2720 result
->transport
->transport
= NCALRPC
;
2722 result
->binding_handle
= rpccli_bh_create(result
);
2723 if (result
->binding_handle
== NULL
) {
2724 TALLOC_FREE(result
);
2725 return NT_STATUS_NO_MEMORY
;
2729 return NT_STATUS_OK
;
2732 TALLOC_FREE(result
);
2736 struct rpc_pipe_client_np_ref
{
2737 struct cli_state
*cli
;
2738 struct rpc_pipe_client
*pipe
;
2741 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref
*np_ref
)
2743 DLIST_REMOVE(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
2747 /****************************************************************************
2748 Open a named pipe over SMB to a remote server.
2750 * CAVEAT CALLER OF THIS FUNCTION:
2751 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2752 * so be sure that this function is called AFTER any structure (vs pointer)
2753 * assignment of the cli. In particular, libsmbclient does structure
2754 * assignments of cli, which invalidates the data in the returned
2755 * rpc_pipe_client if this function is called before the structure assignment
2758 ****************************************************************************/
2760 static NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
2761 const struct ndr_syntax_id
*abstract_syntax
,
2762 struct rpc_pipe_client
**presult
)
2764 struct rpc_pipe_client
*result
;
2766 struct rpc_pipe_client_np_ref
*np_ref
;
2768 /* sanity check to protect against crashes */
2771 return NT_STATUS_INVALID_HANDLE
;
2774 result
= talloc_zero(NULL
, struct rpc_pipe_client
);
2775 if (result
== NULL
) {
2776 return NT_STATUS_NO_MEMORY
;
2779 result
->abstract_syntax
= *abstract_syntax
;
2780 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2781 result
->desthost
= talloc_strdup(result
, smbXcli_conn_remote_name(cli
->conn
));
2782 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2783 result
, "\\\\%s", result
->desthost
);
2785 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2786 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
2788 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2789 TALLOC_FREE(result
);
2790 return NT_STATUS_NO_MEMORY
;
2793 status
= rpc_transport_np_init(result
, cli
, abstract_syntax
,
2794 &result
->transport
);
2795 if (!NT_STATUS_IS_OK(status
)) {
2796 TALLOC_FREE(result
);
2800 result
->transport
->transport
= NCACN_NP
;
2802 np_ref
= talloc(result
->transport
, struct rpc_pipe_client_np_ref
);
2803 if (np_ref
== NULL
) {
2804 TALLOC_FREE(result
);
2805 return NT_STATUS_NO_MEMORY
;
2808 np_ref
->pipe
= result
;
2810 DLIST_ADD(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
2811 talloc_set_destructor(np_ref
, rpc_pipe_client_np_ref_destructor
);
2813 result
->binding_handle
= rpccli_bh_create(result
);
2814 if (result
->binding_handle
== NULL
) {
2815 TALLOC_FREE(result
);
2816 return NT_STATUS_NO_MEMORY
;
2820 return NT_STATUS_OK
;
2823 /****************************************************************************
2824 Open a pipe to a remote server.
2825 ****************************************************************************/
2827 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
2828 enum dcerpc_transport_t transport
,
2829 const struct ndr_syntax_id
*interface
,
2830 struct rpc_pipe_client
**presult
)
2832 switch (transport
) {
2834 return rpc_pipe_open_tcp(NULL
,
2835 smbXcli_conn_remote_name(cli
->conn
),
2836 smbXcli_conn_remote_sockaddr(cli
->conn
),
2837 interface
, presult
);
2839 return rpc_pipe_open_np(cli
, interface
, presult
);
2841 return NT_STATUS_NOT_IMPLEMENTED
;
2845 /****************************************************************************
2846 Open a named pipe to an SMB server and bind anonymously.
2847 ****************************************************************************/
2849 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
2850 enum dcerpc_transport_t transport
,
2851 const struct ndr_syntax_id
*interface
,
2852 struct rpc_pipe_client
**presult
)
2854 struct rpc_pipe_client
*result
;
2855 struct pipe_auth_data
*auth
;
2858 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
2859 if (!NT_STATUS_IS_OK(status
)) {
2863 status
= rpccli_anon_bind_data(result
, &auth
);
2864 if (!NT_STATUS_IS_OK(status
)) {
2865 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2866 nt_errstr(status
)));
2867 TALLOC_FREE(result
);
2872 * This is a bit of an abstraction violation due to the fact that an
2873 * anonymous bind on an authenticated SMB inherits the user/domain
2874 * from the enclosing SMB creds
2877 TALLOC_FREE(auth
->user_name
);
2878 TALLOC_FREE(auth
->domain
);
2880 auth
->user_name
= talloc_strdup(auth
, cli
->user_name
);
2881 auth
->domain
= talloc_strdup(auth
, cli
->domain
);
2883 if (transport
== NCACN_NP
) {
2884 struct smbXcli_session
*session
;
2886 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2887 session
= cli
->smb2
.session
;
2889 session
= cli
->smb1
.session
;
2892 status
= smbXcli_session_application_key(session
, auth
,
2893 &auth
->transport_session_key
);
2894 if (!NT_STATUS_IS_OK(status
)) {
2895 auth
->transport_session_key
= data_blob_null
;
2899 if ((auth
->user_name
== NULL
) || (auth
->domain
== NULL
)) {
2900 TALLOC_FREE(result
);
2901 return NT_STATUS_NO_MEMORY
;
2904 status
= rpc_pipe_bind(result
, auth
);
2905 if (!NT_STATUS_IS_OK(status
)) {
2907 if (ndr_syntax_id_equal(interface
,
2908 &ndr_table_dssetup
.syntax_id
)) {
2909 /* non AD domains just don't have this pipe, avoid
2910 * level 0 statement in that case - gd */
2913 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2914 "%s failed with error %s\n",
2915 get_pipe_name_from_syntax(talloc_tos(), interface
),
2916 nt_errstr(status
) ));
2917 TALLOC_FREE(result
);
2921 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2922 "%s and bound anonymously.\n",
2923 get_pipe_name_from_syntax(talloc_tos(), interface
),
2927 return NT_STATUS_OK
;
2930 /****************************************************************************
2931 ****************************************************************************/
2933 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
2934 const struct ndr_syntax_id
*interface
,
2935 struct rpc_pipe_client
**presult
)
2937 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
2938 interface
, presult
);
2941 /****************************************************************************
2942 Open a named pipe to an SMB server and bind using the mech specified
2943 ****************************************************************************/
2945 NTSTATUS
cli_rpc_pipe_open_generic_auth(struct cli_state
*cli
,
2946 const struct ndr_interface_table
*table
,
2947 enum dcerpc_transport_t transport
,
2948 enum dcerpc_AuthType auth_type
,
2949 enum dcerpc_AuthLevel auth_level
,
2952 const char *username
,
2953 const char *password
,
2954 struct rpc_pipe_client
**presult
)
2956 struct rpc_pipe_client
*result
;
2957 struct pipe_auth_data
*auth
= NULL
;
2958 const char *target_service
= table
->authservices
->names
[0];
2962 status
= cli_rpc_pipe_open(cli
, transport
, &table
->syntax_id
, &result
);
2963 if (!NT_STATUS_IS_OK(status
)) {
2967 status
= rpccli_generic_bind_data(result
,
2968 auth_type
, auth_level
,
2969 server
, target_service
,
2970 domain
, username
, password
,
2971 CRED_AUTO_USE_KERBEROS
,
2973 if (!NT_STATUS_IS_OK(status
)) {
2974 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
2975 nt_errstr(status
)));
2979 status
= rpc_pipe_bind(result
, auth
);
2980 if (!NT_STATUS_IS_OK(status
)) {
2981 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
2982 nt_errstr(status
) ));
2986 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
2987 "machine %s and bound as user %s\\%s.\n", table
->name
,
2988 result
->desthost
, domain
, username
));
2991 return NT_STATUS_OK
;
2995 TALLOC_FREE(result
);
2999 /****************************************************************************
3001 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3002 using session_key. sign and seal.
3004 The *pdc will be stolen onto this new pipe
3005 ****************************************************************************/
3007 NTSTATUS
cli_rpc_pipe_open_schannel_with_key(struct cli_state
*cli
,
3008 const struct ndr_syntax_id
*interface
,
3009 enum dcerpc_transport_t transport
,
3010 enum dcerpc_AuthLevel auth_level
,
3012 struct netlogon_creds_CredentialState
**pdc
,
3013 struct rpc_pipe_client
**presult
)
3015 struct rpc_pipe_client
*result
;
3016 struct pipe_auth_data
*auth
;
3019 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3020 if (!NT_STATUS_IS_OK(status
)) {
3024 status
= rpccli_schannel_bind_data(result
, domain
, auth_level
,
3026 if (!NT_STATUS_IS_OK(status
)) {
3027 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3028 nt_errstr(status
)));
3029 TALLOC_FREE(result
);
3033 status
= rpc_pipe_bind(result
, auth
);
3034 if (!NT_STATUS_IS_OK(status
)) {
3035 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3036 "cli_rpc_pipe_bind failed with error %s\n",
3037 nt_errstr(status
) ));
3038 TALLOC_FREE(result
);
3043 * The credentials on a new netlogon pipe are the ones we are passed
3044 * in - copy them over
3046 if (result
->dc
== NULL
) {
3047 result
->dc
= netlogon_creds_copy(result
, *pdc
);
3048 if (result
->dc
== NULL
) {
3049 TALLOC_FREE(result
);
3050 return NT_STATUS_NO_MEMORY
;
3054 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3055 "for domain %s and bound using schannel.\n",
3056 get_pipe_name_from_syntax(talloc_tos(), interface
),
3057 result
->desthost
, domain
));
3060 return NT_STATUS_OK
;
3063 NTSTATUS
cli_rpc_pipe_open_spnego(struct cli_state
*cli
,
3064 const struct ndr_interface_table
*table
,
3065 enum dcerpc_transport_t transport
,
3067 enum dcerpc_AuthLevel auth_level
,
3070 const char *username
,
3071 const char *password
,
3072 struct rpc_pipe_client
**presult
)
3074 struct rpc_pipe_client
*result
;
3075 struct pipe_auth_data
*auth
= NULL
;
3076 const char *target_service
= table
->authservices
->names
[0];
3079 enum credentials_use_kerberos use_kerberos
;
3081 if (strcmp(oid
, GENSEC_OID_KERBEROS5
) == 0) {
3082 use_kerberos
= CRED_MUST_USE_KERBEROS
;
3083 } else if (strcmp(oid
, GENSEC_OID_NTLMSSP
) == 0) {
3084 use_kerberos
= CRED_DONT_USE_KERBEROS
;
3086 return NT_STATUS_INVALID_PARAMETER
;
3089 status
= cli_rpc_pipe_open(cli
, transport
, &table
->syntax_id
, &result
);
3090 if (!NT_STATUS_IS_OK(status
)) {
3094 status
= rpccli_generic_bind_data(result
,
3095 DCERPC_AUTH_TYPE_SPNEGO
, auth_level
,
3096 server
, target_service
,
3097 domain
, username
, password
,
3100 if (!NT_STATUS_IS_OK(status
)) {
3101 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3102 nt_errstr(status
)));
3106 status
= rpc_pipe_bind(result
, auth
);
3107 if (!NT_STATUS_IS_OK(status
)) {
3108 DEBUG(0, ("cli_rpc_pipe_open_spnego: cli_rpc_pipe_bind failed with error %s\n",
3109 nt_errstr(status
) ));
3113 DEBUG(10,("cli_rpc_pipe_open_spnego: opened pipe %s to "
3114 "machine %s.\n", table
->name
,
3118 return NT_STATUS_OK
;
3122 TALLOC_FREE(result
);
3126 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
3127 struct rpc_pipe_client
*cli
,
3128 DATA_BLOB
*session_key
)
3131 struct pipe_auth_data
*a
;
3132 struct schannel_state
*schannel_auth
;
3133 struct gensec_security
*gensec_security
;
3134 DATA_BLOB sk
= data_blob_null
;
3135 bool make_dup
= false;
3137 if (!session_key
|| !cli
) {
3138 return NT_STATUS_INVALID_PARAMETER
;
3144 return NT_STATUS_INVALID_PARAMETER
;
3147 switch (cli
->auth
->auth_type
) {
3148 case DCERPC_AUTH_TYPE_SCHANNEL
:
3149 schannel_auth
= talloc_get_type_abort(a
->auth_ctx
,
3150 struct schannel_state
);
3151 sk
= data_blob_const(schannel_auth
->creds
->session_key
, 16);
3154 case DCERPC_AUTH_TYPE_SPNEGO
:
3155 case DCERPC_AUTH_TYPE_NTLMSSP
:
3156 case DCERPC_AUTH_TYPE_KRB5
:
3157 gensec_security
= talloc_get_type_abort(a
->auth_ctx
,
3158 struct gensec_security
);
3159 status
= gensec_session_key(gensec_security
, mem_ctx
, &sk
);
3160 if (!NT_STATUS_IS_OK(status
)) {
3165 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
:
3166 case DCERPC_AUTH_TYPE_NONE
:
3167 sk
= data_blob_const(a
->transport_session_key
.data
,
3168 a
->transport_session_key
.length
);
3176 return NT_STATUS_NO_USER_SESSION_KEY
;
3180 *session_key
= data_blob_dup_talloc(mem_ctx
, sk
);
3185 return NT_STATUS_OK
;