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 "libsmb/namequery.h"
24 #include "../lib/util/tevent_ntstatus.h"
25 #include "librpc/gen_ndr/ndr_epmapper_c.h"
26 #include "../librpc/gen_ndr/ndr_dssetup.h"
27 #include "../libcli/auth/schannel.h"
28 #include "../libcli/auth/netlogon_creds_cli.h"
29 #include "auth_generic.h"
30 #include "librpc/gen_ndr/ndr_dcerpc.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/rpc/dcerpc.h"
35 #include "libsmb/libsmb.h"
36 #include "auth/gensec/gensec.h"
37 #include "auth/credentials/credentials.h"
38 #include "../libcli/smb/smbXcli_base.h"
41 #define DBGC_CLASS DBGC_RPC_CLI
43 /********************************************************************
44 Pipe description for a DEBUG
45 ********************************************************************/
46 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
47 struct rpc_pipe_client
*cli
)
49 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
56 /********************************************************************
58 ********************************************************************/
60 static uint32_t get_rpc_call_id(void)
62 static uint32_t call_id
= 0;
66 /*******************************************************************
67 Use SMBreadX to get rest of one fragment's worth of rpc data.
68 Reads the whole size or give an error message
69 ********************************************************************/
71 struct rpc_read_state
{
72 struct tevent_context
*ev
;
73 struct rpc_cli_transport
*transport
;
79 static void rpc_read_done(struct tevent_req
*subreq
);
81 static struct tevent_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
82 struct tevent_context
*ev
,
83 struct rpc_cli_transport
*transport
,
84 uint8_t *data
, size_t size
)
86 struct tevent_req
*req
, *subreq
;
87 struct rpc_read_state
*state
;
89 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_read_state
);
94 state
->transport
= transport
;
99 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size
));
101 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
103 if (subreq
== NULL
) {
106 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
114 static void rpc_read_done(struct tevent_req
*subreq
)
116 struct tevent_req
*req
= tevent_req_callback_data(
117 subreq
, struct tevent_req
);
118 struct rpc_read_state
*state
= tevent_req_data(
119 req
, struct rpc_read_state
);
123 status
= state
->transport
->read_recv(subreq
, &received
);
125 if (!NT_STATUS_IS_OK(status
)) {
126 tevent_req_nterror(req
, status
);
130 state
->num_read
+= received
;
131 if (state
->num_read
== state
->size
) {
132 tevent_req_done(req
);
136 subreq
= state
->transport
->read_send(state
, state
->ev
,
137 state
->data
+ state
->num_read
,
138 state
->size
- state
->num_read
,
139 state
->transport
->priv
);
140 if (tevent_req_nomem(subreq
, req
)) {
143 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
146 static NTSTATUS
rpc_read_recv(struct tevent_req
*req
)
148 return tevent_req_simple_recv_ntstatus(req
);
151 struct rpc_write_state
{
152 struct tevent_context
*ev
;
153 struct rpc_cli_transport
*transport
;
159 static void rpc_write_done(struct tevent_req
*subreq
);
161 static struct tevent_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
162 struct tevent_context
*ev
,
163 struct rpc_cli_transport
*transport
,
164 const uint8_t *data
, size_t size
)
166 struct tevent_req
*req
, *subreq
;
167 struct rpc_write_state
*state
;
169 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_write_state
);
174 state
->transport
= transport
;
177 state
->num_written
= 0;
179 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size
));
181 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
182 if (subreq
== NULL
) {
185 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
192 static void rpc_write_done(struct tevent_req
*subreq
)
194 struct tevent_req
*req
= tevent_req_callback_data(
195 subreq
, struct tevent_req
);
196 struct rpc_write_state
*state
= tevent_req_data(
197 req
, struct rpc_write_state
);
201 status
= state
->transport
->write_recv(subreq
, &written
);
203 if (!NT_STATUS_IS_OK(status
)) {
204 tevent_req_nterror(req
, status
);
208 state
->num_written
+= written
;
210 if (state
->num_written
== state
->size
) {
211 tevent_req_done(req
);
215 subreq
= state
->transport
->write_send(state
, state
->ev
,
216 state
->data
+ state
->num_written
,
217 state
->size
- state
->num_written
,
218 state
->transport
->priv
);
219 if (tevent_req_nomem(subreq
, req
)) {
222 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
225 static NTSTATUS
rpc_write_recv(struct tevent_req
*req
)
227 return tevent_req_simple_recv_ntstatus(req
);
231 /****************************************************************************
232 Try and get a PDU's worth of data from current_pdu. If not, then read more
234 ****************************************************************************/
236 struct get_complete_frag_state
{
237 struct tevent_context
*ev
;
238 struct rpc_pipe_client
*cli
;
243 static void get_complete_frag_got_header(struct tevent_req
*subreq
);
244 static void get_complete_frag_got_rest(struct tevent_req
*subreq
);
246 static struct tevent_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
247 struct tevent_context
*ev
,
248 struct rpc_pipe_client
*cli
,
251 struct tevent_req
*req
, *subreq
;
252 struct get_complete_frag_state
*state
;
256 req
= tevent_req_create(mem_ctx
, &state
,
257 struct get_complete_frag_state
);
263 state
->frag_len
= RPC_HEADER_LEN
;
266 received
= pdu
->length
;
267 if (received
< RPC_HEADER_LEN
) {
268 if (!data_blob_realloc(mem_ctx
, pdu
, RPC_HEADER_LEN
)) {
269 status
= NT_STATUS_NO_MEMORY
;
272 subreq
= rpc_read_send(state
, state
->ev
,
273 state
->cli
->transport
,
274 pdu
->data
+ received
,
275 RPC_HEADER_LEN
- received
);
276 if (subreq
== NULL
) {
277 status
= NT_STATUS_NO_MEMORY
;
280 tevent_req_set_callback(subreq
, get_complete_frag_got_header
,
285 state
->frag_len
= dcerpc_get_frag_length(pdu
);
286 if (state
->frag_len
< RPC_HEADER_LEN
) {
287 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
288 return tevent_req_post(req
, ev
);
292 * Ensure we have frag_len bytes of data.
294 if (received
< state
->frag_len
) {
295 if (!data_blob_realloc(NULL
, pdu
, state
->frag_len
)) {
296 status
= NT_STATUS_NO_MEMORY
;
299 subreq
= rpc_read_send(state
, state
->ev
,
300 state
->cli
->transport
,
301 pdu
->data
+ received
,
302 state
->frag_len
- received
);
303 if (subreq
== NULL
) {
304 status
= NT_STATUS_NO_MEMORY
;
307 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
,
312 status
= NT_STATUS_OK
;
314 if (NT_STATUS_IS_OK(status
)) {
315 tevent_req_done(req
);
317 tevent_req_nterror(req
, status
);
319 return tevent_req_post(req
, ev
);
322 static void get_complete_frag_got_header(struct tevent_req
*subreq
)
324 struct tevent_req
*req
= tevent_req_callback_data(
325 subreq
, struct tevent_req
);
326 struct get_complete_frag_state
*state
= tevent_req_data(
327 req
, struct get_complete_frag_state
);
330 status
= rpc_read_recv(subreq
);
332 if (!NT_STATUS_IS_OK(status
)) {
333 tevent_req_nterror(req
, status
);
337 state
->frag_len
= dcerpc_get_frag_length(state
->pdu
);
338 if (state
->frag_len
< RPC_HEADER_LEN
) {
339 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
343 if (!data_blob_realloc(NULL
, state
->pdu
, state
->frag_len
)) {
344 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
349 * We're here in this piece of code because we've read exactly
350 * RPC_HEADER_LEN bytes into state->pdu.
353 subreq
= rpc_read_send(state
, state
->ev
, state
->cli
->transport
,
354 state
->pdu
->data
+ RPC_HEADER_LEN
,
355 state
->frag_len
- RPC_HEADER_LEN
);
356 if (tevent_req_nomem(subreq
, req
)) {
359 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
362 static void get_complete_frag_got_rest(struct tevent_req
*subreq
)
364 struct tevent_req
*req
= tevent_req_callback_data(
365 subreq
, struct tevent_req
);
368 status
= rpc_read_recv(subreq
);
370 if (!NT_STATUS_IS_OK(status
)) {
371 tevent_req_nterror(req
, status
);
374 tevent_req_done(req
);
377 static NTSTATUS
get_complete_frag_recv(struct tevent_req
*req
)
379 return tevent_req_simple_recv_ntstatus(req
);
382 /****************************************************************************
383 Do basic authentication checks on an incoming pdu.
384 ****************************************************************************/
386 static NTSTATUS
cli_pipe_validate_current_pdu(TALLOC_CTX
*mem_ctx
,
387 struct rpc_pipe_client
*cli
,
388 struct ncacn_packet
*pkt
,
390 uint8_t expected_pkt_type
,
393 DATA_BLOB
*reply_pdu
)
395 const struct dcerpc_response
*r
= NULL
;
396 DATA_BLOB tmp_stub
= data_blob_null
;
400 * Point the return values at the real data including the RPC
401 * header. Just in case the caller wants it.
405 if ((pkt
->ptype
== DCERPC_PKT_BIND_ACK
) &&
406 !(pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
408 * TODO: do we still need this hack which was introduced
409 * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
411 * I don't even know what AS/U might be...
413 DEBUG(5, (__location__
": bug in server (AS/U?), setting "
414 "fragment first/last ON.\n"));
415 pkt
->pfc_flags
|= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
418 /* Ensure we have the correct type. */
419 switch (pkt
->ptype
) {
420 case DCERPC_PKT_BIND_NAK
:
421 DEBUG(1, (__location__
": Bind NACK received from %s!\n",
422 rpccli_pipe_txt(talloc_tos(), cli
)));
424 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
426 0, /* max_auth_info */
427 DCERPC_PFC_FLAG_FIRST
|
428 DCERPC_PFC_FLAG_LAST
,
429 0); /* optional flags */
430 if (!NT_STATUS_IS_OK(ret
)) {
431 DEBUG(1, (__location__
": Connection to %s got an unexpected "
432 "RPC packet type - %u, expected %u: %s\n",
433 rpccli_pipe_txt(talloc_tos(), cli
),
434 pkt
->ptype
, expected_pkt_type
,
436 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
440 /* Use this for now... */
441 return NT_STATUS_NETWORK_ACCESS_DENIED
;
443 case DCERPC_PKT_BIND_ACK
:
444 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
446 pkt
->u
.bind_ack
.auth_info
.length
,
447 DCERPC_PFC_FLAG_FIRST
|
448 DCERPC_PFC_FLAG_LAST
,
449 DCERPC_PFC_FLAG_CONC_MPX
|
450 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
451 if (!NT_STATUS_IS_OK(ret
)) {
452 DEBUG(1, (__location__
": Connection to %s got an unexpected "
453 "RPC packet type - %u, expected %u: %s\n",
454 rpccli_pipe_txt(talloc_tos(), cli
),
455 pkt
->ptype
, expected_pkt_type
,
457 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
463 case DCERPC_PKT_ALTER_RESP
:
464 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
466 pkt
->u
.alter_resp
.auth_info
.length
,
467 DCERPC_PFC_FLAG_FIRST
|
468 DCERPC_PFC_FLAG_LAST
,
469 DCERPC_PFC_FLAG_CONC_MPX
|
470 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
471 if (!NT_STATUS_IS_OK(ret
)) {
472 DEBUG(1, (__location__
": Connection to %s got an unexpected "
473 "RPC packet type - %u, expected %u: %s\n",
474 rpccli_pipe_txt(talloc_tos(), cli
),
475 pkt
->ptype
, expected_pkt_type
,
477 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
483 case DCERPC_PKT_RESPONSE
:
485 r
= &pkt
->u
.response
;
487 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
489 r
->stub_and_verifier
.length
,
490 0, /* required_flags */
491 DCERPC_PFC_FLAG_FIRST
|
492 DCERPC_PFC_FLAG_LAST
);
493 if (!NT_STATUS_IS_OK(ret
)) {
494 DEBUG(1, (__location__
": Connection to %s got an unexpected "
495 "RPC packet type - %u, expected %u: %s\n",
496 rpccli_pipe_txt(talloc_tos(), cli
),
497 pkt
->ptype
, expected_pkt_type
,
499 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
503 tmp_stub
.data
= r
->stub_and_verifier
.data
;
504 tmp_stub
.length
= r
->stub_and_verifier
.length
;
506 /* Here's where we deal with incoming sign/seal. */
507 ret
= dcerpc_check_auth(cli
->auth
, pkt
,
509 DCERPC_RESPONSE_LENGTH
,
511 if (!NT_STATUS_IS_OK(ret
)) {
512 DEBUG(1, (__location__
": Connection to %s got an unexpected "
513 "RPC packet type - %u, expected %u: %s\n",
514 rpccli_pipe_txt(talloc_tos(), cli
),
515 pkt
->ptype
, expected_pkt_type
,
517 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
521 /* Point the return values at the NDR data. */
524 DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
525 (long unsigned int)pdu
->length
,
526 (long unsigned int)rdata
->length
));
529 * If this is the first reply, and the allocation hint is
530 * reasonable, try and set up the reply_pdu DATA_BLOB to the
534 if ((reply_pdu
->length
== 0) &&
535 r
->alloc_hint
&& (r
->alloc_hint
< 15*1024*1024)) {
536 if (!data_blob_realloc(mem_ctx
, reply_pdu
,
538 DEBUG(0, ("reply alloc hint %d too "
539 "large to allocate\n",
540 (int)r
->alloc_hint
));
541 return NT_STATUS_NO_MEMORY
;
547 case DCERPC_PKT_FAULT
:
549 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
551 0, /* max_auth_info */
552 DCERPC_PFC_FLAG_FIRST
|
553 DCERPC_PFC_FLAG_LAST
,
554 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
555 if (!NT_STATUS_IS_OK(ret
)) {
556 DEBUG(1, (__location__
": Connection to %s got an unexpected "
557 "RPC packet type - %u, expected %u: %s\n",
558 rpccli_pipe_txt(talloc_tos(), cli
),
559 pkt
->ptype
, expected_pkt_type
,
561 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
565 DEBUG(1, (__location__
": RPC fault code %s received "
567 dcerpc_errstr(talloc_tos(),
568 pkt
->u
.fault
.status
),
569 rpccli_pipe_txt(talloc_tos(), cli
)));
571 return dcerpc_fault_to_nt_status(pkt
->u
.fault
.status
);
574 DEBUG(0, (__location__
"Unknown packet type %u received "
576 (unsigned int)pkt
->ptype
,
577 rpccli_pipe_txt(talloc_tos(), cli
)));
578 return NT_STATUS_RPC_PROTOCOL_ERROR
;
582 if (pkt
->call_id
!= call_id
) {
583 DEBUG(3, (__location__
": Connection to %s got an unexpected "
584 "RPC call_id - %u, not %u\n",
585 rpccli_pipe_txt(talloc_tos(), cli
),
586 pkt
->call_id
, call_id
));
587 return NT_STATUS_RPC_PROTOCOL_ERROR
;
593 /****************************************************************************
594 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
595 ****************************************************************************/
597 struct cli_api_pipe_state
{
598 struct tevent_context
*ev
;
599 struct rpc_cli_transport
*transport
;
604 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
);
605 static void cli_api_pipe_write_done(struct tevent_req
*subreq
);
606 static void cli_api_pipe_read_done(struct tevent_req
*subreq
);
608 static struct tevent_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
609 struct tevent_context
*ev
,
610 struct rpc_cli_transport
*transport
,
611 uint8_t *data
, size_t data_len
,
612 uint32_t max_rdata_len
)
614 struct tevent_req
*req
, *subreq
;
615 struct cli_api_pipe_state
*state
;
618 req
= tevent_req_create(mem_ctx
, &state
, struct cli_api_pipe_state
);
623 state
->transport
= transport
;
625 if (max_rdata_len
< RPC_HEADER_LEN
) {
627 * For a RPC reply we always need at least RPC_HEADER_LEN
628 * bytes. We check this here because we will receive
629 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
631 status
= NT_STATUS_INVALID_PARAMETER
;
635 if (transport
->trans_send
!= NULL
) {
636 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
637 max_rdata_len
, transport
->priv
);
638 if (subreq
== NULL
) {
641 tevent_req_set_callback(subreq
, cli_api_pipe_trans_done
, req
);
646 * If the transport does not provide a "trans" routine, i.e. for
647 * example the ncacn_ip_tcp transport, do the write/read step here.
650 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
651 if (subreq
== NULL
) {
654 tevent_req_set_callback(subreq
, cli_api_pipe_write_done
, req
);
658 tevent_req_nterror(req
, status
);
659 return tevent_req_post(req
, ev
);
665 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
)
667 struct tevent_req
*req
= tevent_req_callback_data(
668 subreq
, struct tevent_req
);
669 struct cli_api_pipe_state
*state
= tevent_req_data(
670 req
, struct cli_api_pipe_state
);
673 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
676 if (!NT_STATUS_IS_OK(status
)) {
677 tevent_req_nterror(req
, status
);
680 tevent_req_done(req
);
683 static void cli_api_pipe_write_done(struct tevent_req
*subreq
)
685 struct tevent_req
*req
= tevent_req_callback_data(
686 subreq
, struct tevent_req
);
687 struct cli_api_pipe_state
*state
= tevent_req_data(
688 req
, struct cli_api_pipe_state
);
691 status
= rpc_write_recv(subreq
);
693 if (!NT_STATUS_IS_OK(status
)) {
694 tevent_req_nterror(req
, status
);
698 state
->rdata
= talloc_array(state
, uint8_t, RPC_HEADER_LEN
);
699 if (tevent_req_nomem(state
->rdata
, req
)) {
704 * We don't need to use rpc_read_send here, the upper layer will cope
705 * with a short read, transport->trans_send could also return less
706 * than state->max_rdata_len.
708 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
710 state
->transport
->priv
);
711 if (tevent_req_nomem(subreq
, req
)) {
714 tevent_req_set_callback(subreq
, cli_api_pipe_read_done
, req
);
717 static void cli_api_pipe_read_done(struct tevent_req
*subreq
)
719 struct tevent_req
*req
= tevent_req_callback_data(
720 subreq
, struct tevent_req
);
721 struct cli_api_pipe_state
*state
= tevent_req_data(
722 req
, struct cli_api_pipe_state
);
726 status
= state
->transport
->read_recv(subreq
, &received
);
728 if (!NT_STATUS_IS_OK(status
)) {
729 tevent_req_nterror(req
, status
);
732 state
->rdata_len
= received
;
733 tevent_req_done(req
);
736 static NTSTATUS
cli_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
737 uint8_t **prdata
, uint32_t *prdata_len
)
739 struct cli_api_pipe_state
*state
= tevent_req_data(
740 req
, struct cli_api_pipe_state
);
743 if (tevent_req_is_nterror(req
, &status
)) {
747 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
748 *prdata_len
= state
->rdata_len
;
752 /****************************************************************************
753 Send data on an rpc pipe via trans. The data must be the last
754 pdu fragment of an NDR data stream.
756 Receive response data from an rpc pipe, which may be large...
758 Read the first fragment: unfortunately have to use SMBtrans for the first
759 bit, then SMBreadX for subsequent bits.
761 If first fragment received also wasn't the last fragment, continue
762 getting fragments until we _do_ receive the last fragment.
764 Request/Response PDU's look like the following...
766 |<------------------PDU len----------------------------------------------->|
767 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
769 +------------+-----------------+-------------+---------------+-------------+
770 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
771 +------------+-----------------+-------------+---------------+-------------+
773 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
774 signing & sealing being negotiated.
776 ****************************************************************************/
778 struct rpc_api_pipe_state
{
779 struct tevent_context
*ev
;
780 struct rpc_pipe_client
*cli
;
781 uint8_t expected_pkt_type
;
784 DATA_BLOB incoming_frag
;
785 struct ncacn_packet
*pkt
;
789 size_t reply_pdu_offset
;
793 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
);
794 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
);
795 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
);
797 static struct tevent_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
798 struct tevent_context
*ev
,
799 struct rpc_pipe_client
*cli
,
800 DATA_BLOB
*data
, /* Outgoing PDU */
801 uint8_t expected_pkt_type
,
804 struct tevent_req
*req
, *subreq
;
805 struct rpc_api_pipe_state
*state
;
806 uint16_t max_recv_frag
;
809 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_api_pipe_state
);
815 state
->expected_pkt_type
= expected_pkt_type
;
816 state
->call_id
= call_id
;
817 state
->endianess
= DCERPC_DREP_LE
;
820 * Ensure we're not sending too much.
822 if (data
->length
> cli
->max_xmit_frag
) {
823 status
= NT_STATUS_INVALID_PARAMETER
;
827 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli
)));
829 if (state
->expected_pkt_type
== DCERPC_PKT_AUTH3
) {
830 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
831 data
->data
, data
->length
);
832 if (subreq
== NULL
) {
835 tevent_req_set_callback(subreq
, rpc_api_pipe_auth3_done
, req
);
839 /* get the header first, then fetch the rest once we have
840 * the frag_length available */
841 max_recv_frag
= RPC_HEADER_LEN
;
843 subreq
= cli_api_pipe_send(state
, ev
, cli
->transport
,
844 data
->data
, data
->length
, max_recv_frag
);
845 if (subreq
== NULL
) {
848 tevent_req_set_callback(subreq
, rpc_api_pipe_trans_done
, req
);
852 tevent_req_nterror(req
, status
);
853 return tevent_req_post(req
, ev
);
859 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
)
861 struct tevent_req
*req
=
862 tevent_req_callback_data(subreq
,
866 status
= rpc_write_recv(subreq
);
868 if (!NT_STATUS_IS_OK(status
)) {
869 tevent_req_nterror(req
, status
);
873 tevent_req_done(req
);
876 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
)
878 struct tevent_req
*req
= tevent_req_callback_data(
879 subreq
, struct tevent_req
);
880 struct rpc_api_pipe_state
*state
= tevent_req_data(
881 req
, struct rpc_api_pipe_state
);
883 uint8_t *rdata
= NULL
;
884 uint32_t rdata_len
= 0;
886 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
888 if (!NT_STATUS_IS_OK(status
)) {
889 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
890 tevent_req_nterror(req
, status
);
895 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
896 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
897 tevent_req_done(req
);
902 * Move data on state->incoming_frag.
904 state
->incoming_frag
.data
= talloc_move(state
, &rdata
);
905 state
->incoming_frag
.length
= rdata_len
;
906 if (!state
->incoming_frag
.data
) {
907 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
911 /* Ensure we have enough data for a pdu. */
912 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
913 &state
->incoming_frag
);
914 if (tevent_req_nomem(subreq
, req
)) {
917 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
920 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
)
922 struct tevent_req
*req
= tevent_req_callback_data(
923 subreq
, struct tevent_req
);
924 struct rpc_api_pipe_state
*state
= tevent_req_data(
925 req
, struct rpc_api_pipe_state
);
927 DATA_BLOB rdata
= data_blob_null
;
929 status
= get_complete_frag_recv(subreq
);
931 if (!NT_STATUS_IS_OK(status
)) {
932 DEBUG(5, ("get_complete_frag failed: %s\n",
934 tevent_req_nterror(req
, status
);
938 state
->pkt
= talloc(state
, struct ncacn_packet
);
941 * TODO: do a real async disconnect ...
943 * For now do it sync...
945 TALLOC_FREE(state
->cli
->transport
);
946 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
950 status
= dcerpc_pull_ncacn_packet(state
->pkt
,
951 &state
->incoming_frag
,
953 if (!NT_STATUS_IS_OK(status
)) {
955 * TODO: do a real async disconnect ...
957 * For now do it sync...
959 TALLOC_FREE(state
->cli
->transport
);
960 tevent_req_nterror(req
, status
);
964 if (DEBUGLEVEL
>= 10) {
965 NDR_PRINT_DEBUG(ncacn_packet
, state
->pkt
);
968 status
= cli_pipe_validate_current_pdu(state
,
969 state
->cli
, state
->pkt
,
970 &state
->incoming_frag
,
971 state
->expected_pkt_type
,
976 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
977 (unsigned)state
->incoming_frag
.length
,
978 (unsigned)state
->reply_pdu_offset
,
981 if (state
->pkt
->ptype
!= DCERPC_PKT_FAULT
&& !NT_STATUS_IS_OK(status
)) {
983 * TODO: do a real async disconnect ...
985 * For now do it sync...
987 TALLOC_FREE(state
->cli
->transport
);
988 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
990 * TODO: do a real async disconnect ...
992 * For now do it sync...
994 TALLOC_FREE(state
->cli
->transport
);
995 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
)) {
997 * TODO: do a real async disconnect ...
999 * For now do it sync...
1001 TALLOC_FREE(state
->cli
->transport
);
1003 if (!NT_STATUS_IS_OK(status
)) {
1004 tevent_req_nterror(req
, status
);
1008 if ((state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_FIRST
)
1009 && (state
->pkt
->drep
[0] != DCERPC_DREP_LE
)) {
1011 * Set the data type correctly for big-endian data on the
1014 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1016 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1017 state
->endianess
= 0x00; /* BIG ENDIAN */
1020 * Check endianness on subsequent packets.
1022 if (state
->endianess
!= state
->pkt
->drep
[0]) {
1023 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1025 state
->endianess
?"little":"big",
1026 state
->pkt
->drep
[0]?"little":"big"));
1028 * TODO: do a real async disconnect ...
1030 * For now do it sync...
1032 TALLOC_FREE(state
->cli
->transport
);
1033 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1037 if (state
->reply_pdu_offset
+ rdata
.length
> MAX_RPC_DATA_SIZE
) {
1039 * TODO: do a real async disconnect ...
1041 * For now do it sync...
1043 TALLOC_FREE(state
->cli
->transport
);
1044 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1048 /* Now copy the data portion out of the pdu into rbuf. */
1049 if (state
->reply_pdu
.length
< state
->reply_pdu_offset
+ rdata
.length
) {
1050 if (!data_blob_realloc(NULL
, &state
->reply_pdu
,
1051 state
->reply_pdu_offset
+ rdata
.length
)) {
1053 * TODO: do a real async disconnect ...
1055 * For now do it sync...
1057 TALLOC_FREE(state
->cli
->transport
);
1058 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1063 memcpy(state
->reply_pdu
.data
+ state
->reply_pdu_offset
,
1064 rdata
.data
, rdata
.length
);
1065 state
->reply_pdu_offset
+= rdata
.length
;
1067 /* reset state->incoming_frag, there is no need to free it,
1068 * it will be reallocated to the right size the next time
1070 state
->incoming_frag
.length
= 0;
1072 if (state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
) {
1073 /* make sure the pdu length is right now that we
1074 * have all the data available (alloc hint may
1075 * have allocated more than was actually used) */
1076 state
->reply_pdu
.length
= state
->reply_pdu_offset
;
1077 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1078 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1079 (unsigned)state
->reply_pdu
.length
));
1080 tevent_req_done(req
);
1084 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1085 &state
->incoming_frag
);
1086 if (subreq
== NULL
) {
1088 * TODO: do a real async disconnect ...
1090 * For now do it sync...
1092 TALLOC_FREE(state
->cli
->transport
);
1094 if (tevent_req_nomem(subreq
, req
)) {
1097 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1100 static NTSTATUS
rpc_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1101 struct ncacn_packet
**pkt
,
1102 DATA_BLOB
*reply_pdu
)
1104 struct rpc_api_pipe_state
*state
= tevent_req_data(
1105 req
, struct rpc_api_pipe_state
);
1108 if (tevent_req_is_nterror(req
, &status
)) {
1112 /* return data to caller and assign it ownership of memory */
1114 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1115 reply_pdu
->length
= state
->reply_pdu
.length
;
1116 state
->reply_pdu
.length
= 0;
1118 data_blob_free(&state
->reply_pdu
);
1122 *pkt
= talloc_steal(mem_ctx
, state
->pkt
);
1125 return NT_STATUS_OK
;
1128 /*******************************************************************
1129 Creates NTLMSSP auth bind.
1130 ********************************************************************/
1132 static NTSTATUS
create_generic_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1133 TALLOC_CTX
*mem_ctx
,
1134 DATA_BLOB
*auth_token
,
1135 bool *client_hdr_signing
)
1137 struct gensec_security
*gensec_security
;
1138 DATA_BLOB null_blob
= data_blob_null
;
1141 gensec_security
= cli
->auth
->auth_ctx
;
1143 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1144 status
= gensec_update(gensec_security
, mem_ctx
, null_blob
, auth_token
);
1146 if (!NT_STATUS_IS_OK(status
) &&
1147 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1152 if (client_hdr_signing
== NULL
) {
1156 if (cli
->auth
->auth_level
< DCERPC_AUTH_LEVEL_PACKET
) {
1157 *client_hdr_signing
= false;
1161 *client_hdr_signing
= gensec_have_feature(gensec_security
,
1162 GENSEC_FEATURE_SIGN_PKT_HEADER
);
1167 /*******************************************************************
1168 Creates the internals of a DCE/RPC bind request or alter context PDU.
1169 ********************************************************************/
1171 static NTSTATUS
create_bind_or_alt_ctx_internal(TALLOC_CTX
*mem_ctx
,
1172 enum dcerpc_pkt_type ptype
,
1173 uint32_t rpc_call_id
,
1174 const struct ndr_syntax_id
*abstract
,
1175 const struct ndr_syntax_id
*transfer
,
1176 const DATA_BLOB
*auth_info
,
1177 bool client_hdr_signing
,
1180 uint16_t auth_len
= auth_info
->length
;
1182 union dcerpc_payload u
;
1183 struct dcerpc_ctx_list ctx_list
;
1184 uint8_t pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
1187 auth_len
-= DCERPC_AUTH_TRAILER_LENGTH
;
1190 if (client_hdr_signing
) {
1191 pfc_flags
|= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
;
1194 ctx_list
.context_id
= 0;
1195 ctx_list
.num_transfer_syntaxes
= 1;
1196 ctx_list
.abstract_syntax
= *abstract
;
1197 ctx_list
.transfer_syntaxes
= (struct ndr_syntax_id
*)discard_const(transfer
);
1199 u
.bind
.max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
1200 u
.bind
.max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
1201 u
.bind
.assoc_group_id
= 0x0;
1202 u
.bind
.num_contexts
= 1;
1203 u
.bind
.ctx_list
= &ctx_list
;
1204 u
.bind
.auth_info
= *auth_info
;
1206 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1212 if (!NT_STATUS_IS_OK(status
)) {
1213 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1217 return NT_STATUS_OK
;
1220 /*******************************************************************
1221 Creates a DCE/RPC bind request.
1222 ********************************************************************/
1224 static NTSTATUS
create_rpc_bind_req(TALLOC_CTX
*mem_ctx
,
1225 struct rpc_pipe_client
*cli
,
1226 struct pipe_auth_data
*auth
,
1227 uint32_t rpc_call_id
,
1228 const struct ndr_syntax_id
*abstract
,
1229 const struct ndr_syntax_id
*transfer
,
1232 DATA_BLOB auth_token
= data_blob_null
;
1233 DATA_BLOB auth_info
= data_blob_null
;
1236 switch (auth
->auth_type
) {
1237 case DCERPC_AUTH_TYPE_NONE
:
1241 ret
= create_generic_auth_rpc_bind_req(cli
, mem_ctx
,
1243 &auth
->client_hdr_signing
);
1245 if (!NT_STATUS_IS_OK(ret
) &&
1246 !NT_STATUS_EQUAL(ret
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1252 if (auth_token
.length
!= 0) {
1253 ret
= dcerpc_push_dcerpc_auth(cli
,
1256 0, /* auth_pad_length */
1257 auth
->auth_context_id
,
1260 if (!NT_STATUS_IS_OK(ret
)) {
1263 data_blob_free(&auth_token
);
1266 ret
= create_bind_or_alt_ctx_internal(mem_ctx
,
1272 auth
->client_hdr_signing
,
1277 /*******************************************************************
1279 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1280 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1281 and deals with signing/sealing details.
1282 ********************************************************************/
1284 struct rpc_api_pipe_req_state
{
1285 struct tevent_context
*ev
;
1286 struct rpc_pipe_client
*cli
;
1289 const DATA_BLOB
*req_data
;
1290 const struct GUID
*object_uuid
;
1291 uint32_t req_data_sent
;
1292 DATA_BLOB req_trailer
;
1293 uint32_t req_trailer_sent
;
1294 bool verify_bitmask1
;
1295 bool verify_pcontext
;
1297 DATA_BLOB reply_pdu
;
1300 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
1301 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
1302 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
);
1303 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1304 bool *is_last_frag
);
1306 static struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
1307 struct tevent_context
*ev
,
1308 struct rpc_pipe_client
*cli
,
1310 const struct GUID
*object_uuid
,
1311 const DATA_BLOB
*req_data
)
1313 struct tevent_req
*req
, *subreq
;
1314 struct rpc_api_pipe_req_state
*state
;
1318 req
= tevent_req_create(mem_ctx
, &state
,
1319 struct rpc_api_pipe_req_state
);
1325 state
->op_num
= op_num
;
1326 state
->object_uuid
= object_uuid
;
1327 state
->req_data
= req_data
;
1328 state
->req_data_sent
= 0;
1329 state
->call_id
= get_rpc_call_id();
1330 state
->reply_pdu
= data_blob_null
;
1331 state
->rpc_out
= data_blob_null
;
1333 if (cli
->max_xmit_frag
< DCERPC_REQUEST_LENGTH
1334 + RPC_MAX_SIGN_SIZE
) {
1335 /* Server is screwed up ! */
1336 status
= NT_STATUS_INVALID_PARAMETER
;
1340 status
= prepare_verification_trailer(state
);
1341 if (!NT_STATUS_IS_OK(status
)) {
1345 status
= prepare_next_frag(state
, &is_last_frag
);
1346 if (!NT_STATUS_IS_OK(status
)) {
1351 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
1353 DCERPC_PKT_RESPONSE
,
1355 if (subreq
== NULL
) {
1358 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1360 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
1361 state
->rpc_out
.data
,
1362 state
->rpc_out
.length
);
1363 if (subreq
== NULL
) {
1366 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1372 tevent_req_nterror(req
, status
);
1373 return tevent_req_post(req
, ev
);
1379 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
)
1381 struct pipe_auth_data
*a
= state
->cli
->auth
;
1382 struct dcerpc_sec_verification_trailer
*t
;
1383 struct dcerpc_sec_vt
*c
= NULL
;
1384 struct ndr_push
*ndr
= NULL
;
1385 enum ndr_err_code ndr_err
;
1390 return NT_STATUS_OK
;
1393 if (a
->auth_level
< DCERPC_AUTH_LEVEL_PACKET
) {
1394 return NT_STATUS_OK
;
1397 t
= talloc_zero(state
, struct dcerpc_sec_verification_trailer
);
1399 return NT_STATUS_NO_MEMORY
;
1402 if (!a
->verified_bitmask1
) {
1403 t
->commands
= talloc_realloc(t
, t
->commands
,
1404 struct dcerpc_sec_vt
,
1405 t
->count
.count
+ 1);
1406 if (t
->commands
== NULL
) {
1407 return NT_STATUS_NO_MEMORY
;
1409 c
= &t
->commands
[t
->count
.count
++];
1412 c
->command
= DCERPC_SEC_VT_COMMAND_BITMASK1
;
1413 if (a
->client_hdr_signing
) {
1414 c
->u
.bitmask1
= DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING
;
1416 state
->verify_bitmask1
= true;
1419 if (!state
->cli
->verified_pcontext
) {
1420 t
->commands
= talloc_realloc(t
, t
->commands
,
1421 struct dcerpc_sec_vt
,
1422 t
->count
.count
+ 1);
1423 if (t
->commands
== NULL
) {
1424 return NT_STATUS_NO_MEMORY
;
1426 c
= &t
->commands
[t
->count
.count
++];
1429 c
->command
= DCERPC_SEC_VT_COMMAND_PCONTEXT
;
1430 c
->u
.pcontext
.abstract_syntax
= state
->cli
->abstract_syntax
;
1431 c
->u
.pcontext
.transfer_syntax
= state
->cli
->transfer_syntax
;
1433 state
->verify_pcontext
= true;
1436 if (!a
->hdr_signing
) {
1437 t
->commands
= talloc_realloc(t
, t
->commands
,
1438 struct dcerpc_sec_vt
,
1439 t
->count
.count
+ 1);
1440 if (t
->commands
== NULL
) {
1441 return NT_STATUS_NO_MEMORY
;
1443 c
= &t
->commands
[t
->count
.count
++];
1446 c
->command
= DCERPC_SEC_VT_COMMAND_HEADER2
;
1447 c
->u
.header2
.ptype
= DCERPC_PKT_REQUEST
;
1448 c
->u
.header2
.drep
[0] = DCERPC_DREP_LE
;
1449 c
->u
.header2
.drep
[1] = 0;
1450 c
->u
.header2
.drep
[2] = 0;
1451 c
->u
.header2
.drep
[3] = 0;
1452 c
->u
.header2
.call_id
= state
->call_id
;
1453 c
->u
.header2
.context_id
= 0;
1454 c
->u
.header2
.opnum
= state
->op_num
;
1457 if (t
->count
.count
== 0) {
1459 return NT_STATUS_OK
;
1462 c
= &t
->commands
[t
->count
.count
- 1];
1463 c
->command
|= DCERPC_SEC_VT_COMMAND_END
;
1465 if (DEBUGLEVEL
>= 10) {
1466 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer
, t
);
1469 ndr
= ndr_push_init_ctx(state
);
1471 return NT_STATUS_NO_MEMORY
;
1474 ndr_err
= ndr_push_dcerpc_sec_verification_trailer(ndr
,
1475 NDR_SCALARS
| NDR_BUFFERS
,
1477 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1478 return ndr_map_error2ntstatus(ndr_err
);
1480 state
->req_trailer
= ndr_push_blob(ndr
);
1482 align
= state
->req_data
->length
& 0x3;
1489 const uint8_t zeros
[4] = { 0, };
1491 ok
= data_blob_append(ndr
, &state
->req_trailer
, zeros
, pad
);
1493 return NT_STATUS_NO_MEMORY
;
1496 /* move the padding to the start */
1497 p
= state
->req_trailer
.data
;
1498 memmove(p
+ pad
, p
, state
->req_trailer
.length
- pad
);
1502 return NT_STATUS_OK
;
1505 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1513 size_t data_thistime
;
1514 size_t trailer_left
;
1515 size_t trailer_thistime
= 0;
1517 size_t total_thistime
;
1520 union dcerpc_payload u
;
1522 data_left
= state
->req_data
->length
- state
->req_data_sent
;
1523 trailer_left
= state
->req_trailer
.length
- state
->req_trailer_sent
;
1524 total_left
= data_left
+ trailer_left
;
1525 if ((total_left
< data_left
) || (total_left
< trailer_left
)) {
1529 return NT_STATUS_INVALID_PARAMETER_MIX
;
1532 status
= dcerpc_guess_sizes(state
->cli
->auth
,
1533 DCERPC_REQUEST_LENGTH
, total_left
,
1534 state
->cli
->max_xmit_frag
,
1536 &frag_len
, &auth_len
, &pad_len
);
1537 if (!NT_STATUS_IS_OK(status
)) {
1541 if (state
->req_data_sent
== 0) {
1542 flags
= DCERPC_PFC_FLAG_FIRST
;
1545 if (total_thistime
== total_left
) {
1546 flags
|= DCERPC_PFC_FLAG_LAST
;
1549 data_thistime
= MIN(total_thistime
, data_left
);
1550 if (data_thistime
< total_thistime
) {
1551 trailer_thistime
= total_thistime
- data_thistime
;
1554 data_blob_free(&state
->rpc_out
);
1556 ZERO_STRUCT(u
.request
);
1558 u
.request
.alloc_hint
= total_left
;
1559 u
.request
.context_id
= 0;
1560 u
.request
.opnum
= state
->op_num
;
1562 if (state
->object_uuid
) {
1563 flags
|= DCERPC_PFC_FLAG_OBJECT_UUID
;
1564 u
.request
.object
.object
= *state
->object_uuid
;
1565 frag_len
+= ndr_size_GUID(state
->object_uuid
, 0);
1568 status
= dcerpc_push_ncacn_packet(state
,
1575 if (!NT_STATUS_IS_OK(status
)) {
1579 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1580 * compute it right for requests because the auth trailer is missing
1582 dcerpc_set_frag_length(&state
->rpc_out
, frag_len
);
1584 if (data_thistime
> 0) {
1585 /* Copy in the data. */
1586 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1587 state
->req_data
->data
+ state
->req_data_sent
,
1590 return NT_STATUS_NO_MEMORY
;
1592 state
->req_data_sent
+= data_thistime
;
1595 if (trailer_thistime
> 0) {
1596 /* Copy in the verification trailer. */
1597 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1598 state
->req_trailer
.data
+ state
->req_trailer_sent
,
1601 return NT_STATUS_NO_MEMORY
;
1603 state
->req_trailer_sent
+= trailer_thistime
;
1606 switch (state
->cli
->auth
->auth_level
) {
1607 case DCERPC_AUTH_LEVEL_NONE
:
1608 case DCERPC_AUTH_LEVEL_CONNECT
:
1610 case DCERPC_AUTH_LEVEL_PACKET
:
1611 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1612 case DCERPC_AUTH_LEVEL_PRIVACY
:
1613 status
= dcerpc_add_auth_footer(state
->cli
->auth
, pad_len
,
1615 if (!NT_STATUS_IS_OK(status
)) {
1620 return NT_STATUS_INVALID_PARAMETER
;
1623 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
1628 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
1630 struct tevent_req
*req
= tevent_req_callback_data(
1631 subreq
, struct tevent_req
);
1632 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1633 req
, struct rpc_api_pipe_req_state
);
1637 status
= rpc_write_recv(subreq
);
1638 TALLOC_FREE(subreq
);
1639 if (!NT_STATUS_IS_OK(status
)) {
1640 tevent_req_nterror(req
, status
);
1644 status
= prepare_next_frag(state
, &is_last_frag
);
1645 if (!NT_STATUS_IS_OK(status
)) {
1646 tevent_req_nterror(req
, status
);
1651 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
1653 DCERPC_PKT_RESPONSE
,
1655 if (tevent_req_nomem(subreq
, req
)) {
1658 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1660 subreq
= rpc_write_send(state
, state
->ev
,
1661 state
->cli
->transport
,
1662 state
->rpc_out
.data
,
1663 state
->rpc_out
.length
);
1664 if (tevent_req_nomem(subreq
, req
)) {
1667 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1672 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
1674 struct tevent_req
*req
= tevent_req_callback_data(
1675 subreq
, struct tevent_req
);
1676 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1677 req
, struct rpc_api_pipe_req_state
);
1680 status
= rpc_api_pipe_recv(subreq
, state
, NULL
, &state
->reply_pdu
);
1681 TALLOC_FREE(subreq
);
1682 if (!NT_STATUS_IS_OK(status
)) {
1683 tevent_req_nterror(req
, status
);
1687 if (state
->cli
->auth
== NULL
) {
1688 tevent_req_done(req
);
1692 if (state
->verify_bitmask1
) {
1693 state
->cli
->auth
->verified_bitmask1
= true;
1696 if (state
->verify_pcontext
) {
1697 state
->cli
->verified_pcontext
= true;
1700 tevent_req_done(req
);
1703 static NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1704 DATA_BLOB
*reply_pdu
)
1706 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1707 req
, struct rpc_api_pipe_req_state
);
1710 if (tevent_req_is_nterror(req
, &status
)) {
1712 * We always have to initialize to reply pdu, even if there is
1713 * none. The rpccli_* caller routines expect this.
1715 *reply_pdu
= data_blob_null
;
1719 /* return data to caller and assign it ownership of memory */
1720 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1721 reply_pdu
->length
= state
->reply_pdu
.length
;
1722 state
->reply_pdu
.length
= 0;
1724 return NT_STATUS_OK
;
1727 /****************************************************************************
1728 Check the rpc bind acknowledge response.
1729 ****************************************************************************/
1731 static bool check_bind_response(const struct dcerpc_bind_ack
*r
,
1732 const struct ndr_syntax_id
*transfer
)
1734 struct dcerpc_ack_ctx ctx
;
1736 if (r
->secondary_address_size
== 0) {
1737 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1740 if (r
->num_results
< 1 || !r
->ctx_list
) {
1744 ctx
= r
->ctx_list
[0];
1746 /* check the transfer syntax */
1747 if ((ctx
.syntax
.if_version
!= transfer
->if_version
) ||
1748 (memcmp(&ctx
.syntax
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
1749 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1753 if (r
->num_results
!= 0x1 || ctx
.result
!= 0) {
1754 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1755 r
->num_results
, ctx
.reason
.value
));
1758 DEBUG(5,("check_bind_response: accepted!\n"));
1762 /*******************************************************************
1763 Creates a DCE/RPC bind authentication response.
1764 This is the packet that is sent back to the server once we
1765 have received a BIND-ACK, to finish the third leg of
1766 the authentication handshake.
1767 ********************************************************************/
1769 static NTSTATUS
create_rpc_bind_auth3(TALLOC_CTX
*mem_ctx
,
1770 struct rpc_pipe_client
*cli
,
1771 struct pipe_auth_data
*auth
,
1772 uint32_t rpc_call_id
,
1773 DATA_BLOB
*pauth_blob
,
1777 union dcerpc_payload u
;
1781 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1784 0, /* auth_pad_length */
1785 auth
->auth_context_id
,
1787 &u
.auth3
.auth_info
);
1788 if (!NT_STATUS_IS_OK(status
)) {
1792 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1794 DCERPC_PFC_FLAG_FIRST
|
1795 DCERPC_PFC_FLAG_LAST
,
1800 data_blob_free(&u
.auth3
.auth_info
);
1801 if (!NT_STATUS_IS_OK(status
)) {
1802 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1806 return NT_STATUS_OK
;
1809 /*******************************************************************
1810 Creates a DCE/RPC bind alter context authentication request which
1811 may contain a spnego auth blobl
1812 ********************************************************************/
1814 static NTSTATUS
create_rpc_alter_context(TALLOC_CTX
*mem_ctx
,
1815 struct pipe_auth_data
*auth
,
1816 uint32_t rpc_call_id
,
1817 const struct ndr_syntax_id
*abstract
,
1818 const struct ndr_syntax_id
*transfer
,
1819 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
1822 DATA_BLOB auth_info
;
1825 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1828 0, /* auth_pad_length */
1829 auth
->auth_context_id
,
1832 if (!NT_STATUS_IS_OK(status
)) {
1836 status
= create_bind_or_alt_ctx_internal(mem_ctx
,
1842 false, /* client_hdr_signing */
1844 data_blob_free(&auth_info
);
1848 /****************************************************************************
1850 ****************************************************************************/
1852 struct rpc_pipe_bind_state
{
1853 struct tevent_context
*ev
;
1854 struct rpc_pipe_client
*cli
;
1857 uint32_t rpc_call_id
;
1860 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
1861 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
1862 struct rpc_pipe_bind_state
*state
,
1863 DATA_BLOB
*credentials
);
1864 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
1865 struct rpc_pipe_bind_state
*state
,
1866 DATA_BLOB
*credentials
);
1868 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
1869 struct tevent_context
*ev
,
1870 struct rpc_pipe_client
*cli
,
1871 struct pipe_auth_data
*auth
)
1873 struct tevent_req
*req
, *subreq
;
1874 struct rpc_pipe_bind_state
*state
;
1877 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
1882 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1883 rpccli_pipe_txt(talloc_tos(), cli
),
1884 (unsigned int)auth
->auth_type
,
1885 (unsigned int)auth
->auth_level
));
1889 state
->rpc_call_id
= get_rpc_call_id();
1891 cli
->auth
= talloc_move(cli
, &auth
);
1893 /* Marshall the outgoing data. */
1894 status
= create_rpc_bind_req(state
, cli
,
1897 &cli
->abstract_syntax
,
1898 &cli
->transfer_syntax
,
1901 if (!NT_STATUS_IS_OK(status
) &&
1902 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1906 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
1907 DCERPC_PKT_BIND_ACK
, state
->rpc_call_id
);
1908 if (subreq
== NULL
) {
1911 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
1915 tevent_req_nterror(req
, status
);
1916 return tevent_req_post(req
, ev
);
1922 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
1924 struct tevent_req
*req
= tevent_req_callback_data(
1925 subreq
, struct tevent_req
);
1926 struct rpc_pipe_bind_state
*state
= tevent_req_data(
1927 req
, struct rpc_pipe_bind_state
);
1928 struct pipe_auth_data
*pauth
= state
->cli
->auth
;
1929 struct gensec_security
*gensec_security
;
1930 struct ncacn_packet
*pkt
= NULL
;
1931 struct dcerpc_auth auth
;
1932 DATA_BLOB auth_token
= data_blob_null
;
1935 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, NULL
);
1936 TALLOC_FREE(subreq
);
1937 if (!NT_STATUS_IS_OK(status
)) {
1938 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1939 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1940 nt_errstr(status
)));
1941 tevent_req_nterror(req
, status
);
1946 tevent_req_done(req
);
1950 if (!check_bind_response(&pkt
->u
.bind_ack
, &state
->cli
->transfer_syntax
)) {
1951 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1952 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
1956 if (pkt
->ptype
== DCERPC_PKT_BIND_ACK
) {
1957 if (pkt
->pfc_flags
& DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
) {
1958 if (pauth
->client_hdr_signing
) {
1959 pauth
->hdr_signing
= true;
1964 state
->cli
->max_xmit_frag
= pkt
->u
.bind_ack
.max_xmit_frag
;
1966 switch(pauth
->auth_type
) {
1968 case DCERPC_AUTH_TYPE_NONE
:
1969 /* Bind complete. */
1970 tevent_req_done(req
);
1974 if (pkt
->auth_length
== 0) {
1975 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1979 /* get auth credentials */
1980 status
= dcerpc_pull_auth_trailer(pkt
, talloc_tos(),
1981 &pkt
->u
.bind_ack
.auth_info
,
1983 if (!NT_STATUS_IS_OK(status
)) {
1984 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1985 nt_errstr(status
)));
1986 tevent_req_nterror(req
, status
);
1990 if (auth
.auth_type
!= pauth
->auth_type
) {
1991 DEBUG(0, (__location__
" Auth type %u mismatch expected %u.\n",
1992 auth
.auth_type
, pauth
->auth_type
));
1993 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1997 if (auth
.auth_level
!= pauth
->auth_level
) {
1998 DEBUG(0, (__location__
" Auth level %u mismatch expected %u.\n",
1999 auth
.auth_level
, pauth
->auth_level
));
2000 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2004 if (auth
.auth_context_id
!= pauth
->auth_context_id
) {
2005 DEBUG(0, (__location__
" Auth context id %u mismatch expected %u.\n",
2006 (unsigned)auth
.auth_context_id
,
2007 (unsigned)pauth
->auth_context_id
));
2008 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2016 * For authenticated binds we may need to do 3 or 4 leg binds.
2019 switch(pauth
->auth_type
) {
2021 case DCERPC_AUTH_TYPE_NONE
:
2022 /* Bind complete. */
2023 tevent_req_done(req
);
2027 gensec_security
= pauth
->auth_ctx
;
2030 status
= gensec_update(gensec_security
, state
,
2031 auth
.credentials
, &auth_token
);
2032 if (NT_STATUS_EQUAL(status
,
2033 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2034 status
= rpc_bind_next_send(req
, state
,
2036 } else if (NT_STATUS_IS_OK(status
)) {
2037 if (pauth
->hdr_signing
) {
2038 gensec_want_feature(gensec_security
,
2039 GENSEC_FEATURE_SIGN_PKT_HEADER
);
2042 if (auth_token
.length
== 0) {
2043 /* Bind complete. */
2044 tevent_req_done(req
);
2047 status
= rpc_bind_finish_send(req
, state
,
2053 if (!NT_STATUS_IS_OK(status
)) {
2054 tevent_req_nterror(req
, status
);
2059 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
2060 struct rpc_pipe_bind_state
*state
,
2061 DATA_BLOB
*auth_token
)
2063 struct pipe_auth_data
*auth
= state
->cli
->auth
;
2064 struct tevent_req
*subreq
;
2067 /* Now prepare the alter context pdu. */
2068 data_blob_free(&state
->rpc_out
);
2070 status
= create_rpc_alter_context(state
, auth
,
2072 &state
->cli
->abstract_syntax
,
2073 &state
->cli
->transfer_syntax
,
2076 if (!NT_STATUS_IS_OK(status
)) {
2080 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2081 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
,
2082 state
->rpc_call_id
);
2083 if (subreq
== NULL
) {
2084 return NT_STATUS_NO_MEMORY
;
2086 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2087 return NT_STATUS_OK
;
2090 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
2091 struct rpc_pipe_bind_state
*state
,
2092 DATA_BLOB
*auth_token
)
2094 struct pipe_auth_data
*auth
= state
->cli
->auth
;
2095 struct tevent_req
*subreq
;
2098 state
->auth3
= true;
2100 /* Now prepare the auth3 context pdu. */
2101 data_blob_free(&state
->rpc_out
);
2103 status
= create_rpc_bind_auth3(state
, state
->cli
, auth
,
2107 if (!NT_STATUS_IS_OK(status
)) {
2111 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2112 &state
->rpc_out
, DCERPC_PKT_AUTH3
,
2113 state
->rpc_call_id
);
2114 if (subreq
== NULL
) {
2115 return NT_STATUS_NO_MEMORY
;
2117 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2118 return NT_STATUS_OK
;
2121 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
2123 return tevent_req_simple_recv_ntstatus(req
);
2126 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2127 struct pipe_auth_data
*auth
)
2129 TALLOC_CTX
*frame
= talloc_stackframe();
2130 struct tevent_context
*ev
;
2131 struct tevent_req
*req
;
2132 NTSTATUS status
= NT_STATUS_OK
;
2134 ev
= samba_tevent_context_init(frame
);
2136 status
= NT_STATUS_NO_MEMORY
;
2140 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
2142 status
= NT_STATUS_NO_MEMORY
;
2146 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2150 status
= rpc_pipe_bind_recv(req
);
2156 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2158 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
2159 unsigned int timeout
)
2163 if (rpc_cli
->transport
== NULL
) {
2164 return RPCCLI_DEFAULT_TIMEOUT
;
2167 if (rpc_cli
->transport
->set_timeout
== NULL
) {
2168 return RPCCLI_DEFAULT_TIMEOUT
;
2171 old
= rpc_cli
->transport
->set_timeout(rpc_cli
->transport
->priv
, timeout
);
2173 return RPCCLI_DEFAULT_TIMEOUT
;
2179 bool rpccli_is_connected(struct rpc_pipe_client
*rpc_cli
)
2181 if (rpc_cli
== NULL
) {
2185 if (rpc_cli
->transport
== NULL
) {
2189 return rpc_cli
->transport
->is_connected(rpc_cli
->transport
->priv
);
2192 struct rpccli_bh_state
{
2193 struct rpc_pipe_client
*rpc_cli
;
2196 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle
*h
)
2198 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2199 struct rpccli_bh_state
);
2201 return rpccli_is_connected(hs
->rpc_cli
);
2204 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle
*h
,
2207 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2208 struct rpccli_bh_state
);
2210 return rpccli_set_timeout(hs
->rpc_cli
, timeout
);
2213 static void rpccli_bh_auth_info(struct dcerpc_binding_handle
*h
,
2214 enum dcerpc_AuthType
*auth_type
,
2215 enum dcerpc_AuthLevel
*auth_level
)
2217 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2218 struct rpccli_bh_state
);
2220 if (hs
->rpc_cli
== NULL
) {
2224 if (hs
->rpc_cli
->auth
== NULL
) {
2228 *auth_type
= hs
->rpc_cli
->auth
->auth_type
;
2229 *auth_level
= hs
->rpc_cli
->auth
->auth_level
;
2232 struct rpccli_bh_raw_call_state
{
2238 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
);
2240 static struct tevent_req
*rpccli_bh_raw_call_send(TALLOC_CTX
*mem_ctx
,
2241 struct tevent_context
*ev
,
2242 struct dcerpc_binding_handle
*h
,
2243 const struct GUID
*object
,
2246 const uint8_t *in_data
,
2249 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2250 struct rpccli_bh_state
);
2251 struct tevent_req
*req
;
2252 struct rpccli_bh_raw_call_state
*state
;
2254 struct tevent_req
*subreq
;
2256 req
= tevent_req_create(mem_ctx
, &state
,
2257 struct rpccli_bh_raw_call_state
);
2261 state
->in_data
.data
= discard_const_p(uint8_t, in_data
);
2262 state
->in_data
.length
= in_length
;
2264 ok
= rpccli_bh_is_connected(h
);
2266 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2267 return tevent_req_post(req
, ev
);
2270 subreq
= rpc_api_pipe_req_send(state
, ev
, hs
->rpc_cli
,
2271 opnum
, object
, &state
->in_data
);
2272 if (tevent_req_nomem(subreq
, req
)) {
2273 return tevent_req_post(req
, ev
);
2275 tevent_req_set_callback(subreq
, rpccli_bh_raw_call_done
, req
);
2280 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
)
2282 struct tevent_req
*req
=
2283 tevent_req_callback_data(subreq
,
2285 struct rpccli_bh_raw_call_state
*state
=
2286 tevent_req_data(req
,
2287 struct rpccli_bh_raw_call_state
);
2290 state
->out_flags
= 0;
2292 /* TODO: support bigendian responses */
2294 status
= rpc_api_pipe_req_recv(subreq
, state
, &state
->out_data
);
2295 TALLOC_FREE(subreq
);
2296 if (!NT_STATUS_IS_OK(status
)) {
2297 tevent_req_nterror(req
, status
);
2301 tevent_req_done(req
);
2304 static NTSTATUS
rpccli_bh_raw_call_recv(struct tevent_req
*req
,
2305 TALLOC_CTX
*mem_ctx
,
2308 uint32_t *out_flags
)
2310 struct rpccli_bh_raw_call_state
*state
=
2311 tevent_req_data(req
,
2312 struct rpccli_bh_raw_call_state
);
2315 if (tevent_req_is_nterror(req
, &status
)) {
2316 tevent_req_received(req
);
2320 *out_data
= talloc_move(mem_ctx
, &state
->out_data
.data
);
2321 *out_length
= state
->out_data
.length
;
2322 *out_flags
= state
->out_flags
;
2323 tevent_req_received(req
);
2324 return NT_STATUS_OK
;
2327 struct rpccli_bh_disconnect_state
{
2331 static struct tevent_req
*rpccli_bh_disconnect_send(TALLOC_CTX
*mem_ctx
,
2332 struct tevent_context
*ev
,
2333 struct dcerpc_binding_handle
*h
)
2335 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2336 struct rpccli_bh_state
);
2337 struct tevent_req
*req
;
2338 struct rpccli_bh_disconnect_state
*state
;
2341 req
= tevent_req_create(mem_ctx
, &state
,
2342 struct rpccli_bh_disconnect_state
);
2347 ok
= rpccli_bh_is_connected(h
);
2349 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2350 return tevent_req_post(req
, ev
);
2354 * TODO: do a real async disconnect ...
2356 * For now we do it sync...
2358 TALLOC_FREE(hs
->rpc_cli
->transport
);
2361 tevent_req_done(req
);
2362 return tevent_req_post(req
, ev
);
2365 static NTSTATUS
rpccli_bh_disconnect_recv(struct tevent_req
*req
)
2369 if (tevent_req_is_nterror(req
, &status
)) {
2370 tevent_req_received(req
);
2374 tevent_req_received(req
);
2375 return NT_STATUS_OK
;
2378 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle
*h
)
2383 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle
*h
,
2385 const void *_struct_ptr
,
2386 const struct ndr_interface_call
*call
)
2388 void *struct_ptr
= discard_const(_struct_ptr
);
2390 if (DEBUGLEVEL
< 10) {
2394 if (ndr_flags
& NDR_IN
) {
2395 ndr_print_function_debug(call
->ndr_print
,
2400 if (ndr_flags
& NDR_OUT
) {
2401 ndr_print_function_debug(call
->ndr_print
,
2408 static const struct dcerpc_binding_handle_ops rpccli_bh_ops
= {
2410 .is_connected
= rpccli_bh_is_connected
,
2411 .set_timeout
= rpccli_bh_set_timeout
,
2412 .auth_info
= rpccli_bh_auth_info
,
2413 .raw_call_send
= rpccli_bh_raw_call_send
,
2414 .raw_call_recv
= rpccli_bh_raw_call_recv
,
2415 .disconnect_send
= rpccli_bh_disconnect_send
,
2416 .disconnect_recv
= rpccli_bh_disconnect_recv
,
2418 .ref_alloc
= rpccli_bh_ref_alloc
,
2419 .do_ndr_print
= rpccli_bh_do_ndr_print
,
2422 /* initialise a rpc_pipe_client binding handle */
2423 struct dcerpc_binding_handle
*rpccli_bh_create(struct rpc_pipe_client
*c
,
2424 const struct GUID
*object
,
2425 const struct ndr_interface_table
*table
)
2427 struct dcerpc_binding_handle
*h
;
2428 struct rpccli_bh_state
*hs
;
2430 h
= dcerpc_binding_handle_create(c
,
2435 struct rpccli_bh_state
,
2445 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
2446 struct pipe_auth_data
**presult
)
2448 struct pipe_auth_data
*result
;
2449 struct auth_generic_state
*auth_generic_ctx
;
2452 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2453 if (result
== NULL
) {
2454 return NT_STATUS_NO_MEMORY
;
2457 result
->auth_type
= DCERPC_AUTH_TYPE_NONE
;
2458 result
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
2459 result
->auth_context_id
= 0;
2461 status
= auth_generic_client_prepare(result
,
2463 if (!NT_STATUS_IS_OK(status
)) {
2464 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2465 nt_errstr(status
)));
2468 status
= auth_generic_set_username(auth_generic_ctx
, "");
2469 if (!NT_STATUS_IS_OK(status
)) {
2470 DEBUG(1, ("Failed to set username: %s\n",
2471 nt_errstr(status
)));
2474 status
= auth_generic_set_domain(auth_generic_ctx
, "");
2475 if (!NT_STATUS_IS_OK(status
)) {
2476 DEBUG(1, ("Failed to set domain: %s\n",
2477 nt_errstr(status
)));
2481 status
= gensec_set_credentials(auth_generic_ctx
->gensec_security
,
2482 auth_generic_ctx
->credentials
);
2483 if (!NT_STATUS_IS_OK(status
)) {
2484 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2485 nt_errstr(status
)));
2488 talloc_unlink(auth_generic_ctx
, auth_generic_ctx
->credentials
);
2489 auth_generic_ctx
->credentials
= NULL
;
2491 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2492 talloc_free(auth_generic_ctx
);
2494 return NT_STATUS_OK
;
2497 static NTSTATUS
rpccli_generic_bind_data(TALLOC_CTX
*mem_ctx
,
2498 enum dcerpc_AuthType auth_type
,
2499 enum dcerpc_AuthLevel auth_level
,
2501 const char *target_service
,
2503 const char *username
,
2504 const char *password
,
2505 enum credentials_use_kerberos use_kerberos
,
2506 struct netlogon_creds_CredentialState
*creds
,
2507 struct pipe_auth_data
**presult
)
2509 struct auth_generic_state
*auth_generic_ctx
;
2510 struct pipe_auth_data
*result
;
2513 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2514 if (result
== NULL
) {
2515 return NT_STATUS_NO_MEMORY
;
2518 result
->auth_type
= auth_type
;
2519 result
->auth_level
= auth_level
;
2520 result
->auth_context_id
= 1;
2522 status
= auth_generic_client_prepare(result
,
2524 if (!NT_STATUS_IS_OK(status
)) {
2528 status
= auth_generic_set_username(auth_generic_ctx
, username
);
2529 if (!NT_STATUS_IS_OK(status
)) {
2533 status
= auth_generic_set_domain(auth_generic_ctx
, domain
);
2534 if (!NT_STATUS_IS_OK(status
)) {
2538 status
= auth_generic_set_password(auth_generic_ctx
, password
);
2539 if (!NT_STATUS_IS_OK(status
)) {
2543 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
2544 if (!NT_STATUS_IS_OK(status
)) {
2548 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
2549 if (!NT_STATUS_IS_OK(status
)) {
2553 cli_credentials_set_kerberos_state(auth_generic_ctx
->credentials
, use_kerberos
);
2554 cli_credentials_set_netlogon_creds(auth_generic_ctx
->credentials
, creds
);
2556 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
2557 if (!NT_STATUS_IS_OK(status
)) {
2561 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2562 talloc_free(auth_generic_ctx
);
2564 return NT_STATUS_OK
;
2567 TALLOC_FREE(result
);
2571 /* This routine steals the creds pointer that is passed in */
2572 static NTSTATUS
rpccli_generic_bind_data_from_creds(TALLOC_CTX
*mem_ctx
,
2573 enum dcerpc_AuthType auth_type
,
2574 enum dcerpc_AuthLevel auth_level
,
2576 const char *target_service
,
2577 struct cli_credentials
*creds
,
2578 struct pipe_auth_data
**presult
)
2580 struct auth_generic_state
*auth_generic_ctx
;
2581 struct pipe_auth_data
*result
;
2584 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2585 if (result
== NULL
) {
2586 return NT_STATUS_NO_MEMORY
;
2589 result
->auth_type
= auth_type
;
2590 result
->auth_level
= auth_level
;
2591 result
->auth_context_id
= 1;
2593 status
= auth_generic_client_prepare(result
,
2595 if (!NT_STATUS_IS_OK(status
)) {
2599 status
= auth_generic_set_creds(auth_generic_ctx
, creds
);
2600 if (!NT_STATUS_IS_OK(status
)) {
2604 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
2605 if (!NT_STATUS_IS_OK(status
)) {
2609 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
2610 if (!NT_STATUS_IS_OK(status
)) {
2614 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
2615 if (!NT_STATUS_IS_OK(status
)) {
2619 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2620 talloc_free(auth_generic_ctx
);
2622 return NT_STATUS_OK
;
2625 TALLOC_FREE(result
);
2629 NTSTATUS
rpccli_ncalrpc_bind_data(TALLOC_CTX
*mem_ctx
,
2630 struct pipe_auth_data
**presult
)
2632 return rpccli_generic_bind_data(mem_ctx
,
2633 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
,
2634 DCERPC_AUTH_LEVEL_CONNECT
,
2636 "host", /* target_service */
2637 NAME_NT_AUTHORITY
, /* domain */
2639 NULL
, /* password */
2640 CRED_DONT_USE_KERBEROS
,
2641 NULL
, /* netlogon_creds_CredentialState */
2646 * Create an rpc pipe client struct, connecting to a tcp port.
2648 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
2649 const struct sockaddr_storage
*ss_addr
,
2651 const struct ndr_interface_table
*table
,
2652 struct rpc_pipe_client
**presult
)
2654 struct rpc_pipe_client
*result
;
2655 struct sockaddr_storage addr
;
2659 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
2660 if (result
== NULL
) {
2661 return NT_STATUS_NO_MEMORY
;
2664 result
->abstract_syntax
= table
->syntax_id
;
2665 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2667 result
->desthost
= talloc_strdup(result
, host
);
2668 if (result
->desthost
== NULL
) {
2669 status
= NT_STATUS_NO_MEMORY
;
2673 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2674 result
, "\\\\%s", result
->desthost
);
2675 if (result
->srv_name_slash
== NULL
) {
2676 status
= NT_STATUS_NO_MEMORY
;
2680 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2682 if (ss_addr
== NULL
) {
2683 if (!resolve_name(host
, &addr
, NBT_NAME_SERVER
, false)) {
2684 status
= NT_STATUS_NOT_FOUND
;
2691 status
= open_socket_out(&addr
, port
, 60*1000, &fd
);
2692 if (!NT_STATUS_IS_OK(status
)) {
2695 set_socket_options(fd
, lp_socket_options());
2697 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
2698 if (!NT_STATUS_IS_OK(status
)) {
2703 result
->transport
->transport
= NCACN_IP_TCP
;
2705 result
->binding_handle
= rpccli_bh_create(result
, NULL
, table
);
2706 if (result
->binding_handle
== NULL
) {
2707 TALLOC_FREE(result
);
2708 return NT_STATUS_NO_MEMORY
;
2712 return NT_STATUS_OK
;
2715 TALLOC_FREE(result
);
2720 * Determine the tcp port on which a dcerpc interface is listening
2721 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2724 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
2725 const struct sockaddr_storage
*addr
,
2726 const struct ndr_interface_table
*table
,
2730 struct rpc_pipe_client
*epm_pipe
= NULL
;
2731 struct dcerpc_binding_handle
*epm_handle
= NULL
;
2732 struct pipe_auth_data
*auth
= NULL
;
2733 struct dcerpc_binding
*map_binding
= NULL
;
2734 struct dcerpc_binding
*res_binding
= NULL
;
2735 enum dcerpc_transport_t transport
;
2736 const char *endpoint
= NULL
;
2737 struct epm_twr_t
*map_tower
= NULL
;
2738 struct epm_twr_t
*res_towers
= NULL
;
2739 struct policy_handle
*entry_handle
= NULL
;
2740 uint32_t num_towers
= 0;
2741 uint32_t max_towers
= 1;
2742 struct epm_twr_p_t towers
;
2743 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2744 uint32_t result
= 0;
2746 if (pport
== NULL
) {
2747 status
= NT_STATUS_INVALID_PARAMETER
;
2751 if (ndr_syntax_id_equal(&table
->syntax_id
,
2752 &ndr_table_epmapper
.syntax_id
)) {
2754 status
= NT_STATUS_OK
;
2758 /* open the connection to the endpoint mapper */
2759 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, addr
, 135,
2760 &ndr_table_epmapper
,
2763 if (!NT_STATUS_IS_OK(status
)) {
2766 epm_handle
= epm_pipe
->binding_handle
;
2768 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
2769 if (!NT_STATUS_IS_OK(status
)) {
2773 status
= rpc_pipe_bind(epm_pipe
, auth
);
2774 if (!NT_STATUS_IS_OK(status
)) {
2778 /* create tower for asking the epmapper */
2780 status
= dcerpc_parse_binding(tmp_ctx
, "ncacn_ip_tcp:[135]",
2782 if (!NT_STATUS_IS_OK(status
)) {
2786 status
= dcerpc_binding_set_abstract_syntax(map_binding
,
2788 if (!NT_STATUS_IS_OK(status
)) {
2792 map_tower
= talloc_zero(tmp_ctx
, struct epm_twr_t
);
2793 if (map_tower
== NULL
) {
2794 status
= NT_STATUS_NO_MEMORY
;
2798 status
= dcerpc_binding_build_tower(tmp_ctx
, map_binding
,
2799 &(map_tower
->tower
));
2800 if (!NT_STATUS_IS_OK(status
)) {
2804 /* allocate further parameters for the epm_Map call */
2806 res_towers
= talloc_array(tmp_ctx
, struct epm_twr_t
, max_towers
);
2807 if (res_towers
== NULL
) {
2808 status
= NT_STATUS_NO_MEMORY
;
2811 towers
.twr
= res_towers
;
2813 entry_handle
= talloc_zero(tmp_ctx
, struct policy_handle
);
2814 if (entry_handle
== NULL
) {
2815 status
= NT_STATUS_NO_MEMORY
;
2819 /* ask the endpoint mapper for the port */
2821 status
= dcerpc_epm_Map(epm_handle
,
2823 discard_const_p(struct GUID
,
2824 &(table
->syntax_id
.uuid
)),
2832 if (!NT_STATUS_IS_OK(status
)) {
2836 if (result
!= EPMAPPER_STATUS_OK
) {
2837 status
= NT_STATUS_UNSUCCESSFUL
;
2841 if (num_towers
!= 1) {
2842 status
= NT_STATUS_UNSUCCESSFUL
;
2846 /* extract the port from the answer */
2848 status
= dcerpc_binding_from_tower(tmp_ctx
,
2849 &(towers
.twr
->tower
),
2851 if (!NT_STATUS_IS_OK(status
)) {
2855 transport
= dcerpc_binding_get_transport(res_binding
);
2856 endpoint
= dcerpc_binding_get_string_option(res_binding
, "endpoint");
2858 /* are further checks here necessary? */
2859 if (transport
!= NCACN_IP_TCP
) {
2860 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2864 if (endpoint
== NULL
) {
2865 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2869 *pport
= (uint16_t)atoi(endpoint
);
2872 TALLOC_FREE(tmp_ctx
);
2877 * Create a rpc pipe client struct, connecting to a host via tcp.
2878 * The port is determined by asking the endpoint mapper on the given
2881 NTSTATUS
rpc_pipe_open_tcp(TALLOC_CTX
*mem_ctx
, const char *host
,
2882 const struct sockaddr_storage
*addr
,
2883 const struct ndr_interface_table
*table
,
2884 struct rpc_pipe_client
**presult
)
2889 status
= rpc_pipe_get_tcp_port(host
, addr
, table
, &port
);
2890 if (!NT_STATUS_IS_OK(status
)) {
2894 return rpc_pipe_open_tcp_port(mem_ctx
, host
, addr
, port
,
2898 /********************************************************************
2899 Create a rpc pipe client struct, connecting to a unix domain socket
2900 ********************************************************************/
2901 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
, const char *socket_path
,
2902 const struct ndr_interface_table
*table
,
2903 struct rpc_pipe_client
**presult
)
2905 struct rpc_pipe_client
*result
;
2906 struct sockaddr_un addr
;
2911 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
2912 if (result
== NULL
) {
2913 return NT_STATUS_NO_MEMORY
;
2916 result
->abstract_syntax
= table
->syntax_id
;
2917 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2919 result
->desthost
= get_myname(result
);
2920 if (result
->desthost
== NULL
) {
2921 status
= NT_STATUS_NO_MEMORY
;
2925 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2926 result
, "\\\\%s", result
->desthost
);
2927 if (result
->srv_name_slash
== NULL
) {
2928 status
= NT_STATUS_NO_MEMORY
;
2932 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2934 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
2936 status
= map_nt_error_from_unix(errno
);
2941 addr
.sun_family
= AF_UNIX
;
2942 strlcpy(addr
.sun_path
, socket_path
, sizeof(addr
.sun_path
));
2943 salen
= sizeof(struct sockaddr_un
);
2945 if (connect(fd
, (struct sockaddr
*)(void *)&addr
, salen
) == -1) {
2946 DEBUG(0, ("connect(%s) failed: %s\n", socket_path
,
2949 return map_nt_error_from_unix(errno
);
2952 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
2953 if (!NT_STATUS_IS_OK(status
)) {
2958 result
->transport
->transport
= NCALRPC
;
2960 result
->binding_handle
= rpccli_bh_create(result
, NULL
, table
);
2961 if (result
->binding_handle
== NULL
) {
2962 TALLOC_FREE(result
);
2963 return NT_STATUS_NO_MEMORY
;
2967 return NT_STATUS_OK
;
2970 TALLOC_FREE(result
);
2974 struct rpc_pipe_client_np_ref
{
2975 struct cli_state
*cli
;
2976 struct rpc_pipe_client
*pipe
;
2979 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref
*np_ref
)
2981 DLIST_REMOVE(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
2985 /****************************************************************************
2986 Open a named pipe over SMB to a remote server.
2988 * CAVEAT CALLER OF THIS FUNCTION:
2989 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2990 * so be sure that this function is called AFTER any structure (vs pointer)
2991 * assignment of the cli. In particular, libsmbclient does structure
2992 * assignments of cli, which invalidates the data in the returned
2993 * rpc_pipe_client if this function is called before the structure assignment
2996 ****************************************************************************/
2998 static NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
2999 const struct ndr_interface_table
*table
,
3000 struct rpc_pipe_client
**presult
)
3002 struct rpc_pipe_client
*result
;
3004 struct rpc_pipe_client_np_ref
*np_ref
;
3006 /* sanity check to protect against crashes */
3009 return NT_STATUS_INVALID_HANDLE
;
3012 result
= talloc_zero(NULL
, struct rpc_pipe_client
);
3013 if (result
== NULL
) {
3014 return NT_STATUS_NO_MEMORY
;
3017 result
->abstract_syntax
= table
->syntax_id
;
3018 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
3020 result
->desthost
= talloc_strdup(
3021 result
, smbXcli_conn_remote_name(cli
->conn
));
3022 if (result
->desthost
== NULL
) {
3023 TALLOC_FREE(result
);
3024 return NT_STATUS_NO_MEMORY
;
3027 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3028 result
, "\\\\%s", result
->desthost
);
3029 if (result
->srv_name_slash
== NULL
) {
3030 TALLOC_FREE(result
);
3031 return NT_STATUS_NO_MEMORY
;
3034 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3036 status
= rpc_transport_np_init(result
, cli
, table
,
3037 &result
->transport
);
3038 if (!NT_STATUS_IS_OK(status
)) {
3039 TALLOC_FREE(result
);
3043 result
->transport
->transport
= NCACN_NP
;
3045 np_ref
= talloc(result
->transport
, struct rpc_pipe_client_np_ref
);
3046 if (np_ref
== NULL
) {
3047 TALLOC_FREE(result
);
3048 return NT_STATUS_NO_MEMORY
;
3051 np_ref
->pipe
= result
;
3053 DLIST_ADD(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3054 talloc_set_destructor(np_ref
, rpc_pipe_client_np_ref_destructor
);
3056 result
->binding_handle
= rpccli_bh_create(result
, NULL
, table
);
3057 if (result
->binding_handle
== NULL
) {
3058 TALLOC_FREE(result
);
3059 return NT_STATUS_NO_MEMORY
;
3063 return NT_STATUS_OK
;
3066 /****************************************************************************
3067 Open a pipe to a remote server.
3068 ****************************************************************************/
3070 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3071 enum dcerpc_transport_t transport
,
3072 const struct ndr_interface_table
*table
,
3073 struct rpc_pipe_client
**presult
)
3075 switch (transport
) {
3077 return rpc_pipe_open_tcp(NULL
,
3078 smbXcli_conn_remote_name(cli
->conn
),
3079 smbXcli_conn_remote_sockaddr(cli
->conn
),
3082 return rpc_pipe_open_np(cli
, table
, presult
);
3084 return NT_STATUS_NOT_IMPLEMENTED
;
3088 /****************************************************************************
3089 Open a named pipe to an SMB server and bind anonymously.
3090 ****************************************************************************/
3092 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
3093 enum dcerpc_transport_t transport
,
3094 const struct ndr_interface_table
*table
,
3095 struct rpc_pipe_client
**presult
)
3097 struct rpc_pipe_client
*result
;
3098 struct pipe_auth_data
*auth
;
3101 status
= cli_rpc_pipe_open(cli
, transport
, table
, &result
);
3102 if (!NT_STATUS_IS_OK(status
)) {
3106 status
= rpccli_anon_bind_data(result
, &auth
);
3107 if (!NT_STATUS_IS_OK(status
)) {
3108 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3109 nt_errstr(status
)));
3110 TALLOC_FREE(result
);
3115 * This is a bit of an abstraction violation due to the fact that an
3116 * anonymous bind on an authenticated SMB inherits the user/domain
3117 * from the enclosing SMB creds
3120 if (transport
== NCACN_NP
) {
3121 struct smbXcli_session
*session
;
3123 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
3124 session
= cli
->smb2
.session
;
3126 session
= cli
->smb1
.session
;
3129 status
= smbXcli_session_application_key(session
, auth
,
3130 &auth
->transport_session_key
);
3131 if (!NT_STATUS_IS_OK(status
)) {
3132 auth
->transport_session_key
= data_blob_null
;
3136 status
= rpc_pipe_bind(result
, auth
);
3137 if (!NT_STATUS_IS_OK(status
)) {
3139 if (ndr_syntax_id_equal(&table
->syntax_id
,
3140 &ndr_table_dssetup
.syntax_id
)) {
3141 /* non AD domains just don't have this pipe, avoid
3142 * level 0 statement in that case - gd */
3145 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3146 "%s failed with error %s\n",
3148 nt_errstr(status
) ));
3149 TALLOC_FREE(result
);
3153 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3154 "%s and bound anonymously.\n",
3159 return NT_STATUS_OK
;
3162 /****************************************************************************
3163 ****************************************************************************/
3165 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
3166 const struct ndr_interface_table
*table
,
3167 struct rpc_pipe_client
**presult
)
3169 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
3173 /****************************************************************************
3174 Open a named pipe to an SMB server and bind using the mech specified
3176 This routine references the creds pointer that is passed in
3177 ****************************************************************************/
3179 NTSTATUS
cli_rpc_pipe_open_with_creds(struct cli_state
*cli
,
3180 const struct ndr_interface_table
*table
,
3181 enum dcerpc_transport_t transport
,
3182 enum dcerpc_AuthType auth_type
,
3183 enum dcerpc_AuthLevel auth_level
,
3185 struct cli_credentials
*creds
,
3186 struct rpc_pipe_client
**presult
)
3188 struct rpc_pipe_client
*result
;
3189 struct pipe_auth_data
*auth
= NULL
;
3190 const char *target_service
= table
->authservices
->names
[0];
3193 status
= cli_rpc_pipe_open(cli
, transport
, table
, &result
);
3194 if (!NT_STATUS_IS_OK(status
)) {
3198 status
= rpccli_generic_bind_data_from_creds(result
,
3199 auth_type
, auth_level
,
3200 server
, target_service
,
3203 if (!NT_STATUS_IS_OK(status
)) {
3204 DBG_ERR("rpccli_generic_bind_data_from_creds returned %s\n",
3209 status
= rpc_pipe_bind(result
, auth
);
3210 if (!NT_STATUS_IS_OK(status
)) {
3211 DBG_ERR("cli_rpc_pipe_bind failed with error %s\n",
3216 DBG_DEBUG("opened pipe %s to machine %s and bound as user %s.\n",
3219 cli_credentials_get_unparsed_name(creds
, talloc_tos()));
3222 return NT_STATUS_OK
;
3226 TALLOC_FREE(result
);
3230 NTSTATUS
cli_rpc_pipe_open_bind_schannel(
3231 struct cli_state
*cli
,
3232 const struct ndr_interface_table
*table
,
3233 enum dcerpc_transport_t transport
,
3234 struct netlogon_creds_cli_context
*netlogon_creds
,
3235 struct rpc_pipe_client
**_rpccli
)
3237 struct rpc_pipe_client
*rpccli
;
3238 struct pipe_auth_data
*rpcauth
;
3239 const char *target_service
= table
->authservices
->names
[0];
3240 struct cli_credentials
*cli_creds
;
3241 enum dcerpc_AuthLevel auth_level
;
3244 status
= cli_rpc_pipe_open(cli
, transport
, table
, &rpccli
);
3245 if (!NT_STATUS_IS_OK(status
)) {
3249 auth_level
= netlogon_creds_cli_auth_level(netlogon_creds
);
3251 status
= netlogon_creds_bind_cli_credentials(
3252 netlogon_creds
, rpccli
, &cli_creds
);
3253 if (!NT_STATUS_IS_OK(status
)) {
3254 DBG_DEBUG("netlogon_creds_bind_cli_credentials failed: %s\n",
3256 TALLOC_FREE(rpccli
);
3260 status
= rpccli_generic_bind_data_from_creds(rpccli
,
3261 DCERPC_AUTH_TYPE_SCHANNEL
,
3267 if (!NT_STATUS_IS_OK(status
)) {
3268 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
3269 nt_errstr(status
)));
3270 TALLOC_FREE(rpccli
);
3274 status
= rpc_pipe_bind(rpccli
, rpcauth
);
3276 /* No TALLOC_FREE, gensec takes references */
3277 talloc_unlink(rpccli
, cli_creds
);
3280 if (!NT_STATUS_IS_OK(status
)) {
3281 DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
3283 TALLOC_FREE(rpccli
);
3289 return NT_STATUS_OK
;
3292 NTSTATUS
cli_rpc_pipe_open_schannel_with_creds(struct cli_state
*cli
,
3293 const struct ndr_interface_table
*table
,
3294 enum dcerpc_transport_t transport
,
3295 struct netlogon_creds_cli_context
*netlogon_creds
,
3296 struct rpc_pipe_client
**_rpccli
)
3298 TALLOC_CTX
*frame
= talloc_stackframe();
3299 struct rpc_pipe_client
*rpccli
;
3300 struct netlogon_creds_cli_lck
*lck
;
3303 status
= netlogon_creds_cli_lck(
3304 netlogon_creds
, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE
,
3306 if (!NT_STATUS_IS_OK(status
)) {
3307 DBG_WARNING("netlogon_creds_cli_lck returned %s\n",
3313 status
= cli_rpc_pipe_open_bind_schannel(
3314 cli
, table
, transport
, netlogon_creds
, &rpccli
);
3315 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3316 netlogon_creds_cli_delete_lck(netlogon_creds
);
3318 if (!NT_STATUS_IS_OK(status
)) {
3319 DBG_DEBUG("cli_rpc_pipe_open_bind_schannel failed: %s\n",
3325 if (ndr_syntax_id_equal(&table
->syntax_id
,
3326 &ndr_table_netlogon
.syntax_id
)) {
3327 status
= netlogon_creds_cli_check(netlogon_creds
,
3328 rpccli
->binding_handle
,
3330 if (!NT_STATUS_IS_OK(status
)) {
3331 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3332 nt_errstr(status
)));
3338 DBG_DEBUG("opened pipe %s to machine %s with key %s "
3339 "and bound using schannel.\n",
3340 table
->name
, rpccli
->desthost
,
3341 netlogon_creds_cli_debug_string(netlogon_creds
, lck
));
3346 return NT_STATUS_OK
;
3349 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
3350 struct rpc_pipe_client
*cli
,
3351 DATA_BLOB
*session_key
)
3354 struct pipe_auth_data
*a
;
3355 struct gensec_security
*gensec_security
;
3356 DATA_BLOB sk
= data_blob_null
;
3357 bool make_dup
= false;
3359 if (!session_key
|| !cli
) {
3360 return NT_STATUS_INVALID_PARAMETER
;
3366 return NT_STATUS_INVALID_PARAMETER
;
3369 switch (cli
->auth
->auth_type
) {
3370 case DCERPC_AUTH_TYPE_NONE
:
3371 sk
= data_blob_const(a
->transport_session_key
.data
,
3372 a
->transport_session_key
.length
);
3376 gensec_security
= a
->auth_ctx
;
3377 status
= gensec_session_key(gensec_security
, mem_ctx
, &sk
);
3378 if (!NT_STATUS_IS_OK(status
)) {
3386 return NT_STATUS_NO_USER_SESSION_KEY
;
3390 *session_key
= data_blob_dup_talloc(mem_ctx
, sk
);
3395 return NT_STATUS_OK
;