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_dssetup.h"
26 #include "../libcli/auth/schannel.h"
27 #include "../libcli/auth/netlogon_creds_cli.h"
28 #include "auth_generic.h"
29 #include "librpc/gen_ndr/ndr_dcerpc.h"
30 #include "librpc/gen_ndr/ndr_netlogon_c.h"
31 #include "librpc/rpc/dcerpc.h"
34 #include "libsmb/libsmb.h"
35 #include "auth/gensec/gensec.h"
36 #include "auth/credentials/credentials.h"
37 #include "../libcli/smb/smbXcli_base.h"
40 #define DBGC_CLASS DBGC_RPC_CLI
42 /********************************************************************
43 Pipe description for a DEBUG
44 ********************************************************************/
45 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
46 struct rpc_pipe_client
*cli
)
48 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
55 /********************************************************************
57 ********************************************************************/
59 static uint32_t get_rpc_call_id(void)
61 static uint32_t call_id
= 0;
65 /*******************************************************************
66 Use SMBreadX to get rest of one fragment's worth of rpc data.
67 Reads the whole size or give an error message
68 ********************************************************************/
70 struct rpc_read_state
{
71 struct tevent_context
*ev
;
72 struct rpc_cli_transport
*transport
;
78 static void rpc_read_done(struct tevent_req
*subreq
);
80 static struct tevent_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
81 struct tevent_context
*ev
,
82 struct rpc_cli_transport
*transport
,
83 uint8_t *data
, size_t size
)
85 struct tevent_req
*req
, *subreq
;
86 struct rpc_read_state
*state
;
88 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_read_state
);
93 state
->transport
= transport
;
98 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size
));
100 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
102 if (subreq
== NULL
) {
105 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
113 static void rpc_read_done(struct tevent_req
*subreq
)
115 struct tevent_req
*req
= tevent_req_callback_data(
116 subreq
, struct tevent_req
);
117 struct rpc_read_state
*state
= tevent_req_data(
118 req
, struct rpc_read_state
);
122 status
= state
->transport
->read_recv(subreq
, &received
);
124 if (!NT_STATUS_IS_OK(status
)) {
125 tevent_req_nterror(req
, status
);
129 state
->num_read
+= received
;
130 if (state
->num_read
== state
->size
) {
131 tevent_req_done(req
);
135 subreq
= state
->transport
->read_send(state
, state
->ev
,
136 state
->data
+ state
->num_read
,
137 state
->size
- state
->num_read
,
138 state
->transport
->priv
);
139 if (tevent_req_nomem(subreq
, req
)) {
142 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
145 static NTSTATUS
rpc_read_recv(struct tevent_req
*req
)
147 return tevent_req_simple_recv_ntstatus(req
);
150 struct rpc_write_state
{
151 struct tevent_context
*ev
;
152 struct rpc_cli_transport
*transport
;
158 static void rpc_write_done(struct tevent_req
*subreq
);
160 static struct tevent_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
161 struct tevent_context
*ev
,
162 struct rpc_cli_transport
*transport
,
163 const uint8_t *data
, size_t size
)
165 struct tevent_req
*req
, *subreq
;
166 struct rpc_write_state
*state
;
168 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_write_state
);
173 state
->transport
= transport
;
176 state
->num_written
= 0;
178 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size
));
180 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
181 if (subreq
== NULL
) {
184 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
191 static void rpc_write_done(struct tevent_req
*subreq
)
193 struct tevent_req
*req
= tevent_req_callback_data(
194 subreq
, struct tevent_req
);
195 struct rpc_write_state
*state
= tevent_req_data(
196 req
, struct rpc_write_state
);
200 status
= state
->transport
->write_recv(subreq
, &written
);
202 if (!NT_STATUS_IS_OK(status
)) {
203 tevent_req_nterror(req
, status
);
207 state
->num_written
+= written
;
209 if (state
->num_written
== state
->size
) {
210 tevent_req_done(req
);
214 subreq
= state
->transport
->write_send(state
, state
->ev
,
215 state
->data
+ state
->num_written
,
216 state
->size
- state
->num_written
,
217 state
->transport
->priv
);
218 if (tevent_req_nomem(subreq
, req
)) {
221 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
224 static NTSTATUS
rpc_write_recv(struct tevent_req
*req
)
226 return tevent_req_simple_recv_ntstatus(req
);
230 /****************************************************************************
231 Try and get a PDU's worth of data from current_pdu. If not, then read more
233 ****************************************************************************/
235 struct get_complete_frag_state
{
236 struct tevent_context
*ev
;
237 struct rpc_pipe_client
*cli
;
242 static void get_complete_frag_got_header(struct tevent_req
*subreq
);
243 static void get_complete_frag_got_rest(struct tevent_req
*subreq
);
245 static struct tevent_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
246 struct tevent_context
*ev
,
247 struct rpc_pipe_client
*cli
,
250 struct tevent_req
*req
, *subreq
;
251 struct get_complete_frag_state
*state
;
255 req
= tevent_req_create(mem_ctx
, &state
,
256 struct get_complete_frag_state
);
262 state
->frag_len
= RPC_HEADER_LEN
;
265 received
= pdu
->length
;
266 if (received
< RPC_HEADER_LEN
) {
267 if (!data_blob_realloc(mem_ctx
, pdu
, RPC_HEADER_LEN
)) {
268 status
= NT_STATUS_NO_MEMORY
;
271 subreq
= rpc_read_send(state
, state
->ev
,
272 state
->cli
->transport
,
273 pdu
->data
+ received
,
274 RPC_HEADER_LEN
- received
);
275 if (subreq
== NULL
) {
276 status
= NT_STATUS_NO_MEMORY
;
279 tevent_req_set_callback(subreq
, get_complete_frag_got_header
,
284 state
->frag_len
= dcerpc_get_frag_length(pdu
);
285 if (state
->frag_len
< RPC_HEADER_LEN
) {
286 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
287 return tevent_req_post(req
, ev
);
291 * Ensure we have frag_len bytes of data.
293 if (received
< state
->frag_len
) {
294 if (!data_blob_realloc(NULL
, pdu
, state
->frag_len
)) {
295 status
= NT_STATUS_NO_MEMORY
;
298 subreq
= rpc_read_send(state
, state
->ev
,
299 state
->cli
->transport
,
300 pdu
->data
+ received
,
301 state
->frag_len
- received
);
302 if (subreq
== NULL
) {
303 status
= NT_STATUS_NO_MEMORY
;
306 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
,
311 status
= NT_STATUS_OK
;
313 if (NT_STATUS_IS_OK(status
)) {
314 tevent_req_done(req
);
316 tevent_req_nterror(req
, status
);
318 return tevent_req_post(req
, ev
);
321 static void get_complete_frag_got_header(struct tevent_req
*subreq
)
323 struct tevent_req
*req
= tevent_req_callback_data(
324 subreq
, struct tevent_req
);
325 struct get_complete_frag_state
*state
= tevent_req_data(
326 req
, struct get_complete_frag_state
);
329 status
= rpc_read_recv(subreq
);
331 if (!NT_STATUS_IS_OK(status
)) {
332 tevent_req_nterror(req
, status
);
336 state
->frag_len
= dcerpc_get_frag_length(state
->pdu
);
337 if (state
->frag_len
< RPC_HEADER_LEN
) {
338 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
342 if (!data_blob_realloc(NULL
, state
->pdu
, state
->frag_len
)) {
343 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
348 * We're here in this piece of code because we've read exactly
349 * RPC_HEADER_LEN bytes into state->pdu.
352 subreq
= rpc_read_send(state
, state
->ev
, state
->cli
->transport
,
353 state
->pdu
->data
+ RPC_HEADER_LEN
,
354 state
->frag_len
- RPC_HEADER_LEN
);
355 if (tevent_req_nomem(subreq
, req
)) {
358 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
361 static void get_complete_frag_got_rest(struct tevent_req
*subreq
)
363 struct tevent_req
*req
= tevent_req_callback_data(
364 subreq
, struct tevent_req
);
367 status
= rpc_read_recv(subreq
);
369 if (!NT_STATUS_IS_OK(status
)) {
370 tevent_req_nterror(req
, status
);
373 tevent_req_done(req
);
376 static NTSTATUS
get_complete_frag_recv(struct tevent_req
*req
)
378 return tevent_req_simple_recv_ntstatus(req
);
381 /****************************************************************************
382 Do basic authentication checks on an incoming pdu.
383 ****************************************************************************/
385 static NTSTATUS
cli_pipe_validate_current_pdu(TALLOC_CTX
*mem_ctx
,
386 struct rpc_pipe_client
*cli
,
387 struct ncacn_packet
*pkt
,
389 uint8_t expected_pkt_type
,
392 DATA_BLOB
*reply_pdu
)
394 const struct dcerpc_response
*r
= NULL
;
395 DATA_BLOB tmp_stub
= data_blob_null
;
396 NTSTATUS ret
= NT_STATUS_OK
;
399 * Point the return values at the real data including the RPC
400 * header. Just in case the caller wants it.
404 if ((pkt
->ptype
== DCERPC_PKT_BIND_ACK
) &&
405 !(pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
407 * TODO: do we still need this hack which was introduced
408 * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
410 * I don't even know what AS/U might be...
412 DEBUG(5, (__location__
": bug in server (AS/U?), setting "
413 "fragment first/last ON.\n"));
414 pkt
->pfc_flags
|= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
417 /* Ensure we have the correct type. */
418 switch (pkt
->ptype
) {
419 case DCERPC_PKT_BIND_NAK
:
420 DEBUG(1, (__location__
": Bind NACK received from %s!\n",
421 rpccli_pipe_txt(talloc_tos(), cli
)));
423 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
425 0, /* max_auth_info */
426 DCERPC_PFC_FLAG_FIRST
|
427 DCERPC_PFC_FLAG_LAST
,
428 0); /* optional flags */
429 if (!NT_STATUS_IS_OK(ret
)) {
430 DEBUG(1, (__location__
": Connection to %s got an unexpected "
431 "RPC packet type - %u, expected %u: %s\n",
432 rpccli_pipe_txt(talloc_tos(), cli
),
433 pkt
->ptype
, expected_pkt_type
,
435 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
439 /* Use this for now... */
440 return NT_STATUS_NETWORK_ACCESS_DENIED
;
442 case DCERPC_PKT_BIND_ACK
:
443 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
445 pkt
->u
.bind_ack
.auth_info
.length
,
446 DCERPC_PFC_FLAG_FIRST
|
447 DCERPC_PFC_FLAG_LAST
,
448 DCERPC_PFC_FLAG_CONC_MPX
|
449 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
450 if (!NT_STATUS_IS_OK(ret
)) {
451 DEBUG(1, (__location__
": Connection to %s got an unexpected "
452 "RPC packet type - %u, expected %u: %s\n",
453 rpccli_pipe_txt(talloc_tos(), cli
),
454 pkt
->ptype
, expected_pkt_type
,
456 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
462 case DCERPC_PKT_ALTER_RESP
:
463 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
465 pkt
->u
.alter_resp
.auth_info
.length
,
466 DCERPC_PFC_FLAG_FIRST
|
467 DCERPC_PFC_FLAG_LAST
,
468 DCERPC_PFC_FLAG_CONC_MPX
|
469 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
470 if (!NT_STATUS_IS_OK(ret
)) {
471 DEBUG(1, (__location__
": Connection to %s got an unexpected "
472 "RPC packet type - %u, expected %u: %s\n",
473 rpccli_pipe_txt(talloc_tos(), cli
),
474 pkt
->ptype
, expected_pkt_type
,
476 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
482 case DCERPC_PKT_RESPONSE
:
484 r
= &pkt
->u
.response
;
486 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
488 r
->stub_and_verifier
.length
,
489 0, /* required_flags */
490 DCERPC_PFC_FLAG_FIRST
|
491 DCERPC_PFC_FLAG_LAST
);
492 if (!NT_STATUS_IS_OK(ret
)) {
493 DEBUG(1, (__location__
": Connection to %s got an unexpected "
494 "RPC packet type - %u, expected %u: %s\n",
495 rpccli_pipe_txt(talloc_tos(), cli
),
496 pkt
->ptype
, expected_pkt_type
,
498 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
502 tmp_stub
.data
= r
->stub_and_verifier
.data
;
503 tmp_stub
.length
= r
->stub_and_verifier
.length
;
505 /* Here's where we deal with incoming sign/seal. */
506 ret
= dcerpc_check_auth(cli
->auth
, pkt
,
508 DCERPC_RESPONSE_LENGTH
,
510 if (!NT_STATUS_IS_OK(ret
)) {
511 DEBUG(1, (__location__
": Connection to %s got an unexpected "
512 "RPC packet type - %u, expected %u: %s\n",
513 rpccli_pipe_txt(talloc_tos(), cli
),
514 pkt
->ptype
, expected_pkt_type
,
516 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
520 /* Point the return values at the NDR data. */
523 DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
524 (long unsigned int)pdu
->length
,
525 (long unsigned int)rdata
->length
));
528 * If this is the first reply, and the allocation hint is
529 * reasonable, try and set up the reply_pdu DATA_BLOB to the
533 if ((reply_pdu
->length
== 0) &&
534 r
->alloc_hint
&& (r
->alloc_hint
< 15*1024*1024)) {
535 if (!data_blob_realloc(mem_ctx
, reply_pdu
,
537 DEBUG(0, ("reply alloc hint %d too "
538 "large to allocate\n",
539 (int)r
->alloc_hint
));
540 return NT_STATUS_NO_MEMORY
;
546 case DCERPC_PKT_FAULT
:
548 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
550 0, /* max_auth_info */
551 DCERPC_PFC_FLAG_FIRST
|
552 DCERPC_PFC_FLAG_LAST
,
553 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
554 if (!NT_STATUS_IS_OK(ret
)) {
555 DEBUG(1, (__location__
": Connection to %s got an unexpected "
556 "RPC packet type - %u, expected %u: %s\n",
557 rpccli_pipe_txt(talloc_tos(), cli
),
558 pkt
->ptype
, expected_pkt_type
,
560 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
564 DEBUG(1, (__location__
": RPC fault code %s received "
566 dcerpc_errstr(talloc_tos(),
567 pkt
->u
.fault
.status
),
568 rpccli_pipe_txt(talloc_tos(), cli
)));
570 return dcerpc_fault_to_nt_status(pkt
->u
.fault
.status
);
573 DEBUG(0, (__location__
"Unknown packet type %u received "
575 (unsigned int)pkt
->ptype
,
576 rpccli_pipe_txt(talloc_tos(), cli
)));
577 return NT_STATUS_RPC_PROTOCOL_ERROR
;
581 if (pkt
->call_id
!= call_id
) {
582 DEBUG(3, (__location__
": Connection to %s got an unexpected "
583 "RPC call_id - %u, not %u\n",
584 rpccli_pipe_txt(talloc_tos(), cli
),
585 pkt
->call_id
, call_id
));
586 return NT_STATUS_RPC_PROTOCOL_ERROR
;
592 /****************************************************************************
593 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
594 ****************************************************************************/
596 struct cli_api_pipe_state
{
597 struct tevent_context
*ev
;
598 struct rpc_cli_transport
*transport
;
603 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
);
604 static void cli_api_pipe_write_done(struct tevent_req
*subreq
);
605 static void cli_api_pipe_read_done(struct tevent_req
*subreq
);
607 static struct tevent_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
608 struct tevent_context
*ev
,
609 struct rpc_cli_transport
*transport
,
610 uint8_t *data
, size_t data_len
,
611 uint32_t max_rdata_len
)
613 struct tevent_req
*req
, *subreq
;
614 struct cli_api_pipe_state
*state
;
617 req
= tevent_req_create(mem_ctx
, &state
, struct cli_api_pipe_state
);
622 state
->transport
= transport
;
624 if (max_rdata_len
< RPC_HEADER_LEN
) {
626 * For a RPC reply we always need at least RPC_HEADER_LEN
627 * bytes. We check this here because we will receive
628 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
630 status
= NT_STATUS_INVALID_PARAMETER
;
634 if (transport
->trans_send
!= NULL
) {
635 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
636 max_rdata_len
, transport
->priv
);
637 if (subreq
== NULL
) {
640 tevent_req_set_callback(subreq
, cli_api_pipe_trans_done
, req
);
645 * If the transport does not provide a "trans" routine, i.e. for
646 * example the ncacn_ip_tcp transport, do the write/read step here.
649 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
650 if (subreq
== NULL
) {
653 tevent_req_set_callback(subreq
, cli_api_pipe_write_done
, req
);
657 tevent_req_nterror(req
, status
);
658 return tevent_req_post(req
, ev
);
664 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
)
666 struct tevent_req
*req
= tevent_req_callback_data(
667 subreq
, struct tevent_req
);
668 struct cli_api_pipe_state
*state
= tevent_req_data(
669 req
, struct cli_api_pipe_state
);
672 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
675 if (!NT_STATUS_IS_OK(status
)) {
676 tevent_req_nterror(req
, status
);
679 tevent_req_done(req
);
682 static void cli_api_pipe_write_done(struct tevent_req
*subreq
)
684 struct tevent_req
*req
= tevent_req_callback_data(
685 subreq
, struct tevent_req
);
686 struct cli_api_pipe_state
*state
= tevent_req_data(
687 req
, struct cli_api_pipe_state
);
690 status
= rpc_write_recv(subreq
);
692 if (!NT_STATUS_IS_OK(status
)) {
693 tevent_req_nterror(req
, status
);
697 state
->rdata
= talloc_array(state
, uint8_t, RPC_HEADER_LEN
);
698 if (tevent_req_nomem(state
->rdata
, req
)) {
703 * We don't need to use rpc_read_send here, the upper layer will cope
704 * with a short read, transport->trans_send could also return less
705 * than state->max_rdata_len.
707 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
709 state
->transport
->priv
);
710 if (tevent_req_nomem(subreq
, req
)) {
713 tevent_req_set_callback(subreq
, cli_api_pipe_read_done
, req
);
716 static void cli_api_pipe_read_done(struct tevent_req
*subreq
)
718 struct tevent_req
*req
= tevent_req_callback_data(
719 subreq
, struct tevent_req
);
720 struct cli_api_pipe_state
*state
= tevent_req_data(
721 req
, struct cli_api_pipe_state
);
725 status
= state
->transport
->read_recv(subreq
, &received
);
727 if (!NT_STATUS_IS_OK(status
)) {
728 tevent_req_nterror(req
, status
);
731 state
->rdata_len
= received
;
732 tevent_req_done(req
);
735 static NTSTATUS
cli_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
736 uint8_t **prdata
, uint32_t *prdata_len
)
738 struct cli_api_pipe_state
*state
= tevent_req_data(
739 req
, struct cli_api_pipe_state
);
742 if (tevent_req_is_nterror(req
, &status
)) {
746 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
747 *prdata_len
= state
->rdata_len
;
751 /****************************************************************************
752 Send data on an rpc pipe via trans. The data must be the last
753 pdu fragment of an NDR data stream.
755 Receive response data from an rpc pipe, which may be large...
757 Read the first fragment: unfortunately have to use SMBtrans for the first
758 bit, then SMBreadX for subsequent bits.
760 If first fragment received also wasn't the last fragment, continue
761 getting fragments until we _do_ receive the last fragment.
763 Request/Response PDU's look like the following...
765 |<------------------PDU len----------------------------------------------->|
766 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
768 +------------+-----------------+-------------+---------------+-------------+
769 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
770 +------------+-----------------+-------------+---------------+-------------+
772 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
773 signing & sealing being negotiated.
775 ****************************************************************************/
777 struct rpc_api_pipe_state
{
778 struct tevent_context
*ev
;
779 struct rpc_pipe_client
*cli
;
780 uint8_t expected_pkt_type
;
783 DATA_BLOB incoming_frag
;
784 struct ncacn_packet
*pkt
;
788 size_t reply_pdu_offset
;
792 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
);
793 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
);
794 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
);
796 static struct tevent_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
797 struct tevent_context
*ev
,
798 struct rpc_pipe_client
*cli
,
799 DATA_BLOB
*data
, /* Outgoing PDU */
800 uint8_t expected_pkt_type
,
803 struct tevent_req
*req
, *subreq
;
804 struct rpc_api_pipe_state
*state
;
805 uint16_t max_recv_frag
;
808 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_api_pipe_state
);
814 state
->expected_pkt_type
= expected_pkt_type
;
815 state
->call_id
= call_id
;
816 state
->endianess
= DCERPC_DREP_LE
;
819 * Ensure we're not sending too much.
821 if (data
->length
> cli
->max_xmit_frag
) {
822 status
= NT_STATUS_INVALID_PARAMETER
;
826 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli
)));
828 if (state
->expected_pkt_type
== DCERPC_PKT_AUTH3
) {
829 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
830 data
->data
, data
->length
);
831 if (subreq
== NULL
) {
834 tevent_req_set_callback(subreq
, rpc_api_pipe_auth3_done
, req
);
838 /* get the header first, then fetch the rest once we have
839 * the frag_length available */
840 max_recv_frag
= RPC_HEADER_LEN
;
842 subreq
= cli_api_pipe_send(state
, ev
, cli
->transport
,
843 data
->data
, data
->length
, max_recv_frag
);
844 if (subreq
== NULL
) {
847 tevent_req_set_callback(subreq
, rpc_api_pipe_trans_done
, req
);
851 tevent_req_nterror(req
, status
);
852 return tevent_req_post(req
, ev
);
858 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
)
860 struct tevent_req
*req
=
861 tevent_req_callback_data(subreq
,
865 status
= rpc_write_recv(subreq
);
867 if (!NT_STATUS_IS_OK(status
)) {
868 tevent_req_nterror(req
, status
);
872 tevent_req_done(req
);
875 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
)
877 struct tevent_req
*req
= tevent_req_callback_data(
878 subreq
, struct tevent_req
);
879 struct rpc_api_pipe_state
*state
= tevent_req_data(
880 req
, struct rpc_api_pipe_state
);
882 uint8_t *rdata
= NULL
;
883 uint32_t rdata_len
= 0;
885 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
887 if (!NT_STATUS_IS_OK(status
)) {
888 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
889 tevent_req_nterror(req
, status
);
894 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
895 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
896 tevent_req_done(req
);
901 * Move data on state->incoming_frag.
903 state
->incoming_frag
.data
= talloc_move(state
, &rdata
);
904 state
->incoming_frag
.length
= rdata_len
;
905 if (!state
->incoming_frag
.data
) {
906 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
910 /* Ensure we have enough data for a pdu. */
911 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
912 &state
->incoming_frag
);
913 if (tevent_req_nomem(subreq
, req
)) {
916 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
919 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
)
921 struct tevent_req
*req
= tevent_req_callback_data(
922 subreq
, struct tevent_req
);
923 struct rpc_api_pipe_state
*state
= tevent_req_data(
924 req
, struct rpc_api_pipe_state
);
926 DATA_BLOB rdata
= data_blob_null
;
928 status
= get_complete_frag_recv(subreq
);
930 if (!NT_STATUS_IS_OK(status
)) {
931 DEBUG(5, ("get_complete_frag failed: %s\n",
933 tevent_req_nterror(req
, status
);
937 state
->pkt
= talloc(state
, struct ncacn_packet
);
940 * TODO: do a real async disconnect ...
942 * For now do it sync...
944 TALLOC_FREE(state
->cli
->transport
);
945 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
949 status
= dcerpc_pull_ncacn_packet(state
->pkt
,
950 &state
->incoming_frag
,
952 if (!NT_STATUS_IS_OK(status
)) {
954 * TODO: do a real async disconnect ...
956 * For now do it sync...
958 TALLOC_FREE(state
->cli
->transport
);
959 tevent_req_nterror(req
, status
);
963 if (DEBUGLEVEL
>= 10) {
964 NDR_PRINT_DEBUG(ncacn_packet
, state
->pkt
);
967 status
= cli_pipe_validate_current_pdu(state
,
968 state
->cli
, state
->pkt
,
969 &state
->incoming_frag
,
970 state
->expected_pkt_type
,
975 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
976 (unsigned)state
->incoming_frag
.length
,
977 (unsigned)state
->reply_pdu_offset
,
980 if (state
->pkt
->ptype
!= DCERPC_PKT_FAULT
&& !NT_STATUS_IS_OK(status
)) {
982 * TODO: do a real async disconnect ...
984 * For now do it sync...
986 TALLOC_FREE(state
->cli
->transport
);
987 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
989 * TODO: do a real async disconnect ...
991 * For now do it sync...
993 TALLOC_FREE(state
->cli
->transport
);
994 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
)) {
996 * TODO: do a real async disconnect ...
998 * For now do it sync...
1000 TALLOC_FREE(state
->cli
->transport
);
1002 if (!NT_STATUS_IS_OK(status
)) {
1003 tevent_req_nterror(req
, status
);
1007 if ((state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_FIRST
)
1008 && (state
->pkt
->drep
[0] != DCERPC_DREP_LE
)) {
1010 * Set the data type correctly for big-endian data on the
1013 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1015 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1016 state
->endianess
= 0x00; /* BIG ENDIAN */
1019 * Check endianness on subsequent packets.
1021 if (state
->endianess
!= state
->pkt
->drep
[0]) {
1022 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1024 state
->endianess
?"little":"big",
1025 state
->pkt
->drep
[0]?"little":"big"));
1027 * TODO: do a real async disconnect ...
1029 * For now do it sync...
1031 TALLOC_FREE(state
->cli
->transport
);
1032 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1036 if (state
->reply_pdu_offset
+ rdata
.length
> MAX_RPC_DATA_SIZE
) {
1038 * TODO: do a real async disconnect ...
1040 * For now do it sync...
1042 TALLOC_FREE(state
->cli
->transport
);
1043 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1047 /* Now copy the data portion out of the pdu into rbuf. */
1048 if (state
->reply_pdu
.length
< state
->reply_pdu_offset
+ rdata
.length
) {
1049 if (!data_blob_realloc(NULL
, &state
->reply_pdu
,
1050 state
->reply_pdu_offset
+ rdata
.length
)) {
1052 * TODO: do a real async disconnect ...
1054 * For now do it sync...
1056 TALLOC_FREE(state
->cli
->transport
);
1057 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1062 memcpy(state
->reply_pdu
.data
+ state
->reply_pdu_offset
,
1063 rdata
.data
, rdata
.length
);
1064 state
->reply_pdu_offset
+= rdata
.length
;
1066 /* reset state->incoming_frag, there is no need to free it,
1067 * it will be reallocated to the right size the next time
1069 state
->incoming_frag
.length
= 0;
1071 if (state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
) {
1072 /* make sure the pdu length is right now that we
1073 * have all the data available (alloc hint may
1074 * have allocated more than was actually used) */
1075 state
->reply_pdu
.length
= state
->reply_pdu_offset
;
1076 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1077 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1078 (unsigned)state
->reply_pdu
.length
));
1079 tevent_req_done(req
);
1083 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1084 &state
->incoming_frag
);
1085 if (subreq
== NULL
) {
1087 * TODO: do a real async disconnect ...
1089 * For now do it sync...
1091 TALLOC_FREE(state
->cli
->transport
);
1093 if (tevent_req_nomem(subreq
, req
)) {
1096 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1099 static NTSTATUS
rpc_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1100 struct ncacn_packet
**pkt
,
1101 DATA_BLOB
*reply_pdu
)
1103 struct rpc_api_pipe_state
*state
= tevent_req_data(
1104 req
, struct rpc_api_pipe_state
);
1107 if (tevent_req_is_nterror(req
, &status
)) {
1111 /* return data to caller and assign it ownership of memory */
1113 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1114 reply_pdu
->length
= state
->reply_pdu
.length
;
1115 state
->reply_pdu
.length
= 0;
1117 data_blob_free(&state
->reply_pdu
);
1121 *pkt
= talloc_steal(mem_ctx
, state
->pkt
);
1124 return NT_STATUS_OK
;
1127 /*******************************************************************
1128 Creates NTLMSSP auth bind.
1129 ********************************************************************/
1131 static NTSTATUS
create_generic_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1132 TALLOC_CTX
*mem_ctx
,
1133 DATA_BLOB
*auth_token
,
1134 bool *client_hdr_signing
)
1136 struct gensec_security
*gensec_security
;
1137 DATA_BLOB null_blob
= data_blob_null
;
1140 gensec_security
= cli
->auth
->auth_ctx
;
1142 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1143 status
= gensec_update(gensec_security
, mem_ctx
, null_blob
, auth_token
);
1145 if (!NT_STATUS_IS_OK(status
) &&
1146 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1151 if (client_hdr_signing
== NULL
) {
1155 if (cli
->auth
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
1156 *client_hdr_signing
= false;
1160 *client_hdr_signing
= gensec_have_feature(gensec_security
,
1161 GENSEC_FEATURE_SIGN_PKT_HEADER
);
1166 /*******************************************************************
1167 Creates the internals of a DCE/RPC bind request or alter context PDU.
1168 ********************************************************************/
1170 static NTSTATUS
create_bind_or_alt_ctx_internal(TALLOC_CTX
*mem_ctx
,
1171 enum dcerpc_pkt_type ptype
,
1172 uint32_t rpc_call_id
,
1173 const struct ndr_syntax_id
*abstract
,
1174 const struct ndr_syntax_id
*transfer
,
1175 const DATA_BLOB
*auth_info
,
1176 bool client_hdr_signing
,
1179 uint16_t auth_len
= auth_info
->length
;
1181 union dcerpc_payload u
;
1182 struct dcerpc_ctx_list ctx_list
;
1183 uint8_t pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
1186 auth_len
-= DCERPC_AUTH_TRAILER_LENGTH
;
1189 if (client_hdr_signing
) {
1190 pfc_flags
|= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
;
1193 ctx_list
.context_id
= 0;
1194 ctx_list
.num_transfer_syntaxes
= 1;
1195 ctx_list
.abstract_syntax
= *abstract
;
1196 ctx_list
.transfer_syntaxes
= (struct ndr_syntax_id
*)discard_const(transfer
);
1198 u
.bind
.max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
1199 u
.bind
.max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
1200 u
.bind
.assoc_group_id
= 0x0;
1201 u
.bind
.num_contexts
= 1;
1202 u
.bind
.ctx_list
= &ctx_list
;
1203 u
.bind
.auth_info
= *auth_info
;
1205 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1211 if (!NT_STATUS_IS_OK(status
)) {
1212 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1216 return NT_STATUS_OK
;
1219 /*******************************************************************
1220 Creates a DCE/RPC bind request.
1221 ********************************************************************/
1223 static NTSTATUS
create_rpc_bind_req(TALLOC_CTX
*mem_ctx
,
1224 struct rpc_pipe_client
*cli
,
1225 struct pipe_auth_data
*auth
,
1226 uint32_t rpc_call_id
,
1227 const struct ndr_syntax_id
*abstract
,
1228 const struct ndr_syntax_id
*transfer
,
1231 DATA_BLOB auth_token
= data_blob_null
;
1232 DATA_BLOB auth_info
= data_blob_null
;
1233 NTSTATUS ret
= NT_STATUS_OK
;
1235 switch (auth
->auth_type
) {
1236 case DCERPC_AUTH_TYPE_NONE
:
1240 ret
= create_generic_auth_rpc_bind_req(cli
, mem_ctx
,
1242 &auth
->client_hdr_signing
);
1244 if (!NT_STATUS_IS_OK(ret
) &&
1245 !NT_STATUS_EQUAL(ret
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1251 if (auth_token
.length
!= 0) {
1252 ret
= dcerpc_push_dcerpc_auth(cli
,
1255 0, /* auth_pad_length */
1256 auth
->auth_context_id
,
1259 if (!NT_STATUS_IS_OK(ret
)) {
1262 data_blob_free(&auth_token
);
1265 ret
= create_bind_or_alt_ctx_internal(mem_ctx
,
1271 auth
->client_hdr_signing
,
1276 /*******************************************************************
1278 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1279 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1280 and deals with signing/sealing details.
1281 ********************************************************************/
1283 struct rpc_api_pipe_req_state
{
1284 struct tevent_context
*ev
;
1285 struct rpc_pipe_client
*cli
;
1288 const DATA_BLOB
*req_data
;
1289 uint32_t req_data_sent
;
1290 DATA_BLOB req_trailer
;
1291 uint32_t req_trailer_sent
;
1292 bool verify_bitmask1
;
1293 bool verify_pcontext
;
1295 DATA_BLOB reply_pdu
;
1298 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
1299 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
1300 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
);
1301 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1302 bool *is_last_frag
);
1304 static struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
1305 struct tevent_context
*ev
,
1306 struct rpc_pipe_client
*cli
,
1308 const DATA_BLOB
*req_data
)
1310 struct tevent_req
*req
, *subreq
;
1311 struct rpc_api_pipe_req_state
*state
;
1315 req
= tevent_req_create(mem_ctx
, &state
,
1316 struct rpc_api_pipe_req_state
);
1322 state
->op_num
= op_num
;
1323 state
->req_data
= req_data
;
1324 state
->req_data_sent
= 0;
1325 state
->call_id
= get_rpc_call_id();
1326 state
->reply_pdu
= data_blob_null
;
1327 state
->rpc_out
= data_blob_null
;
1329 if (cli
->max_xmit_frag
< DCERPC_REQUEST_LENGTH
1330 + RPC_MAX_SIGN_SIZE
) {
1331 /* Server is screwed up ! */
1332 status
= NT_STATUS_INVALID_PARAMETER
;
1336 status
= prepare_verification_trailer(state
);
1337 if (!NT_STATUS_IS_OK(status
)) {
1341 status
= prepare_next_frag(state
, &is_last_frag
);
1342 if (!NT_STATUS_IS_OK(status
)) {
1347 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
1349 DCERPC_PKT_RESPONSE
,
1351 if (subreq
== NULL
) {
1354 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1356 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
1357 state
->rpc_out
.data
,
1358 state
->rpc_out
.length
);
1359 if (subreq
== NULL
) {
1362 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1368 tevent_req_nterror(req
, status
);
1369 return tevent_req_post(req
, ev
);
1375 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
)
1377 struct pipe_auth_data
*a
= state
->cli
->auth
;
1378 struct dcerpc_sec_verification_trailer
*t
;
1379 struct dcerpc_sec_vt
*c
= NULL
;
1380 struct ndr_push
*ndr
= NULL
;
1381 enum ndr_err_code ndr_err
;
1386 return NT_STATUS_OK
;
1389 if (a
->auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
1390 return NT_STATUS_OK
;
1393 t
= talloc_zero(state
, struct dcerpc_sec_verification_trailer
);
1395 return NT_STATUS_NO_MEMORY
;
1398 if (!a
->verified_bitmask1
) {
1399 t
->commands
= talloc_realloc(t
, t
->commands
,
1400 struct dcerpc_sec_vt
,
1401 t
->count
.count
+ 1);
1402 if (t
->commands
== NULL
) {
1403 return NT_STATUS_NO_MEMORY
;
1405 c
= &t
->commands
[t
->count
.count
++];
1408 c
->command
= DCERPC_SEC_VT_COMMAND_BITMASK1
;
1409 if (a
->client_hdr_signing
) {
1410 c
->u
.bitmask1
= DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING
;
1412 state
->verify_bitmask1
= true;
1415 if (!state
->cli
->verified_pcontext
) {
1416 t
->commands
= talloc_realloc(t
, t
->commands
,
1417 struct dcerpc_sec_vt
,
1418 t
->count
.count
+ 1);
1419 if (t
->commands
== NULL
) {
1420 return NT_STATUS_NO_MEMORY
;
1422 c
= &t
->commands
[t
->count
.count
++];
1425 c
->command
= DCERPC_SEC_VT_COMMAND_PCONTEXT
;
1426 c
->u
.pcontext
.abstract_syntax
= state
->cli
->abstract_syntax
;
1427 c
->u
.pcontext
.transfer_syntax
= state
->cli
->transfer_syntax
;
1429 state
->verify_pcontext
= true;
1432 if (!a
->hdr_signing
) {
1433 t
->commands
= talloc_realloc(t
, t
->commands
,
1434 struct dcerpc_sec_vt
,
1435 t
->count
.count
+ 1);
1436 if (t
->commands
== NULL
) {
1437 return NT_STATUS_NO_MEMORY
;
1439 c
= &t
->commands
[t
->count
.count
++];
1442 c
->command
= DCERPC_SEC_VT_COMMAND_HEADER2
;
1443 c
->u
.header2
.ptype
= DCERPC_PKT_REQUEST
;
1444 c
->u
.header2
.drep
[0] = DCERPC_DREP_LE
;
1445 c
->u
.header2
.drep
[1] = 0;
1446 c
->u
.header2
.drep
[2] = 0;
1447 c
->u
.header2
.drep
[3] = 0;
1448 c
->u
.header2
.call_id
= state
->call_id
;
1449 c
->u
.header2
.context_id
= 0;
1450 c
->u
.header2
.opnum
= state
->op_num
;
1453 if (t
->count
.count
== 0) {
1455 return NT_STATUS_OK
;
1458 c
= &t
->commands
[t
->count
.count
- 1];
1459 c
->command
|= DCERPC_SEC_VT_COMMAND_END
;
1461 if (DEBUGLEVEL
>= 10) {
1462 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer
, t
);
1465 ndr
= ndr_push_init_ctx(state
);
1467 return NT_STATUS_NO_MEMORY
;
1470 ndr_err
= ndr_push_dcerpc_sec_verification_trailer(ndr
,
1471 NDR_SCALARS
| NDR_BUFFERS
,
1473 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1474 return ndr_map_error2ntstatus(ndr_err
);
1476 state
->req_trailer
= ndr_push_blob(ndr
);
1478 align
= state
->req_data
->length
& 0x3;
1485 const uint8_t zeros
[4] = { 0, };
1487 ok
= data_blob_append(ndr
, &state
->req_trailer
, zeros
, pad
);
1489 return NT_STATUS_NO_MEMORY
;
1492 /* move the padding to the start */
1493 p
= state
->req_trailer
.data
;
1494 memmove(p
+ pad
, p
, state
->req_trailer
.length
- pad
);
1498 return NT_STATUS_OK
;
1501 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1509 size_t data_thistime
;
1510 size_t trailer_left
;
1511 size_t trailer_thistime
= 0;
1513 size_t total_thistime
;
1516 union dcerpc_payload u
;
1518 data_left
= state
->req_data
->length
- state
->req_data_sent
;
1519 trailer_left
= state
->req_trailer
.length
- state
->req_trailer_sent
;
1520 total_left
= data_left
+ trailer_left
;
1521 if ((total_left
< data_left
) || (total_left
< trailer_left
)) {
1525 return NT_STATUS_INVALID_PARAMETER_MIX
;
1528 status
= dcerpc_guess_sizes(state
->cli
->auth
,
1529 DCERPC_REQUEST_LENGTH
, total_left
,
1530 state
->cli
->max_xmit_frag
,
1532 &frag_len
, &auth_len
, &pad_len
);
1533 if (!NT_STATUS_IS_OK(status
)) {
1537 if (state
->req_data_sent
== 0) {
1538 flags
= DCERPC_PFC_FLAG_FIRST
;
1541 if (total_thistime
== total_left
) {
1542 flags
|= DCERPC_PFC_FLAG_LAST
;
1545 data_thistime
= MIN(total_thistime
, data_left
);
1546 if (data_thistime
< total_thistime
) {
1547 trailer_thistime
= total_thistime
- data_thistime
;
1550 data_blob_free(&state
->rpc_out
);
1552 ZERO_STRUCT(u
.request
);
1554 u
.request
.alloc_hint
= total_left
;
1555 u
.request
.context_id
= 0;
1556 u
.request
.opnum
= state
->op_num
;
1558 status
= dcerpc_push_ncacn_packet(state
,
1565 if (!NT_STATUS_IS_OK(status
)) {
1569 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1570 * compute it right for requests because the auth trailer is missing
1572 dcerpc_set_frag_length(&state
->rpc_out
, frag_len
);
1574 if (data_thistime
> 0) {
1575 /* Copy in the data. */
1576 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1577 state
->req_data
->data
+ state
->req_data_sent
,
1580 return NT_STATUS_NO_MEMORY
;
1582 state
->req_data_sent
+= data_thistime
;
1585 if (trailer_thistime
> 0) {
1586 /* Copy in the verification trailer. */
1587 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1588 state
->req_trailer
.data
+ state
->req_trailer_sent
,
1591 return NT_STATUS_NO_MEMORY
;
1593 state
->req_trailer_sent
+= trailer_thistime
;
1596 switch (state
->cli
->auth
->auth_level
) {
1597 case DCERPC_AUTH_LEVEL_NONE
:
1598 case DCERPC_AUTH_LEVEL_CONNECT
:
1599 case DCERPC_AUTH_LEVEL_PACKET
:
1601 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1602 case DCERPC_AUTH_LEVEL_PRIVACY
:
1603 status
= dcerpc_add_auth_footer(state
->cli
->auth
, pad_len
,
1605 if (!NT_STATUS_IS_OK(status
)) {
1610 return NT_STATUS_INVALID_PARAMETER
;
1613 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
1618 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
1620 struct tevent_req
*req
= tevent_req_callback_data(
1621 subreq
, struct tevent_req
);
1622 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1623 req
, struct rpc_api_pipe_req_state
);
1627 status
= rpc_write_recv(subreq
);
1628 TALLOC_FREE(subreq
);
1629 if (!NT_STATUS_IS_OK(status
)) {
1630 tevent_req_nterror(req
, status
);
1634 status
= prepare_next_frag(state
, &is_last_frag
);
1635 if (!NT_STATUS_IS_OK(status
)) {
1636 tevent_req_nterror(req
, status
);
1641 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
1643 DCERPC_PKT_RESPONSE
,
1645 if (tevent_req_nomem(subreq
, req
)) {
1648 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1650 subreq
= rpc_write_send(state
, state
->ev
,
1651 state
->cli
->transport
,
1652 state
->rpc_out
.data
,
1653 state
->rpc_out
.length
);
1654 if (tevent_req_nomem(subreq
, req
)) {
1657 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1662 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
1664 struct tevent_req
*req
= tevent_req_callback_data(
1665 subreq
, struct tevent_req
);
1666 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1667 req
, struct rpc_api_pipe_req_state
);
1670 status
= rpc_api_pipe_recv(subreq
, state
, NULL
, &state
->reply_pdu
);
1671 TALLOC_FREE(subreq
);
1672 if (!NT_STATUS_IS_OK(status
)) {
1673 tevent_req_nterror(req
, status
);
1677 if (state
->cli
->auth
== NULL
) {
1678 tevent_req_done(req
);
1682 if (state
->verify_bitmask1
) {
1683 state
->cli
->auth
->verified_bitmask1
= true;
1686 if (state
->verify_pcontext
) {
1687 state
->cli
->verified_pcontext
= true;
1690 tevent_req_done(req
);
1693 static NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1694 DATA_BLOB
*reply_pdu
)
1696 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1697 req
, struct rpc_api_pipe_req_state
);
1700 if (tevent_req_is_nterror(req
, &status
)) {
1702 * We always have to initialize to reply pdu, even if there is
1703 * none. The rpccli_* caller routines expect this.
1705 *reply_pdu
= data_blob_null
;
1709 /* return data to caller and assign it ownership of memory */
1710 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1711 reply_pdu
->length
= state
->reply_pdu
.length
;
1712 state
->reply_pdu
.length
= 0;
1714 return NT_STATUS_OK
;
1717 /****************************************************************************
1718 Check the rpc bind acknowledge response.
1719 ****************************************************************************/
1721 static bool check_bind_response(const struct dcerpc_bind_ack
*r
,
1722 const struct ndr_syntax_id
*transfer
)
1724 struct dcerpc_ack_ctx ctx
;
1726 if (r
->secondary_address_size
== 0) {
1727 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1730 if (r
->num_results
< 1 || !r
->ctx_list
) {
1734 ctx
= r
->ctx_list
[0];
1736 /* check the transfer syntax */
1737 if ((ctx
.syntax
.if_version
!= transfer
->if_version
) ||
1738 (memcmp(&ctx
.syntax
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
1739 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1743 if (r
->num_results
!= 0x1 || ctx
.result
!= 0) {
1744 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1745 r
->num_results
, ctx
.reason
.value
));
1748 DEBUG(5,("check_bind_response: accepted!\n"));
1752 /*******************************************************************
1753 Creates a DCE/RPC bind authentication response.
1754 This is the packet that is sent back to the server once we
1755 have received a BIND-ACK, to finish the third leg of
1756 the authentication handshake.
1757 ********************************************************************/
1759 static NTSTATUS
create_rpc_bind_auth3(TALLOC_CTX
*mem_ctx
,
1760 struct rpc_pipe_client
*cli
,
1761 struct pipe_auth_data
*auth
,
1762 uint32_t rpc_call_id
,
1763 DATA_BLOB
*pauth_blob
,
1767 union dcerpc_payload u
;
1771 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1774 0, /* auth_pad_length */
1775 auth
->auth_context_id
,
1777 &u
.auth3
.auth_info
);
1778 if (!NT_STATUS_IS_OK(status
)) {
1782 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1784 DCERPC_PFC_FLAG_FIRST
|
1785 DCERPC_PFC_FLAG_LAST
,
1790 data_blob_free(&u
.auth3
.auth_info
);
1791 if (!NT_STATUS_IS_OK(status
)) {
1792 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1796 return NT_STATUS_OK
;
1799 /*******************************************************************
1800 Creates a DCE/RPC bind alter context authentication request which
1801 may contain a spnego auth blobl
1802 ********************************************************************/
1804 static NTSTATUS
create_rpc_alter_context(TALLOC_CTX
*mem_ctx
,
1805 struct pipe_auth_data
*auth
,
1806 uint32_t rpc_call_id
,
1807 const struct ndr_syntax_id
*abstract
,
1808 const struct ndr_syntax_id
*transfer
,
1809 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
1812 DATA_BLOB auth_info
;
1815 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1818 0, /* auth_pad_length */
1819 auth
->auth_context_id
,
1822 if (!NT_STATUS_IS_OK(status
)) {
1826 status
= create_bind_or_alt_ctx_internal(mem_ctx
,
1832 false, /* client_hdr_signing */
1834 data_blob_free(&auth_info
);
1838 /****************************************************************************
1840 ****************************************************************************/
1842 struct rpc_pipe_bind_state
{
1843 struct tevent_context
*ev
;
1844 struct rpc_pipe_client
*cli
;
1847 uint32_t rpc_call_id
;
1850 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
1851 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
1852 struct rpc_pipe_bind_state
*state
,
1853 DATA_BLOB
*credentials
);
1854 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
1855 struct rpc_pipe_bind_state
*state
,
1856 DATA_BLOB
*credentials
);
1858 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
1859 struct tevent_context
*ev
,
1860 struct rpc_pipe_client
*cli
,
1861 struct pipe_auth_data
*auth
)
1863 struct tevent_req
*req
, *subreq
;
1864 struct rpc_pipe_bind_state
*state
;
1867 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
1872 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1873 rpccli_pipe_txt(talloc_tos(), cli
),
1874 (unsigned int)auth
->auth_type
,
1875 (unsigned int)auth
->auth_level
));
1879 state
->rpc_call_id
= get_rpc_call_id();
1881 cli
->auth
= talloc_move(cli
, &auth
);
1883 /* Marshall the outgoing data. */
1884 status
= create_rpc_bind_req(state
, cli
,
1887 &cli
->abstract_syntax
,
1888 &cli
->transfer_syntax
,
1891 if (!NT_STATUS_IS_OK(status
) &&
1892 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1896 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
1897 DCERPC_PKT_BIND_ACK
, state
->rpc_call_id
);
1898 if (subreq
== NULL
) {
1901 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
1905 tevent_req_nterror(req
, status
);
1906 return tevent_req_post(req
, ev
);
1912 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
1914 struct tevent_req
*req
= tevent_req_callback_data(
1915 subreq
, struct tevent_req
);
1916 struct rpc_pipe_bind_state
*state
= tevent_req_data(
1917 req
, struct rpc_pipe_bind_state
);
1918 struct pipe_auth_data
*pauth
= state
->cli
->auth
;
1919 struct gensec_security
*gensec_security
;
1920 struct ncacn_packet
*pkt
= NULL
;
1921 struct dcerpc_auth auth
;
1922 DATA_BLOB auth_token
= data_blob_null
;
1925 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, NULL
);
1926 TALLOC_FREE(subreq
);
1927 if (!NT_STATUS_IS_OK(status
)) {
1928 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1929 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1930 nt_errstr(status
)));
1931 tevent_req_nterror(req
, status
);
1936 tevent_req_done(req
);
1940 if (!check_bind_response(&pkt
->u
.bind_ack
, &state
->cli
->transfer_syntax
)) {
1941 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1942 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
1946 state
->cli
->max_xmit_frag
= pkt
->u
.bind_ack
.max_xmit_frag
;
1948 switch(pauth
->auth_type
) {
1950 case DCERPC_AUTH_TYPE_NONE
:
1951 /* Bind complete. */
1952 tevent_req_done(req
);
1956 if (pkt
->auth_length
== 0) {
1957 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1961 /* get auth credentials */
1962 status
= dcerpc_pull_auth_trailer(pkt
, talloc_tos(),
1963 &pkt
->u
.bind_ack
.auth_info
,
1965 if (!NT_STATUS_IS_OK(status
)) {
1966 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1967 nt_errstr(status
)));
1968 tevent_req_nterror(req
, status
);
1972 if (auth
.auth_type
!= pauth
->auth_type
) {
1973 DEBUG(0, (__location__
" Auth type %u mismatch expected %u.\n",
1974 auth
.auth_type
, pauth
->auth_type
));
1975 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1979 if (auth
.auth_level
!= pauth
->auth_level
) {
1980 DEBUG(0, (__location__
" Auth level %u mismatch expected %u.\n",
1981 auth
.auth_level
, pauth
->auth_level
));
1982 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1986 if (auth
.auth_context_id
!= pauth
->auth_context_id
) {
1987 DEBUG(0, (__location__
" Auth context id %u mismatch expected %u.\n",
1988 (unsigned)auth
.auth_context_id
,
1989 (unsigned)pauth
->auth_context_id
));
1990 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1998 * For authenticated binds we may need to do 3 or 4 leg binds.
2001 switch(pauth
->auth_type
) {
2003 case DCERPC_AUTH_TYPE_NONE
:
2004 /* Bind complete. */
2005 tevent_req_done(req
);
2009 gensec_security
= pauth
->auth_ctx
;
2011 if (pkt
->pfc_flags
& DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
) {
2012 if (pauth
->client_hdr_signing
) {
2013 pauth
->hdr_signing
= true;
2014 gensec_want_feature(gensec_security
,
2015 GENSEC_FEATURE_SIGN_PKT_HEADER
);
2019 status
= gensec_update(gensec_security
, state
,
2020 auth
.credentials
, &auth_token
);
2021 if (NT_STATUS_EQUAL(status
,
2022 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2023 status
= rpc_bind_next_send(req
, state
,
2025 } else if (NT_STATUS_IS_OK(status
)) {
2026 if (auth_token
.length
== 0) {
2027 /* Bind complete. */
2028 tevent_req_done(req
);
2031 status
= rpc_bind_finish_send(req
, state
,
2037 if (!NT_STATUS_IS_OK(status
)) {
2038 tevent_req_nterror(req
, status
);
2043 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
2044 struct rpc_pipe_bind_state
*state
,
2045 DATA_BLOB
*auth_token
)
2047 struct pipe_auth_data
*auth
= state
->cli
->auth
;
2048 struct tevent_req
*subreq
;
2051 /* Now prepare the alter context pdu. */
2052 data_blob_free(&state
->rpc_out
);
2054 status
= create_rpc_alter_context(state
, auth
,
2056 &state
->cli
->abstract_syntax
,
2057 &state
->cli
->transfer_syntax
,
2060 if (!NT_STATUS_IS_OK(status
)) {
2064 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2065 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
,
2066 state
->rpc_call_id
);
2067 if (subreq
== NULL
) {
2068 return NT_STATUS_NO_MEMORY
;
2070 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2071 return NT_STATUS_OK
;
2074 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
2075 struct rpc_pipe_bind_state
*state
,
2076 DATA_BLOB
*auth_token
)
2078 struct pipe_auth_data
*auth
= state
->cli
->auth
;
2079 struct tevent_req
*subreq
;
2082 state
->auth3
= true;
2084 /* Now prepare the auth3 context pdu. */
2085 data_blob_free(&state
->rpc_out
);
2087 status
= create_rpc_bind_auth3(state
, state
->cli
, auth
,
2091 if (!NT_STATUS_IS_OK(status
)) {
2095 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2096 &state
->rpc_out
, DCERPC_PKT_AUTH3
,
2097 state
->rpc_call_id
);
2098 if (subreq
== NULL
) {
2099 return NT_STATUS_NO_MEMORY
;
2101 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2102 return NT_STATUS_OK
;
2105 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
2107 return tevent_req_simple_recv_ntstatus(req
);
2110 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2111 struct pipe_auth_data
*auth
)
2113 TALLOC_CTX
*frame
= talloc_stackframe();
2114 struct tevent_context
*ev
;
2115 struct tevent_req
*req
;
2116 NTSTATUS status
= NT_STATUS_OK
;
2118 ev
= samba_tevent_context_init(frame
);
2120 status
= NT_STATUS_NO_MEMORY
;
2124 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
2126 status
= NT_STATUS_NO_MEMORY
;
2130 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2134 status
= rpc_pipe_bind_recv(req
);
2140 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2142 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
2143 unsigned int timeout
)
2147 if (rpc_cli
->transport
== NULL
) {
2148 return RPCCLI_DEFAULT_TIMEOUT
;
2151 if (rpc_cli
->transport
->set_timeout
== NULL
) {
2152 return RPCCLI_DEFAULT_TIMEOUT
;
2155 old
= rpc_cli
->transport
->set_timeout(rpc_cli
->transport
->priv
, timeout
);
2157 return RPCCLI_DEFAULT_TIMEOUT
;
2163 bool rpccli_is_connected(struct rpc_pipe_client
*rpc_cli
)
2165 if (rpc_cli
== NULL
) {
2169 if (rpc_cli
->transport
== NULL
) {
2173 return rpc_cli
->transport
->is_connected(rpc_cli
->transport
->priv
);
2176 struct rpccli_bh_state
{
2177 struct rpc_pipe_client
*rpc_cli
;
2180 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle
*h
)
2182 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2183 struct rpccli_bh_state
);
2185 return rpccli_is_connected(hs
->rpc_cli
);
2188 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle
*h
,
2191 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2192 struct rpccli_bh_state
);
2194 return rpccli_set_timeout(hs
->rpc_cli
, timeout
);
2197 static void rpccli_bh_auth_info(struct dcerpc_binding_handle
*h
,
2198 enum dcerpc_AuthType
*auth_type
,
2199 enum dcerpc_AuthLevel
*auth_level
)
2201 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2202 struct rpccli_bh_state
);
2204 if (hs
->rpc_cli
== NULL
) {
2208 if (hs
->rpc_cli
->auth
== NULL
) {
2212 *auth_type
= hs
->rpc_cli
->auth
->auth_type
;
2213 *auth_level
= hs
->rpc_cli
->auth
->auth_level
;
2216 struct rpccli_bh_raw_call_state
{
2222 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
);
2224 static struct tevent_req
*rpccli_bh_raw_call_send(TALLOC_CTX
*mem_ctx
,
2225 struct tevent_context
*ev
,
2226 struct dcerpc_binding_handle
*h
,
2227 const struct GUID
*object
,
2230 const uint8_t *in_data
,
2233 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2234 struct rpccli_bh_state
);
2235 struct tevent_req
*req
;
2236 struct rpccli_bh_raw_call_state
*state
;
2238 struct tevent_req
*subreq
;
2240 req
= tevent_req_create(mem_ctx
, &state
,
2241 struct rpccli_bh_raw_call_state
);
2245 state
->in_data
.data
= discard_const_p(uint8_t, in_data
);
2246 state
->in_data
.length
= in_length
;
2248 ok
= rpccli_bh_is_connected(h
);
2250 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2251 return tevent_req_post(req
, ev
);
2254 subreq
= rpc_api_pipe_req_send(state
, ev
, hs
->rpc_cli
,
2255 opnum
, &state
->in_data
);
2256 if (tevent_req_nomem(subreq
, req
)) {
2257 return tevent_req_post(req
, ev
);
2259 tevent_req_set_callback(subreq
, rpccli_bh_raw_call_done
, req
);
2264 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
)
2266 struct tevent_req
*req
=
2267 tevent_req_callback_data(subreq
,
2269 struct rpccli_bh_raw_call_state
*state
=
2270 tevent_req_data(req
,
2271 struct rpccli_bh_raw_call_state
);
2274 state
->out_flags
= 0;
2276 /* TODO: support bigendian responses */
2278 status
= rpc_api_pipe_req_recv(subreq
, state
, &state
->out_data
);
2279 TALLOC_FREE(subreq
);
2280 if (!NT_STATUS_IS_OK(status
)) {
2281 tevent_req_nterror(req
, status
);
2285 tevent_req_done(req
);
2288 static NTSTATUS
rpccli_bh_raw_call_recv(struct tevent_req
*req
,
2289 TALLOC_CTX
*mem_ctx
,
2292 uint32_t *out_flags
)
2294 struct rpccli_bh_raw_call_state
*state
=
2295 tevent_req_data(req
,
2296 struct rpccli_bh_raw_call_state
);
2299 if (tevent_req_is_nterror(req
, &status
)) {
2300 tevent_req_received(req
);
2304 *out_data
= talloc_move(mem_ctx
, &state
->out_data
.data
);
2305 *out_length
= state
->out_data
.length
;
2306 *out_flags
= state
->out_flags
;
2307 tevent_req_received(req
);
2308 return NT_STATUS_OK
;
2311 struct rpccli_bh_disconnect_state
{
2315 static struct tevent_req
*rpccli_bh_disconnect_send(TALLOC_CTX
*mem_ctx
,
2316 struct tevent_context
*ev
,
2317 struct dcerpc_binding_handle
*h
)
2319 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2320 struct rpccli_bh_state
);
2321 struct tevent_req
*req
;
2322 struct rpccli_bh_disconnect_state
*state
;
2325 req
= tevent_req_create(mem_ctx
, &state
,
2326 struct rpccli_bh_disconnect_state
);
2331 ok
= rpccli_bh_is_connected(h
);
2333 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2334 return tevent_req_post(req
, ev
);
2338 * TODO: do a real async disconnect ...
2340 * For now we do it sync...
2342 TALLOC_FREE(hs
->rpc_cli
->transport
);
2345 tevent_req_done(req
);
2346 return tevent_req_post(req
, ev
);
2349 static NTSTATUS
rpccli_bh_disconnect_recv(struct tevent_req
*req
)
2353 if (tevent_req_is_nterror(req
, &status
)) {
2354 tevent_req_received(req
);
2358 tevent_req_received(req
);
2359 return NT_STATUS_OK
;
2362 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle
*h
)
2367 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle
*h
,
2369 const void *_struct_ptr
,
2370 const struct ndr_interface_call
*call
)
2372 void *struct_ptr
= discard_const(_struct_ptr
);
2374 if (DEBUGLEVEL
< 10) {
2378 if (ndr_flags
& NDR_IN
) {
2379 ndr_print_function_debug(call
->ndr_print
,
2384 if (ndr_flags
& NDR_OUT
) {
2385 ndr_print_function_debug(call
->ndr_print
,
2392 static const struct dcerpc_binding_handle_ops rpccli_bh_ops
= {
2394 .is_connected
= rpccli_bh_is_connected
,
2395 .set_timeout
= rpccli_bh_set_timeout
,
2396 .auth_info
= rpccli_bh_auth_info
,
2397 .raw_call_send
= rpccli_bh_raw_call_send
,
2398 .raw_call_recv
= rpccli_bh_raw_call_recv
,
2399 .disconnect_send
= rpccli_bh_disconnect_send
,
2400 .disconnect_recv
= rpccli_bh_disconnect_recv
,
2402 .ref_alloc
= rpccli_bh_ref_alloc
,
2403 .do_ndr_print
= rpccli_bh_do_ndr_print
,
2406 /* initialise a rpc_pipe_client binding handle */
2407 struct dcerpc_binding_handle
*rpccli_bh_create(struct rpc_pipe_client
*c
,
2408 const struct GUID
*object
,
2409 const struct ndr_interface_table
*table
)
2411 struct dcerpc_binding_handle
*h
;
2412 struct rpccli_bh_state
*hs
;
2414 h
= dcerpc_binding_handle_create(c
,
2419 struct rpccli_bh_state
,
2429 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
2430 struct pipe_auth_data
**presult
)
2432 struct pipe_auth_data
*result
;
2433 struct auth_generic_state
*auth_generic_ctx
;
2436 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2437 if (result
== NULL
) {
2438 return NT_STATUS_NO_MEMORY
;
2441 result
->auth_type
= DCERPC_AUTH_TYPE_NONE
;
2442 result
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
2443 result
->auth_context_id
= 0;
2445 status
= auth_generic_client_prepare(result
,
2447 if (!NT_STATUS_IS_OK(status
)) {
2448 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2449 nt_errstr(status
)));
2452 status
= auth_generic_set_username(auth_generic_ctx
, "");
2453 if (!NT_STATUS_IS_OK(status
)) {
2454 DEBUG(1, ("Failed to set username: %s\n",
2455 nt_errstr(status
)));
2458 status
= auth_generic_set_domain(auth_generic_ctx
, "");
2459 if (!NT_STATUS_IS_OK(status
)) {
2460 DEBUG(1, ("Failed to set domain: %s\n",
2461 nt_errstr(status
)));
2465 status
= gensec_set_credentials(auth_generic_ctx
->gensec_security
,
2466 auth_generic_ctx
->credentials
);
2467 if (!NT_STATUS_IS_OK(status
)) {
2468 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2469 nt_errstr(status
)));
2472 talloc_unlink(auth_generic_ctx
, auth_generic_ctx
->credentials
);
2473 auth_generic_ctx
->credentials
= NULL
;
2475 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2476 talloc_free(auth_generic_ctx
);
2478 return NT_STATUS_OK
;
2481 static NTSTATUS
rpccli_generic_bind_data(TALLOC_CTX
*mem_ctx
,
2482 enum dcerpc_AuthType auth_type
,
2483 enum dcerpc_AuthLevel auth_level
,
2485 const char *target_service
,
2487 const char *username
,
2488 const char *password
,
2489 enum credentials_use_kerberos use_kerberos
,
2490 struct netlogon_creds_CredentialState
*creds
,
2491 struct pipe_auth_data
**presult
)
2493 struct auth_generic_state
*auth_generic_ctx
;
2494 struct pipe_auth_data
*result
;
2497 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2498 if (result
== NULL
) {
2499 return NT_STATUS_NO_MEMORY
;
2502 result
->auth_type
= auth_type
;
2503 result
->auth_level
= auth_level
;
2504 result
->auth_context_id
= 1;
2506 status
= auth_generic_client_prepare(result
,
2508 if (!NT_STATUS_IS_OK(status
)) {
2512 status
= auth_generic_set_username(auth_generic_ctx
, username
);
2513 if (!NT_STATUS_IS_OK(status
)) {
2517 status
= auth_generic_set_domain(auth_generic_ctx
, domain
);
2518 if (!NT_STATUS_IS_OK(status
)) {
2522 status
= auth_generic_set_password(auth_generic_ctx
, password
);
2523 if (!NT_STATUS_IS_OK(status
)) {
2527 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
2528 if (!NT_STATUS_IS_OK(status
)) {
2532 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
2533 if (!NT_STATUS_IS_OK(status
)) {
2537 cli_credentials_set_kerberos_state(auth_generic_ctx
->credentials
, use_kerberos
);
2538 cli_credentials_set_netlogon_creds(auth_generic_ctx
->credentials
, creds
);
2540 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
2541 if (!NT_STATUS_IS_OK(status
)) {
2545 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2546 talloc_free(auth_generic_ctx
);
2548 return NT_STATUS_OK
;
2551 TALLOC_FREE(result
);
2555 /* This routine steals the creds pointer that is passed in */
2556 static NTSTATUS
rpccli_generic_bind_data_from_creds(TALLOC_CTX
*mem_ctx
,
2557 enum dcerpc_AuthType auth_type
,
2558 enum dcerpc_AuthLevel auth_level
,
2560 const char *target_service
,
2561 struct cli_credentials
*creds
,
2562 struct pipe_auth_data
**presult
)
2564 struct auth_generic_state
*auth_generic_ctx
;
2565 struct pipe_auth_data
*result
;
2568 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2569 if (result
== NULL
) {
2570 return NT_STATUS_NO_MEMORY
;
2573 result
->auth_type
= auth_type
;
2574 result
->auth_level
= auth_level
;
2575 result
->auth_context_id
= 1;
2577 status
= auth_generic_client_prepare(result
,
2579 if (!NT_STATUS_IS_OK(status
)) {
2583 status
= auth_generic_set_creds(auth_generic_ctx
, creds
);
2584 if (!NT_STATUS_IS_OK(status
)) {
2588 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
2589 if (!NT_STATUS_IS_OK(status
)) {
2593 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
2594 if (!NT_STATUS_IS_OK(status
)) {
2598 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
2599 if (!NT_STATUS_IS_OK(status
)) {
2603 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2604 talloc_free(auth_generic_ctx
);
2606 return NT_STATUS_OK
;
2609 TALLOC_FREE(result
);
2613 NTSTATUS
rpccli_ncalrpc_bind_data(TALLOC_CTX
*mem_ctx
,
2614 struct pipe_auth_data
**presult
)
2616 return rpccli_generic_bind_data(mem_ctx
,
2617 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
,
2618 DCERPC_AUTH_LEVEL_CONNECT
,
2620 "host", /* target_service */
2621 NAME_NT_AUTHORITY
, /* domain */
2624 CRED_DONT_USE_KERBEROS
,
2625 NULL
, /* netlogon_creds_CredentialState */
2630 * Create an rpc pipe client struct, connecting to a tcp port.
2632 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
2633 const struct sockaddr_storage
*ss_addr
,
2635 const struct ndr_interface_table
*table
,
2636 struct rpc_pipe_client
**presult
)
2638 struct rpc_pipe_client
*result
;
2639 struct sockaddr_storage addr
;
2643 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
2644 if (result
== NULL
) {
2645 return NT_STATUS_NO_MEMORY
;
2648 result
->abstract_syntax
= table
->syntax_id
;
2649 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2651 result
->desthost
= talloc_strdup(result
, host
);
2652 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2653 result
, "\\\\%s", result
->desthost
);
2654 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2655 status
= NT_STATUS_NO_MEMORY
;
2659 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2661 if (ss_addr
== NULL
) {
2662 if (!resolve_name(host
, &addr
, NBT_NAME_SERVER
, false)) {
2663 status
= NT_STATUS_NOT_FOUND
;
2670 status
= open_socket_out(&addr
, port
, 60*1000, &fd
);
2671 if (!NT_STATUS_IS_OK(status
)) {
2674 set_socket_options(fd
, lp_socket_options());
2676 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
2677 if (!NT_STATUS_IS_OK(status
)) {
2682 result
->transport
->transport
= NCACN_IP_TCP
;
2684 result
->binding_handle
= rpccli_bh_create(result
, NULL
, table
);
2685 if (result
->binding_handle
== NULL
) {
2686 TALLOC_FREE(result
);
2687 return NT_STATUS_NO_MEMORY
;
2691 return NT_STATUS_OK
;
2694 TALLOC_FREE(result
);
2699 * Determine the tcp port on which a dcerpc interface is listening
2700 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2703 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
2704 const struct sockaddr_storage
*addr
,
2705 const struct ndr_interface_table
*table
,
2709 struct rpc_pipe_client
*epm_pipe
= NULL
;
2710 struct dcerpc_binding_handle
*epm_handle
= NULL
;
2711 struct pipe_auth_data
*auth
= NULL
;
2712 struct dcerpc_binding
*map_binding
= NULL
;
2713 struct dcerpc_binding
*res_binding
= NULL
;
2714 enum dcerpc_transport_t transport
;
2715 const char *endpoint
= NULL
;
2716 struct epm_twr_t
*map_tower
= NULL
;
2717 struct epm_twr_t
*res_towers
= NULL
;
2718 struct policy_handle
*entry_handle
= NULL
;
2719 uint32_t num_towers
= 0;
2720 uint32_t max_towers
= 1;
2721 struct epm_twr_p_t towers
;
2722 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2723 uint32_t result
= 0;
2725 if (pport
== NULL
) {
2726 status
= NT_STATUS_INVALID_PARAMETER
;
2730 if (ndr_syntax_id_equal(&table
->syntax_id
,
2731 &ndr_table_epmapper
.syntax_id
)) {
2733 status
= NT_STATUS_OK
;
2737 /* open the connection to the endpoint mapper */
2738 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, addr
, 135,
2739 &ndr_table_epmapper
,
2742 if (!NT_STATUS_IS_OK(status
)) {
2745 epm_handle
= epm_pipe
->binding_handle
;
2747 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
2748 if (!NT_STATUS_IS_OK(status
)) {
2752 status
= rpc_pipe_bind(epm_pipe
, auth
);
2753 if (!NT_STATUS_IS_OK(status
)) {
2757 /* create tower for asking the epmapper */
2759 status
= dcerpc_parse_binding(tmp_ctx
, "ncacn_ip_tcp:[135]",
2761 if (!NT_STATUS_IS_OK(status
)) {
2765 status
= dcerpc_binding_set_abstract_syntax(map_binding
,
2767 if (!NT_STATUS_IS_OK(status
)) {
2771 map_tower
= talloc_zero(tmp_ctx
, struct epm_twr_t
);
2772 if (map_tower
== NULL
) {
2773 status
= NT_STATUS_NO_MEMORY
;
2777 status
= dcerpc_binding_build_tower(tmp_ctx
, map_binding
,
2778 &(map_tower
->tower
));
2779 if (!NT_STATUS_IS_OK(status
)) {
2783 /* allocate further parameters for the epm_Map call */
2785 res_towers
= talloc_array(tmp_ctx
, struct epm_twr_t
, max_towers
);
2786 if (res_towers
== NULL
) {
2787 status
= NT_STATUS_NO_MEMORY
;
2790 towers
.twr
= res_towers
;
2792 entry_handle
= talloc_zero(tmp_ctx
, struct policy_handle
);
2793 if (entry_handle
== NULL
) {
2794 status
= NT_STATUS_NO_MEMORY
;
2798 /* ask the endpoint mapper for the port */
2800 status
= dcerpc_epm_Map(epm_handle
,
2802 discard_const_p(struct GUID
,
2803 &(table
->syntax_id
.uuid
)),
2811 if (!NT_STATUS_IS_OK(status
)) {
2815 if (result
!= EPMAPPER_STATUS_OK
) {
2816 status
= NT_STATUS_UNSUCCESSFUL
;
2820 if (num_towers
!= 1) {
2821 status
= NT_STATUS_UNSUCCESSFUL
;
2825 /* extract the port from the answer */
2827 status
= dcerpc_binding_from_tower(tmp_ctx
,
2828 &(towers
.twr
->tower
),
2830 if (!NT_STATUS_IS_OK(status
)) {
2834 transport
= dcerpc_binding_get_transport(res_binding
);
2835 endpoint
= dcerpc_binding_get_string_option(res_binding
, "endpoint");
2837 /* are further checks here necessary? */
2838 if (transport
!= NCACN_IP_TCP
) {
2839 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2843 if (endpoint
== NULL
) {
2844 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2848 *pport
= (uint16_t)atoi(endpoint
);
2851 TALLOC_FREE(tmp_ctx
);
2856 * Create a rpc pipe client struct, connecting to a host via tcp.
2857 * The port is determined by asking the endpoint mapper on the given
2860 NTSTATUS
rpc_pipe_open_tcp(TALLOC_CTX
*mem_ctx
, const char *host
,
2861 const struct sockaddr_storage
*addr
,
2862 const struct ndr_interface_table
*table
,
2863 struct rpc_pipe_client
**presult
)
2868 status
= rpc_pipe_get_tcp_port(host
, addr
, table
, &port
);
2869 if (!NT_STATUS_IS_OK(status
)) {
2873 return rpc_pipe_open_tcp_port(mem_ctx
, host
, addr
, port
,
2877 /********************************************************************
2878 Create a rpc pipe client struct, connecting to a unix domain socket
2879 ********************************************************************/
2880 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
, const char *socket_path
,
2881 const struct ndr_interface_table
*table
,
2882 struct rpc_pipe_client
**presult
)
2884 struct rpc_pipe_client
*result
;
2885 struct sockaddr_un addr
;
2890 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
2891 if (result
== NULL
) {
2892 return NT_STATUS_NO_MEMORY
;
2895 result
->abstract_syntax
= table
->syntax_id
;
2896 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2898 result
->desthost
= get_myname(result
);
2899 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2900 result
, "\\\\%s", result
->desthost
);
2901 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2902 status
= NT_STATUS_NO_MEMORY
;
2906 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2908 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
2910 status
= map_nt_error_from_unix(errno
);
2915 addr
.sun_family
= AF_UNIX
;
2916 strlcpy(addr
.sun_path
, socket_path
, sizeof(addr
.sun_path
));
2917 salen
= sizeof(struct sockaddr_un
);
2919 if (connect(fd
, (struct sockaddr
*)(void *)&addr
, salen
) == -1) {
2920 DEBUG(0, ("connect(%s) failed: %s\n", socket_path
,
2923 return map_nt_error_from_unix(errno
);
2926 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
2927 if (!NT_STATUS_IS_OK(status
)) {
2932 result
->transport
->transport
= NCALRPC
;
2934 result
->binding_handle
= rpccli_bh_create(result
, NULL
, table
);
2935 if (result
->binding_handle
== NULL
) {
2936 TALLOC_FREE(result
);
2937 return NT_STATUS_NO_MEMORY
;
2941 return NT_STATUS_OK
;
2944 TALLOC_FREE(result
);
2948 struct rpc_pipe_client_np_ref
{
2949 struct cli_state
*cli
;
2950 struct rpc_pipe_client
*pipe
;
2953 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref
*np_ref
)
2955 DLIST_REMOVE(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
2959 /****************************************************************************
2960 Open a named pipe over SMB to a remote server.
2962 * CAVEAT CALLER OF THIS FUNCTION:
2963 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2964 * so be sure that this function is called AFTER any structure (vs pointer)
2965 * assignment of the cli. In particular, libsmbclient does structure
2966 * assignments of cli, which invalidates the data in the returned
2967 * rpc_pipe_client if this function is called before the structure assignment
2970 ****************************************************************************/
2972 static NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
2973 const struct ndr_interface_table
*table
,
2974 struct rpc_pipe_client
**presult
)
2976 struct rpc_pipe_client
*result
;
2978 struct rpc_pipe_client_np_ref
*np_ref
;
2980 /* sanity check to protect against crashes */
2983 return NT_STATUS_INVALID_HANDLE
;
2986 result
= talloc_zero(NULL
, struct rpc_pipe_client
);
2987 if (result
== NULL
) {
2988 return NT_STATUS_NO_MEMORY
;
2991 result
->abstract_syntax
= table
->syntax_id
;
2992 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2993 result
->desthost
= talloc_strdup(result
, smbXcli_conn_remote_name(cli
->conn
));
2994 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2995 result
, "\\\\%s", result
->desthost
);
2997 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2999 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3000 TALLOC_FREE(result
);
3001 return NT_STATUS_NO_MEMORY
;
3004 status
= rpc_transport_np_init(result
, cli
, table
,
3005 &result
->transport
);
3006 if (!NT_STATUS_IS_OK(status
)) {
3007 TALLOC_FREE(result
);
3011 result
->transport
->transport
= NCACN_NP
;
3013 np_ref
= talloc(result
->transport
, struct rpc_pipe_client_np_ref
);
3014 if (np_ref
== NULL
) {
3015 TALLOC_FREE(result
);
3016 return NT_STATUS_NO_MEMORY
;
3019 np_ref
->pipe
= result
;
3021 DLIST_ADD(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3022 talloc_set_destructor(np_ref
, rpc_pipe_client_np_ref_destructor
);
3024 result
->binding_handle
= rpccli_bh_create(result
, NULL
, table
);
3025 if (result
->binding_handle
== NULL
) {
3026 TALLOC_FREE(result
);
3027 return NT_STATUS_NO_MEMORY
;
3031 return NT_STATUS_OK
;
3034 /****************************************************************************
3035 Open a pipe to a remote server.
3036 ****************************************************************************/
3038 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3039 enum dcerpc_transport_t transport
,
3040 const struct ndr_interface_table
*table
,
3041 struct rpc_pipe_client
**presult
)
3043 switch (transport
) {
3045 return rpc_pipe_open_tcp(NULL
,
3046 smbXcli_conn_remote_name(cli
->conn
),
3047 smbXcli_conn_remote_sockaddr(cli
->conn
),
3050 return rpc_pipe_open_np(cli
, table
, presult
);
3052 return NT_STATUS_NOT_IMPLEMENTED
;
3056 /****************************************************************************
3057 Open a named pipe to an SMB server and bind anonymously.
3058 ****************************************************************************/
3060 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
3061 enum dcerpc_transport_t transport
,
3062 const struct ndr_interface_table
*table
,
3063 struct rpc_pipe_client
**presult
)
3065 struct rpc_pipe_client
*result
;
3066 struct pipe_auth_data
*auth
;
3069 status
= cli_rpc_pipe_open(cli
, transport
, table
, &result
);
3070 if (!NT_STATUS_IS_OK(status
)) {
3074 status
= rpccli_anon_bind_data(result
, &auth
);
3075 if (!NT_STATUS_IS_OK(status
)) {
3076 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3077 nt_errstr(status
)));
3078 TALLOC_FREE(result
);
3083 * This is a bit of an abstraction violation due to the fact that an
3084 * anonymous bind on an authenticated SMB inherits the user/domain
3085 * from the enclosing SMB creds
3088 if (transport
== NCACN_NP
) {
3089 struct smbXcli_session
*session
;
3091 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
3092 session
= cli
->smb2
.session
;
3094 session
= cli
->smb1
.session
;
3097 status
= smbXcli_session_application_key(session
, auth
,
3098 &auth
->transport_session_key
);
3099 if (!NT_STATUS_IS_OK(status
)) {
3100 auth
->transport_session_key
= data_blob_null
;
3104 status
= rpc_pipe_bind(result
, auth
);
3105 if (!NT_STATUS_IS_OK(status
)) {
3107 if (ndr_syntax_id_equal(&table
->syntax_id
,
3108 &ndr_table_dssetup
.syntax_id
)) {
3109 /* non AD domains just don't have this pipe, avoid
3110 * level 0 statement in that case - gd */
3113 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3114 "%s failed with error %s\n",
3116 nt_errstr(status
) ));
3117 TALLOC_FREE(result
);
3121 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3122 "%s and bound anonymously.\n",
3127 return NT_STATUS_OK
;
3130 /****************************************************************************
3131 ****************************************************************************/
3133 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
3134 const struct ndr_interface_table
*table
,
3135 struct rpc_pipe_client
**presult
)
3137 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
3141 /****************************************************************************
3142 Open a named pipe to an SMB server and bind using the mech specified
3144 This routine references the creds pointer that is passed in
3145 ****************************************************************************/
3147 NTSTATUS
cli_rpc_pipe_open_with_creds(struct cli_state
*cli
,
3148 const struct ndr_interface_table
*table
,
3149 enum dcerpc_transport_t transport
,
3150 enum dcerpc_AuthType auth_type
,
3151 enum dcerpc_AuthLevel auth_level
,
3153 struct cli_credentials
*creds
,
3154 struct rpc_pipe_client
**presult
)
3156 struct rpc_pipe_client
*result
;
3157 struct pipe_auth_data
*auth
= NULL
;
3158 const char *target_service
= table
->authservices
->names
[0];
3162 status
= cli_rpc_pipe_open(cli
, transport
, table
, &result
);
3163 if (!NT_STATUS_IS_OK(status
)) {
3167 status
= rpccli_generic_bind_data_from_creds(result
,
3168 auth_type
, auth_level
,
3169 server
, target_service
,
3172 if (!NT_STATUS_IS_OK(status
)) {
3173 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3174 nt_errstr(status
)));
3178 status
= rpc_pipe_bind(result
, auth
);
3179 if (!NT_STATUS_IS_OK(status
)) {
3180 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3181 nt_errstr(status
) ));
3185 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3186 "machine %s and bound as user %s.\n", table
->name
,
3187 result
->desthost
, cli_credentials_get_unparsed_name(creds
, talloc_tos())));
3190 return NT_STATUS_OK
;
3194 TALLOC_FREE(result
);
3198 /****************************************************************************
3199 Open a named pipe to an SMB server and bind using the mech specified
3201 This routine steals the creds pointer that is passed in
3202 ****************************************************************************/
3204 NTSTATUS
cli_rpc_pipe_open_generic_auth(struct cli_state
*cli
,
3205 const struct ndr_interface_table
*table
,
3206 enum dcerpc_transport_t transport
,
3207 enum credentials_use_kerberos use_kerberos
,
3208 enum dcerpc_AuthType auth_type
,
3209 enum dcerpc_AuthLevel auth_level
,
3212 const char *username
,
3213 const char *password
,
3214 struct rpc_pipe_client
**presult
)
3216 struct rpc_pipe_client
*result
;
3217 struct pipe_auth_data
*auth
= NULL
;
3218 const char *target_service
= table
->authservices
->names
[0];
3222 status
= cli_rpc_pipe_open(cli
, transport
, table
, &result
);
3223 if (!NT_STATUS_IS_OK(status
)) {
3227 status
= rpccli_generic_bind_data(result
,
3228 auth_type
, auth_level
,
3229 server
, target_service
,
3230 domain
, username
, password
,
3231 CRED_AUTO_USE_KERBEROS
,
3234 if (!NT_STATUS_IS_OK(status
)) {
3235 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3236 nt_errstr(status
)));
3240 status
= rpc_pipe_bind(result
, auth
);
3241 if (!NT_STATUS_IS_OK(status
)) {
3242 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3243 nt_errstr(status
) ));
3247 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3248 "machine %s and bound as user %s\\%s.\n", table
->name
,
3249 result
->desthost
, domain
, username
));
3252 return NT_STATUS_OK
;
3256 TALLOC_FREE(result
);
3260 NTSTATUS
cli_rpc_pipe_open_schannel_with_creds(struct cli_state
*cli
,
3261 const struct ndr_interface_table
*table
,
3262 enum dcerpc_transport_t transport
,
3263 struct cli_credentials
*cli_creds
,
3264 struct netlogon_creds_cli_context
*netlogon_creds
,
3265 struct rpc_pipe_client
**_rpccli
)
3267 struct rpc_pipe_client
*rpccli
;
3268 struct pipe_auth_data
*rpcauth
;
3269 const char *target_service
= table
->authservices
->names
[0];
3270 struct netlogon_creds_CredentialState
*ncreds
= NULL
;
3271 enum dcerpc_AuthLevel auth_level
;
3273 int rpc_pipe_bind_dbglvl
= 0;
3275 status
= cli_rpc_pipe_open(cli
, transport
, table
, &rpccli
);
3276 if (!NT_STATUS_IS_OK(status
)) {
3280 status
= netlogon_creds_cli_lock(netlogon_creds
, rpccli
, &ncreds
);
3281 if (!NT_STATUS_IS_OK(status
)) {
3282 DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
3283 nt_errstr(status
)));
3284 TALLOC_FREE(rpccli
);
3288 auth_level
= netlogon_creds_cli_auth_level(netlogon_creds
);
3290 cli_credentials_set_netlogon_creds(cli_creds
, ncreds
);
3292 status
= rpccli_generic_bind_data_from_creds(rpccli
,
3293 DCERPC_AUTH_TYPE_SCHANNEL
,
3299 if (!NT_STATUS_IS_OK(status
)) {
3300 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
3301 nt_errstr(status
)));
3302 TALLOC_FREE(rpccli
);
3306 status
= rpc_pipe_bind(rpccli
, rpcauth
);
3307 cli_credentials_set_netlogon_creds(cli_creds
, NULL
);
3308 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3309 rpc_pipe_bind_dbglvl
= 1;
3310 netlogon_creds_cli_delete(netlogon_creds
, &ncreds
);
3312 if (!NT_STATUS_IS_OK(status
)) {
3313 DEBUG(rpc_pipe_bind_dbglvl
,
3314 ("%s: rpc_pipe_bind failed with error %s\n",
3315 __func__
, nt_errstr(status
)));
3316 TALLOC_FREE(rpccli
);
3320 TALLOC_FREE(ncreds
);
3322 if (!ndr_syntax_id_equal(&table
->syntax_id
, &ndr_table_netlogon
.syntax_id
)) {
3326 status
= netlogon_creds_cli_check(netlogon_creds
,
3327 rpccli
->binding_handle
);
3328 if (!NT_STATUS_IS_OK(status
)) {
3329 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3330 nt_errstr(status
)));
3331 TALLOC_FREE(rpccli
);
3337 DEBUG(10,("%s: opened pipe %s to machine %s "
3338 "for domain %s and bound using schannel.\n",
3339 __func__
, table
->name
,
3340 rpccli
->desthost
, cli_credentials_get_domain(cli_creds
)));
3343 return NT_STATUS_OK
;
3346 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
3347 struct rpc_pipe_client
*cli
,
3348 DATA_BLOB
*session_key
)
3351 struct pipe_auth_data
*a
;
3352 struct gensec_security
*gensec_security
;
3353 DATA_BLOB sk
= data_blob_null
;
3354 bool make_dup
= false;
3356 if (!session_key
|| !cli
) {
3357 return NT_STATUS_INVALID_PARAMETER
;
3363 return NT_STATUS_INVALID_PARAMETER
;
3366 switch (cli
->auth
->auth_type
) {
3367 case DCERPC_AUTH_TYPE_NONE
:
3368 sk
= data_blob_const(a
->transport_session_key
.data
,
3369 a
->transport_session_key
.length
);
3373 gensec_security
= a
->auth_ctx
;
3374 status
= gensec_session_key(gensec_security
, mem_ctx
, &sk
);
3375 if (!NT_STATUS_IS_OK(status
)) {
3383 return NT_STATUS_NO_USER_SESSION_KEY
;
3387 *session_key
= data_blob_dup_talloc(mem_ctx
, sk
);
3392 return NT_STATUS_OK
;