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/gen_ndr/auth.h"
33 #include "librpc/rpc/dcerpc.h"
34 #include "librpc/rpc/dcerpc_util.h"
37 #include "libsmb/libsmb.h"
38 #include "auth/gensec/gensec.h"
39 #include "auth/credentials/credentials.h"
40 #include "auth/auth_util.h"
41 #include "../libcli/smb/smbXcli_base.h"
42 #include "lib/tsocket/tsocket.h"
43 #include "libcli/named_pipe_auth/npa_tstream.h"
44 #include "librpc/gen_ndr/ndr_winreg.h"
48 #define DBGC_CLASS DBGC_RPC_CLI
50 /********************************************************************
51 Pipe description for a DEBUG
52 ********************************************************************/
53 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
54 struct rpc_pipe_client
*cli
)
56 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
63 /********************************************************************
65 ********************************************************************/
67 static uint32_t get_rpc_call_id(void)
69 static uint32_t call_id
= 0;
73 /*******************************************************************
74 Use SMBreadX to get rest of one fragment's worth of rpc data.
75 Reads the whole size or give an error message
76 ********************************************************************/
78 struct rpc_read_state
{
79 struct tevent_context
*ev
;
80 struct rpc_cli_transport
*transport
;
86 static void rpc_read_done(struct tevent_req
*subreq
);
88 static struct tevent_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
89 struct tevent_context
*ev
,
90 struct rpc_cli_transport
*transport
,
91 uint8_t *data
, size_t size
)
93 struct tevent_req
*req
, *subreq
;
94 struct rpc_read_state
*state
;
96 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_read_state
);
101 state
->transport
= transport
;
106 DBG_INFO("data_to_read: %zu\n", size
);
108 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
110 if (subreq
== NULL
) {
113 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
121 static void rpc_read_done(struct tevent_req
*subreq
)
123 struct tevent_req
*req
= tevent_req_callback_data(
124 subreq
, struct tevent_req
);
125 struct rpc_read_state
*state
= tevent_req_data(
126 req
, struct rpc_read_state
);
130 status
= state
->transport
->read_recv(subreq
, &received
);
132 if (tevent_req_nterror(req
, status
)) {
136 state
->num_read
+= received
;
137 if (state
->num_read
== state
->size
) {
138 tevent_req_done(req
);
142 subreq
= state
->transport
->read_send(state
, state
->ev
,
143 state
->data
+ state
->num_read
,
144 state
->size
- state
->num_read
,
145 state
->transport
->priv
);
146 if (tevent_req_nomem(subreq
, req
)) {
149 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
152 static NTSTATUS
rpc_read_recv(struct tevent_req
*req
)
154 return tevent_req_simple_recv_ntstatus(req
);
157 struct rpc_write_state
{
158 struct tevent_context
*ev
;
159 struct rpc_cli_transport
*transport
;
165 static void rpc_write_done(struct tevent_req
*subreq
);
167 static struct tevent_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
168 struct tevent_context
*ev
,
169 struct rpc_cli_transport
*transport
,
170 const uint8_t *data
, size_t size
)
172 struct tevent_req
*req
, *subreq
;
173 struct rpc_write_state
*state
;
175 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_write_state
);
180 state
->transport
= transport
;
183 state
->num_written
= 0;
185 DBG_INFO("data_to_write: %zu\n", size
);
187 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
188 if (tevent_req_nomem(subreq
, req
)) {
189 return tevent_req_post(req
, ev
);
191 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
195 static void rpc_write_done(struct tevent_req
*subreq
)
197 struct tevent_req
*req
= tevent_req_callback_data(
198 subreq
, struct tevent_req
);
199 struct rpc_write_state
*state
= tevent_req_data(
200 req
, struct rpc_write_state
);
204 status
= state
->transport
->write_recv(subreq
, &written
);
206 if (tevent_req_nterror(req
, status
)) {
210 state
->num_written
+= written
;
212 if (state
->num_written
== state
->size
) {
213 tevent_req_done(req
);
217 subreq
= state
->transport
->write_send(state
, state
->ev
,
218 state
->data
+ state
->num_written
,
219 state
->size
- state
->num_written
,
220 state
->transport
->priv
);
221 if (tevent_req_nomem(subreq
, req
)) {
224 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
227 static NTSTATUS
rpc_write_recv(struct tevent_req
*req
)
229 return tevent_req_simple_recv_ntstatus(req
);
233 /****************************************************************************
234 Try and get a PDU's worth of data from current_pdu. If not, then read more
236 ****************************************************************************/
238 struct get_complete_frag_state
{
239 struct tevent_context
*ev
;
240 struct rpc_pipe_client
*cli
;
245 static void get_complete_frag_got_header(struct tevent_req
*subreq
);
246 static void get_complete_frag_got_rest(struct tevent_req
*subreq
);
248 static struct tevent_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
249 struct tevent_context
*ev
,
250 struct rpc_pipe_client
*cli
,
253 struct tevent_req
*req
, *subreq
;
254 struct get_complete_frag_state
*state
;
257 req
= tevent_req_create(mem_ctx
, &state
,
258 struct get_complete_frag_state
);
264 state
->frag_len
= RPC_HEADER_LEN
;
267 received
= pdu
->length
;
268 if (received
< RPC_HEADER_LEN
) {
269 if (!data_blob_realloc(mem_ctx
, pdu
, RPC_HEADER_LEN
)) {
271 return tevent_req_post(req
, ev
);
273 subreq
= rpc_read_send(state
, state
->ev
,
274 state
->cli
->transport
,
275 pdu
->data
+ received
,
276 RPC_HEADER_LEN
- received
);
277 if (tevent_req_nomem(subreq
, req
)) {
278 return tevent_req_post(req
, ev
);
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
);
291 if (received
>= state
->frag_len
) {
293 * Got the whole fragment
295 tevent_req_done(req
);
296 return tevent_req_post(req
, ev
);
299 if (!data_blob_realloc(NULL
, pdu
, state
->frag_len
)) {
301 return tevent_req_post(req
, ev
);
304 subreq
= rpc_read_send(
307 state
->cli
->transport
,
308 pdu
->data
+ received
,
309 state
->frag_len
- received
);
310 if (tevent_req_nomem(subreq
, req
)) {
311 return tevent_req_post(req
, ev
);
313 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
317 static void get_complete_frag_got_header(struct tevent_req
*subreq
)
319 struct tevent_req
*req
= tevent_req_callback_data(
320 subreq
, struct tevent_req
);
321 struct get_complete_frag_state
*state
= tevent_req_data(
322 req
, struct get_complete_frag_state
);
325 status
= rpc_read_recv(subreq
);
327 if (tevent_req_nterror(req
, status
)) {
331 state
->frag_len
= dcerpc_get_frag_length(state
->pdu
);
332 if (state
->frag_len
< RPC_HEADER_LEN
) {
333 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
337 if (!data_blob_realloc(NULL
, state
->pdu
, state
->frag_len
)) {
343 * We're here in this piece of code because we've read exactly
344 * RPC_HEADER_LEN bytes into state->pdu.
347 subreq
= rpc_read_send(state
, state
->ev
, state
->cli
->transport
,
348 state
->pdu
->data
+ RPC_HEADER_LEN
,
349 state
->frag_len
- RPC_HEADER_LEN
);
350 if (tevent_req_nomem(subreq
, req
)) {
353 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
356 static void get_complete_frag_got_rest(struct tevent_req
*subreq
)
358 NTSTATUS status
= rpc_read_recv(subreq
);
359 return tevent_req_simple_finish_ntstatus(subreq
, status
);
362 static NTSTATUS
get_complete_frag_recv(struct tevent_req
*req
)
364 return tevent_req_simple_recv_ntstatus(req
);
367 /****************************************************************************
368 Do basic authentication checks on an incoming pdu.
369 ****************************************************************************/
371 static NTSTATUS
cli_pipe_validate_current_pdu(TALLOC_CTX
*mem_ctx
,
372 struct rpc_pipe_client
*cli
,
373 struct ncacn_packet
*pkt
,
375 uint8_t expected_pkt_type
,
378 DATA_BLOB
*reply_pdu
)
380 const struct dcerpc_response
*r
= NULL
;
381 DATA_BLOB tmp_stub
= { .data
= NULL
};
385 * Point the return values at the real data including the RPC
386 * header. Just in case the caller wants it.
390 if ((pkt
->ptype
== DCERPC_PKT_BIND_ACK
) &&
391 !(pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
393 * TODO: do we still need this hack which was introduced
394 * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
396 * I don't even know what AS/U might be...
398 DEBUG(5, (__location__
": bug in server (AS/U?), setting "
399 "fragment first/last ON.\n"));
400 pkt
->pfc_flags
|= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
403 /* Ensure we have the correct type. */
404 switch (pkt
->ptype
) {
405 case DCERPC_PKT_BIND_NAK
:
406 DEBUG(1, (__location__
": Bind NACK received from %s!\n",
407 rpccli_pipe_txt(talloc_tos(), cli
)));
409 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
411 0, /* max_auth_info */
412 DCERPC_PFC_FLAG_FIRST
|
413 DCERPC_PFC_FLAG_LAST
,
414 0); /* optional flags */
415 if (!NT_STATUS_IS_OK(ret
)) {
416 DEBUG(1, (__location__
": Connection to %s got an unexpected "
417 "RPC packet type - %u, expected %u: %s\n",
418 rpccli_pipe_txt(talloc_tos(), cli
),
419 pkt
->ptype
, expected_pkt_type
,
421 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
425 /* Use this for now... */
426 return NT_STATUS_NETWORK_ACCESS_DENIED
;
428 case DCERPC_PKT_BIND_ACK
:
429 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
431 pkt
->u
.bind_ack
.auth_info
.length
,
432 DCERPC_PFC_FLAG_FIRST
|
433 DCERPC_PFC_FLAG_LAST
,
434 DCERPC_PFC_FLAG_CONC_MPX
|
435 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
436 if (!NT_STATUS_IS_OK(ret
)) {
437 DEBUG(1, (__location__
": Connection to %s got an unexpected "
438 "RPC packet type - %u, expected %u: %s\n",
439 rpccli_pipe_txt(talloc_tos(), cli
),
440 pkt
->ptype
, expected_pkt_type
,
442 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
448 case DCERPC_PKT_ALTER_RESP
:
449 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
451 pkt
->u
.alter_resp
.auth_info
.length
,
452 DCERPC_PFC_FLAG_FIRST
|
453 DCERPC_PFC_FLAG_LAST
,
454 DCERPC_PFC_FLAG_CONC_MPX
|
455 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
456 if (!NT_STATUS_IS_OK(ret
)) {
457 DEBUG(1, (__location__
": Connection to %s got an unexpected "
458 "RPC packet type - %u, expected %u: %s\n",
459 rpccli_pipe_txt(talloc_tos(), cli
),
460 pkt
->ptype
, expected_pkt_type
,
462 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
468 case DCERPC_PKT_RESPONSE
:
470 r
= &pkt
->u
.response
;
472 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
474 r
->stub_and_verifier
.length
,
475 0, /* required_flags */
476 DCERPC_PFC_FLAG_FIRST
|
477 DCERPC_PFC_FLAG_LAST
);
478 if (!NT_STATUS_IS_OK(ret
)) {
479 DEBUG(1, (__location__
": Connection to %s got an unexpected "
480 "RPC packet type - %u, expected %u: %s\n",
481 rpccli_pipe_txt(talloc_tos(), cli
),
482 pkt
->ptype
, expected_pkt_type
,
484 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
488 tmp_stub
.data
= r
->stub_and_verifier
.data
;
489 tmp_stub
.length
= r
->stub_and_verifier
.length
;
491 /* Here's where we deal with incoming sign/seal. */
492 ret
= dcerpc_check_auth(cli
->auth
, pkt
,
494 DCERPC_RESPONSE_LENGTH
,
496 if (!NT_STATUS_IS_OK(ret
)) {
497 DEBUG(1, (__location__
": Connection to %s got an unexpected "
498 "RPC packet type - %u, expected %u: %s\n",
499 rpccli_pipe_txt(talloc_tos(), cli
),
500 pkt
->ptype
, expected_pkt_type
,
502 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
506 /* Point the return values at the NDR data. */
509 DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
510 (long unsigned int)pdu
->length
,
511 (long unsigned int)rdata
->length
));
514 * If this is the first reply, and the allocation hint is
515 * reasonable, try and set up the reply_pdu DATA_BLOB to the
519 if ((reply_pdu
->length
== 0) &&
520 r
->alloc_hint
&& (r
->alloc_hint
< 15*1024*1024)) {
521 if (!data_blob_realloc(mem_ctx
, reply_pdu
,
523 DEBUG(0, ("reply alloc hint %d too "
524 "large to allocate\n",
525 (int)r
->alloc_hint
));
526 return NT_STATUS_NO_MEMORY
;
532 case DCERPC_PKT_FAULT
:
534 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
536 0, /* max_auth_info */
537 DCERPC_PFC_FLAG_FIRST
|
538 DCERPC_PFC_FLAG_LAST
,
539 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
540 if (!NT_STATUS_IS_OK(ret
)) {
541 DEBUG(1, (__location__
": Connection to %s got an unexpected "
542 "RPC packet type - %u, expected %u: %s\n",
543 rpccli_pipe_txt(talloc_tos(), cli
),
544 pkt
->ptype
, expected_pkt_type
,
546 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
550 DEBUG(1, (__location__
": RPC fault code %s received "
552 dcerpc_errstr(talloc_tos(),
553 pkt
->u
.fault
.status
),
554 rpccli_pipe_txt(talloc_tos(), cli
)));
556 return dcerpc_fault_to_nt_status(pkt
->u
.fault
.status
);
559 DEBUG(0, (__location__
"Unknown packet type %u received "
561 (unsigned int)pkt
->ptype
,
562 rpccli_pipe_txt(talloc_tos(), cli
)));
563 return NT_STATUS_RPC_PROTOCOL_ERROR
;
567 if (pkt
->call_id
!= call_id
) {
568 DEBUG(3, (__location__
": Connection to %s got an unexpected "
569 "RPC call_id - %u, not %u\n",
570 rpccli_pipe_txt(talloc_tos(), cli
),
571 pkt
->call_id
, call_id
));
572 return NT_STATUS_RPC_PROTOCOL_ERROR
;
578 /****************************************************************************
579 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
580 ****************************************************************************/
582 struct cli_api_pipe_state
{
583 struct tevent_context
*ev
;
584 struct rpc_cli_transport
*transport
;
589 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
);
590 static void cli_api_pipe_write_done(struct tevent_req
*subreq
);
591 static void cli_api_pipe_read_done(struct tevent_req
*subreq
);
593 static struct tevent_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
594 struct tevent_context
*ev
,
595 struct rpc_cli_transport
*transport
,
596 uint8_t *data
, size_t data_len
,
597 uint32_t max_rdata_len
)
599 struct tevent_req
*req
, *subreq
;
600 struct cli_api_pipe_state
*state
;
602 req
= tevent_req_create(mem_ctx
, &state
, struct cli_api_pipe_state
);
607 state
->transport
= transport
;
609 if (max_rdata_len
< RPC_HEADER_LEN
) {
611 * For a RPC reply we always need at least RPC_HEADER_LEN
612 * bytes. We check this here because we will receive
613 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
615 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
616 return tevent_req_post(req
, ev
);
619 if (transport
->trans_send
!= NULL
) {
620 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
621 max_rdata_len
, transport
->priv
);
622 if (tevent_req_nomem(subreq
, req
)) {
623 return tevent_req_post(req
, ev
);
625 tevent_req_set_callback(subreq
, cli_api_pipe_trans_done
, req
);
630 * If the transport does not provide a "trans" routine, i.e. for
631 * example the ncacn_ip_tcp transport, do the write/read step here.
634 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
635 if (tevent_req_nomem(subreq
, req
)) {
636 return tevent_req_post(req
, ev
);
638 tevent_req_set_callback(subreq
, cli_api_pipe_write_done
, req
);
642 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
)
644 struct tevent_req
*req
= tevent_req_callback_data(
645 subreq
, struct tevent_req
);
646 struct cli_api_pipe_state
*state
= tevent_req_data(
647 req
, struct cli_api_pipe_state
);
650 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
653 if (tevent_req_nterror(req
, status
)) {
656 tevent_req_done(req
);
659 static void cli_api_pipe_write_done(struct tevent_req
*subreq
)
661 struct tevent_req
*req
= tevent_req_callback_data(
662 subreq
, struct tevent_req
);
663 struct cli_api_pipe_state
*state
= tevent_req_data(
664 req
, struct cli_api_pipe_state
);
667 status
= rpc_write_recv(subreq
);
669 if (tevent_req_nterror(req
, status
)) {
673 state
->rdata
= talloc_array(state
, uint8_t, RPC_HEADER_LEN
);
674 if (tevent_req_nomem(state
->rdata
, req
)) {
679 * We don't need to use rpc_read_send here, the upper layer will cope
680 * with a short read, transport->trans_send could also return less
681 * than state->max_rdata_len.
683 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
685 state
->transport
->priv
);
686 if (tevent_req_nomem(subreq
, req
)) {
689 tevent_req_set_callback(subreq
, cli_api_pipe_read_done
, req
);
692 static void cli_api_pipe_read_done(struct tevent_req
*subreq
)
694 struct tevent_req
*req
= tevent_req_callback_data(
695 subreq
, struct tevent_req
);
696 struct cli_api_pipe_state
*state
= tevent_req_data(
697 req
, struct cli_api_pipe_state
);
701 status
= state
->transport
->read_recv(subreq
, &received
);
703 if (tevent_req_nterror(req
, status
)) {
706 state
->rdata_len
= received
;
707 tevent_req_done(req
);
710 static NTSTATUS
cli_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
711 uint8_t **prdata
, uint32_t *prdata_len
)
713 struct cli_api_pipe_state
*state
= tevent_req_data(
714 req
, struct cli_api_pipe_state
);
717 if (tevent_req_is_nterror(req
, &status
)) {
721 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
722 *prdata_len
= state
->rdata_len
;
726 /****************************************************************************
727 Send data on an rpc pipe via trans. The data must be the last
728 pdu fragment of an NDR data stream.
730 Receive response data from an rpc pipe, which may be large...
732 Read the first fragment: unfortunately have to use SMBtrans for the first
733 bit, then SMBreadX for subsequent bits.
735 If first fragment received also wasn't the last fragment, continue
736 getting fragments until we _do_ receive the last fragment.
738 Request/Response PDU's look like the following...
740 |<------------------PDU len----------------------------------------------->|
741 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
743 +------------+-----------------+-------------+---------------+-------------+
744 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
745 +------------+-----------------+-------------+---------------+-------------+
747 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
748 signing & sealing being negotiated.
750 ****************************************************************************/
752 struct rpc_api_pipe_state
{
753 struct tevent_context
*ev
;
754 struct rpc_pipe_client
*cli
;
755 uint8_t expected_pkt_type
;
758 DATA_BLOB incoming_frag
;
759 struct ncacn_packet
*pkt
;
763 size_t reply_pdu_offset
;
767 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
);
768 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
);
769 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
);
771 static struct tevent_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
772 struct tevent_context
*ev
,
773 struct rpc_pipe_client
*cli
,
774 DATA_BLOB
*data
, /* Outgoing PDU */
775 uint8_t expected_pkt_type
,
778 struct tevent_req
*req
, *subreq
;
779 struct rpc_api_pipe_state
*state
;
780 uint16_t max_recv_frag
;
782 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_api_pipe_state
);
788 state
->expected_pkt_type
= expected_pkt_type
;
789 state
->call_id
= call_id
;
790 state
->endianness
= DCERPC_DREP_LE
;
793 * Ensure we're not sending too much.
795 if (data
->length
> cli
->max_xmit_frag
) {
796 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
797 return tevent_req_post(req
, ev
);
800 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli
)));
802 if (state
->expected_pkt_type
== DCERPC_PKT_AUTH3
) {
803 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
804 data
->data
, data
->length
);
805 if (tevent_req_nomem(subreq
, req
)) {
806 return tevent_req_post(req
, ev
);
808 tevent_req_set_callback(subreq
, rpc_api_pipe_auth3_done
, req
);
812 /* get the header first, then fetch the rest once we have
813 * the frag_length available */
814 max_recv_frag
= RPC_HEADER_LEN
;
816 subreq
= cli_api_pipe_send(state
, ev
, cli
->transport
,
817 data
->data
, data
->length
, max_recv_frag
);
818 if (tevent_req_nomem(subreq
, req
)) {
819 return tevent_req_post(req
, ev
);
821 tevent_req_set_callback(subreq
, rpc_api_pipe_trans_done
, req
);
825 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
)
827 NTSTATUS status
= rpc_write_recv(subreq
);
828 return tevent_req_simple_finish_ntstatus(subreq
, status
);
831 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
)
833 struct tevent_req
*req
= tevent_req_callback_data(
834 subreq
, struct tevent_req
);
835 struct rpc_api_pipe_state
*state
= tevent_req_data(
836 req
, struct rpc_api_pipe_state
);
838 uint8_t *rdata
= NULL
;
839 uint32_t rdata_len
= 0;
841 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
843 if (tevent_req_nterror(req
, status
)) {;
844 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
849 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
850 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
851 tevent_req_done(req
);
856 * Move data on state->incoming_frag.
858 state
->incoming_frag
.data
= talloc_move(state
, &rdata
);
859 state
->incoming_frag
.length
= rdata_len
;
860 if (!state
->incoming_frag
.data
) {
861 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
865 /* Ensure we have enough data for a pdu. */
866 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
867 &state
->incoming_frag
);
868 if (tevent_req_nomem(subreq
, req
)) {
871 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
874 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
)
876 struct tevent_req
*req
= tevent_req_callback_data(
877 subreq
, struct tevent_req
);
878 struct rpc_api_pipe_state
*state
= tevent_req_data(
879 req
, struct rpc_api_pipe_state
);
881 DATA_BLOB rdata
= { .data
= NULL
};
883 status
= get_complete_frag_recv(subreq
);
885 if (tevent_req_nterror(req
, status
)) {
886 DEBUG(5, ("get_complete_frag failed: %s\n",
891 state
->pkt
= talloc(state
, struct ncacn_packet
);
894 * TODO: do a real async disconnect ...
896 * For now do it sync...
898 TALLOC_FREE(state
->cli
->transport
);
903 status
= dcerpc_pull_ncacn_packet(state
->pkt
,
904 &state
->incoming_frag
,
906 if (tevent_req_nterror(req
, status
)) {
908 * TODO: do a real async disconnect ...
910 * For now do it sync...
912 TALLOC_FREE(state
->cli
->transport
);
916 if (DEBUGLEVEL
>= 10) {
917 NDR_PRINT_DEBUG(ncacn_packet
, state
->pkt
);
920 status
= cli_pipe_validate_current_pdu(state
,
921 state
->cli
, state
->pkt
,
922 &state
->incoming_frag
,
923 state
->expected_pkt_type
,
928 DBG_DEBUG("got frag len of %zu at offset %zu: %s\n",
929 state
->incoming_frag
.length
,
930 state
->reply_pdu_offset
,
933 if (state
->pkt
->ptype
!= DCERPC_PKT_FAULT
&& !NT_STATUS_IS_OK(status
)) {
935 * TODO: do a real async disconnect ...
937 * For now do it sync...
939 TALLOC_FREE(state
->cli
->transport
);
940 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
942 * TODO: do a real async disconnect ...
944 * For now do it sync...
946 TALLOC_FREE(state
->cli
->transport
);
947 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
)) {
949 * TODO: do a real async disconnect ...
951 * For now do it sync...
953 TALLOC_FREE(state
->cli
->transport
);
955 if (tevent_req_nterror(req
, status
)) {
959 if ((state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_FIRST
)
960 && (state
->pkt
->drep
[0] != DCERPC_DREP_LE
)) {
962 * Set the data type correctly for big-endian data on the
965 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
967 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
968 state
->endianness
= 0x00; /* BIG ENDIAN */
971 * Check endianness on subsequent packets.
973 if (state
->endianness
!= state
->pkt
->drep
[0]) {
974 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
976 state
->endianness
?"little":"big",
977 state
->pkt
->drep
[0]?"little":"big"));
979 * TODO: do a real async disconnect ...
981 * For now do it sync...
983 TALLOC_FREE(state
->cli
->transport
);
984 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
988 if (state
->reply_pdu_offset
+ rdata
.length
> MAX_RPC_DATA_SIZE
) {
990 * TODO: do a real async disconnect ...
992 * For now do it sync...
994 TALLOC_FREE(state
->cli
->transport
);
995 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
999 /* Now copy the data portion out of the pdu into rbuf. */
1000 if (state
->reply_pdu
.length
< state
->reply_pdu_offset
+ rdata
.length
) {
1001 if (!data_blob_realloc(NULL
, &state
->reply_pdu
,
1002 state
->reply_pdu_offset
+ rdata
.length
)) {
1004 * TODO: do a real async disconnect ...
1006 * For now do it sync...
1008 TALLOC_FREE(state
->cli
->transport
);
1009 tevent_req_oom(req
);
1014 memcpy(state
->reply_pdu
.data
+ state
->reply_pdu_offset
,
1015 rdata
.data
, rdata
.length
);
1016 state
->reply_pdu_offset
+= rdata
.length
;
1018 /* reset state->incoming_frag, there is no need to free it,
1019 * it will be reallocated to the right size the next time
1021 state
->incoming_frag
.length
= 0;
1023 if (state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
) {
1024 /* make sure the pdu length is right now that we
1025 * have all the data available (alloc hint may
1026 * have allocated more than was actually used) */
1027 state
->reply_pdu
.length
= state
->reply_pdu_offset
;
1028 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1029 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1030 (unsigned)state
->reply_pdu
.length
));
1031 tevent_req_done(req
);
1035 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1036 &state
->incoming_frag
);
1037 if (subreq
== NULL
) {
1039 * TODO: do a real async disconnect ...
1041 * For now do it sync...
1043 TALLOC_FREE(state
->cli
->transport
);
1045 if (tevent_req_nomem(subreq
, req
)) {
1048 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1051 static NTSTATUS
rpc_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1052 struct ncacn_packet
**pkt
,
1053 DATA_BLOB
*reply_pdu
)
1055 struct rpc_api_pipe_state
*state
= tevent_req_data(
1056 req
, struct rpc_api_pipe_state
);
1059 if (tevent_req_is_nterror(req
, &status
)) {
1063 /* return data to caller and assign it ownership of memory */
1065 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1066 reply_pdu
->length
= state
->reply_pdu
.length
;
1067 state
->reply_pdu
.length
= 0;
1069 data_blob_free(&state
->reply_pdu
);
1073 *pkt
= talloc_steal(mem_ctx
, state
->pkt
);
1076 return NT_STATUS_OK
;
1079 /*******************************************************************
1080 Creates NTLMSSP auth bind.
1081 ********************************************************************/
1083 static NTSTATUS
create_generic_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1084 TALLOC_CTX
*mem_ctx
,
1085 DATA_BLOB
*auth_token
,
1086 bool *client_hdr_signing
)
1088 struct gensec_security
*gensec_security
;
1089 DATA_BLOB null_blob
= { .data
= NULL
};
1092 gensec_security
= cli
->auth
->auth_ctx
;
1094 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1095 status
= gensec_update(gensec_security
, mem_ctx
, null_blob
, auth_token
);
1097 if (!NT_STATUS_IS_OK(status
) &&
1098 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1103 if (client_hdr_signing
== NULL
) {
1107 if (cli
->auth
->auth_level
< DCERPC_AUTH_LEVEL_PACKET
) {
1108 *client_hdr_signing
= false;
1112 *client_hdr_signing
= gensec_have_feature(gensec_security
,
1113 GENSEC_FEATURE_SIGN_PKT_HEADER
);
1118 /*******************************************************************
1119 Creates the internals of a DCE/RPC bind request or alter context PDU.
1120 ********************************************************************/
1122 static NTSTATUS
create_bind_or_alt_ctx_internal(TALLOC_CTX
*mem_ctx
,
1123 enum dcerpc_pkt_type ptype
,
1124 uint32_t rpc_call_id
,
1125 const struct ndr_syntax_id
*abstract
,
1126 const struct ndr_syntax_id
*transfer
,
1127 const DATA_BLOB
*auth_info
,
1128 bool client_hdr_signing
,
1131 uint16_t auth_len
= auth_info
->length
;
1133 struct dcerpc_ctx_list ctx_list
= {
1135 .num_transfer_syntaxes
= 1,
1136 .abstract_syntax
= *abstract
,
1137 .transfer_syntaxes
= (struct ndr_syntax_id
*)discard_const(transfer
),
1139 union dcerpc_payload u
= {
1140 .bind
.max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
,
1141 .bind
.max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
,
1142 .bind
.num_contexts
= 1,
1143 .bind
.ctx_list
= &ctx_list
,
1144 .bind
.auth_info
= *auth_info
,
1146 uint8_t pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
1149 auth_len
-= DCERPC_AUTH_TRAILER_LENGTH
;
1152 if (client_hdr_signing
) {
1153 pfc_flags
|= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
;
1156 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1162 if (!NT_STATUS_IS_OK(status
)) {
1163 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1167 return NT_STATUS_OK
;
1170 /*******************************************************************
1171 Creates a DCE/RPC bind request.
1172 ********************************************************************/
1174 static NTSTATUS
create_rpc_bind_req(TALLOC_CTX
*mem_ctx
,
1175 struct rpc_pipe_client
*cli
,
1176 struct pipe_auth_data
*auth
,
1177 uint32_t rpc_call_id
,
1178 const struct ndr_syntax_id
*abstract
,
1179 const struct ndr_syntax_id
*transfer
,
1182 DATA_BLOB auth_token
= { .data
= NULL
};
1183 DATA_BLOB auth_info
= { .data
= NULL
};
1186 if (auth
->auth_type
!= DCERPC_AUTH_TYPE_NONE
) {
1187 ret
= create_generic_auth_rpc_bind_req(
1188 cli
, mem_ctx
, &auth_token
, &auth
->client_hdr_signing
);
1190 if (!NT_STATUS_IS_OK(ret
) &&
1191 !NT_STATUS_EQUAL(ret
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1196 if (auth_token
.length
!= 0) {
1197 ret
= dcerpc_push_dcerpc_auth(cli
,
1200 0, /* auth_pad_length */
1201 auth
->auth_context_id
,
1204 if (!NT_STATUS_IS_OK(ret
)) {
1207 data_blob_free(&auth_token
);
1210 ret
= create_bind_or_alt_ctx_internal(mem_ctx
,
1216 auth
->client_hdr_signing
,
1218 data_blob_free(&auth_info
);
1223 /*******************************************************************
1225 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1226 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1227 and deals with signing/sealing details.
1228 ********************************************************************/
1230 struct rpc_api_pipe_req_state
{
1231 struct tevent_context
*ev
;
1232 struct rpc_pipe_client
*cli
;
1235 const DATA_BLOB
*req_data
;
1236 const struct GUID
*object_uuid
;
1237 uint32_t req_data_sent
;
1238 DATA_BLOB req_trailer
;
1239 uint32_t req_trailer_sent
;
1240 bool verify_bitmask1
;
1241 bool verify_pcontext
;
1243 DATA_BLOB reply_pdu
;
1246 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
1247 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
1248 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
);
1249 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1250 bool *is_last_frag
);
1252 static struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
1253 struct tevent_context
*ev
,
1254 struct rpc_pipe_client
*cli
,
1256 const struct GUID
*object_uuid
,
1257 const DATA_BLOB
*req_data
)
1259 struct tevent_req
*req
, *subreq
;
1260 struct rpc_api_pipe_req_state
*state
;
1264 req
= tevent_req_create(mem_ctx
, &state
,
1265 struct rpc_api_pipe_req_state
);
1271 state
->op_num
= op_num
;
1272 state
->object_uuid
= object_uuid
;
1273 state
->req_data
= req_data
;
1274 state
->call_id
= get_rpc_call_id();
1276 if (cli
->max_xmit_frag
< DCERPC_REQUEST_LENGTH
1277 + RPC_MAX_SIGN_SIZE
) {
1278 /* Server is screwed up ! */
1279 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1280 return tevent_req_post(req
, ev
);
1283 status
= prepare_verification_trailer(state
);
1284 if (tevent_req_nterror(req
, status
)) {
1285 return tevent_req_post(req
, ev
);
1288 status
= prepare_next_frag(state
, &is_last_frag
);
1289 if (tevent_req_nterror(req
, status
)) {
1290 return tevent_req_post(req
, ev
);
1294 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
1296 DCERPC_PKT_RESPONSE
,
1298 if (tevent_req_nomem(subreq
, req
)) {
1299 return tevent_req_post(req
, ev
);
1301 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1303 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
1304 state
->rpc_out
.data
,
1305 state
->rpc_out
.length
);
1306 if (tevent_req_nomem(subreq
, req
)) {
1307 return tevent_req_post(req
, ev
);
1309 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1315 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
)
1317 struct pipe_auth_data
*a
= state
->cli
->auth
;
1318 struct dcerpc_sec_verification_trailer
*t
;
1319 struct ndr_push
*ndr
= NULL
;
1320 enum ndr_err_code ndr_err
;
1325 return NT_STATUS_OK
;
1328 if (a
->auth_level
< DCERPC_AUTH_LEVEL_PACKET
) {
1329 return NT_STATUS_OK
;
1332 t
= talloc_zero(state
, struct dcerpc_sec_verification_trailer
);
1334 return NT_STATUS_NO_MEMORY
;
1337 if (!a
->verified_bitmask1
) {
1338 t
->commands
= talloc_realloc(t
, t
->commands
,
1339 struct dcerpc_sec_vt
,
1340 t
->count
.count
+ 1);
1341 if (t
->commands
== NULL
) {
1342 return NT_STATUS_NO_MEMORY
;
1344 t
->commands
[t
->count
.count
++] = (struct dcerpc_sec_vt
) {
1345 .command
= DCERPC_SEC_VT_COMMAND_BITMASK1
,
1346 .u
.bitmask1
= (a
->client_hdr_signing
) ?
1347 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING
:
1350 state
->verify_bitmask1
= true;
1353 if (!state
->cli
->verified_pcontext
) {
1354 t
->commands
= talloc_realloc(t
, t
->commands
,
1355 struct dcerpc_sec_vt
,
1356 t
->count
.count
+ 1);
1357 if (t
->commands
== NULL
) {
1358 return NT_STATUS_NO_MEMORY
;
1360 t
->commands
[t
->count
.count
++] = (struct dcerpc_sec_vt
) {
1361 .command
= DCERPC_SEC_VT_COMMAND_PCONTEXT
,
1362 .u
.pcontext
.abstract_syntax
=
1363 state
->cli
->abstract_syntax
,
1364 .u
.pcontext
.transfer_syntax
=
1365 state
->cli
->transfer_syntax
,
1367 state
->verify_pcontext
= true;
1370 if (!a
->hdr_signing
) {
1371 t
->commands
= talloc_realloc(t
, t
->commands
,
1372 struct dcerpc_sec_vt
,
1373 t
->count
.count
+ 1);
1374 if (t
->commands
== NULL
) {
1375 return NT_STATUS_NO_MEMORY
;
1377 t
->commands
[t
->count
.count
++] = (struct dcerpc_sec_vt
) {
1378 .command
= DCERPC_SEC_VT_COMMAND_HEADER2
,
1379 .u
.header2
.ptype
= DCERPC_PKT_REQUEST
,
1380 .u
.header2
.drep
[0] = DCERPC_DREP_LE
,
1381 .u
.header2
.call_id
= state
->call_id
,
1382 .u
.header2
.context_id
= 0,
1383 .u
.header2
.opnum
= state
->op_num
,
1387 if (t
->count
.count
== 0) {
1389 return NT_STATUS_OK
;
1392 t
->commands
[t
->count
.count
- 1].command
|= DCERPC_SEC_VT_COMMAND_END
;
1394 if (DEBUGLEVEL
>= 10) {
1395 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer
, t
);
1398 ndr
= ndr_push_init_ctx(state
);
1400 return NT_STATUS_NO_MEMORY
;
1403 ndr_err
= ndr_push_dcerpc_sec_verification_trailer(ndr
,
1404 NDR_SCALARS
| NDR_BUFFERS
,
1407 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1408 return ndr_map_error2ntstatus(ndr_err
);
1410 state
->req_trailer
= ndr_push_blob(ndr
);
1412 align
= state
->req_data
->length
& 0x3;
1419 const uint8_t zeros
[4] = { 0, };
1421 ok
= data_blob_append(ndr
, &state
->req_trailer
, zeros
, pad
);
1423 return NT_STATUS_NO_MEMORY
;
1426 /* move the padding to the start */
1427 p
= state
->req_trailer
.data
;
1428 memmove(p
+ pad
, p
, state
->req_trailer
.length
- pad
);
1432 return NT_STATUS_OK
;
1435 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1443 size_t data_thistime
;
1444 size_t trailer_left
;
1445 size_t trailer_thistime
= 0;
1447 size_t total_thistime
;
1450 union dcerpc_payload u
;
1452 data_left
= state
->req_data
->length
- state
->req_data_sent
;
1453 trailer_left
= state
->req_trailer
.length
- state
->req_trailer_sent
;
1454 total_left
= data_left
+ trailer_left
;
1455 if ((total_left
< data_left
) || (total_left
< trailer_left
)) {
1459 return NT_STATUS_INVALID_PARAMETER_MIX
;
1462 status
= dcerpc_guess_sizes(state
->cli
->auth
,
1463 DCERPC_REQUEST_LENGTH
, total_left
,
1464 state
->cli
->max_xmit_frag
,
1466 &frag_len
, &auth_len
, &pad_len
);
1467 if (!NT_STATUS_IS_OK(status
)) {
1471 if (state
->req_data_sent
== 0) {
1472 flags
= DCERPC_PFC_FLAG_FIRST
;
1475 if (total_thistime
== total_left
) {
1476 flags
|= DCERPC_PFC_FLAG_LAST
;
1479 data_thistime
= MIN(total_thistime
, data_left
);
1480 if (data_thistime
< total_thistime
) {
1481 trailer_thistime
= total_thistime
- data_thistime
;
1484 data_blob_free(&state
->rpc_out
);
1486 u
= (union dcerpc_payload
) {
1487 .request
.alloc_hint
= total_left
,
1488 .request
.context_id
= 0,
1489 .request
.opnum
= state
->op_num
,
1492 if (state
->object_uuid
) {
1493 flags
|= DCERPC_PFC_FLAG_OBJECT_UUID
;
1494 u
.request
.object
.object
= *state
->object_uuid
;
1495 frag_len
+= ndr_size_GUID(state
->object_uuid
, 0);
1498 status
= dcerpc_push_ncacn_packet(state
,
1505 if (!NT_STATUS_IS_OK(status
)) {
1509 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1510 * compute it right for requests because the auth trailer is missing
1512 dcerpc_set_frag_length(&state
->rpc_out
, frag_len
);
1514 if (data_thistime
> 0) {
1515 /* Copy in the data. */
1516 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1517 state
->req_data
->data
+ state
->req_data_sent
,
1520 return NT_STATUS_NO_MEMORY
;
1522 state
->req_data_sent
+= data_thistime
;
1525 if (trailer_thistime
> 0) {
1526 /* Copy in the verification trailer. */
1527 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1528 state
->req_trailer
.data
+ state
->req_trailer_sent
,
1531 return NT_STATUS_NO_MEMORY
;
1533 state
->req_trailer_sent
+= trailer_thistime
;
1536 switch (state
->cli
->auth
->auth_level
) {
1537 case DCERPC_AUTH_LEVEL_NONE
:
1538 case DCERPC_AUTH_LEVEL_CONNECT
:
1540 case DCERPC_AUTH_LEVEL_PACKET
:
1541 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1542 case DCERPC_AUTH_LEVEL_PRIVACY
:
1543 status
= dcerpc_add_auth_footer(state
->cli
->auth
, pad_len
,
1545 if (!NT_STATUS_IS_OK(status
)) {
1550 return NT_STATUS_INVALID_PARAMETER
;
1553 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
1558 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
1560 struct tevent_req
*req
= tevent_req_callback_data(
1561 subreq
, struct tevent_req
);
1562 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1563 req
, struct rpc_api_pipe_req_state
);
1567 status
= rpc_write_recv(subreq
);
1568 TALLOC_FREE(subreq
);
1569 if (tevent_req_nterror(req
, status
)) {
1573 status
= prepare_next_frag(state
, &is_last_frag
);
1574 if (tevent_req_nterror(req
, status
)) {
1579 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
1581 DCERPC_PKT_RESPONSE
,
1583 if (tevent_req_nomem(subreq
, req
)) {
1586 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1588 subreq
= rpc_write_send(state
, state
->ev
,
1589 state
->cli
->transport
,
1590 state
->rpc_out
.data
,
1591 state
->rpc_out
.length
);
1592 if (tevent_req_nomem(subreq
, req
)) {
1595 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1600 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
1602 struct tevent_req
*req
= tevent_req_callback_data(
1603 subreq
, struct tevent_req
);
1604 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1605 req
, struct rpc_api_pipe_req_state
);
1608 status
= rpc_api_pipe_recv(subreq
, state
, NULL
, &state
->reply_pdu
);
1609 TALLOC_FREE(subreq
);
1610 if (tevent_req_nterror(req
, status
)) {
1614 if (state
->cli
->auth
== NULL
) {
1615 tevent_req_done(req
);
1619 if (state
->verify_bitmask1
) {
1620 state
->cli
->auth
->verified_bitmask1
= true;
1623 if (state
->verify_pcontext
) {
1624 state
->cli
->verified_pcontext
= true;
1627 tevent_req_done(req
);
1630 static NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1631 DATA_BLOB
*reply_pdu
)
1633 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1634 req
, struct rpc_api_pipe_req_state
);
1637 if (tevent_req_is_nterror(req
, &status
)) {
1639 * We always have to initialize to reply pdu, even if there is
1640 * none. The rpccli_* caller routines expect this.
1642 *reply_pdu
= data_blob_null
;
1646 /* return data to caller and assign it ownership of memory */
1647 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1648 reply_pdu
->length
= state
->reply_pdu
.length
;
1649 state
->reply_pdu
.length
= 0;
1651 return NT_STATUS_OK
;
1654 /****************************************************************************
1655 Check the rpc bind acknowledge response.
1656 ****************************************************************************/
1658 static bool check_bind_response(const struct dcerpc_bind_ack
*r
,
1659 const struct ndr_syntax_id
*transfer
)
1661 struct dcerpc_ack_ctx ctx
;
1664 if (r
->secondary_address_size
== 0) {
1665 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1668 if (r
->num_results
< 1 || !r
->ctx_list
) {
1672 ctx
= r
->ctx_list
[0];
1674 /* check the transfer syntax */
1675 equal
= ndr_syntax_id_equal(&ctx
.syntax
, transfer
);
1677 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1681 if (r
->num_results
!= 0x1 || ctx
.result
!= 0) {
1682 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1683 r
->num_results
, ctx
.reason
.value
));
1686 DEBUG(5,("check_bind_response: accepted!\n"));
1690 /*******************************************************************
1691 Creates a DCE/RPC bind authentication response.
1692 This is the packet that is sent back to the server once we
1693 have received a BIND-ACK, to finish the third leg of
1694 the authentication handshake.
1695 ********************************************************************/
1697 static NTSTATUS
create_rpc_bind_auth3(TALLOC_CTX
*mem_ctx
,
1698 struct rpc_pipe_client
*cli
,
1699 struct pipe_auth_data
*auth
,
1700 uint32_t rpc_call_id
,
1701 DATA_BLOB
*pauth_blob
,
1705 union dcerpc_payload u
= { .auth3
._pad
= 0, };
1707 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1710 0, /* auth_pad_length */
1711 auth
->auth_context_id
,
1713 &u
.auth3
.auth_info
);
1714 if (!NT_STATUS_IS_OK(status
)) {
1718 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1720 DCERPC_PFC_FLAG_FIRST
|
1721 DCERPC_PFC_FLAG_LAST
,
1726 data_blob_free(&u
.auth3
.auth_info
);
1727 if (!NT_STATUS_IS_OK(status
)) {
1728 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1732 return NT_STATUS_OK
;
1735 /*******************************************************************
1736 Creates a DCE/RPC bind alter context authentication request which
1737 may contain a spnego auth blob
1738 ********************************************************************/
1740 static NTSTATUS
create_rpc_alter_context(TALLOC_CTX
*mem_ctx
,
1741 struct pipe_auth_data
*auth
,
1742 uint32_t rpc_call_id
,
1743 const struct ndr_syntax_id
*abstract
,
1744 const struct ndr_syntax_id
*transfer
,
1745 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
1748 DATA_BLOB auth_info
;
1751 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1754 0, /* auth_pad_length */
1755 auth
->auth_context_id
,
1758 if (!NT_STATUS_IS_OK(status
)) {
1762 status
= create_bind_or_alt_ctx_internal(mem_ctx
,
1768 false, /* client_hdr_signing */
1770 data_blob_free(&auth_info
);
1774 /****************************************************************************
1776 ****************************************************************************/
1778 struct rpc_pipe_bind_state
{
1779 struct tevent_context
*ev
;
1780 struct rpc_pipe_client
*cli
;
1783 uint32_t rpc_call_id
;
1786 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
1787 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
1788 struct rpc_pipe_bind_state
*state
,
1789 DATA_BLOB
*credentials
);
1790 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
1791 struct rpc_pipe_bind_state
*state
,
1792 DATA_BLOB
*credentials
);
1794 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
1795 struct tevent_context
*ev
,
1796 struct rpc_pipe_client
*cli
,
1797 struct pipe_auth_data
*auth
)
1799 struct tevent_req
*req
, *subreq
;
1800 struct rpc_pipe_bind_state
*state
;
1803 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
1808 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1809 rpccli_pipe_txt(talloc_tos(), cli
),
1810 (unsigned int)auth
->auth_type
,
1811 (unsigned int)auth
->auth_level
));
1815 state
->rpc_call_id
= get_rpc_call_id();
1817 cli
->auth
= talloc_move(cli
, &auth
);
1819 /* Marshall the outgoing data. */
1820 status
= create_rpc_bind_req(state
, cli
,
1823 &cli
->abstract_syntax
,
1824 &cli
->transfer_syntax
,
1827 if (!NT_STATUS_IS_OK(status
) &&
1828 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1829 tevent_req_nterror(req
, status
);
1830 return tevent_req_post(req
, ev
);
1833 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
1834 DCERPC_PKT_BIND_ACK
, state
->rpc_call_id
);
1835 if (tevent_req_nomem(subreq
, req
)) {
1836 return tevent_req_post(req
, ev
);
1838 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
1842 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
1844 struct tevent_req
*req
= tevent_req_callback_data(
1845 subreq
, struct tevent_req
);
1846 struct rpc_pipe_bind_state
*state
= tevent_req_data(
1847 req
, struct rpc_pipe_bind_state
);
1848 struct pipe_auth_data
*pauth
= state
->cli
->auth
;
1849 struct gensec_security
*gensec_security
;
1850 struct ncacn_packet
*pkt
= NULL
;
1851 struct dcerpc_auth auth
;
1852 DATA_BLOB auth_token
= { .data
= NULL
};
1855 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, NULL
);
1856 TALLOC_FREE(subreq
);
1857 if (tevent_req_nterror(req
, status
)) {
1858 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1859 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1860 nt_errstr(status
)));
1865 tevent_req_done(req
);
1869 if (!check_bind_response(&pkt
->u
.bind_ack
, &state
->cli
->transfer_syntax
)) {
1870 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1871 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
1875 if (pkt
->ptype
== DCERPC_PKT_BIND_ACK
) {
1876 if (pkt
->pfc_flags
& DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
) {
1877 if (pauth
->client_hdr_signing
) {
1878 pauth
->hdr_signing
= true;
1883 state
->cli
->max_xmit_frag
= pkt
->u
.bind_ack
.max_xmit_frag
;
1885 if (pauth
->auth_type
== DCERPC_AUTH_TYPE_NONE
) {
1886 /* Bind complete. */
1887 tevent_req_done(req
);
1891 if (pkt
->auth_length
== 0) {
1892 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1896 /* get auth credentials */
1897 status
= dcerpc_pull_auth_trailer(pkt
, talloc_tos(),
1898 &pkt
->u
.bind_ack
.auth_info
,
1900 if (tevent_req_nterror(req
, status
)) {
1901 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1902 nt_errstr(status
)));
1906 if (auth
.auth_type
!= pauth
->auth_type
) {
1907 DBG_ERR("Auth type %u mismatch expected %u.\n",
1908 auth
.auth_type
, pauth
->auth_type
);
1909 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1913 if (auth
.auth_level
!= pauth
->auth_level
) {
1914 DBG_ERR("Auth level %u mismatch expected %u.\n",
1915 auth
.auth_level
, pauth
->auth_level
);
1916 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1920 if (auth
.auth_context_id
!= pauth
->auth_context_id
) {
1921 DBG_ERR("Auth context id %"PRIu32
" mismatch "
1922 "expected %"PRIu32
".\n",
1923 auth
.auth_context_id
,
1924 pauth
->auth_context_id
);
1925 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1930 * For authenticated binds we may need to do 3 or 4 leg binds.
1933 if (pauth
->auth_type
== DCERPC_AUTH_TYPE_NONE
) {
1934 /* Bind complete. */
1935 tevent_req_done(req
);
1939 gensec_security
= pauth
->auth_ctx
;
1941 status
= gensec_update(gensec_security
, state
,
1942 auth
.credentials
, &auth_token
);
1943 if (NT_STATUS_EQUAL(status
,
1944 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1945 status
= rpc_bind_next_send(req
, state
,
1947 } else if (NT_STATUS_IS_OK(status
)) {
1948 if (pauth
->hdr_signing
) {
1949 gensec_want_feature(gensec_security
,
1950 GENSEC_FEATURE_SIGN_PKT_HEADER
);
1953 if (auth_token
.length
== 0) {
1954 /* Bind complete. */
1955 tevent_req_done(req
);
1958 status
= rpc_bind_finish_send(req
, state
,
1962 if (!NT_STATUS_IS_OK(status
)) {
1963 tevent_req_nterror(req
, status
);
1968 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
1969 struct rpc_pipe_bind_state
*state
,
1970 DATA_BLOB
*auth_token
)
1972 struct pipe_auth_data
*auth
= state
->cli
->auth
;
1973 struct tevent_req
*subreq
;
1976 /* Now prepare the alter context pdu. */
1977 data_blob_free(&state
->rpc_out
);
1979 status
= create_rpc_alter_context(state
, auth
,
1981 &state
->cli
->abstract_syntax
,
1982 &state
->cli
->transfer_syntax
,
1985 if (!NT_STATUS_IS_OK(status
)) {
1989 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
1990 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
,
1991 state
->rpc_call_id
);
1992 if (subreq
== NULL
) {
1993 return NT_STATUS_NO_MEMORY
;
1995 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
1996 return NT_STATUS_OK
;
1999 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
2000 struct rpc_pipe_bind_state
*state
,
2001 DATA_BLOB
*auth_token
)
2003 struct pipe_auth_data
*auth
= state
->cli
->auth
;
2004 struct tevent_req
*subreq
;
2007 state
->auth3
= true;
2009 /* Now prepare the auth3 context pdu. */
2010 data_blob_free(&state
->rpc_out
);
2012 status
= create_rpc_bind_auth3(state
, state
->cli
, auth
,
2016 if (!NT_STATUS_IS_OK(status
)) {
2020 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2021 &state
->rpc_out
, DCERPC_PKT_AUTH3
,
2022 state
->rpc_call_id
);
2023 if (subreq
== NULL
) {
2024 return NT_STATUS_NO_MEMORY
;
2026 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2027 return NT_STATUS_OK
;
2030 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
2032 return tevent_req_simple_recv_ntstatus(req
);
2035 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2036 struct pipe_auth_data
*auth
)
2038 TALLOC_CTX
*frame
= talloc_stackframe();
2039 struct tevent_context
*ev
;
2040 struct tevent_req
*req
;
2041 NTSTATUS status
= NT_STATUS_OK
;
2043 ev
= samba_tevent_context_init(frame
);
2045 status
= NT_STATUS_NO_MEMORY
;
2049 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
2051 status
= NT_STATUS_NO_MEMORY
;
2055 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2059 status
= rpc_pipe_bind_recv(req
);
2065 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2067 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
2068 unsigned int timeout
)
2070 if (rpc_cli
== NULL
) {
2071 return RPCCLI_DEFAULT_TIMEOUT
;
2074 if (rpc_cli
->binding_handle
== NULL
) {
2075 return RPCCLI_DEFAULT_TIMEOUT
;
2078 return dcerpc_binding_handle_set_timeout(rpc_cli
->binding_handle
,
2082 bool rpccli_is_connected(struct rpc_pipe_client
*rpc_cli
)
2084 if (rpc_cli
== NULL
) {
2088 if (rpc_cli
->binding_handle
== NULL
) {
2092 return dcerpc_binding_handle_is_connected(rpc_cli
->binding_handle
);
2095 struct rpccli_bh_state
{
2096 struct rpc_pipe_client
*rpc_cli
;
2099 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle
*h
)
2101 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2102 struct rpccli_bh_state
);
2103 struct rpc_cli_transport
*transport
= hs
->rpc_cli
->transport
;
2105 if (transport
== NULL
) {
2109 if (transport
->is_connected
== NULL
) {
2113 return transport
->is_connected(transport
->priv
);
2116 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle
*h
,
2119 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2120 struct rpccli_bh_state
);
2121 struct rpc_cli_transport
*transport
= hs
->rpc_cli
->transport
;
2124 if (transport
== NULL
) {
2125 return RPCCLI_DEFAULT_TIMEOUT
;
2128 if (transport
->set_timeout
== NULL
) {
2129 return RPCCLI_DEFAULT_TIMEOUT
;
2132 old
= transport
->set_timeout(transport
->priv
, timeout
);
2134 return RPCCLI_DEFAULT_TIMEOUT
;
2140 static void rpccli_bh_auth_info(struct dcerpc_binding_handle
*h
,
2141 enum dcerpc_AuthType
*auth_type
,
2142 enum dcerpc_AuthLevel
*auth_level
)
2144 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2145 struct rpccli_bh_state
);
2147 if (hs
->rpc_cli
== NULL
) {
2151 if (hs
->rpc_cli
->auth
== NULL
) {
2155 *auth_type
= hs
->rpc_cli
->auth
->auth_type
;
2156 *auth_level
= hs
->rpc_cli
->auth
->auth_level
;
2159 struct rpccli_bh_raw_call_state
{
2165 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
);
2167 static struct tevent_req
*rpccli_bh_raw_call_send(TALLOC_CTX
*mem_ctx
,
2168 struct tevent_context
*ev
,
2169 struct dcerpc_binding_handle
*h
,
2170 const struct GUID
*object
,
2173 const uint8_t *in_data
,
2176 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2177 struct rpccli_bh_state
);
2178 struct tevent_req
*req
;
2179 struct rpccli_bh_raw_call_state
*state
;
2181 struct tevent_req
*subreq
;
2183 req
= tevent_req_create(mem_ctx
, &state
,
2184 struct rpccli_bh_raw_call_state
);
2188 state
->in_data
.data
= discard_const_p(uint8_t, in_data
);
2189 state
->in_data
.length
= in_length
;
2191 ok
= rpccli_bh_is_connected(h
);
2193 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2194 return tevent_req_post(req
, ev
);
2197 subreq
= rpc_api_pipe_req_send(state
, ev
, hs
->rpc_cli
,
2198 opnum
, object
, &state
->in_data
);
2199 if (tevent_req_nomem(subreq
, req
)) {
2200 return tevent_req_post(req
, ev
);
2202 tevent_req_set_callback(subreq
, rpccli_bh_raw_call_done
, req
);
2207 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
)
2209 struct tevent_req
*req
=
2210 tevent_req_callback_data(subreq
,
2212 struct rpccli_bh_raw_call_state
*state
=
2213 tevent_req_data(req
,
2214 struct rpccli_bh_raw_call_state
);
2217 state
->out_flags
= 0;
2219 /* TODO: support bigendian responses */
2221 status
= rpc_api_pipe_req_recv(subreq
, state
, &state
->out_data
);
2222 TALLOC_FREE(subreq
);
2223 if (tevent_req_nterror(req
, status
)) {
2227 tevent_req_done(req
);
2230 static NTSTATUS
rpccli_bh_raw_call_recv(struct tevent_req
*req
,
2231 TALLOC_CTX
*mem_ctx
,
2234 uint32_t *out_flags
)
2236 struct rpccli_bh_raw_call_state
*state
=
2237 tevent_req_data(req
,
2238 struct rpccli_bh_raw_call_state
);
2241 if (tevent_req_is_nterror(req
, &status
)) {
2242 tevent_req_received(req
);
2246 *out_data
= talloc_move(mem_ctx
, &state
->out_data
.data
);
2247 *out_length
= state
->out_data
.length
;
2248 *out_flags
= state
->out_flags
;
2249 tevent_req_received(req
);
2250 return NT_STATUS_OK
;
2253 struct rpccli_bh_disconnect_state
{
2257 static struct tevent_req
*rpccli_bh_disconnect_send(TALLOC_CTX
*mem_ctx
,
2258 struct tevent_context
*ev
,
2259 struct dcerpc_binding_handle
*h
)
2261 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2262 struct rpccli_bh_state
);
2263 struct tevent_req
*req
;
2264 struct rpccli_bh_disconnect_state
*state
;
2267 req
= tevent_req_create(mem_ctx
, &state
,
2268 struct rpccli_bh_disconnect_state
);
2273 ok
= rpccli_bh_is_connected(h
);
2275 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2276 return tevent_req_post(req
, ev
);
2280 * TODO: do a real async disconnect ...
2282 * For now we do it sync...
2284 TALLOC_FREE(hs
->rpc_cli
->transport
);
2287 tevent_req_done(req
);
2288 return tevent_req_post(req
, ev
);
2291 static NTSTATUS
rpccli_bh_disconnect_recv(struct tevent_req
*req
)
2293 return tevent_req_simple_recv_ntstatus(req
);
2296 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle
*h
)
2301 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle
*h
,
2303 const void *_struct_ptr
,
2304 const struct ndr_interface_call
*call
)
2306 void *struct_ptr
= discard_const(_struct_ptr
);
2308 if (DEBUGLEVEL
< 10) {
2312 if (ndr_flags
& NDR_IN
) {
2313 ndr_print_function_debug(call
->ndr_print
,
2318 if (ndr_flags
& NDR_OUT
) {
2319 ndr_print_function_debug(call
->ndr_print
,
2326 static const struct dcerpc_binding_handle_ops rpccli_bh_ops
= {
2328 .is_connected
= rpccli_bh_is_connected
,
2329 .set_timeout
= rpccli_bh_set_timeout
,
2330 .auth_info
= rpccli_bh_auth_info
,
2331 .raw_call_send
= rpccli_bh_raw_call_send
,
2332 .raw_call_recv
= rpccli_bh_raw_call_recv
,
2333 .disconnect_send
= rpccli_bh_disconnect_send
,
2334 .disconnect_recv
= rpccli_bh_disconnect_recv
,
2336 .ref_alloc
= rpccli_bh_ref_alloc
,
2337 .do_ndr_print
= rpccli_bh_do_ndr_print
,
2340 /* initialise a rpc_pipe_client binding handle */
2341 struct dcerpc_binding_handle
*rpccli_bh_create(struct rpc_pipe_client
*c
,
2342 const struct GUID
*object
,
2343 const struct ndr_interface_table
*table
)
2345 struct dcerpc_binding_handle
*h
;
2346 struct rpccli_bh_state
*hs
;
2348 h
= dcerpc_binding_handle_create(c
,
2353 struct rpccli_bh_state
,
2363 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
2364 struct pipe_auth_data
**presult
)
2366 struct pipe_auth_data
*result
;
2367 struct auth_generic_state
*auth_generic_ctx
;
2370 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2371 if (result
== NULL
) {
2372 return NT_STATUS_NO_MEMORY
;
2375 result
->auth_type
= DCERPC_AUTH_TYPE_NONE
;
2376 result
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
2377 result
->auth_context_id
= 0;
2379 status
= auth_generic_client_prepare(result
,
2381 if (!NT_STATUS_IS_OK(status
)) {
2382 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2383 nt_errstr(status
)));
2386 status
= auth_generic_set_username(auth_generic_ctx
, "");
2387 if (!NT_STATUS_IS_OK(status
)) {
2388 DEBUG(1, ("Failed to set username: %s\n",
2389 nt_errstr(status
)));
2392 status
= auth_generic_set_domain(auth_generic_ctx
, "");
2393 if (!NT_STATUS_IS_OK(status
)) {
2394 DEBUG(1, ("Failed to set domain: %s\n",
2395 nt_errstr(status
)));
2399 status
= gensec_set_credentials(auth_generic_ctx
->gensec_security
,
2400 auth_generic_ctx
->credentials
);
2401 if (!NT_STATUS_IS_OK(status
)) {
2402 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2403 nt_errstr(status
)));
2406 talloc_unlink(auth_generic_ctx
, auth_generic_ctx
->credentials
);
2407 auth_generic_ctx
->credentials
= NULL
;
2409 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2410 talloc_free(auth_generic_ctx
);
2412 return NT_STATUS_OK
;
2415 static NTSTATUS
rpccli_generic_bind_data(TALLOC_CTX
*mem_ctx
,
2416 enum dcerpc_AuthType auth_type
,
2417 enum dcerpc_AuthLevel auth_level
,
2419 const char *target_service
,
2421 const char *username
,
2422 const char *password
,
2423 enum credentials_use_kerberos use_kerberos
,
2424 struct netlogon_creds_CredentialState
*creds
,
2425 struct pipe_auth_data
**presult
)
2427 struct auth_generic_state
*auth_generic_ctx
;
2428 struct pipe_auth_data
*result
;
2431 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2432 if (result
== NULL
) {
2433 return NT_STATUS_NO_MEMORY
;
2436 result
->auth_type
= auth_type
;
2437 result
->auth_level
= auth_level
;
2438 result
->auth_context_id
= 1;
2440 status
= auth_generic_client_prepare(result
,
2442 if (!NT_STATUS_IS_OK(status
)) {
2446 status
= auth_generic_set_username(auth_generic_ctx
, username
);
2447 if (!NT_STATUS_IS_OK(status
)) {
2451 status
= auth_generic_set_domain(auth_generic_ctx
, domain
);
2452 if (!NT_STATUS_IS_OK(status
)) {
2456 status
= auth_generic_set_password(auth_generic_ctx
, password
);
2457 if (!NT_STATUS_IS_OK(status
)) {
2461 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
2462 if (!NT_STATUS_IS_OK(status
)) {
2466 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
2467 if (!NT_STATUS_IS_OK(status
)) {
2471 cli_credentials_set_kerberos_state(auth_generic_ctx
->credentials
,
2474 cli_credentials_set_netlogon_creds(auth_generic_ctx
->credentials
, creds
);
2476 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
2477 if (!NT_STATUS_IS_OK(status
)) {
2481 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2482 talloc_free(auth_generic_ctx
);
2484 return NT_STATUS_OK
;
2487 TALLOC_FREE(result
);
2491 /* This routine steals the creds pointer that is passed in */
2492 static NTSTATUS
rpccli_generic_bind_data_from_creds(TALLOC_CTX
*mem_ctx
,
2493 enum dcerpc_AuthType auth_type
,
2494 enum dcerpc_AuthLevel auth_level
,
2496 const char *target_service
,
2497 struct cli_credentials
*creds
,
2498 struct pipe_auth_data
**presult
)
2500 struct auth_generic_state
*auth_generic_ctx
;
2501 struct pipe_auth_data
*result
;
2504 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2505 if (result
== NULL
) {
2506 return NT_STATUS_NO_MEMORY
;
2509 result
->auth_type
= auth_type
;
2510 result
->auth_level
= auth_level
;
2511 result
->auth_context_id
= 1;
2513 status
= auth_generic_client_prepare(result
,
2515 if (!NT_STATUS_IS_OK(status
)) {
2519 status
= auth_generic_set_creds(auth_generic_ctx
, creds
);
2520 if (!NT_STATUS_IS_OK(status
)) {
2524 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
2525 if (!NT_STATUS_IS_OK(status
)) {
2529 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
2530 if (!NT_STATUS_IS_OK(status
)) {
2534 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
2535 if (!NT_STATUS_IS_OK(status
)) {
2539 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2540 talloc_free(auth_generic_ctx
);
2542 return NT_STATUS_OK
;
2545 TALLOC_FREE(result
);
2549 NTSTATUS
rpccli_ncalrpc_bind_data(TALLOC_CTX
*mem_ctx
,
2550 struct pipe_auth_data
**presult
)
2552 return rpccli_generic_bind_data(mem_ctx
,
2553 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
,
2554 DCERPC_AUTH_LEVEL_CONNECT
,
2556 "host", /* target_service */
2557 NAME_NT_AUTHORITY
, /* domain */
2559 NULL
, /* password */
2560 CRED_USE_KERBEROS_DISABLED
,
2561 NULL
, /* netlogon_creds_CredentialState */
2566 * Create an rpc pipe client struct, connecting to a tcp port.
2568 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
2569 const struct sockaddr_storage
*ss_addr
,
2571 const struct ndr_interface_table
*table
,
2572 struct rpc_pipe_client
**presult
)
2574 struct rpc_pipe_client
*result
;
2575 struct sockaddr_storage addr
;
2579 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
2580 if (result
== NULL
) {
2581 return NT_STATUS_NO_MEMORY
;
2584 result
->abstract_syntax
= table
->syntax_id
;
2585 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2587 result
->desthost
= talloc_strdup(result
, host
);
2588 if (result
->desthost
== NULL
) {
2589 status
= NT_STATUS_NO_MEMORY
;
2593 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2594 result
, "\\\\%s", result
->desthost
);
2595 if (result
->srv_name_slash
== NULL
) {
2596 status
= NT_STATUS_NO_MEMORY
;
2600 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2602 if (ss_addr
== NULL
) {
2603 if (!resolve_name(host
, &addr
, NBT_NAME_SERVER
, false)) {
2604 status
= NT_STATUS_NOT_FOUND
;
2611 status
= open_socket_out(&addr
, port
, 60*1000, &fd
);
2612 if (!NT_STATUS_IS_OK(status
)) {
2615 set_socket_options(fd
, lp_socket_options());
2617 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
2618 if (!NT_STATUS_IS_OK(status
)) {
2623 result
->transport
->transport
= NCACN_IP_TCP
;
2625 result
->binding_handle
= rpccli_bh_create(result
, NULL
, table
);
2626 if (result
->binding_handle
== NULL
) {
2627 TALLOC_FREE(result
);
2628 return NT_STATUS_NO_MEMORY
;
2632 return NT_STATUS_OK
;
2635 TALLOC_FREE(result
);
2639 static NTSTATUS
rpccli_epm_map_binding(
2640 struct dcerpc_binding_handle
*epm_connection
,
2641 struct dcerpc_binding
*binding
,
2642 TALLOC_CTX
*mem_ctx
,
2645 TALLOC_CTX
*frame
= talloc_stackframe();
2646 enum dcerpc_transport_t transport
=
2647 dcerpc_binding_get_transport(binding
);
2648 enum dcerpc_transport_t res_transport
;
2649 struct dcerpc_binding
*res_binding
= NULL
;
2650 struct epm_twr_t
*map_tower
= NULL
;
2651 struct epm_twr_p_t res_towers
= { .twr
= NULL
};
2652 struct policy_handle
*entry_handle
= NULL
;
2653 uint32_t num_towers
= 0;
2654 const uint32_t max_towers
= 1;
2655 const char *endpoint
= NULL
;
2660 map_tower
= talloc_zero(frame
, struct epm_twr_t
);
2661 if (map_tower
== NULL
) {
2665 status
= dcerpc_binding_build_tower(
2666 frame
, binding
, &(map_tower
->tower
));
2667 if (!NT_STATUS_IS_OK(status
)) {
2668 DBG_DEBUG("dcerpc_binding_build_tower failed: %s\n",
2673 res_towers
.twr
= talloc_array(frame
, struct epm_twr_t
, max_towers
);
2674 if (res_towers
.twr
== NULL
) {
2678 entry_handle
= talloc_zero(frame
, struct policy_handle
);
2679 if (entry_handle
== NULL
) {
2683 status
= dcerpc_epm_Map(
2694 if (!NT_STATUS_IS_OK(status
)) {
2695 DBG_DEBUG("dcerpc_epm_Map failed: %s\n", nt_errstr(status
));
2699 if (result
!= EPMAPPER_STATUS_OK
) {
2700 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32
"\n", result
);
2701 status
= NT_STATUS_NOT_FOUND
;
2705 if (num_towers
!= 1) {
2706 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32
" towers\n",
2708 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2712 status
= dcerpc_binding_from_tower(
2713 frame
, &(res_towers
.twr
->tower
), &res_binding
);
2714 if (!NT_STATUS_IS_OK(status
)) {
2715 DBG_DEBUG("dcerpc_binding_from_tower failed: %s\n",
2720 res_transport
= dcerpc_binding_get_transport(res_binding
);
2721 if (res_transport
!= transport
) {
2722 DBG_DEBUG("dcerpc_epm_Map returned transport %d, "
2726 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2730 endpoint
= dcerpc_binding_get_string_option(res_binding
, "endpoint");
2731 if (endpoint
== NULL
) {
2732 DBG_DEBUG("dcerpc_epm_Map returned no endpoint\n");
2733 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2737 tmp
= talloc_strdup(mem_ctx
, endpoint
);
2743 status
= NT_STATUS_OK
;
2747 status
= NT_STATUS_NO_MEMORY
;
2753 static NTSTATUS
rpccli_epm_map_interface(
2754 struct dcerpc_binding_handle
*epm_connection
,
2755 enum dcerpc_transport_t transport
,
2756 const struct ndr_syntax_id
*iface
,
2757 TALLOC_CTX
*mem_ctx
,
2760 struct dcerpc_binding
*binding
= NULL
;
2761 char *endpoint
= NULL
;
2764 status
= dcerpc_parse_binding(mem_ctx
, "", &binding
);
2765 if (!NT_STATUS_IS_OK(status
)) {
2766 DBG_DEBUG("dcerpc_parse_binding failed: %s\n",
2771 status
= dcerpc_binding_set_transport(binding
, transport
);
2772 if (!NT_STATUS_IS_OK(status
)) {
2773 DBG_DEBUG("dcerpc_binding_set_transport failed: %s\n",
2778 status
= dcerpc_binding_set_abstract_syntax(binding
, iface
);
2779 if (!NT_STATUS_IS_OK(status
)) {
2780 DBG_DEBUG("dcerpc_binding_set_abstract_syntax failed: %s\n",
2785 status
= rpccli_epm_map_binding(
2786 epm_connection
, binding
, mem_ctx
, &endpoint
);
2787 if (!NT_STATUS_IS_OK(status
)) {
2788 DBG_DEBUG("rpccli_epm_map_binding failed: %s\n",
2792 *pendpoint
= endpoint
;
2795 TALLOC_FREE(binding
);
2800 * Determine the tcp port on which a dcerpc interface is listening
2801 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2804 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
2805 const struct sockaddr_storage
*addr
,
2806 const struct ndr_interface_table
*table
,
2810 struct rpc_pipe_client
*epm_pipe
= NULL
;
2811 struct pipe_auth_data
*auth
= NULL
;
2812 char *endpoint
= NULL
;
2813 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2815 if (pport
== NULL
) {
2816 status
= NT_STATUS_INVALID_PARAMETER
;
2820 if (ndr_syntax_id_equal(&table
->syntax_id
,
2821 &ndr_table_epmapper
.syntax_id
)) {
2823 status
= NT_STATUS_OK
;
2827 /* open the connection to the endpoint mapper */
2828 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, addr
, 135,
2829 &ndr_table_epmapper
,
2832 if (!NT_STATUS_IS_OK(status
)) {
2836 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
2837 if (!NT_STATUS_IS_OK(status
)) {
2841 status
= rpc_pipe_bind(epm_pipe
, auth
);
2842 if (!NT_STATUS_IS_OK(status
)) {
2846 status
= rpccli_epm_map_interface(
2847 epm_pipe
->binding_handle
,
2852 if (!NT_STATUS_IS_OK(status
)) {
2853 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
2858 *pport
= (uint16_t)atoi(endpoint
);
2861 TALLOC_FREE(tmp_ctx
);
2866 * Create a rpc pipe client struct, connecting to a host via tcp.
2867 * The port is determined by asking the endpoint mapper on the given
2870 static NTSTATUS
rpc_pipe_open_tcp(
2871 TALLOC_CTX
*mem_ctx
,
2873 const struct sockaddr_storage
*addr
,
2874 const struct ndr_interface_table
*table
,
2875 struct rpc_pipe_client
**presult
)
2880 status
= rpc_pipe_get_tcp_port(host
, addr
, table
, &port
);
2881 if (!NT_STATUS_IS_OK(status
)) {
2885 return rpc_pipe_open_tcp_port(mem_ctx
, host
, addr
, port
,
2889 static NTSTATUS
rpc_pipe_get_ncalrpc_name(
2890 const struct ndr_syntax_id
*iface
,
2891 TALLOC_CTX
*mem_ctx
,
2892 char **psocket_name
)
2894 TALLOC_CTX
*frame
= talloc_stackframe();
2895 struct rpc_pipe_client
*epm_pipe
= NULL
;
2896 struct pipe_auth_data
*auth
= NULL
;
2897 NTSTATUS status
= NT_STATUS_OK
;
2900 is_epm
= ndr_syntax_id_equal(iface
, &ndr_table_epmapper
.syntax_id
);
2902 char *endpoint
= talloc_strdup(mem_ctx
, "EPMAPPER");
2903 if (endpoint
== NULL
) {
2904 status
= NT_STATUS_NO_MEMORY
;
2907 *psocket_name
= endpoint
;
2911 status
= rpc_pipe_open_ncalrpc(
2912 frame
, &ndr_table_epmapper
, &epm_pipe
);
2913 if (!NT_STATUS_IS_OK(status
)) {
2914 DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
2919 status
= rpccli_anon_bind_data(epm_pipe
, &auth
);
2920 if (!NT_STATUS_IS_OK(status
)) {
2921 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
2926 status
= rpc_pipe_bind(epm_pipe
, auth
);
2927 if (!NT_STATUS_IS_OK(status
)) {
2928 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status
));
2932 status
= rpccli_epm_map_interface(
2933 epm_pipe
->binding_handle
,
2938 if (!NT_STATUS_IS_OK(status
)) {
2939 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
2948 /********************************************************************
2949 Create a rpc pipe client struct, connecting to a unix domain socket
2950 ********************************************************************/
2951 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
,
2952 const struct ndr_interface_table
*table
,
2953 struct rpc_pipe_client
**presult
)
2955 char *socket_name
= NULL
;
2956 struct rpc_pipe_client
*result
;
2957 struct sockaddr_un addr
= { .sun_family
= AF_UNIX
};
2958 socklen_t salen
= sizeof(addr
);
2963 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
2964 if (result
== NULL
) {
2965 return NT_STATUS_NO_MEMORY
;
2968 status
= rpc_pipe_get_ncalrpc_name(
2969 &table
->syntax_id
, result
, &socket_name
);
2970 if (!NT_STATUS_IS_OK(status
)) {
2971 DBG_DEBUG("rpc_pipe_get_ncalrpc_name failed: %s\n",
2978 sizeof(addr
.sun_path
),
2982 if ((pathlen
< 0) || ((size_t)pathlen
>= sizeof(addr
.sun_path
))) {
2983 DBG_DEBUG("socket_path for %s too long\n", socket_name
);
2984 status
= NT_STATUS_NAME_TOO_LONG
;
2987 TALLOC_FREE(socket_name
);
2989 result
->abstract_syntax
= table
->syntax_id
;
2990 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
2992 result
->desthost
= get_myname(result
);
2993 if (result
->desthost
== NULL
) {
2994 status
= NT_STATUS_NO_MEMORY
;
2998 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2999 result
, "\\\\%s", result
->desthost
);
3000 if (result
->srv_name_slash
== NULL
) {
3001 status
= NT_STATUS_NO_MEMORY
;
3005 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3007 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3009 status
= map_nt_error_from_unix(errno
);
3013 if (connect(fd
, (struct sockaddr
*)(void *)&addr
, salen
) == -1) {
3014 DBG_WARNING("connect(%s) failed: %s\n",
3017 status
= map_nt_error_from_unix(errno
);
3021 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
3022 if (!NT_STATUS_IS_OK(status
)) {
3027 result
->transport
->transport
= NCALRPC
;
3029 result
->binding_handle
= rpccli_bh_create(result
, NULL
, table
);
3030 if (result
->binding_handle
== NULL
) {
3031 status
= NT_STATUS_NO_MEMORY
;
3036 return NT_STATUS_OK
;
3042 TALLOC_FREE(result
);
3046 NTSTATUS
rpc_pipe_open_local_np(
3047 TALLOC_CTX
*mem_ctx
,
3048 const struct ndr_interface_table
*table
,
3049 const char *remote_client_name
,
3050 const struct tsocket_address
*remote_client_addr
,
3051 const char *local_server_name
,
3052 const struct tsocket_address
*local_server_addr
,
3053 const struct auth_session_info
*session_info
,
3054 struct rpc_pipe_client
**presult
)
3056 struct rpc_pipe_client
*result
= NULL
;
3057 struct pipe_auth_data
*auth
= NULL
;
3058 const char *pipe_name
= NULL
;
3059 struct tstream_context
*npa_stream
= NULL
;
3060 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3063 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
3064 if (result
== NULL
) {
3067 result
->abstract_syntax
= table
->syntax_id
;
3068 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
3069 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3071 pipe_name
= dcerpc_default_transport_endpoint(
3072 result
, NCACN_NP
, table
);
3073 if (pipe_name
== NULL
) {
3074 DBG_DEBUG("dcerpc_default_transport_endpoint failed\n");
3075 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3079 if (local_server_name
== NULL
) {
3080 result
->desthost
= get_myname(result
);
3082 result
->desthost
= talloc_strdup(result
, local_server_name
);
3084 if (result
->desthost
== NULL
) {
3087 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3088 result
, "\\\\%s", result
->desthost
);
3089 if (result
->srv_name_slash
== NULL
) {
3093 ret
= local_np_connect(
3105 DBG_DEBUG("local_np_connect for %s and "
3106 "user %s\\%s failed: %s\n",
3108 session_info
->info
->domain_name
,
3109 session_info
->info
->account_name
,
3111 status
= map_nt_error_from_unix(ret
);
3115 status
= rpc_transport_tstream_init(
3116 result
, &npa_stream
, &result
->transport
);
3117 if (!NT_STATUS_IS_OK(status
)) {
3118 DBG_DEBUG("rpc_transport_tstream_init failed: %s\n",
3123 result
->binding_handle
= rpccli_bh_create(result
, NULL
, table
);
3124 if (result
->binding_handle
== NULL
) {
3125 status
= NT_STATUS_NO_MEMORY
;
3126 DBG_DEBUG("Failed to create binding handle.\n");
3130 status
= rpccli_anon_bind_data(result
, &auth
);
3131 if (!NT_STATUS_IS_OK(status
)) {
3132 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3137 status
= rpc_pipe_bind(result
, auth
);
3138 if (!NT_STATUS_IS_OK(status
)) {
3139 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status
));
3144 return NT_STATUS_OK
;
3147 TALLOC_FREE(result
);
3151 struct rpc_pipe_client_np_ref
{
3152 struct cli_state
*cli
;
3153 struct rpc_pipe_client
*pipe
;
3156 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref
*np_ref
)
3158 DLIST_REMOVE(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3162 /****************************************************************************
3163 Open a named pipe over SMB to a remote server.
3165 * CAVEAT CALLER OF THIS FUNCTION:
3166 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3167 * so be sure that this function is called AFTER any structure (vs pointer)
3168 * assignment of the cli. In particular, libsmbclient does structure
3169 * assignments of cli, which invalidates the data in the returned
3170 * rpc_pipe_client if this function is called before the structure assignment
3173 ****************************************************************************/
3175 struct rpc_pipe_open_np_state
{
3176 struct cli_state
*cli
;
3177 const struct ndr_interface_table
*table
;
3178 struct rpc_pipe_client
*result
;
3181 static void rpc_pipe_open_np_done(struct tevent_req
*subreq
);
3183 struct tevent_req
*rpc_pipe_open_np_send(
3184 TALLOC_CTX
*mem_ctx
,
3185 struct tevent_context
*ev
,
3186 struct cli_state
*cli
,
3187 const struct ndr_interface_table
*table
)
3189 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
3190 struct rpc_pipe_open_np_state
*state
= NULL
;
3191 struct rpc_pipe_client
*result
= NULL
;
3193 req
= tevent_req_create(
3194 mem_ctx
, &state
, struct rpc_pipe_open_np_state
);
3199 state
->table
= table
;
3201 state
->result
= talloc_zero(state
, struct rpc_pipe_client
);
3202 if (tevent_req_nomem(state
->result
, req
)) {
3203 return tevent_req_post(req
, ev
);
3205 result
= state
->result
;
3207 result
->abstract_syntax
= table
->syntax_id
;
3208 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
3210 result
->desthost
= talloc_strdup(
3211 result
, smbXcli_conn_remote_name(cli
->conn
));
3212 if (tevent_req_nomem(result
->desthost
, req
)) {
3213 return tevent_req_post(req
, ev
);
3216 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3217 result
, "\\\\%s", result
->desthost
);
3218 if (tevent_req_nomem(result
->srv_name_slash
, req
)) {
3219 return tevent_req_post(req
, ev
);
3222 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3224 subreq
= rpc_transport_np_init_send(state
, ev
, cli
, table
);
3225 if (tevent_req_nomem(subreq
, req
)) {
3226 return tevent_req_post(req
, ev
);
3228 tevent_req_set_callback(subreq
, rpc_pipe_open_np_done
, req
);
3232 static void rpc_pipe_open_np_done(struct tevent_req
*subreq
)
3234 struct tevent_req
*req
= tevent_req_callback_data(
3235 subreq
, struct tevent_req
);
3236 struct rpc_pipe_open_np_state
*state
= tevent_req_data(
3237 req
, struct rpc_pipe_open_np_state
);
3238 struct rpc_pipe_client
*result
= state
->result
;
3239 struct rpc_pipe_client_np_ref
*np_ref
= NULL
;
3242 status
= rpc_transport_np_init_recv(
3243 subreq
, result
, &result
->transport
);
3244 TALLOC_FREE(subreq
);
3245 if (tevent_req_nterror(req
, status
)) {
3249 result
->transport
->transport
= NCACN_NP
;
3251 np_ref
= talloc(result
->transport
, struct rpc_pipe_client_np_ref
);
3252 if (tevent_req_nomem(np_ref
, req
)) {
3255 np_ref
->cli
= state
->cli
;
3256 np_ref
->pipe
= result
;
3258 DLIST_ADD(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3259 talloc_set_destructor(np_ref
, rpc_pipe_client_np_ref_destructor
);
3261 result
->binding_handle
= rpccli_bh_create(result
, NULL
, state
->table
);
3262 if (tevent_req_nomem(result
->binding_handle
, req
)) {
3266 tevent_req_done(req
);
3269 NTSTATUS
rpc_pipe_open_np_recv(
3270 struct tevent_req
*req
,
3271 TALLOC_CTX
*mem_ctx
,
3272 struct rpc_pipe_client
**_result
)
3274 struct rpc_pipe_open_np_state
*state
= tevent_req_data(
3275 req
, struct rpc_pipe_open_np_state
);
3278 if (tevent_req_is_nterror(req
, &status
)) {
3281 *_result
= talloc_move(mem_ctx
, &state
->result
);
3282 return NT_STATUS_OK
;
3285 NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
3286 const struct ndr_interface_table
*table
,
3287 struct rpc_pipe_client
**presult
)
3289 struct tevent_context
*ev
= NULL
;
3290 struct tevent_req
*req
= NULL
;
3291 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3293 ev
= samba_tevent_context_init(cli
);
3297 req
= rpc_pipe_open_np_send(ev
, ev
, cli
, table
);
3301 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3304 status
= rpc_pipe_open_np_recv(req
, NULL
, presult
);
3311 /****************************************************************************
3312 Open a pipe to a remote server.
3313 ****************************************************************************/
3315 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3316 enum dcerpc_transport_t transport
,
3317 const struct ndr_interface_table
*table
,
3318 const char *remote_name
,
3319 const struct sockaddr_storage
*remote_sockaddr
,
3320 struct rpc_pipe_client
**presult
)
3322 switch (transport
) {
3324 return rpc_pipe_open_tcp(NULL
,
3329 return rpc_pipe_open_np(cli
, table
, presult
);
3331 return NT_STATUS_NOT_IMPLEMENTED
;
3335 /****************************************************************************
3336 Open a named pipe to an SMB server and bind anonymously.
3337 ****************************************************************************/
3339 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
3340 enum dcerpc_transport_t transport
,
3341 const struct ndr_interface_table
*table
,
3342 const char *remote_name
,
3343 const struct sockaddr_storage
*remote_sockaddr
,
3344 struct rpc_pipe_client
**presult
)
3346 struct rpc_pipe_client
*result
;
3347 struct pipe_auth_data
*auth
;
3350 status
= cli_rpc_pipe_open(cli
,
3356 if (!NT_STATUS_IS_OK(status
)) {
3360 status
= rpccli_anon_bind_data(result
, &auth
);
3361 if (!NT_STATUS_IS_OK(status
)) {
3362 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3363 nt_errstr(status
)));
3364 TALLOC_FREE(result
);
3369 * This is a bit of an abstraction violation due to the fact that an
3370 * anonymous bind on an authenticated SMB inherits the user/domain
3371 * from the enclosing SMB creds
3374 if (transport
== NCACN_NP
) {
3375 struct smbXcli_session
*session
;
3377 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
3378 session
= cli
->smb2
.session
;
3380 session
= cli
->smb1
.session
;
3383 status
= smbXcli_session_application_key(session
, auth
,
3384 &auth
->transport_session_key
);
3385 if (!NT_STATUS_IS_OK(status
)) {
3386 auth
->transport_session_key
= data_blob_null
;
3390 status
= rpc_pipe_bind(result
, auth
);
3391 if (!NT_STATUS_IS_OK(status
)) {
3393 if (ndr_syntax_id_equal(&table
->syntax_id
,
3394 &ndr_table_dssetup
.syntax_id
)) {
3395 /* non AD domains just don't have this pipe, avoid
3396 * level 0 statement in that case - gd */
3399 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3400 "%s failed with error %s\n",
3402 nt_errstr(status
) ));
3403 TALLOC_FREE(result
);
3407 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3408 "%s and bound anonymously.\n",
3413 return NT_STATUS_OK
;
3416 /****************************************************************************
3417 ****************************************************************************/
3419 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
3420 const struct ndr_interface_table
*table
,
3421 struct rpc_pipe_client
**presult
)
3423 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
3424 const struct sockaddr_storage
*remote_sockaddr
=
3425 smbXcli_conn_remote_sockaddr(cli
->conn
);
3427 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
3434 /****************************************************************************
3435 Open a named pipe to an SMB server and bind using the mech specified
3437 This routine references the creds pointer that is passed in
3438 ****************************************************************************/
3440 NTSTATUS
cli_rpc_pipe_open_with_creds(struct cli_state
*cli
,
3441 const struct ndr_interface_table
*table
,
3442 enum dcerpc_transport_t transport
,
3443 enum dcerpc_AuthType auth_type
,
3444 enum dcerpc_AuthLevel auth_level
,
3446 const struct sockaddr_storage
*remote_sockaddr
,
3447 struct cli_credentials
*creds
,
3448 struct rpc_pipe_client
**presult
)
3450 struct rpc_pipe_client
*result
;
3451 struct pipe_auth_data
*auth
= NULL
;
3452 const char *target_service
= table
->authservices
->names
[0];
3455 status
= cli_rpc_pipe_open(cli
,
3461 if (!NT_STATUS_IS_OK(status
)) {
3465 status
= rpccli_generic_bind_data_from_creds(result
,
3466 auth_type
, auth_level
,
3467 server
, target_service
,
3470 if (!NT_STATUS_IS_OK(status
)) {
3471 DBG_ERR("rpccli_generic_bind_data_from_creds returned %s\n",
3476 status
= rpc_pipe_bind(result
, auth
);
3477 if (!NT_STATUS_IS_OK(status
)) {
3478 DBG_ERR("cli_rpc_pipe_bind failed with error %s\n",
3483 DBG_DEBUG("opened pipe %s to machine %s and bound as user %s.\n",
3486 cli_credentials_get_unparsed_name(creds
, talloc_tos()));
3489 return NT_STATUS_OK
;
3493 TALLOC_FREE(result
);
3497 NTSTATUS
cli_rpc_pipe_open_bind_schannel(
3498 struct cli_state
*cli
,
3499 const struct ndr_interface_table
*table
,
3500 enum dcerpc_transport_t transport
,
3501 struct netlogon_creds_cli_context
*netlogon_creds
,
3502 const char *remote_name
,
3503 const struct sockaddr_storage
*remote_sockaddr
,
3504 struct rpc_pipe_client
**_rpccli
)
3506 struct rpc_pipe_client
*rpccli
;
3507 struct pipe_auth_data
*rpcauth
;
3508 const char *target_service
= table
->authservices
->names
[0];
3509 struct cli_credentials
*cli_creds
;
3510 enum dcerpc_AuthLevel auth_level
;
3513 status
= cli_rpc_pipe_open(cli
,
3519 if (!NT_STATUS_IS_OK(status
)) {
3523 auth_level
= netlogon_creds_cli_auth_level(netlogon_creds
);
3525 status
= netlogon_creds_bind_cli_credentials(
3526 netlogon_creds
, rpccli
, &cli_creds
);
3527 if (!NT_STATUS_IS_OK(status
)) {
3528 DBG_DEBUG("netlogon_creds_bind_cli_credentials failed: %s\n",
3530 TALLOC_FREE(rpccli
);
3534 status
= rpccli_generic_bind_data_from_creds(rpccli
,
3535 DCERPC_AUTH_TYPE_SCHANNEL
,
3541 if (!NT_STATUS_IS_OK(status
)) {
3542 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
3543 nt_errstr(status
)));
3544 TALLOC_FREE(rpccli
);
3548 status
= rpc_pipe_bind(rpccli
, rpcauth
);
3550 /* No TALLOC_FREE, gensec takes references */
3551 talloc_unlink(rpccli
, cli_creds
);
3554 if (!NT_STATUS_IS_OK(status
)) {
3555 DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
3557 TALLOC_FREE(rpccli
);
3563 return NT_STATUS_OK
;
3566 NTSTATUS
cli_rpc_pipe_open_schannel_with_creds(struct cli_state
*cli
,
3567 const struct ndr_interface_table
*table
,
3568 enum dcerpc_transport_t transport
,
3569 struct netlogon_creds_cli_context
*netlogon_creds
,
3570 const char *remote_name
,
3571 const struct sockaddr_storage
*remote_sockaddr
,
3572 struct rpc_pipe_client
**_rpccli
)
3574 TALLOC_CTX
*frame
= talloc_stackframe();
3575 struct rpc_pipe_client
*rpccli
;
3576 struct netlogon_creds_cli_lck
*lck
;
3579 status
= netlogon_creds_cli_lck(
3580 netlogon_creds
, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE
,
3582 if (!NT_STATUS_IS_OK(status
)) {
3583 DBG_WARNING("netlogon_creds_cli_lck returned %s\n",
3589 status
= cli_rpc_pipe_open_bind_schannel(cli
,
3596 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3597 netlogon_creds_cli_delete_lck(netlogon_creds
);
3599 if (!NT_STATUS_IS_OK(status
)) {
3600 DBG_DEBUG("cli_rpc_pipe_open_bind_schannel failed: %s\n",
3606 if (ndr_syntax_id_equal(&table
->syntax_id
,
3607 &ndr_table_netlogon
.syntax_id
)) {
3608 status
= netlogon_creds_cli_check(netlogon_creds
,
3609 rpccli
->binding_handle
,
3611 if (!NT_STATUS_IS_OK(status
)) {
3612 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3613 nt_errstr(status
)));
3619 DBG_DEBUG("opened pipe %s to machine %s with key %s "
3620 "and bound using schannel.\n",
3621 table
->name
, rpccli
->desthost
,
3622 netlogon_creds_cli_debug_string(netlogon_creds
, lck
));
3627 return NT_STATUS_OK
;
3630 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
3631 struct rpc_pipe_client
*cli
,
3632 DATA_BLOB
*session_key
)
3635 struct pipe_auth_data
*a
;
3636 struct gensec_security
*gensec_security
;
3637 DATA_BLOB sk
= { .data
= NULL
};
3638 bool make_dup
= false;
3640 if (!session_key
|| !cli
) {
3641 return NT_STATUS_INVALID_PARAMETER
;
3647 return NT_STATUS_INVALID_PARAMETER
;
3650 switch (cli
->auth
->auth_type
) {
3651 case DCERPC_AUTH_TYPE_NONE
:
3652 sk
= data_blob_const(a
->transport_session_key
.data
,
3653 a
->transport_session_key
.length
);
3657 gensec_security
= a
->auth_ctx
;
3658 status
= gensec_session_key(gensec_security
, mem_ctx
, &sk
);
3659 if (!NT_STATUS_IS_OK(status
)) {
3667 return NT_STATUS_NO_USER_SESSION_KEY
;
3671 *session_key
= data_blob_dup_talloc(mem_ctx
, sk
);
3676 return NT_STATUS_OK
;