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/>.
22 #define SOURCE3_LIBRPC_INTERNALS 1
25 #include "libsmb/namequery.h"
26 #include "../lib/util/tevent_ntstatus.h"
27 #include "librpc/gen_ndr/ndr_epmapper_c.h"
28 #include "../librpc/gen_ndr/ndr_dssetup.h"
29 #include "../libcli/auth/schannel.h"
30 #include "../libcli/auth/netlogon_creds_cli.h"
31 #include "auth_generic.h"
32 #include "librpc/gen_ndr/ndr_dcerpc.h"
33 #include "librpc/gen_ndr/ndr_netlogon_c.h"
34 #include "librpc/gen_ndr/auth.h"
35 #include "librpc/rpc/dcerpc.h"
36 #include "librpc/rpc/dcerpc_internal.h"
37 #include "librpc/rpc/dcerpc_util.h"
40 #include "libsmb/libsmb.h"
41 #include "auth/gensec/gensec.h"
42 #include "auth/credentials/credentials.h"
43 #include "auth/auth_util.h"
44 #include "../libcli/smb/smbXcli_base.h"
45 #include "lib/tsocket/tsocket.h"
46 #include "libcli/named_pipe_auth/npa_tstream.h"
47 #include "librpc/gen_ndr/ndr_winreg.h"
49 #include "libcli/smb/tstream_smbXcli_np.h"
52 #define DBGC_CLASS DBGC_RPC_CLI
54 static const uint16_t default_bt_features
=
55 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
|
56 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
;
58 struct rpc_client_association
{
59 struct dcerpc_binding
*binding
;
64 bool negotiation_done
;
67 struct samba_sockaddr addr
;
69 uint32_t next_call_id
;
72 static NTSTATUS
rpc_client_association_create(TALLOC_CTX
*mem_ctx
,
73 uint16_t client_features
,
75 const char *target_hostname
,
76 enum dcerpc_transport_t transport
,
77 const struct samba_sockaddr
*addr
,
79 struct rpc_client_association
**passoc
)
81 struct rpc_client_association
*assoc
= NULL
;
82 struct dcerpc_binding
*bd
= NULL
;
83 char addrstr
[INET6_ADDRSTRLEN
] = { 0, };
86 assoc
= talloc_zero(mem_ctx
, struct rpc_client_association
);
88 return NT_STATUS_NO_MEMORY
;
90 assoc
->features
.client
= client_features
;
91 if (client_features
== 0) {
93 * Without requested features there
94 * is no point in trying to negotiate
95 * something, so we are done...
97 assoc
->features
.negotiation_done
= true;
100 status
= dcerpc_parse_binding(assoc
, "", &bd
);
101 if (!NT_STATUS_IS_OK(status
)) {
105 status
= dcerpc_binding_set_transport(bd
, transport
);
106 if (!NT_STATUS_IS_OK(status
)) {
110 switch (addr
->u
.sa
.sa_family
) {
113 print_sockaddr(addrstr
,
116 status
= dcerpc_binding_set_string_option(bd
,
119 if (!NT_STATUS_IS_OK(status
)) {
125 status
= dcerpc_binding_set_string_option(bd
,
128 if (!NT_STATUS_IS_OK(status
)) {
134 status
= dcerpc_binding_set_string_option(bd
,
137 if (!NT_STATUS_IS_OK(status
)) {
141 status
= dcerpc_binding_set_string_option(bd
,
144 if (!NT_STATUS_IS_OK(status
)) {
148 status
= dcerpc_binding_set_flags(bd
, flags
, 0);
149 if (!NT_STATUS_IS_OK(status
)) {
161 struct rpc_client_connection
{
162 DATA_BLOB transport_session_key
;
163 struct rpc_cli_transport
*transport
;
164 struct samba_sockaddr localaddr
;
167 uint16_t max_xmit_frag
;
168 uint16_t max_recv_frag
;
169 bool client_hdr_signing
;
174 uint32_t next_auth_context_id
;
175 uint16_t next_pres_context_id
;
178 static NTSTATUS
rpc_client_connection_create(TALLOC_CTX
*mem_ctx
,
179 const struct rpc_client_association
*assoc
,
181 struct rpc_client_connection
**pconn
)
183 struct rpc_client_connection
*conn
= NULL
;
184 uint32_t flags
= dcerpc_binding_get_flags(assoc
->binding
);
185 bool client_hdr_signing
= (flags
& DCERPC_PROPOSE_HEADER_SIGNING
);
187 conn
= talloc_zero(mem_ctx
, struct rpc_client_connection
);
189 return NT_STATUS_NO_MEMORY
;
191 conn
->features
.max_xmit_frag
= max_frag
;
192 conn
->features
.max_recv_frag
= max_frag
;
193 conn
->features
.client_hdr_signing
= client_hdr_signing
;
199 static int rpc_pipe_client_wrap_destructor(struct rpc_pipe_client
*p
)
201 if (p
->np_cli
!= NULL
) {
202 DLIST_REMOVE(p
->np_cli
->pipe_list
, p
);
209 static NTSTATUS
rpc_pipe_wrap_create(
210 const struct ndr_interface_table
*table
,
211 struct cli_state
*np_cli
,
212 struct rpc_client_association
**passoc
,
213 struct rpc_client_connection
**pconn
,
215 struct rpc_pipe_client
**presult
)
217 struct rpc_pipe_client
*result
= NULL
;
218 const char *hostname
= NULL
;
220 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
221 if (result
== NULL
) {
222 return NT_STATUS_NO_MEMORY
;
224 talloc_set_destructor(result
, rpc_pipe_client_wrap_destructor
);
226 result
->assoc
= talloc_move(result
, passoc
);
227 result
->conn
= talloc_move(result
, pconn
);
229 /* rpc_pipe_bind_send should allocate an id... */
230 result
->pres_context_id
= UINT16_MAX
;
231 result
->table
= table
;
232 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
234 hostname
= dcerpc_binding_get_string_option(result
->assoc
->binding
,
236 result
->desthost
= talloc_strdup(result
, hostname
);
237 if (result
->desthost
== NULL
) {
239 return NT_STATUS_NO_MEMORY
;
242 result
->srv_name_slash
= talloc_asprintf_strupper_m(
243 result
, "\\\\%s", result
->desthost
);
244 if (result
->srv_name_slash
== NULL
) {
246 return NT_STATUS_NO_MEMORY
;
249 if (np_cli
!= NULL
) {
250 result
->np_cli
= np_cli
;
251 DLIST_ADD_END(np_cli
->pipe_list
, result
);
258 /********************************************************************
259 Pipe description for a DEBUG
260 ********************************************************************/
261 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
262 struct rpc_pipe_client
*cli
)
264 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
265 if (result
== NULL
) {
271 /*******************************************************************
272 Use SMBreadX to get rest of one fragment's worth of rpc data.
273 Reads the whole size or give an error message
274 ********************************************************************/
276 struct rpc_read_state
{
277 struct tevent_context
*ev
;
278 struct rpc_cli_transport
*transport
;
284 static void rpc_read_done(struct tevent_req
*subreq
);
286 static struct tevent_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
287 struct tevent_context
*ev
,
288 struct rpc_cli_transport
*transport
,
289 uint8_t *data
, size_t size
)
291 struct tevent_req
*req
, *subreq
;
292 struct rpc_read_state
*state
;
294 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_read_state
);
299 state
->transport
= transport
;
304 DBG_INFO("data_to_read: %zu\n", size
);
306 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
308 if (subreq
== NULL
) {
311 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
319 static void rpc_read_done(struct tevent_req
*subreq
)
321 struct tevent_req
*req
= tevent_req_callback_data(
322 subreq
, struct tevent_req
);
323 struct rpc_read_state
*state
= tevent_req_data(
324 req
, struct rpc_read_state
);
328 status
= state
->transport
->read_recv(subreq
, &received
);
330 if (tevent_req_nterror(req
, status
)) {
334 state
->num_read
+= received
;
335 if (state
->num_read
== state
->size
) {
336 tevent_req_done(req
);
340 subreq
= state
->transport
->read_send(state
, state
->ev
,
341 state
->data
+ state
->num_read
,
342 state
->size
- state
->num_read
,
343 state
->transport
->priv
);
344 if (tevent_req_nomem(subreq
, req
)) {
347 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
350 static NTSTATUS
rpc_read_recv(struct tevent_req
*req
)
352 return tevent_req_simple_recv_ntstatus(req
);
355 struct rpc_write_state
{
356 struct tevent_context
*ev
;
357 struct rpc_cli_transport
*transport
;
363 static void rpc_write_done(struct tevent_req
*subreq
);
365 static struct tevent_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
366 struct tevent_context
*ev
,
367 struct rpc_cli_transport
*transport
,
368 const uint8_t *data
, size_t size
)
370 struct tevent_req
*req
, *subreq
;
371 struct rpc_write_state
*state
;
373 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_write_state
);
378 state
->transport
= transport
;
381 state
->num_written
= 0;
383 DBG_INFO("data_to_write: %zu\n", size
);
385 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
386 if (tevent_req_nomem(subreq
, req
)) {
387 return tevent_req_post(req
, ev
);
389 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
393 static void rpc_write_done(struct tevent_req
*subreq
)
395 struct tevent_req
*req
= tevent_req_callback_data(
396 subreq
, struct tevent_req
);
397 struct rpc_write_state
*state
= tevent_req_data(
398 req
, struct rpc_write_state
);
402 status
= state
->transport
->write_recv(subreq
, &written
);
404 if (tevent_req_nterror(req
, status
)) {
408 state
->num_written
+= written
;
410 if (state
->num_written
== state
->size
) {
411 tevent_req_done(req
);
415 subreq
= state
->transport
->write_send(state
, state
->ev
,
416 state
->data
+ state
->num_written
,
417 state
->size
- state
->num_written
,
418 state
->transport
->priv
);
419 if (tevent_req_nomem(subreq
, req
)) {
422 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
425 static NTSTATUS
rpc_write_recv(struct tevent_req
*req
)
427 return tevent_req_simple_recv_ntstatus(req
);
431 /****************************************************************************
432 Try and get a PDU's worth of data from current_pdu. If not, then read more
434 ****************************************************************************/
436 struct get_complete_frag_state
{
437 struct tevent_context
*ev
;
438 struct rpc_pipe_client
*cli
;
443 static void get_complete_frag_got_header(struct tevent_req
*subreq
);
444 static void get_complete_frag_got_rest(struct tevent_req
*subreq
);
446 static struct tevent_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
447 struct tevent_context
*ev
,
448 struct rpc_pipe_client
*cli
,
451 struct tevent_req
*req
, *subreq
;
452 struct get_complete_frag_state
*state
;
455 req
= tevent_req_create(mem_ctx
, &state
,
456 struct get_complete_frag_state
);
462 state
->frag_len
= RPC_HEADER_LEN
;
465 received
= pdu
->length
;
466 if (received
< RPC_HEADER_LEN
) {
467 if (!data_blob_realloc(mem_ctx
, pdu
, RPC_HEADER_LEN
)) {
469 return tevent_req_post(req
, ev
);
471 subreq
= rpc_read_send(state
, state
->ev
,
472 state
->cli
->conn
->transport
,
473 pdu
->data
+ received
,
474 RPC_HEADER_LEN
- received
);
475 if (tevent_req_nomem(subreq
, req
)) {
476 return tevent_req_post(req
, ev
);
478 tevent_req_set_callback(subreq
, get_complete_frag_got_header
,
483 state
->frag_len
= dcerpc_get_frag_length(pdu
);
484 if (state
->frag_len
< RPC_HEADER_LEN
) {
485 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
486 return tevent_req_post(req
, ev
);
489 if (received
>= state
->frag_len
) {
491 * Got the whole fragment
493 tevent_req_done(req
);
494 return tevent_req_post(req
, ev
);
497 if (!data_blob_realloc(NULL
, pdu
, state
->frag_len
)) {
499 return tevent_req_post(req
, ev
);
502 subreq
= rpc_read_send(
505 state
->cli
->conn
->transport
,
506 pdu
->data
+ received
,
507 state
->frag_len
- received
);
508 if (tevent_req_nomem(subreq
, req
)) {
509 return tevent_req_post(req
, ev
);
511 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
515 static void get_complete_frag_got_header(struct tevent_req
*subreq
)
517 struct tevent_req
*req
= tevent_req_callback_data(
518 subreq
, struct tevent_req
);
519 struct get_complete_frag_state
*state
= tevent_req_data(
520 req
, struct get_complete_frag_state
);
523 status
= rpc_read_recv(subreq
);
525 if (tevent_req_nterror(req
, status
)) {
529 state
->frag_len
= dcerpc_get_frag_length(state
->pdu
);
530 if (state
->frag_len
< RPC_HEADER_LEN
) {
531 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
535 if (!data_blob_realloc(NULL
, state
->pdu
, state
->frag_len
)) {
541 * We're here in this piece of code because we've read exactly
542 * RPC_HEADER_LEN bytes into state->pdu.
545 subreq
= rpc_read_send(state
, state
->ev
,
546 state
->cli
->conn
->transport
,
547 state
->pdu
->data
+ RPC_HEADER_LEN
,
548 state
->frag_len
- RPC_HEADER_LEN
);
549 if (tevent_req_nomem(subreq
, req
)) {
552 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
555 static void get_complete_frag_got_rest(struct tevent_req
*subreq
)
557 NTSTATUS status
= rpc_read_recv(subreq
);
558 return tevent_req_simple_finish_ntstatus(subreq
, status
);
561 static NTSTATUS
get_complete_frag_recv(struct tevent_req
*req
)
563 return tevent_req_simple_recv_ntstatus(req
);
566 /****************************************************************************
567 Do basic authentication checks on an incoming pdu.
568 ****************************************************************************/
570 static NTSTATUS
cli_pipe_validate_current_pdu(TALLOC_CTX
*mem_ctx
,
571 struct rpc_pipe_client
*cli
,
572 struct ncacn_packet
*pkt
,
574 uint8_t expected_pkt_type
,
577 DATA_BLOB
*reply_pdu
)
579 const struct dcerpc_response
*r
= NULL
;
580 DATA_BLOB tmp_stub
= { .data
= NULL
};
584 * Point the return values at the real data including the RPC
585 * header. Just in case the caller wants it.
589 if ((pkt
->ptype
== DCERPC_PKT_BIND_ACK
) &&
590 !(pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
592 * TODO: do we still need this hack which was introduced
593 * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
595 * I don't even know what AS/U might be...
597 DEBUG(5, (__location__
": bug in server (AS/U?), setting "
598 "fragment first/last ON.\n"));
599 pkt
->pfc_flags
|= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
602 /* Ensure we have the correct type. */
603 switch (pkt
->ptype
) {
604 case DCERPC_PKT_BIND_NAK
:
605 DEBUG(1, (__location__
": Bind NACK received from %s!\n",
606 rpccli_pipe_txt(talloc_tos(), cli
)));
608 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
610 0, /* max_auth_info */
611 DCERPC_PFC_FLAG_FIRST
|
612 DCERPC_PFC_FLAG_LAST
,
613 0); /* optional flags */
614 if (!NT_STATUS_IS_OK(ret
)) {
615 DEBUG(1, (__location__
": Connection to %s got an unexpected "
616 "RPC packet type - %u, expected %u: %s\n",
617 rpccli_pipe_txt(talloc_tos(), cli
),
618 pkt
->ptype
, expected_pkt_type
,
620 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
624 /* Use this for now... */
625 return NT_STATUS_NETWORK_ACCESS_DENIED
;
627 case DCERPC_PKT_BIND_ACK
:
628 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
630 pkt
->u
.bind_ack
.auth_info
.length
,
631 DCERPC_PFC_FLAG_FIRST
|
632 DCERPC_PFC_FLAG_LAST
,
633 DCERPC_PFC_FLAG_CONC_MPX
|
634 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
635 if (!NT_STATUS_IS_OK(ret
)) {
636 DEBUG(1, (__location__
": Connection to %s got an unexpected "
637 "RPC packet type - %u, expected %u: %s\n",
638 rpccli_pipe_txt(talloc_tos(), cli
),
639 pkt
->ptype
, expected_pkt_type
,
641 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
647 case DCERPC_PKT_ALTER_RESP
:
648 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
650 pkt
->u
.alter_resp
.auth_info
.length
,
651 DCERPC_PFC_FLAG_FIRST
|
652 DCERPC_PFC_FLAG_LAST
,
653 DCERPC_PFC_FLAG_CONC_MPX
|
654 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
655 if (!NT_STATUS_IS_OK(ret
)) {
656 DEBUG(1, (__location__
": Connection to %s got an unexpected "
657 "RPC packet type - %u, expected %u: %s\n",
658 rpccli_pipe_txt(talloc_tos(), cli
),
659 pkt
->ptype
, expected_pkt_type
,
661 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
667 case DCERPC_PKT_RESPONSE
:
669 r
= &pkt
->u
.response
;
671 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
673 r
->stub_and_verifier
.length
,
674 0, /* required_flags */
675 DCERPC_PFC_FLAG_FIRST
|
676 DCERPC_PFC_FLAG_LAST
);
677 if (!NT_STATUS_IS_OK(ret
)) {
678 DEBUG(1, (__location__
": Connection to %s got an unexpected "
679 "RPC packet type - %u, expected %u: %s\n",
680 rpccli_pipe_txt(talloc_tos(), cli
),
681 pkt
->ptype
, expected_pkt_type
,
683 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
687 tmp_stub
.data
= r
->stub_and_verifier
.data
;
688 tmp_stub
.length
= r
->stub_and_verifier
.length
;
690 /* Here's where we deal with incoming sign/seal. */
691 ret
= dcerpc_check_auth(cli
->auth
, pkt
,
693 DCERPC_RESPONSE_LENGTH
,
695 if (!NT_STATUS_IS_OK(ret
)) {
696 DEBUG(1, (__location__
": Connection to %s got an unexpected "
697 "RPC packet type - %u, expected %u: %s\n",
698 rpccli_pipe_txt(talloc_tos(), cli
),
699 pkt
->ptype
, expected_pkt_type
,
701 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
705 /* Point the return values at the NDR data. */
708 DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
709 (long unsigned int)pdu
->length
,
710 (long unsigned int)rdata
->length
));
713 * If this is the first reply, and the allocation hint is
714 * reasonable, try and set up the reply_pdu DATA_BLOB to the
718 if ((reply_pdu
->length
== 0) &&
719 r
->alloc_hint
&& (r
->alloc_hint
< 15*1024*1024)) {
720 if (!data_blob_realloc(mem_ctx
, reply_pdu
,
722 DEBUG(0, ("reply alloc hint %d too "
723 "large to allocate\n",
724 (int)r
->alloc_hint
));
725 return NT_STATUS_NO_MEMORY
;
731 case DCERPC_PKT_FAULT
:
733 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
735 0, /* max_auth_info */
736 DCERPC_PFC_FLAG_FIRST
|
737 DCERPC_PFC_FLAG_LAST
,
738 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
739 if (!NT_STATUS_IS_OK(ret
)) {
740 DEBUG(1, (__location__
": Connection to %s got an unexpected "
741 "RPC packet type - %u, expected %u: %s\n",
742 rpccli_pipe_txt(talloc_tos(), cli
),
743 pkt
->ptype
, expected_pkt_type
,
745 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
749 DEBUG(1, (__location__
": RPC fault code %s received "
751 dcerpc_errstr(talloc_tos(),
752 pkt
->u
.fault
.status
),
753 rpccli_pipe_txt(talloc_tos(), cli
)));
755 return dcerpc_fault_to_nt_status(pkt
->u
.fault
.status
);
758 DEBUG(0, (__location__
"Unknown packet type %u received "
760 (unsigned int)pkt
->ptype
,
761 rpccli_pipe_txt(talloc_tos(), cli
)));
762 return NT_STATUS_RPC_PROTOCOL_ERROR
;
766 if (pkt
->call_id
!= call_id
) {
767 DEBUG(3, (__location__
": Connection to %s got an unexpected "
768 "RPC call_id - %u, not %u\n",
769 rpccli_pipe_txt(talloc_tos(), cli
),
770 pkt
->call_id
, call_id
));
771 return NT_STATUS_RPC_PROTOCOL_ERROR
;
777 /****************************************************************************
778 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
779 ****************************************************************************/
781 struct cli_api_pipe_state
{
782 struct tevent_context
*ev
;
783 struct rpc_cli_transport
*transport
;
788 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
);
789 static void cli_api_pipe_write_done(struct tevent_req
*subreq
);
790 static void cli_api_pipe_read_done(struct tevent_req
*subreq
);
792 static struct tevent_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
793 struct tevent_context
*ev
,
794 struct rpc_cli_transport
*transport
,
795 uint8_t *data
, size_t data_len
,
796 uint32_t max_rdata_len
)
798 struct tevent_req
*req
, *subreq
;
799 struct cli_api_pipe_state
*state
;
801 req
= tevent_req_create(mem_ctx
, &state
, struct cli_api_pipe_state
);
806 state
->transport
= transport
;
808 if (max_rdata_len
< RPC_HEADER_LEN
) {
810 * For a RPC reply we always need at least RPC_HEADER_LEN
811 * bytes. We check this here because we will receive
812 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
814 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
815 return tevent_req_post(req
, ev
);
818 if (transport
->trans_send
!= NULL
) {
819 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
820 max_rdata_len
, transport
->priv
);
821 if (tevent_req_nomem(subreq
, req
)) {
822 return tevent_req_post(req
, ev
);
824 tevent_req_set_callback(subreq
, cli_api_pipe_trans_done
, req
);
829 * If the transport does not provide a "trans" routine, i.e. for
830 * example the ncacn_ip_tcp transport, do the write/read step here.
833 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
834 if (tevent_req_nomem(subreq
, req
)) {
835 return tevent_req_post(req
, ev
);
837 tevent_req_set_callback(subreq
, cli_api_pipe_write_done
, req
);
841 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
)
843 struct tevent_req
*req
= tevent_req_callback_data(
844 subreq
, struct tevent_req
);
845 struct cli_api_pipe_state
*state
= tevent_req_data(
846 req
, struct cli_api_pipe_state
);
849 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
852 if (tevent_req_nterror(req
, status
)) {
855 tevent_req_done(req
);
858 static void cli_api_pipe_write_done(struct tevent_req
*subreq
)
860 struct tevent_req
*req
= tevent_req_callback_data(
861 subreq
, struct tevent_req
);
862 struct cli_api_pipe_state
*state
= tevent_req_data(
863 req
, struct cli_api_pipe_state
);
866 status
= rpc_write_recv(subreq
);
868 if (tevent_req_nterror(req
, status
)) {
872 state
->rdata
= talloc_array(state
, uint8_t, RPC_HEADER_LEN
);
873 if (tevent_req_nomem(state
->rdata
, req
)) {
878 * We don't need to use rpc_read_send here, the upper layer will cope
879 * with a short read, transport->trans_send could also return less
880 * than state->max_rdata_len.
882 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
884 state
->transport
->priv
);
885 if (tevent_req_nomem(subreq
, req
)) {
888 tevent_req_set_callback(subreq
, cli_api_pipe_read_done
, req
);
891 static void cli_api_pipe_read_done(struct tevent_req
*subreq
)
893 struct tevent_req
*req
= tevent_req_callback_data(
894 subreq
, struct tevent_req
);
895 struct cli_api_pipe_state
*state
= tevent_req_data(
896 req
, struct cli_api_pipe_state
);
900 status
= state
->transport
->read_recv(subreq
, &received
);
902 if (tevent_req_nterror(req
, status
)) {
905 state
->rdata_len
= received
;
906 tevent_req_done(req
);
909 static NTSTATUS
cli_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
910 uint8_t **prdata
, uint32_t *prdata_len
)
912 struct cli_api_pipe_state
*state
= tevent_req_data(
913 req
, struct cli_api_pipe_state
);
916 if (tevent_req_is_nterror(req
, &status
)) {
920 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
921 *prdata_len
= state
->rdata_len
;
925 /****************************************************************************
926 Send data on an rpc pipe via trans. The data must be the last
927 pdu fragment of an NDR data stream.
929 Receive response data from an rpc pipe, which may be large...
931 Read the first fragment: unfortunately have to use SMBtrans for the first
932 bit, then SMBreadX for subsequent bits.
934 If first fragment received also wasn't the last fragment, continue
935 getting fragments until we _do_ receive the last fragment.
937 Request/Response PDU's look like the following...
939 |<------------------PDU len----------------------------------------------->|
940 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
942 +------------+-----------------+-------------+---------------+-------------+
943 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
944 +------------+-----------------+-------------+---------------+-------------+
946 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
947 signing & sealing being negotiated.
949 ****************************************************************************/
951 struct rpc_api_pipe_state
{
952 struct tevent_context
*ev
;
953 struct rpc_pipe_client
*cli
;
954 uint8_t expected_pkt_type
;
957 DATA_BLOB incoming_frag
;
958 struct ncacn_packet
*pkt
;
962 size_t reply_pdu_offset
;
966 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
);
967 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
);
968 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
);
970 static struct tevent_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
971 struct tevent_context
*ev
,
972 struct rpc_pipe_client
*cli
,
973 DATA_BLOB
*data
, /* Outgoing PDU */
974 uint8_t expected_pkt_type
,
977 struct tevent_req
*req
, *subreq
;
978 struct rpc_api_pipe_state
*state
;
979 uint16_t max_recv_frag
;
981 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_api_pipe_state
);
987 state
->expected_pkt_type
= expected_pkt_type
;
988 state
->call_id
= call_id
;
989 state
->endianness
= DCERPC_DREP_LE
;
992 * Ensure we're not sending too much.
994 if (data
->length
> cli
->conn
->features
.max_xmit_frag
) {
995 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
996 return tevent_req_post(req
, ev
);
999 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli
)));
1001 if (state
->expected_pkt_type
== DCERPC_PKT_AUTH3
) {
1002 subreq
= rpc_write_send(state
, ev
, cli
->conn
->transport
,
1003 data
->data
, data
->length
);
1004 if (tevent_req_nomem(subreq
, req
)) {
1005 return tevent_req_post(req
, ev
);
1007 tevent_req_set_callback(subreq
, rpc_api_pipe_auth3_done
, req
);
1011 /* get the header first, then fetch the rest once we have
1012 * the frag_length available */
1013 max_recv_frag
= RPC_HEADER_LEN
;
1015 subreq
= cli_api_pipe_send(state
, ev
, cli
->conn
->transport
,
1016 data
->data
, data
->length
, max_recv_frag
);
1017 if (tevent_req_nomem(subreq
, req
)) {
1018 return tevent_req_post(req
, ev
);
1020 tevent_req_set_callback(subreq
, rpc_api_pipe_trans_done
, req
);
1024 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
)
1026 NTSTATUS status
= rpc_write_recv(subreq
);
1027 return tevent_req_simple_finish_ntstatus(subreq
, status
);
1030 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
)
1032 struct tevent_req
*req
= tevent_req_callback_data(
1033 subreq
, struct tevent_req
);
1034 struct rpc_api_pipe_state
*state
= tevent_req_data(
1035 req
, struct rpc_api_pipe_state
);
1037 uint8_t *rdata
= NULL
;
1038 uint32_t rdata_len
= 0;
1040 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
1041 TALLOC_FREE(subreq
);
1042 if (tevent_req_nterror(req
, status
)) {;
1043 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
1047 if (rdata
== NULL
) {
1048 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1049 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1050 tevent_req_done(req
);
1055 * Move data on state->incoming_frag.
1057 state
->incoming_frag
.data
= talloc_move(state
, &rdata
);
1058 state
->incoming_frag
.length
= rdata_len
;
1059 if (!state
->incoming_frag
.data
) {
1060 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1064 /* Ensure we have enough data for a pdu. */
1065 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1066 &state
->incoming_frag
);
1067 if (tevent_req_nomem(subreq
, req
)) {
1070 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1073 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
)
1075 struct tevent_req
*req
= tevent_req_callback_data(
1076 subreq
, struct tevent_req
);
1077 struct rpc_api_pipe_state
*state
= tevent_req_data(
1078 req
, struct rpc_api_pipe_state
);
1080 DATA_BLOB rdata
= { .data
= NULL
};
1082 status
= get_complete_frag_recv(subreq
);
1083 TALLOC_FREE(subreq
);
1084 if (tevent_req_nterror(req
, status
)) {
1085 DEBUG(5, ("get_complete_frag failed: %s\n",
1086 nt_errstr(status
)));
1090 state
->pkt
= talloc(state
, struct ncacn_packet
);
1093 * TODO: do a real async disconnect ...
1095 * For now do it sync...
1097 TALLOC_FREE(state
->cli
->conn
);
1098 tevent_req_oom(req
);
1102 status
= dcerpc_pull_ncacn_packet(state
->pkt
,
1103 &state
->incoming_frag
,
1105 if (tevent_req_nterror(req
, status
)) {
1107 * TODO: do a real async disconnect ...
1109 * For now do it sync...
1111 TALLOC_FREE(state
->cli
->conn
);
1115 if (DEBUGLEVEL
>= 10) {
1116 NDR_PRINT_DEBUG(ncacn_packet
, state
->pkt
);
1119 status
= cli_pipe_validate_current_pdu(state
,
1120 state
->cli
, state
->pkt
,
1121 &state
->incoming_frag
,
1122 state
->expected_pkt_type
,
1127 DBG_DEBUG("got frag len of %zu at offset %zu: %s\n",
1128 state
->incoming_frag
.length
,
1129 state
->reply_pdu_offset
,
1132 if (state
->pkt
->ptype
!= DCERPC_PKT_FAULT
&& !NT_STATUS_IS_OK(status
)) {
1134 * TODO: do a real async disconnect ...
1136 * For now do it sync...
1138 TALLOC_FREE(state
->cli
->conn
);
1139 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
1141 * TODO: do a real async disconnect ...
1143 * For now do it sync...
1145 TALLOC_FREE(state
->cli
->conn
);
1146 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
)) {
1148 * TODO: do a real async disconnect ...
1150 * For now do it sync...
1152 TALLOC_FREE(state
->cli
->conn
);
1154 if (tevent_req_nterror(req
, status
)) {
1158 if ((state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_FIRST
)
1159 && (state
->pkt
->drep
[0] != DCERPC_DREP_LE
)) {
1161 * Set the data type correctly for big-endian data on the
1164 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1166 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1167 state
->endianness
= 0x00; /* BIG ENDIAN */
1170 * Check endianness on subsequent packets.
1172 if (state
->endianness
!= state
->pkt
->drep
[0]) {
1173 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1175 state
->endianness
?"little":"big",
1176 state
->pkt
->drep
[0]?"little":"big"));
1178 * TODO: do a real async disconnect ...
1180 * For now do it sync...
1182 TALLOC_FREE(state
->cli
->conn
);
1183 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1187 if (state
->reply_pdu_offset
+ rdata
.length
> MAX_RPC_DATA_SIZE
) {
1189 * TODO: do a real async disconnect ...
1191 * For now do it sync...
1193 TALLOC_FREE(state
->cli
->conn
);
1194 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1198 /* Now copy the data portion out of the pdu into rbuf. */
1199 if (state
->reply_pdu
.length
< state
->reply_pdu_offset
+ rdata
.length
) {
1200 if (!data_blob_realloc(NULL
, &state
->reply_pdu
,
1201 state
->reply_pdu_offset
+ rdata
.length
)) {
1203 * TODO: do a real async disconnect ...
1205 * For now do it sync...
1207 TALLOC_FREE(state
->cli
->conn
);
1208 tevent_req_oom(req
);
1213 memcpy(state
->reply_pdu
.data
+ state
->reply_pdu_offset
,
1214 rdata
.data
, rdata
.length
);
1215 state
->reply_pdu_offset
+= rdata
.length
;
1217 /* reset state->incoming_frag, there is no need to free it,
1218 * it will be reallocated to the right size the next time
1220 state
->incoming_frag
.length
= 0;
1222 if (state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
) {
1223 /* make sure the pdu length is right now that we
1224 * have all the data available (alloc hint may
1225 * have allocated more than was actually used) */
1226 state
->reply_pdu
.length
= state
->reply_pdu_offset
;
1227 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1228 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1229 (unsigned)state
->reply_pdu
.length
));
1230 tevent_req_done(req
);
1234 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1235 &state
->incoming_frag
);
1236 if (subreq
== NULL
) {
1238 * TODO: do a real async disconnect ...
1240 * For now do it sync...
1242 TALLOC_FREE(state
->cli
->conn
);
1244 if (tevent_req_nomem(subreq
, req
)) {
1247 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1250 static NTSTATUS
rpc_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1251 struct ncacn_packet
**pkt
,
1252 DATA_BLOB
*reply_pdu
)
1254 struct rpc_api_pipe_state
*state
= tevent_req_data(
1255 req
, struct rpc_api_pipe_state
);
1258 if (tevent_req_is_nterror(req
, &status
)) {
1262 /* return data to caller and assign it ownership of memory */
1264 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1265 reply_pdu
->length
= state
->reply_pdu
.length
;
1266 state
->reply_pdu
.length
= 0;
1268 data_blob_free(&state
->reply_pdu
);
1272 *pkt
= talloc_steal(mem_ctx
, state
->pkt
);
1275 return NT_STATUS_OK
;
1278 /*******************************************************************
1279 Creates NTLMSSP auth bind.
1280 ********************************************************************/
1282 static NTSTATUS
create_generic_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1283 TALLOC_CTX
*mem_ctx
,
1284 DATA_BLOB
*auth_token
)
1286 struct gensec_security
*gensec_security
;
1287 DATA_BLOB null_blob
= { .data
= NULL
};
1290 gensec_security
= cli
->auth
->auth_ctx
;
1292 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1293 status
= gensec_update(gensec_security
, mem_ctx
, null_blob
, auth_token
);
1295 if (!NT_STATUS_IS_OK(status
) &&
1296 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1304 /*******************************************************************
1305 Creates the internals of a DCE/RPC bind request or alter context PDU.
1306 ********************************************************************/
1308 static NTSTATUS
create_bind_or_alt_ctx_internal(TALLOC_CTX
*mem_ctx
,
1309 enum dcerpc_pkt_type ptype
,
1310 uint32_t rpc_call_id
,
1311 struct rpc_client_association
*assoc
,
1312 struct rpc_client_connection
*conn
,
1313 uint16_t pres_context_id
,
1314 const struct ndr_syntax_id
*abstract
,
1315 const struct ndr_syntax_id
*transfer
,
1316 const DATA_BLOB
*auth_info
,
1319 uint16_t auth_len
= auth_info
->length
;
1321 struct ndr_syntax_id bind_time_features
= dcerpc_construct_bind_time_features(
1322 assoc
->features
.client
);
1323 struct dcerpc_ctx_list ctx_list
[2] = {
1325 .context_id
= pres_context_id
,
1326 .num_transfer_syntaxes
= 1,
1327 .abstract_syntax
= *abstract
,
1328 .transfer_syntaxes
= (struct ndr_syntax_id
*)discard_const(transfer
),
1332 * For now we assume pres_context_id is 0
1333 * because bind time feature negotiation
1334 * only happens once per association,
1335 * with the first DCERPC Bind.
1337 * With that we use pres_context_id + 1,
1338 * but only consume it from conn->next_pres_context_id
1339 * in check_bind_response().
1341 .context_id
= pres_context_id
+ 1,
1342 .num_transfer_syntaxes
= 1,
1343 .abstract_syntax
= *abstract
,
1344 .transfer_syntaxes
= &bind_time_features
,
1347 uint32_t assoc_group_id
=
1348 dcerpc_binding_get_assoc_group_id(assoc
->binding
);
1349 union dcerpc_payload u
= {
1350 .bind
.max_xmit_frag
= conn
->features
.max_xmit_frag
,
1351 .bind
.max_recv_frag
= conn
->features
.max_recv_frag
,
1352 .bind
.assoc_group_id
= assoc_group_id
,
1353 .bind
.num_contexts
= assoc
->features
.negotiation_done
? 1 : 2,
1354 .bind
.ctx_list
= ctx_list
,
1355 .bind
.auth_info
= *auth_info
,
1357 uint8_t pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
1359 if (conn
->features
.client_hdr_signing
&&
1361 !conn
->features
.hdr_signing
)
1364 * The first authenticated bind or alter_context
1365 * negotiates header signing
1367 pfc_flags
|= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
;
1371 auth_len
-= DCERPC_AUTH_TRAILER_LENGTH
;
1374 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1380 if (!NT_STATUS_IS_OK(status
)) {
1381 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1385 return NT_STATUS_OK
;
1388 /*******************************************************************
1389 Creates a DCE/RPC bind request.
1390 ********************************************************************/
1392 static NTSTATUS
create_rpc_bind_req(TALLOC_CTX
*mem_ctx
,
1393 struct rpc_pipe_client
*cli
,
1394 struct pipe_auth_data
*auth
,
1395 uint32_t rpc_call_id
,
1396 const struct ndr_syntax_id
*abstract
,
1397 const struct ndr_syntax_id
*transfer
,
1400 enum dcerpc_pkt_type ptype
= DCERPC_PKT_BIND
;
1401 DATA_BLOB auth_token
= { .data
= NULL
};
1402 DATA_BLOB auth_info
= { .data
= NULL
};
1405 if (cli
->conn
->features
.bind_done
) {
1406 ptype
= DCERPC_PKT_ALTER
;
1409 if (auth
->auth_type
!= DCERPC_AUTH_TYPE_NONE
) {
1410 ret
= create_generic_auth_rpc_bind_req(
1411 cli
, mem_ctx
, &auth_token
);
1413 if (!NT_STATUS_IS_OK(ret
) &&
1414 !NT_STATUS_EQUAL(ret
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1419 if (auth_token
.length
!= 0) {
1420 ret
= dcerpc_push_dcerpc_auth(cli
,
1423 0, /* auth_pad_length */
1424 auth
->auth_context_id
,
1427 if (!NT_STATUS_IS_OK(ret
)) {
1430 data_blob_free(&auth_token
);
1433 ret
= create_bind_or_alt_ctx_internal(mem_ctx
,
1438 cli
->pres_context_id
,
1443 data_blob_free(&auth_info
);
1448 /*******************************************************************
1450 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1451 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1452 and deals with signing/sealing details.
1453 ********************************************************************/
1455 struct rpc_api_pipe_req_state
{
1456 struct tevent_context
*ev
;
1457 struct rpc_pipe_client
*cli
;
1460 const DATA_BLOB
*req_data
;
1461 const struct GUID
*object_uuid
;
1462 uint32_t req_data_sent
;
1463 DATA_BLOB req_trailer
;
1464 uint32_t req_trailer_sent
;
1465 bool verify_bitmask1
;
1466 bool verify_pcontext
;
1468 DATA_BLOB reply_pdu
;
1471 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
1472 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
1473 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
);
1474 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1475 bool *is_last_frag
);
1477 static struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
1478 struct tevent_context
*ev
,
1479 struct rpc_pipe_client
*cli
,
1481 const struct GUID
*object_uuid
,
1482 const DATA_BLOB
*req_data
)
1484 struct tevent_req
*req
, *subreq
;
1485 struct rpc_api_pipe_req_state
*state
;
1489 req
= tevent_req_create(mem_ctx
, &state
,
1490 struct rpc_api_pipe_req_state
);
1496 state
->op_num
= op_num
;
1497 state
->object_uuid
= object_uuid
;
1498 state
->req_data
= req_data
;
1499 state
->call_id
= ++cli
->assoc
->next_call_id
;
1501 if (cli
->conn
->features
.max_xmit_frag
< DCERPC_REQUEST_LENGTH
1502 + RPC_MAX_SIGN_SIZE
) {
1503 /* Server is screwed up ! */
1504 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1505 return tevent_req_post(req
, ev
);
1508 status
= prepare_verification_trailer(state
);
1509 if (tevent_req_nterror(req
, status
)) {
1510 return tevent_req_post(req
, ev
);
1513 status
= prepare_next_frag(state
, &is_last_frag
);
1514 if (tevent_req_nterror(req
, status
)) {
1515 return tevent_req_post(req
, ev
);
1519 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
1521 DCERPC_PKT_RESPONSE
,
1523 if (tevent_req_nomem(subreq
, req
)) {
1524 return tevent_req_post(req
, ev
);
1526 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1528 subreq
= rpc_write_send(state
, ev
, cli
->conn
->transport
,
1529 state
->rpc_out
.data
,
1530 state
->rpc_out
.length
);
1531 if (tevent_req_nomem(subreq
, req
)) {
1532 return tevent_req_post(req
, ev
);
1534 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1540 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
)
1542 struct pipe_auth_data
*a
= state
->cli
->auth
;
1543 struct dcerpc_sec_verification_trailer
*t
;
1544 struct ndr_push
*ndr
= NULL
;
1545 enum ndr_err_code ndr_err
;
1550 return NT_STATUS_OK
;
1553 if (a
->auth_level
< DCERPC_AUTH_LEVEL_PACKET
) {
1554 return NT_STATUS_OK
;
1557 t
= talloc_zero(state
, struct dcerpc_sec_verification_trailer
);
1559 return NT_STATUS_NO_MEMORY
;
1562 if (!a
->verified_bitmask1
) {
1563 t
->commands
= talloc_realloc(t
, t
->commands
,
1564 struct dcerpc_sec_vt
,
1565 t
->count
.count
+ 1);
1566 if (t
->commands
== NULL
) {
1567 return NT_STATUS_NO_MEMORY
;
1569 t
->commands
[t
->count
.count
++] = (struct dcerpc_sec_vt
) {
1570 .command
= DCERPC_SEC_VT_COMMAND_BITMASK1
,
1571 .u
.bitmask1
= (state
->cli
->conn
->features
.client_hdr_signing
) ?
1572 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING
:
1575 state
->verify_bitmask1
= true;
1578 if (!state
->cli
->verified_pcontext
) {
1579 t
->commands
= talloc_realloc(t
, t
->commands
,
1580 struct dcerpc_sec_vt
,
1581 t
->count
.count
+ 1);
1582 if (t
->commands
== NULL
) {
1583 return NT_STATUS_NO_MEMORY
;
1585 t
->commands
[t
->count
.count
++] = (struct dcerpc_sec_vt
) {
1586 .command
= DCERPC_SEC_VT_COMMAND_PCONTEXT
,
1587 .u
.pcontext
.abstract_syntax
=
1588 state
->cli
->table
->syntax_id
,
1589 .u
.pcontext
.transfer_syntax
=
1590 state
->cli
->transfer_syntax
,
1592 state
->verify_pcontext
= true;
1595 if (!a
->hdr_signing
) {
1596 t
->commands
= talloc_realloc(t
, t
->commands
,
1597 struct dcerpc_sec_vt
,
1598 t
->count
.count
+ 1);
1599 if (t
->commands
== NULL
) {
1600 return NT_STATUS_NO_MEMORY
;
1602 t
->commands
[t
->count
.count
++] = (struct dcerpc_sec_vt
) {
1603 .command
= DCERPC_SEC_VT_COMMAND_HEADER2
,
1604 .u
.header2
.ptype
= DCERPC_PKT_REQUEST
,
1605 .u
.header2
.drep
[0] = DCERPC_DREP_LE
,
1606 .u
.header2
.call_id
= state
->call_id
,
1607 .u
.header2
.context_id
= state
->cli
->pres_context_id
,
1608 .u
.header2
.opnum
= state
->op_num
,
1612 if (t
->count
.count
== 0) {
1614 return NT_STATUS_OK
;
1617 t
->commands
[t
->count
.count
- 1].command
|= DCERPC_SEC_VT_COMMAND_END
;
1619 if (DEBUGLEVEL
>= 10) {
1620 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer
, t
);
1623 ndr
= ndr_push_init_ctx(state
);
1625 return NT_STATUS_NO_MEMORY
;
1628 ndr_err
= ndr_push_dcerpc_sec_verification_trailer(ndr
,
1629 NDR_SCALARS
| NDR_BUFFERS
,
1632 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1633 return ndr_map_error2ntstatus(ndr_err
);
1635 state
->req_trailer
= ndr_push_blob(ndr
);
1637 align
= state
->req_data
->length
& 0x3;
1644 const uint8_t zeros
[4] = { 0, };
1646 ok
= data_blob_append(ndr
, &state
->req_trailer
, zeros
, pad
);
1648 return NT_STATUS_NO_MEMORY
;
1651 /* move the padding to the start */
1652 p
= state
->req_trailer
.data
;
1653 memmove(p
+ pad
, p
, state
->req_trailer
.length
- pad
);
1657 return NT_STATUS_OK
;
1660 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1668 size_t data_thistime
;
1669 size_t trailer_left
;
1670 size_t trailer_thistime
= 0;
1672 size_t total_thistime
;
1675 union dcerpc_payload u
;
1677 data_left
= state
->req_data
->length
- state
->req_data_sent
;
1678 trailer_left
= state
->req_trailer
.length
- state
->req_trailer_sent
;
1679 total_left
= data_left
+ trailer_left
;
1680 if ((total_left
< data_left
) || (total_left
< trailer_left
)) {
1684 return NT_STATUS_INVALID_PARAMETER_MIX
;
1687 status
= dcerpc_guess_sizes(state
->cli
->auth
,
1688 DCERPC_REQUEST_LENGTH
, total_left
,
1689 state
->cli
->conn
->features
.max_xmit_frag
,
1691 &frag_len
, &auth_len
, &pad_len
);
1692 if (!NT_STATUS_IS_OK(status
)) {
1696 if (state
->req_data_sent
== 0) {
1697 flags
= DCERPC_PFC_FLAG_FIRST
;
1700 if (total_thistime
== total_left
) {
1701 flags
|= DCERPC_PFC_FLAG_LAST
;
1704 data_thistime
= MIN(total_thistime
, data_left
);
1705 if (data_thistime
< total_thistime
) {
1706 trailer_thistime
= total_thistime
- data_thistime
;
1709 data_blob_free(&state
->rpc_out
);
1711 u
= (union dcerpc_payload
) {
1712 .request
.alloc_hint
= total_left
,
1713 .request
.context_id
= state
->cli
->pres_context_id
,
1714 .request
.opnum
= state
->op_num
,
1717 if (state
->object_uuid
) {
1718 flags
|= DCERPC_PFC_FLAG_OBJECT_UUID
;
1719 u
.request
.object
.object
= *state
->object_uuid
;
1720 frag_len
+= ndr_size_GUID(state
->object_uuid
, 0);
1723 status
= dcerpc_push_ncacn_packet(state
,
1730 if (!NT_STATUS_IS_OK(status
)) {
1734 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1735 * compute it right for requests because the auth trailer is missing
1737 dcerpc_set_frag_length(&state
->rpc_out
, frag_len
);
1739 if (data_thistime
> 0) {
1740 /* Copy in the data. */
1741 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1742 state
->req_data
->data
+ state
->req_data_sent
,
1745 return NT_STATUS_NO_MEMORY
;
1747 state
->req_data_sent
+= data_thistime
;
1750 if (trailer_thistime
> 0) {
1751 /* Copy in the verification trailer. */
1752 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1753 state
->req_trailer
.data
+ state
->req_trailer_sent
,
1756 return NT_STATUS_NO_MEMORY
;
1758 state
->req_trailer_sent
+= trailer_thistime
;
1761 switch (state
->cli
->auth
->auth_level
) {
1762 case DCERPC_AUTH_LEVEL_NONE
:
1763 case DCERPC_AUTH_LEVEL_CONNECT
:
1765 case DCERPC_AUTH_LEVEL_PACKET
:
1766 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1767 case DCERPC_AUTH_LEVEL_PRIVACY
:
1768 status
= dcerpc_add_auth_footer(state
->cli
->auth
, pad_len
,
1770 if (!NT_STATUS_IS_OK(status
)) {
1775 return NT_STATUS_INVALID_PARAMETER
;
1778 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
1783 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
1785 struct tevent_req
*req
= tevent_req_callback_data(
1786 subreq
, struct tevent_req
);
1787 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1788 req
, struct rpc_api_pipe_req_state
);
1792 status
= rpc_write_recv(subreq
);
1793 TALLOC_FREE(subreq
);
1794 if (tevent_req_nterror(req
, status
)) {
1798 status
= prepare_next_frag(state
, &is_last_frag
);
1799 if (tevent_req_nterror(req
, status
)) {
1804 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
1806 DCERPC_PKT_RESPONSE
,
1808 if (tevent_req_nomem(subreq
, req
)) {
1811 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1813 subreq
= rpc_write_send(state
, state
->ev
,
1814 state
->cli
->conn
->transport
,
1815 state
->rpc_out
.data
,
1816 state
->rpc_out
.length
);
1817 if (tevent_req_nomem(subreq
, req
)) {
1820 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1825 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
1827 struct tevent_req
*req
= tevent_req_callback_data(
1828 subreq
, struct tevent_req
);
1829 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1830 req
, struct rpc_api_pipe_req_state
);
1833 status
= rpc_api_pipe_recv(subreq
, state
, NULL
, &state
->reply_pdu
);
1834 TALLOC_FREE(subreq
);
1835 if (tevent_req_nterror(req
, status
)) {
1839 if (state
->cli
->auth
== NULL
) {
1840 tevent_req_done(req
);
1844 if (state
->verify_bitmask1
) {
1845 state
->cli
->auth
->verified_bitmask1
= true;
1848 if (state
->verify_pcontext
) {
1849 state
->cli
->verified_pcontext
= true;
1852 tevent_req_done(req
);
1855 static NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1856 DATA_BLOB
*reply_pdu
)
1858 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1859 req
, struct rpc_api_pipe_req_state
);
1862 if (tevent_req_is_nterror(req
, &status
)) {
1864 * We always have to initialize to reply pdu, even if there is
1865 * none. The rpccli_* caller routines expect this.
1867 *reply_pdu
= data_blob_null
;
1871 /* return data to caller and assign it ownership of memory */
1872 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1873 reply_pdu
->length
= state
->reply_pdu
.length
;
1874 state
->reply_pdu
.length
= 0;
1876 return NT_STATUS_OK
;
1879 /****************************************************************************
1880 Check the rpc bind acknowledge response.
1881 ****************************************************************************/
1883 static bool check_bind_response(const struct dcerpc_bind_ack
*r
,
1884 struct rpc_pipe_client
*cli
)
1886 const struct ndr_syntax_id
*transfer
= &cli
->transfer_syntax
;
1887 uint32_t assoc_group_id
=
1888 dcerpc_binding_get_assoc_group_id(cli
->assoc
->binding
);
1889 struct dcerpc_ack_ctx ctx
;
1892 if (r
->secondary_address_size
== 0) {
1893 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)\n"));
1896 if (assoc_group_id
== 0) {
1900 * We only capture the first assoc_group_id we're
1903 * Current samba releases may ignore the client value
1904 * and return a different assoc_group_id if the
1905 * client given one is not found in the preforked
1906 * process. This applies to the source4 netlogon,
1907 * which uses DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED.
1910 status
= dcerpc_binding_set_assoc_group_id(cli
->assoc
->binding
,
1912 if (!NT_STATUS_IS_OK(status
)) {
1917 if (!cli
->conn
->features
.bind_done
) {
1919 * DCE-RPC 1.1 (c706) specifies
1920 * CONST_MUST_RCV_FRAG_SIZE as 1432
1923 if (r
->max_xmit_frag
< 1432) {
1926 if (r
->max_recv_frag
< 1432) {
1930 cli
->conn
->features
.max_xmit_frag
=
1931 MIN(cli
->conn
->features
.max_xmit_frag
, r
->max_xmit_frag
);
1932 cli
->conn
->features
.max_recv_frag
=
1933 MIN(cli
->conn
->features
.max_recv_frag
, r
->max_recv_frag
);
1935 cli
->conn
->features
.bind_done
= true;
1938 if (r
->num_results
< 1 || !r
->ctx_list
) {
1942 ctx
= r
->ctx_list
[0];
1944 /* check the transfer syntax */
1945 equal
= ndr_syntax_id_equal(&ctx
.syntax
, transfer
);
1947 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1951 if (ctx
.result
!= DCERPC_BIND_ACK_RESULT_ACCEPTANCE
) {
1952 DBG_NOTICE("bind denied result: %d reason: %x\n",
1953 ctx
.result
, ctx
.reason
.value
);
1957 if (r
->num_results
>= 2) {
1958 const struct dcerpc_ack_ctx
*neg
= &r
->ctx_list
[1];
1960 if (neg
->result
== DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK
) {
1961 cli
->assoc
->features
.negotiated
= neg
->reason
.negotiate
;
1962 cli
->assoc
->features
.negotiation_done
= true;
1964 * consume presentation context used for bind time
1965 * feature negotiation
1967 cli
->conn
->next_pres_context_id
++;
1969 DBG_DEBUG("bind_time_feature failed - "
1970 "result: %d reason %x\n",
1971 neg
->result
, neg
->reason
.value
);
1975 DEBUG(5,("check_bind_response: accepted!\n"));
1979 /*******************************************************************
1980 Creates a DCE/RPC bind authentication response.
1981 This is the packet that is sent back to the server once we
1982 have received a BIND-ACK, to finish the third leg of
1983 the authentication handshake.
1984 ********************************************************************/
1986 static NTSTATUS
create_rpc_bind_auth3(TALLOC_CTX
*mem_ctx
,
1987 struct rpc_pipe_client
*cli
,
1988 struct pipe_auth_data
*auth
,
1989 uint32_t rpc_call_id
,
1990 DATA_BLOB
*pauth_blob
,
1994 union dcerpc_payload u
= { .auth3
._pad
= 0, };
1996 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1999 0, /* auth_pad_length */
2000 auth
->auth_context_id
,
2002 &u
.auth3
.auth_info
);
2003 if (!NT_STATUS_IS_OK(status
)) {
2007 status
= dcerpc_push_ncacn_packet(mem_ctx
,
2009 DCERPC_PFC_FLAG_FIRST
|
2010 DCERPC_PFC_FLAG_LAST
,
2015 data_blob_free(&u
.auth3
.auth_info
);
2016 if (!NT_STATUS_IS_OK(status
)) {
2017 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2021 return NT_STATUS_OK
;
2024 /*******************************************************************
2025 Creates a DCE/RPC bind alter context authentication request which
2026 may contain a spnego auth blob
2027 ********************************************************************/
2029 static NTSTATUS
create_rpc_alter_context(TALLOC_CTX
*mem_ctx
,
2030 struct pipe_auth_data
*auth
,
2031 uint32_t rpc_call_id
,
2032 struct rpc_client_association
*assoc
,
2033 struct rpc_client_connection
*conn
,
2034 uint16_t pres_context_id
,
2035 const struct ndr_syntax_id
*abstract
,
2036 const struct ndr_syntax_id
*transfer
,
2037 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
2040 DATA_BLOB auth_info
;
2043 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
2046 0, /* auth_pad_length */
2047 auth
->auth_context_id
,
2050 if (!NT_STATUS_IS_OK(status
)) {
2054 status
= create_bind_or_alt_ctx_internal(mem_ctx
,
2064 data_blob_free(&auth_info
);
2068 /****************************************************************************
2070 ****************************************************************************/
2072 struct rpc_pipe_bind_state
{
2073 struct tevent_context
*ev
;
2074 struct rpc_pipe_client
*cli
;
2077 uint32_t rpc_call_id
;
2080 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
2081 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
2082 struct rpc_pipe_bind_state
*state
,
2083 DATA_BLOB
*credentials
);
2084 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
2085 struct rpc_pipe_bind_state
*state
,
2086 DATA_BLOB
*credentials
);
2088 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
2089 struct tevent_context
*ev
,
2090 struct rpc_pipe_client
*cli
,
2091 struct pipe_auth_data
*auth
)
2093 struct tevent_req
*req
, *subreq
;
2094 struct rpc_pipe_bind_state
*state
;
2095 struct cli_credentials
*creds
= NULL
;
2096 const char *username
= NULL
;
2097 enum dcerpc_pkt_type rep_ptype
= DCERPC_PKT_BIND_ACK
;
2100 if (cli
->conn
->features
.bind_done
) {
2101 rep_ptype
= DCERPC_PKT_ALTER_RESP
;
2104 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
2109 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2110 rpccli_pipe_txt(talloc_tos(), cli
),
2111 (unsigned int)auth
->auth_type
,
2112 (unsigned int)auth
->auth_level
));
2116 state
->rpc_call_id
= ++cli
->assoc
->next_call_id
;
2118 cli
->auth
= talloc_move(cli
, &auth
);
2119 if (cli
->auth
->auth_context_id
== UINT32_MAX
) {
2120 if (cli
->conn
->next_auth_context_id
== UINT32_MAX
) {
2121 tevent_req_nterror(req
, NT_STATUS_RPC_NO_MORE_BINDINGS
);
2122 return tevent_req_post(req
, ev
);
2124 cli
->auth
->auth_context_id
= cli
->conn
->next_auth_context_id
++;
2126 if (cli
->pres_context_id
== UINT16_MAX
) {
2127 if (cli
->conn
->next_pres_context_id
== UINT16_MAX
) {
2128 tevent_req_nterror(req
, NT_STATUS_RPC_NO_MORE_BINDINGS
);
2129 return tevent_req_post(req
, ev
);
2131 cli
->pres_context_id
= cli
->conn
->next_pres_context_id
++;
2134 cli
->binding_handle
= rpccli_bh_create(cli
, NULL
, cli
->table
);
2135 if (tevent_req_nomem(cli
->binding_handle
, req
)) {
2136 return tevent_req_post(req
, ev
);
2139 creds
= gensec_get_credentials(cli
->auth
->auth_ctx
);
2140 username
= cli_credentials_get_username(creds
);
2141 cli
->printer_username
= talloc_strdup(cli
, username
);
2142 if (tevent_req_nomem(cli
->printer_username
, req
)) {
2143 return tevent_req_post(req
, ev
);
2146 /* Marshall the outgoing data. */
2147 status
= create_rpc_bind_req(state
, cli
,
2150 &cli
->table
->syntax_id
,
2151 &cli
->transfer_syntax
,
2154 if (!NT_STATUS_IS_OK(status
) &&
2155 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2156 tevent_req_nterror(req
, status
);
2157 return tevent_req_post(req
, ev
);
2160 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
2161 rep_ptype
, state
->rpc_call_id
);
2162 if (tevent_req_nomem(subreq
, req
)) {
2163 return tevent_req_post(req
, ev
);
2165 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2169 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
2171 struct tevent_req
*req
= tevent_req_callback_data(
2172 subreq
, struct tevent_req
);
2173 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2174 req
, struct rpc_pipe_bind_state
);
2175 struct pipe_auth_data
*pauth
= state
->cli
->auth
;
2176 struct gensec_security
*gensec_security
;
2177 struct ncacn_packet
*pkt
= NULL
;
2178 struct dcerpc_auth auth
;
2179 DATA_BLOB auth_token
= { .data
= NULL
};
2182 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, NULL
);
2183 TALLOC_FREE(subreq
);
2184 if (tevent_req_nterror(req
, status
)) {
2185 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2186 rpccli_pipe_txt(talloc_tos(), state
->cli
),
2187 nt_errstr(status
)));
2192 tevent_req_done(req
);
2196 if (!check_bind_response(&pkt
->u
.bind_ack
, state
->cli
)) {
2197 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2198 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2202 if (state
->cli
->conn
->features
.client_hdr_signing
&&
2203 pkt
->pfc_flags
& DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
)
2205 state
->cli
->conn
->features
.hdr_signing
= true;
2208 if (pauth
->auth_type
== DCERPC_AUTH_TYPE_NONE
) {
2209 /* Bind complete. */
2210 tevent_req_done(req
);
2214 if (pkt
->auth_length
== 0) {
2215 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2219 pauth
->hdr_signing
= state
->cli
->conn
->features
.hdr_signing
;
2221 /* get auth credentials */
2222 status
= dcerpc_pull_auth_trailer(pkt
, talloc_tos(),
2223 &pkt
->u
.bind_ack
.auth_info
,
2225 if (tevent_req_nterror(req
, status
)) {
2226 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2227 nt_errstr(status
)));
2231 if (auth
.auth_type
!= pauth
->auth_type
) {
2232 DBG_ERR("Auth type %u mismatch expected %u.\n",
2233 auth
.auth_type
, pauth
->auth_type
);
2234 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2238 if (auth
.auth_level
!= pauth
->auth_level
) {
2239 DBG_ERR("Auth level %u mismatch expected %u.\n",
2240 auth
.auth_level
, pauth
->auth_level
);
2241 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2245 if (auth
.auth_context_id
!= pauth
->auth_context_id
) {
2246 DBG_ERR("Auth context id %"PRIu32
" mismatch "
2247 "expected %"PRIu32
".\n",
2248 auth
.auth_context_id
,
2249 pauth
->auth_context_id
);
2250 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2255 * For authenticated binds we may need to do 3 or 4 leg binds.
2258 if (pauth
->auth_type
== DCERPC_AUTH_TYPE_NONE
) {
2259 /* Bind complete. */
2260 tevent_req_done(req
);
2264 gensec_security
= pauth
->auth_ctx
;
2266 status
= gensec_update(gensec_security
, state
,
2267 auth
.credentials
, &auth_token
);
2268 if (NT_STATUS_EQUAL(status
,
2269 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2270 status
= rpc_bind_next_send(req
, state
,
2272 } else if (NT_STATUS_IS_OK(status
)) {
2273 if (pauth
->hdr_signing
) {
2274 gensec_want_feature(gensec_security
,
2275 GENSEC_FEATURE_SIGN_PKT_HEADER
);
2278 if (auth_token
.length
== 0) {
2279 /* Bind complete. */
2280 tevent_req_done(req
);
2283 status
= rpc_bind_finish_send(req
, state
,
2287 if (!NT_STATUS_IS_OK(status
)) {
2288 tevent_req_nterror(req
, status
);
2293 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
2294 struct rpc_pipe_bind_state
*state
,
2295 DATA_BLOB
*auth_token
)
2297 struct pipe_auth_data
*auth
= state
->cli
->auth
;
2298 struct tevent_req
*subreq
;
2301 /* Now prepare the alter context pdu. */
2302 data_blob_free(&state
->rpc_out
);
2304 status
= create_rpc_alter_context(state
, auth
,
2308 state
->cli
->pres_context_id
,
2309 &state
->cli
->table
->syntax_id
,
2310 &state
->cli
->transfer_syntax
,
2313 if (!NT_STATUS_IS_OK(status
)) {
2317 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2318 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
,
2319 state
->rpc_call_id
);
2320 if (subreq
== NULL
) {
2321 return NT_STATUS_NO_MEMORY
;
2323 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2324 return NT_STATUS_OK
;
2327 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
2328 struct rpc_pipe_bind_state
*state
,
2329 DATA_BLOB
*auth_token
)
2331 struct pipe_auth_data
*auth
= state
->cli
->auth
;
2332 struct tevent_req
*subreq
;
2335 state
->auth3
= true;
2337 /* Now prepare the auth3 context pdu. */
2338 data_blob_free(&state
->rpc_out
);
2340 status
= create_rpc_bind_auth3(state
, state
->cli
, auth
,
2344 if (!NT_STATUS_IS_OK(status
)) {
2348 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2349 &state
->rpc_out
, DCERPC_PKT_AUTH3
,
2350 state
->rpc_call_id
);
2351 if (subreq
== NULL
) {
2352 return NT_STATUS_NO_MEMORY
;
2354 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2355 return NT_STATUS_OK
;
2358 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
2360 return tevent_req_simple_recv_ntstatus(req
);
2363 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2364 struct pipe_auth_data
*auth
)
2366 TALLOC_CTX
*frame
= talloc_stackframe();
2367 struct tevent_context
*ev
;
2368 struct tevent_req
*req
;
2369 NTSTATUS status
= NT_STATUS_OK
;
2371 ev
= samba_tevent_context_init(frame
);
2373 status
= NT_STATUS_NO_MEMORY
;
2377 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
2379 status
= NT_STATUS_NO_MEMORY
;
2383 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2387 status
= rpc_pipe_bind_recv(req
);
2393 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2395 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
2396 unsigned int timeout
)
2398 if (rpc_cli
== NULL
) {
2399 return RPCCLI_DEFAULT_TIMEOUT
;
2402 if (rpc_cli
->binding_handle
== NULL
) {
2403 return RPCCLI_DEFAULT_TIMEOUT
;
2406 return dcerpc_binding_handle_set_timeout(rpc_cli
->binding_handle
,
2410 bool rpccli_is_connected(struct rpc_pipe_client
*rpc_cli
)
2412 if (rpc_cli
== NULL
) {
2416 if (rpc_cli
->binding_handle
== NULL
) {
2420 return dcerpc_binding_handle_is_connected(rpc_cli
->binding_handle
);
2423 struct rpccli_bh_state
{
2424 struct rpc_pipe_client
*rpc_cli
;
2425 struct dcerpc_binding
*binding
;
2428 static const struct dcerpc_binding
*rpccli_bh_get_binding(struct dcerpc_binding_handle
*h
)
2430 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2431 struct rpccli_bh_state
);
2436 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle
*h
)
2438 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2439 struct rpccli_bh_state
);
2440 struct rpc_cli_transport
*transport
= NULL
;
2442 if (hs
->rpc_cli
== NULL
) {
2446 if (hs
->rpc_cli
->conn
== NULL
) {
2450 transport
= hs
->rpc_cli
->conn
->transport
;
2451 if (transport
== NULL
) {
2455 if (transport
->is_connected
== NULL
) {
2459 return transport
->is_connected(transport
->priv
);
2462 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle
*h
,
2465 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2466 struct rpccli_bh_state
);
2467 struct rpc_cli_transport
*transport
= NULL
;
2470 if (hs
->rpc_cli
->conn
== NULL
) {
2471 return RPCCLI_DEFAULT_TIMEOUT
;
2474 transport
= hs
->rpc_cli
->conn
->transport
;
2475 if (transport
== NULL
) {
2476 return RPCCLI_DEFAULT_TIMEOUT
;
2479 if (transport
->set_timeout
== NULL
) {
2480 return RPCCLI_DEFAULT_TIMEOUT
;
2483 old
= transport
->set_timeout(transport
->priv
, timeout
);
2485 return RPCCLI_DEFAULT_TIMEOUT
;
2491 static NTSTATUS
rpccli_bh_transport_session_key(struct dcerpc_binding_handle
*h
,
2492 TALLOC_CTX
*mem_ctx
,
2493 DATA_BLOB
*session_key
)
2495 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2496 struct rpccli_bh_state
);
2497 DATA_BLOB sk
= { .length
= 0, };
2499 if (hs
->rpc_cli
== NULL
) {
2500 return NT_STATUS_NO_USER_SESSION_KEY
;
2503 if (hs
->rpc_cli
->conn
== NULL
) {
2504 return NT_STATUS_NO_USER_SESSION_KEY
;
2507 if (hs
->rpc_cli
->conn
->transport_session_key
.length
== 0) {
2508 return NT_STATUS_NO_USER_SESSION_KEY
;
2511 sk
= hs
->rpc_cli
->conn
->transport_session_key
;
2512 sk
.length
= MIN(sk
.length
, 16);
2514 *session_key
= data_blob_dup_talloc(mem_ctx
, sk
);
2515 if (session_key
->length
!= sk
.length
) {
2516 return NT_STATUS_NO_MEMORY
;
2518 talloc_keep_secret(session_key
->data
);
2519 return NT_STATUS_OK
;
2522 static void rpccli_bh_auth_info(struct dcerpc_binding_handle
*h
,
2523 enum dcerpc_AuthType
*auth_type
,
2524 enum dcerpc_AuthLevel
*auth_level
)
2526 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2527 struct rpccli_bh_state
);
2529 if (hs
->rpc_cli
== NULL
) {
2533 if (hs
->rpc_cli
->auth
== NULL
) {
2537 *auth_type
= hs
->rpc_cli
->auth
->auth_type
;
2538 *auth_level
= hs
->rpc_cli
->auth
->auth_level
;
2541 static NTSTATUS
rpccli_bh_auth_session_key(struct dcerpc_binding_handle
*h
,
2542 TALLOC_CTX
*mem_ctx
,
2543 DATA_BLOB
*session_key
)
2545 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2546 struct rpccli_bh_state
);
2547 struct pipe_auth_data
*auth
= NULL
;
2550 if (hs
->rpc_cli
== NULL
) {
2551 return NT_STATUS_NO_USER_SESSION_KEY
;
2554 if (hs
->rpc_cli
->auth
== NULL
) {
2555 return NT_STATUS_NO_USER_SESSION_KEY
;
2558 auth
= hs
->rpc_cli
->auth
;
2560 if (auth
->auth_type
== DCERPC_AUTH_TYPE_NONE
) {
2561 return NT_STATUS_NO_USER_SESSION_KEY
;
2564 if (auth
->auth_ctx
== NULL
) {
2565 return NT_STATUS_NO_USER_SESSION_KEY
;
2568 status
= gensec_session_key(auth
->auth_ctx
,
2571 if (!NT_STATUS_IS_OK(status
)) {
2575 talloc_keep_secret(session_key
->data
);
2576 return NT_STATUS_OK
;
2579 struct rpccli_bh_raw_call_state
{
2585 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
);
2587 static struct tevent_req
*rpccli_bh_raw_call_send(TALLOC_CTX
*mem_ctx
,
2588 struct tevent_context
*ev
,
2589 struct dcerpc_binding_handle
*h
,
2590 const struct GUID
*object
,
2593 const uint8_t *in_data
,
2596 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2597 struct rpccli_bh_state
);
2598 struct tevent_req
*req
;
2599 struct rpccli_bh_raw_call_state
*state
;
2601 struct tevent_req
*subreq
;
2603 req
= tevent_req_create(mem_ctx
, &state
,
2604 struct rpccli_bh_raw_call_state
);
2608 state
->in_data
.data
= discard_const_p(uint8_t, in_data
);
2609 state
->in_data
.length
= in_length
;
2611 ok
= rpccli_bh_is_connected(h
);
2613 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2614 return tevent_req_post(req
, ev
);
2617 subreq
= rpc_api_pipe_req_send(state
, ev
, hs
->rpc_cli
,
2618 opnum
, object
, &state
->in_data
);
2619 if (tevent_req_nomem(subreq
, req
)) {
2620 return tevent_req_post(req
, ev
);
2622 tevent_req_set_callback(subreq
, rpccli_bh_raw_call_done
, req
);
2627 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
)
2629 struct tevent_req
*req
=
2630 tevent_req_callback_data(subreq
,
2632 struct rpccli_bh_raw_call_state
*state
=
2633 tevent_req_data(req
,
2634 struct rpccli_bh_raw_call_state
);
2637 state
->out_flags
= 0;
2639 /* TODO: support bigendian responses */
2641 status
= rpc_api_pipe_req_recv(subreq
, state
, &state
->out_data
);
2642 TALLOC_FREE(subreq
);
2643 if (tevent_req_nterror(req
, status
)) {
2647 tevent_req_done(req
);
2650 static NTSTATUS
rpccli_bh_raw_call_recv(struct tevent_req
*req
,
2651 TALLOC_CTX
*mem_ctx
,
2654 uint32_t *out_flags
)
2656 struct rpccli_bh_raw_call_state
*state
=
2657 tevent_req_data(req
,
2658 struct rpccli_bh_raw_call_state
);
2661 if (tevent_req_is_nterror(req
, &status
)) {
2662 tevent_req_received(req
);
2666 *out_data
= talloc_move(mem_ctx
, &state
->out_data
.data
);
2667 *out_length
= state
->out_data
.length
;
2668 *out_flags
= state
->out_flags
;
2669 tevent_req_received(req
);
2670 return NT_STATUS_OK
;
2673 struct rpccli_bh_disconnect_state
{
2677 static struct tevent_req
*rpccli_bh_disconnect_send(TALLOC_CTX
*mem_ctx
,
2678 struct tevent_context
*ev
,
2679 struct dcerpc_binding_handle
*h
)
2681 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2682 struct rpccli_bh_state
);
2683 struct tevent_req
*req
;
2684 struct rpccli_bh_disconnect_state
*state
;
2687 req
= tevent_req_create(mem_ctx
, &state
,
2688 struct rpccli_bh_disconnect_state
);
2693 ok
= rpccli_bh_is_connected(h
);
2695 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2696 return tevent_req_post(req
, ev
);
2700 * TODO: do a real async disconnect ...
2702 * For now we do it sync...
2704 TALLOC_FREE(hs
->rpc_cli
->conn
);
2707 tevent_req_done(req
);
2708 return tevent_req_post(req
, ev
);
2711 static NTSTATUS
rpccli_bh_disconnect_recv(struct tevent_req
*req
)
2713 return tevent_req_simple_recv_ntstatus(req
);
2716 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle
*h
)
2721 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle
*h
,
2722 ndr_flags_type ndr_flags
,
2723 const void *_struct_ptr
,
2724 const struct ndr_interface_call
*call
)
2726 void *struct_ptr
= discard_const(_struct_ptr
);
2728 if (DEBUGLEVEL
< 10) {
2732 if (ndr_flags
& NDR_IN
) {
2733 ndr_print_function_debug(call
->ndr_print
,
2738 if (ndr_flags
& NDR_OUT
) {
2739 ndr_print_function_debug(call
->ndr_print
,
2746 static const struct dcerpc_binding_handle_ops rpccli_bh_ops
= {
2748 .get_binding
= rpccli_bh_get_binding
,
2749 .is_connected
= rpccli_bh_is_connected
,
2750 .set_timeout
= rpccli_bh_set_timeout
,
2751 .transport_session_key
= rpccli_bh_transport_session_key
,
2752 .auth_info
= rpccli_bh_auth_info
,
2753 .auth_session_key
= rpccli_bh_auth_session_key
,
2754 .raw_call_send
= rpccli_bh_raw_call_send
,
2755 .raw_call_recv
= rpccli_bh_raw_call_recv
,
2756 .disconnect_send
= rpccli_bh_disconnect_send
,
2757 .disconnect_recv
= rpccli_bh_disconnect_recv
,
2759 .ref_alloc
= rpccli_bh_ref_alloc
,
2760 .do_ndr_print
= rpccli_bh_do_ndr_print
,
2763 /* initialise a rpc_pipe_client binding handle */
2764 struct dcerpc_binding_handle
*rpccli_bh_create(struct rpc_pipe_client
*c
,
2765 const struct GUID
*object
,
2766 const struct ndr_interface_table
*table
)
2768 struct dcerpc_binding_handle
*h
= NULL
;
2769 struct rpccli_bh_state
*hs
= NULL
;
2770 struct dcerpc_binding
*b
= NULL
;
2771 char localaddr
[INET6_ADDRSTRLEN
] = { 0, };
2772 uint32_t a_flags
= 0;
2773 uint32_t c_flags
= 0;
2776 if (c
->conn
->features
.hdr_signing
) {
2777 a_flags
|= DCERPC_HEADER_SIGNING
;
2779 c_flags
|= DCERPC_HEADER_SIGNING
;
2782 switch (c
->auth
->auth_type
) {
2783 case DCERPC_AUTH_TYPE_KRB5
:
2784 a_flags
|= DCERPC_AUTH_KRB5
;
2785 c_flags
|= DCERPC_AUTH_NTLM
;
2786 c_flags
|= DCERPC_AUTH_SPNEGO
;
2787 c_flags
|= DCERPC_SCHANNEL
;
2789 case DCERPC_AUTH_TYPE_NTLMSSP
:
2790 c_flags
|= DCERPC_AUTH_KRB5
;
2791 a_flags
|= DCERPC_AUTH_NTLM
;
2792 c_flags
|= DCERPC_AUTH_SPNEGO
;
2793 c_flags
|= DCERPC_SCHANNEL
;
2795 case DCERPC_AUTH_TYPE_SPNEGO
:
2796 c_flags
|= DCERPC_AUTH_KRB5
;
2797 c_flags
|= DCERPC_AUTH_NTLM
;
2798 a_flags
|= DCERPC_AUTH_SPNEGO
;
2799 c_flags
|= DCERPC_SCHANNEL
;
2801 case DCERPC_AUTH_TYPE_SCHANNEL
:
2802 c_flags
|= DCERPC_AUTH_KRB5
;
2803 c_flags
|= DCERPC_AUTH_NTLM
;
2804 c_flags
|= DCERPC_AUTH_SPNEGO
;
2805 a_flags
|= DCERPC_SCHANNEL
;
2808 c_flags
|= DCERPC_AUTH_KRB5
;
2809 c_flags
|= DCERPC_AUTH_NTLM
;
2810 c_flags
|= DCERPC_AUTH_SPNEGO
;
2811 c_flags
|= DCERPC_SCHANNEL
;
2815 if (c
->auth
->auth_level
>= DCERPC_AUTH_LEVEL_PRIVACY
) {
2816 a_flags
|= DCERPC_SEAL
;
2817 c_flags
|= DCERPC_SIGN
;
2818 c_flags
|= DCERPC_CONNECT
;
2819 } else if (c
->auth
->auth_level
>= DCERPC_AUTH_LEVEL_INTEGRITY
) {
2820 c_flags
|= DCERPC_SEAL
;
2821 a_flags
|= DCERPC_SIGN
;
2822 c_flags
|= DCERPC_CONNECT
;
2823 } else if (c
->auth
->auth_level
>= DCERPC_AUTH_LEVEL_CONNECT
) {
2824 c_flags
|= DCERPC_SEAL
;
2825 c_flags
|= DCERPC_SIGN
;
2826 a_flags
|= DCERPC_CONNECT
;
2828 c_flags
|= DCERPC_SEAL
;
2829 c_flags
|= DCERPC_SIGN
;
2830 c_flags
|= DCERPC_CONNECT
;
2833 h
= dcerpc_binding_handle_create(c
,
2838 struct rpccli_bh_state
,
2845 b
= dcerpc_binding_dup(h
, c
->assoc
->binding
);
2850 status
= dcerpc_binding_set_abstract_syntax(b
, &table
->syntax_id
);
2851 if (!NT_STATUS_IS_OK(status
)) {
2855 status
= dcerpc_binding_set_flags(b
, a_flags
, c_flags
);
2856 if (!NT_STATUS_IS_OK(status
)) {
2861 switch (c
->conn
->localaddr
.u
.sa
.sa_family
) {
2864 print_sockaddr(localaddr
,
2866 &c
->conn
->localaddr
.u
.ss
);
2867 status
= dcerpc_binding_set_string_option(b
,
2870 if (!NT_STATUS_IS_OK(status
)) {
2882 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
2883 struct pipe_auth_data
**presult
)
2885 struct pipe_auth_data
*result
;
2886 struct auth_generic_state
*auth_generic_ctx
;
2889 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2890 if (result
== NULL
) {
2891 return NT_STATUS_NO_MEMORY
;
2894 result
->auth_type
= DCERPC_AUTH_TYPE_NONE
;
2895 result
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
2896 /* rpc_pipe_bind_send should allocate an id... */
2897 result
->auth_context_id
= UINT32_MAX
;
2899 status
= auth_generic_client_prepare(result
,
2901 if (!NT_STATUS_IS_OK(status
)) {
2902 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2903 nt_errstr(status
)));
2906 status
= auth_generic_set_username(auth_generic_ctx
, "");
2907 if (!NT_STATUS_IS_OK(status
)) {
2908 DEBUG(1, ("Failed to set username: %s\n",
2909 nt_errstr(status
)));
2912 status
= auth_generic_set_domain(auth_generic_ctx
, "");
2913 if (!NT_STATUS_IS_OK(status
)) {
2914 DEBUG(1, ("Failed to set domain: %s\n",
2915 nt_errstr(status
)));
2919 status
= gensec_set_credentials(auth_generic_ctx
->gensec_security
,
2920 auth_generic_ctx
->credentials
);
2921 if (!NT_STATUS_IS_OK(status
)) {
2922 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2923 nt_errstr(status
)));
2926 talloc_unlink(auth_generic_ctx
, auth_generic_ctx
->credentials
);
2927 auth_generic_ctx
->credentials
= NULL
;
2929 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2930 talloc_free(auth_generic_ctx
);
2932 return NT_STATUS_OK
;
2935 static NTSTATUS
rpccli_generic_bind_data(TALLOC_CTX
*mem_ctx
,
2936 enum dcerpc_AuthType auth_type
,
2937 enum dcerpc_AuthLevel auth_level
,
2939 const char *target_service
,
2941 const char *username
,
2942 const char *password
,
2943 enum credentials_use_kerberos use_kerberos
,
2944 struct netlogon_creds_CredentialState
*creds
,
2945 struct pipe_auth_data
**presult
)
2947 struct auth_generic_state
*auth_generic_ctx
;
2948 struct pipe_auth_data
*result
;
2951 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2952 if (result
== NULL
) {
2953 return NT_STATUS_NO_MEMORY
;
2956 result
->auth_type
= auth_type
;
2957 result
->auth_level
= auth_level
;
2958 /* rpc_pipe_bind_send should allocate an id... */
2959 result
->auth_context_id
= UINT32_MAX
;
2961 status
= auth_generic_client_prepare(result
,
2963 if (!NT_STATUS_IS_OK(status
)) {
2967 status
= auth_generic_set_username(auth_generic_ctx
, username
);
2968 if (!NT_STATUS_IS_OK(status
)) {
2972 status
= auth_generic_set_domain(auth_generic_ctx
, domain
);
2973 if (!NT_STATUS_IS_OK(status
)) {
2977 status
= auth_generic_set_password(auth_generic_ctx
, password
);
2978 if (!NT_STATUS_IS_OK(status
)) {
2982 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
2983 if (!NT_STATUS_IS_OK(status
)) {
2987 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
2988 if (!NT_STATUS_IS_OK(status
)) {
2992 cli_credentials_set_kerberos_state(auth_generic_ctx
->credentials
,
2995 cli_credentials_set_netlogon_creds(auth_generic_ctx
->credentials
, creds
);
2997 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
2998 if (!NT_STATUS_IS_OK(status
)) {
3002 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
3003 talloc_free(auth_generic_ctx
);
3005 return NT_STATUS_OK
;
3008 TALLOC_FREE(result
);
3012 /* This routine steals the creds pointer that is passed in */
3013 static NTSTATUS
rpccli_generic_bind_data_from_creds(TALLOC_CTX
*mem_ctx
,
3014 enum dcerpc_AuthType auth_type
,
3015 enum dcerpc_AuthLevel auth_level
,
3017 const char *target_service
,
3018 struct cli_credentials
*creds
,
3019 struct pipe_auth_data
**presult
)
3021 struct auth_generic_state
*auth_generic_ctx
;
3022 struct pipe_auth_data
*result
;
3025 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
3026 if (result
== NULL
) {
3027 return NT_STATUS_NO_MEMORY
;
3030 result
->auth_type
= auth_type
;
3031 result
->auth_level
= auth_level
;
3032 /* rpc_pipe_bind_send should allocate an id... */
3033 result
->auth_context_id
= UINT32_MAX
;
3035 status
= auth_generic_client_prepare(result
,
3037 if (!NT_STATUS_IS_OK(status
)) {
3041 status
= auth_generic_set_creds(auth_generic_ctx
, creds
);
3042 if (!NT_STATUS_IS_OK(status
)) {
3046 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
3047 if (!NT_STATUS_IS_OK(status
)) {
3051 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
3052 if (!NT_STATUS_IS_OK(status
)) {
3056 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
3057 if (!NT_STATUS_IS_OK(status
)) {
3061 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
3062 talloc_free(auth_generic_ctx
);
3064 return NT_STATUS_OK
;
3067 TALLOC_FREE(result
);
3071 NTSTATUS
rpccli_ncalrpc_bind_data(TALLOC_CTX
*mem_ctx
,
3072 struct pipe_auth_data
**presult
)
3074 return rpccli_generic_bind_data(mem_ctx
,
3075 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
,
3076 DCERPC_AUTH_LEVEL_CONNECT
,
3078 "host", /* target_service */
3079 NAME_NT_AUTHORITY
, /* domain */
3081 NULL
, /* password */
3082 CRED_USE_KERBEROS_DISABLED
,
3083 NULL
, /* netlogon_creds_CredentialState */
3088 * Create an rpc pipe client struct, connecting to a tcp port.
3090 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
,
3091 const struct rpc_client_association
*assoc
,
3092 struct rpc_client_connection
**pconn
)
3094 struct rpc_client_connection
*conn
= NULL
;
3095 enum dcerpc_transport_t transport
;
3096 const char *endpoint
= NULL
;
3102 transport
= dcerpc_binding_get_transport(assoc
->binding
);
3103 if (transport
!= NCACN_IP_TCP
) {
3104 return NT_STATUS_RPC_WRONG_KIND_OF_BINDING
;
3107 endpoint
= dcerpc_binding_get_string_option(assoc
->binding
,
3109 if (endpoint
== NULL
) {
3110 return NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT
;
3112 port
= (uint16_t)atoi(endpoint
);
3114 return NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT
;
3117 status
= rpc_client_connection_create(mem_ctx
,
3119 DCERPC_FRAG_MAX_SIZE
,
3121 if (!NT_STATUS_IS_OK(status
)) {
3125 status
= open_socket_out(&assoc
->addr
.u
.ss
, port
, 60*1000, &fd
);
3126 if (!NT_STATUS_IS_OK(status
)) {
3130 set_socket_options(fd
, lp_socket_options());
3132 conn
->localaddr
.sa_socklen
= sizeof(conn
->localaddr
.u
.ss
);
3133 ret
= getsockname(fd
, &conn
->localaddr
.u
.sa
, &conn
->localaddr
.sa_socklen
);
3135 status
= map_nt_error_from_unix_common(errno
);
3141 status
= rpc_transport_sock_init(conn
, fd
, &conn
->transport
);
3142 if (!NT_STATUS_IS_OK(status
)) {
3148 conn
->transport
->transport
= NCACN_IP_TCP
;
3151 return NT_STATUS_OK
;
3154 static NTSTATUS
rpccli_epm_map_binding(
3155 struct dcerpc_binding_handle
*epm_connection
,
3156 struct dcerpc_binding
*binding
,
3157 TALLOC_CTX
*mem_ctx
,
3160 TALLOC_CTX
*frame
= talloc_stackframe();
3161 enum dcerpc_transport_t transport
=
3162 dcerpc_binding_get_transport(binding
);
3163 enum dcerpc_transport_t res_transport
;
3164 struct dcerpc_binding
*res_binding
= NULL
;
3165 struct epm_twr_t
*map_tower
= NULL
;
3166 struct epm_twr_p_t res_towers
= { .twr
= NULL
};
3167 struct policy_handle
*entry_handle
= NULL
;
3168 uint32_t num_towers
= 0;
3169 const uint32_t max_towers
= 1;
3170 const char *endpoint
= NULL
;
3175 map_tower
= talloc_zero(frame
, struct epm_twr_t
);
3176 if (map_tower
== NULL
) {
3180 status
= dcerpc_binding_build_tower(
3181 frame
, binding
, &(map_tower
->tower
));
3182 if (!NT_STATUS_IS_OK(status
)) {
3183 DBG_DEBUG("dcerpc_binding_build_tower failed: %s\n",
3188 res_towers
.twr
= talloc_array(frame
, struct epm_twr_t
, max_towers
);
3189 if (res_towers
.twr
== NULL
) {
3193 entry_handle
= talloc_zero(frame
, struct policy_handle
);
3194 if (entry_handle
== NULL
) {
3198 status
= dcerpc_epm_Map(
3209 if (!NT_STATUS_IS_OK(status
)) {
3210 DBG_DEBUG("dcerpc_epm_Map failed: %s\n", nt_errstr(status
));
3214 if (result
!= EPMAPPER_STATUS_OK
) {
3215 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32
"\n", result
);
3216 status
= NT_STATUS_NOT_FOUND
;
3220 if (num_towers
!= 1) {
3221 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32
" towers\n",
3223 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
3227 status
= dcerpc_binding_from_tower(
3228 frame
, &(res_towers
.twr
->tower
), &res_binding
);
3229 if (!NT_STATUS_IS_OK(status
)) {
3230 DBG_DEBUG("dcerpc_binding_from_tower failed: %s\n",
3235 res_transport
= dcerpc_binding_get_transport(res_binding
);
3236 if (res_transport
!= transport
) {
3237 DBG_DEBUG("dcerpc_epm_Map returned transport %d, "
3241 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
3245 endpoint
= dcerpc_binding_get_string_option(res_binding
, "endpoint");
3246 if (endpoint
== NULL
) {
3247 DBG_DEBUG("dcerpc_epm_Map returned no endpoint\n");
3248 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
3252 tmp
= talloc_strdup(mem_ctx
, endpoint
);
3258 status
= NT_STATUS_OK
;
3262 status
= NT_STATUS_NO_MEMORY
;
3268 static NTSTATUS
rpccli_epm_map_interface(
3269 struct dcerpc_binding_handle
*epm_connection
,
3270 enum dcerpc_transport_t transport
,
3271 const struct ndr_syntax_id
*iface
,
3272 TALLOC_CTX
*mem_ctx
,
3275 struct dcerpc_binding
*binding
= NULL
;
3276 char *endpoint
= NULL
;
3279 status
= dcerpc_parse_binding(mem_ctx
, "", &binding
);
3280 if (!NT_STATUS_IS_OK(status
)) {
3281 DBG_DEBUG("dcerpc_parse_binding failed: %s\n",
3286 status
= dcerpc_binding_set_transport(binding
, transport
);
3287 if (!NT_STATUS_IS_OK(status
)) {
3288 DBG_DEBUG("dcerpc_binding_set_transport failed: %s\n",
3293 status
= dcerpc_binding_set_abstract_syntax(binding
, iface
);
3294 if (!NT_STATUS_IS_OK(status
)) {
3295 DBG_DEBUG("dcerpc_binding_set_abstract_syntax failed: %s\n",
3300 status
= rpccli_epm_map_binding(
3301 epm_connection
, binding
, mem_ctx
, &endpoint
);
3302 if (!NT_STATUS_IS_OK(status
)) {
3303 DBG_DEBUG("rpccli_epm_map_binding failed: %s\n",
3307 *pendpoint
= endpoint
;
3310 TALLOC_FREE(binding
);
3315 * Determine the tcp port on which a dcerpc interface is listening
3316 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3319 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
3320 const struct samba_sockaddr
*saddr
,
3321 const struct ndr_interface_table
*table
,
3324 TALLOC_CTX
*frame
= talloc_stackframe();
3325 const char *epm_ep
= NULL
;
3326 struct rpc_client_association
*epm_assoc
= NULL
;
3327 struct rpc_client_connection
*epm_conn
= NULL
;
3328 struct rpc_pipe_client
*epm_pipe
= NULL
;
3329 struct pipe_auth_data
*epm_auth
= NULL
;
3330 char *endpoint
= NULL
;
3334 endpoint
= dcerpc_default_transport_endpoint(frame
,
3337 if (endpoint
!= NULL
) {
3338 port
= (uint16_t)atoi(endpoint
);
3344 return NT_STATUS_OK
;
3347 epm_ep
= dcerpc_default_transport_endpoint(frame
,
3349 &ndr_table_epmapper
);
3350 if (epm_ep
== NULL
) {
3352 return NT_STATUS_RPC_INTERNAL_ERROR
;
3355 status
= rpc_client_association_create(frame
,
3356 default_bt_features
,
3357 DCERPC_PROPOSE_HEADER_SIGNING
,
3363 if (!NT_STATUS_IS_OK(status
)) {
3368 /* open the connection to the endpoint mapper */
3369 status
= rpc_pipe_open_tcp_port(frame
, epm_assoc
, &epm_conn
);
3370 if (!NT_STATUS_IS_OK(status
)) {
3375 status
= rpccli_anon_bind_data(frame
, &epm_auth
);
3376 if (!NT_STATUS_IS_OK(status
)) {
3381 status
= rpc_pipe_wrap_create(&ndr_table_epmapper
,
3387 if (!NT_STATUS_IS_OK(status
)) {
3392 status
= rpc_pipe_bind(epm_pipe
, epm_auth
);
3393 if (!NT_STATUS_IS_OK(status
)) {
3398 status
= rpccli_epm_map_interface(
3399 epm_pipe
->binding_handle
,
3404 if (!NT_STATUS_IS_OK(status
)) {
3405 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
3411 *pport
= (uint16_t)atoi(endpoint
);
3413 return NT_STATUS_OK
;
3416 static NTSTATUS
rpc_pipe_get_ncalrpc_name(
3417 const struct ndr_syntax_id
*iface
,
3418 TALLOC_CTX
*mem_ctx
,
3419 char **psocket_name
)
3421 TALLOC_CTX
*frame
= talloc_stackframe();
3422 struct rpc_pipe_client
*epm_pipe
= NULL
;
3423 struct pipe_auth_data
*auth
= NULL
;
3424 NTSTATUS status
= NT_STATUS_OK
;
3427 is_epm
= ndr_syntax_id_equal(iface
, &ndr_table_epmapper
.syntax_id
);
3429 char *endpoint
= talloc_strdup(mem_ctx
, "EPMAPPER");
3430 if (endpoint
== NULL
) {
3431 status
= NT_STATUS_NO_MEMORY
;
3434 *psocket_name
= endpoint
;
3438 status
= rpc_pipe_open_ncalrpc(
3439 frame
, &ndr_table_epmapper
, &epm_pipe
);
3440 if (!NT_STATUS_IS_OK(status
)) {
3441 DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
3446 status
= rpccli_anon_bind_data(epm_pipe
, &auth
);
3447 if (!NT_STATUS_IS_OK(status
)) {
3448 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3453 status
= rpc_pipe_bind(epm_pipe
, auth
);
3454 if (!NT_STATUS_IS_OK(status
)) {
3455 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status
));
3459 status
= rpccli_epm_map_interface(
3460 epm_pipe
->binding_handle
,
3465 if (!NT_STATUS_IS_OK(status
)) {
3466 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
3475 /********************************************************************
3476 Create a rpc pipe client struct, connecting to a unix domain socket
3477 ********************************************************************/
3478 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
,
3479 const struct ndr_interface_table
*table
,
3480 struct rpc_pipe_client
**presult
)
3482 TALLOC_CTX
*frame
= talloc_stackframe();
3483 char *myname
= NULL
;
3484 char *socket_name
= NULL
;
3485 struct samba_sockaddr saddr
= {
3486 .sa_socklen
= sizeof(struct sockaddr_un
),
3489 .sun_family
= AF_UNIX
,
3493 struct rpc_client_association
*assoc
= NULL
;
3494 struct rpc_client_connection
*conn
= NULL
;
3495 struct rpc_pipe_client
*result
= NULL
;
3500 myname
= get_myname(frame
);
3501 if (myname
== NULL
) {
3503 return NT_STATUS_NO_MEMORY
;
3506 status
= rpc_pipe_get_ncalrpc_name(&table
->syntax_id
,
3509 if (!NT_STATUS_IS_OK(status
)) {
3510 DBG_DEBUG("rpc_pipe_get_ncalrpc_name failed: %s\n",
3517 saddr
.u
.un
.sun_path
,
3518 sizeof(saddr
.u
.un
.sun_path
),
3522 if ((pathlen
< 0) || ((size_t)pathlen
>= sizeof(saddr
.u
.un
.sun_path
))) {
3523 DBG_DEBUG("socket_path for %s too long\n", socket_name
);
3525 return NT_STATUS_NAME_TOO_LONG
;
3527 TALLOC_FREE(socket_name
);
3529 status
= rpc_client_association_create(mem_ctx
,
3530 0, /* no client_features */
3537 if (!NT_STATUS_IS_OK(status
)) {
3541 talloc_steal(frame
, assoc
);
3543 status
= rpc_client_connection_create(mem_ctx
,
3545 DCERPC_FRAG_MAX_SIZE
,
3547 if (!NT_STATUS_IS_OK(status
)) {
3551 talloc_steal(frame
, conn
);
3553 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3555 status
= map_nt_error_from_unix(errno
);
3560 if (connect(fd
, &saddr
.u
.sa
, saddr
.sa_socklen
) == -1) {
3561 status
= map_nt_error_from_unix(errno
);
3563 DBG_WARNING("connect(%s) failed: %s - %s\n",
3564 saddr
.u
.un
.sun_path
,
3565 strerror(errno
), nt_errstr(status
));
3570 status
= rpc_transport_sock_init(conn
, fd
, &conn
->transport
);
3571 if (!NT_STATUS_IS_OK(status
)) {
3578 conn
->transport
->transport
= NCALRPC
;
3580 status
= rpc_pipe_wrap_create(table
,
3586 if (!NT_STATUS_IS_OK(status
)) {
3593 return NT_STATUS_OK
;
3596 NTSTATUS
rpc_pipe_open_local_np(
3597 TALLOC_CTX
*mem_ctx
,
3598 const struct ndr_interface_table
*table
,
3599 const char *remote_client_name
,
3600 const struct tsocket_address
*remote_client_addr
,
3601 const char *local_server_name
,
3602 const struct tsocket_address
*local_server_addr
,
3603 const struct auth_session_info
*session_info
,
3604 struct rpc_pipe_client
**presult
)
3606 TALLOC_CTX
*frame
= talloc_stackframe();
3607 struct rpc_client_association
*assoc
= NULL
;
3608 struct rpc_client_connection
*conn
= NULL
;
3609 struct rpc_pipe_client
*result
= NULL
;
3610 struct pipe_auth_data
*auth
= NULL
;
3611 struct samba_sockaddr saddr
= { .sa_socklen
= 0, };
3612 const char *pipe_name
= NULL
;
3613 struct tstream_context
*npa_stream
= NULL
;
3614 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3617 pipe_name
= dcerpc_default_transport_endpoint(frame
,
3620 if (pipe_name
== NULL
) {
3621 DBG_DEBUG("dcerpc_default_transport_endpoint failed\n");
3623 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3626 if (local_server_name
== NULL
) {
3627 local_server_name
= get_myname(result
);
3630 if (local_server_addr
!= NULL
) {
3631 saddr
.sa_socklen
= tsocket_address_bsd_sockaddr(local_server_addr
,
3633 sizeof(saddr
.u
.ss
));
3634 if (saddr
.sa_socklen
== -1) {
3635 status
= map_nt_error_from_unix(errno
);
3641 status
= rpc_client_association_create(mem_ctx
,
3642 0, /* no client_features */
3649 if (!NT_STATUS_IS_OK(status
)) {
3653 talloc_steal(frame
, assoc
);
3655 status
= rpc_client_connection_create(mem_ctx
,
3657 DCERPC_FRAG_MAX_SIZE
,
3659 if (!NT_STATUS_IS_OK(status
)) {
3663 talloc_steal(frame
, conn
);
3665 ret
= local_np_connect(
3677 DBG_DEBUG("local_np_connect for %s and "
3678 "user %s\\%s failed: %s\n",
3680 session_info
->info
->domain_name
,
3681 session_info
->info
->account_name
,
3683 status
= map_nt_error_from_unix(ret
);
3688 status
= rpc_transport_tstream_init(conn
,
3691 if (!NT_STATUS_IS_OK(status
)) {
3692 DBG_DEBUG("rpc_transport_tstream_init failed: %s\n",
3697 conn
->transport
->transport
= NCACN_NP
;
3699 status
= rpc_pipe_wrap_create(table
,
3705 if (!NT_STATUS_IS_OK(status
)) {
3709 talloc_steal(frame
, result
);
3711 status
= rpccli_anon_bind_data(result
, &auth
);
3712 if (!NT_STATUS_IS_OK(status
)) {
3713 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3719 status
= rpc_pipe_bind(result
, auth
);
3720 if (!NT_STATUS_IS_OK(status
)) {
3721 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status
));
3726 *presult
= talloc_move(mem_ctx
, &result
);
3728 return NT_STATUS_OK
;
3731 struct rpc_client_connection_np_state
{
3732 struct cli_state
*cli
;
3733 const char *pipe_name
;
3734 struct rpc_client_connection
*conn
;
3737 static void rpc_client_connection_np_done(struct tevent_req
*subreq
);
3739 static struct tevent_req
*rpc_client_connection_np_send(
3740 TALLOC_CTX
*mem_ctx
,
3741 struct tevent_context
*ev
,
3742 struct cli_state
*cli
,
3743 const struct rpc_client_association
*assoc
)
3745 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
3746 struct rpc_client_connection_np_state
*state
= NULL
;
3747 enum dcerpc_transport_t transport
;
3748 const char *endpoint
= NULL
;
3749 const struct sockaddr_storage
*local_sockaddr
= NULL
;
3750 struct smbXcli_session
*session
= NULL
;
3753 req
= tevent_req_create(mem_ctx
, &state
,
3754 struct rpc_client_connection_np_state
);
3759 transport
= dcerpc_binding_get_transport(assoc
->binding
);
3760 if (transport
!= NCACN_NP
) {
3761 tevent_req_nterror(req
, NT_STATUS_RPC_WRONG_KIND_OF_BINDING
);
3762 return tevent_req_post(req
, ev
);
3765 endpoint
= dcerpc_binding_get_string_option(assoc
->binding
,
3767 if (endpoint
== NULL
) {
3768 tevent_req_nterror(req
, NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT
);
3769 return tevent_req_post(req
, ev
);
3772 status
= rpc_client_connection_create(state
,
3774 TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE
,
3776 if (tevent_req_nterror(req
, status
)) {
3777 return tevent_req_post(req
, ev
);
3780 local_sockaddr
= smbXcli_conn_local_sockaddr(cli
->conn
);
3781 state
->conn
->localaddr
.u
.ss
= *local_sockaddr
;
3783 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
3784 session
= cli
->smb2
.session
;
3786 session
= cli
->smb1
.session
;
3789 status
= smbXcli_session_application_key(session
, state
->conn
,
3790 &state
->conn
->transport_session_key
);
3791 if (!NT_STATUS_IS_OK(status
)) {
3792 state
->conn
->transport_session_key
= data_blob_null
;
3795 subreq
= rpc_transport_np_init_send(state
, ev
, cli
, endpoint
);
3796 if (tevent_req_nomem(subreq
, req
)) {
3797 return tevent_req_post(req
, ev
);
3799 tevent_req_set_callback(subreq
, rpc_client_connection_np_done
, req
);
3803 static void rpc_client_connection_np_done(struct tevent_req
*subreq
)
3805 struct tevent_req
*req
= tevent_req_callback_data(
3806 subreq
, struct tevent_req
);
3807 struct rpc_client_connection_np_state
*state
= tevent_req_data(
3808 req
, struct rpc_client_connection_np_state
);
3811 status
= rpc_transport_np_init_recv(subreq
,
3813 &state
->conn
->transport
);
3814 TALLOC_FREE(subreq
);
3815 if (tevent_req_nterror(req
, status
)) {
3819 state
->conn
->transport
->transport
= NCACN_NP
;
3821 tevent_req_done(req
);
3824 static NTSTATUS
rpc_client_connection_np_recv(
3825 struct tevent_req
*req
,
3826 TALLOC_CTX
*mem_ctx
,
3827 struct rpc_client_connection
**pconn
)
3829 struct rpc_client_connection_np_state
*state
= tevent_req_data(
3830 req
, struct rpc_client_connection_np_state
);
3833 if (tevent_req_is_nterror(req
, &status
)) {
3834 tevent_req_received(req
);
3837 *pconn
= talloc_move(mem_ctx
, &state
->conn
);
3838 tevent_req_received(req
);
3839 return NT_STATUS_OK
;
3842 static NTSTATUS
rpc_client_connection_np(struct cli_state
*cli
,
3843 const struct rpc_client_association
*assoc
,
3844 struct rpc_client_connection
**pconn
)
3846 struct tevent_context
*ev
= NULL
;
3847 struct tevent_req
*req
= NULL
;
3848 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3850 ev
= samba_tevent_context_init(cli
);
3854 req
= rpc_client_connection_np_send(ev
, ev
, cli
, assoc
);
3858 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3861 status
= rpc_client_connection_np_recv(req
, NULL
, pconn
);
3868 struct rpc_pipe_open_np_state
{
3869 struct cli_state
*cli
;
3870 const struct ndr_interface_table
*table
;
3871 struct rpc_client_association
*assoc
;
3872 struct rpc_client_connection
*conn
;
3873 struct rpc_pipe_client
*result
;
3876 static void rpc_pipe_open_np_done(struct tevent_req
*subreq
);
3878 struct tevent_req
*rpc_pipe_open_np_send(
3879 TALLOC_CTX
*mem_ctx
,
3880 struct tevent_context
*ev
,
3881 struct cli_state
*cli
,
3882 const struct ndr_interface_table
*table
)
3884 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
3885 struct rpc_pipe_open_np_state
*state
= NULL
;
3886 const char *remote_name
= NULL
;
3887 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
3888 struct samba_sockaddr saddr
= { .sa_socklen
= 0, };
3889 const char *pipe_name
= NULL
;
3892 req
= tevent_req_create(
3893 mem_ctx
, &state
, struct rpc_pipe_open_np_state
);
3898 state
->table
= table
;
3900 remote_name
= smbXcli_conn_remote_name(cli
->conn
);
3901 remote_sockaddr
= smbXcli_conn_remote_sockaddr(cli
->conn
);
3902 saddr
.u
.ss
= *remote_sockaddr
;
3904 pipe_name
= dcerpc_default_transport_endpoint(state
,
3907 if (tevent_req_nomem(pipe_name
, req
)) {
3908 return tevent_req_post(req
, ev
);
3911 status
= rpc_client_association_create(state
,
3912 default_bt_features
,
3913 DCERPC_PROPOSE_HEADER_SIGNING
,
3919 if (tevent_req_nterror(req
, status
)) {
3920 return tevent_req_post(req
, ev
);
3923 subreq
= rpc_client_connection_np_send(state
, ev
, cli
, state
->assoc
);
3924 if (tevent_req_nomem(subreq
, req
)) {
3925 return tevent_req_post(req
, ev
);
3927 tevent_req_set_callback(subreq
, rpc_pipe_open_np_done
, req
);
3931 static void rpc_pipe_open_np_done(struct tevent_req
*subreq
)
3933 struct tevent_req
*req
= tevent_req_callback_data(
3934 subreq
, struct tevent_req
);
3935 struct rpc_pipe_open_np_state
*state
= tevent_req_data(
3936 req
, struct rpc_pipe_open_np_state
);
3939 status
= rpc_client_connection_np_recv(subreq
,
3942 TALLOC_FREE(subreq
);
3943 if (tevent_req_nterror(req
, status
)) {
3947 status
= rpc_pipe_wrap_create(state
->table
,
3953 if (tevent_req_nterror(req
, status
)) {
3957 tevent_req_done(req
);
3960 NTSTATUS
rpc_pipe_open_np_recv(
3961 struct tevent_req
*req
,
3962 TALLOC_CTX
*mem_ctx
,
3963 struct rpc_pipe_client
**_result
)
3965 struct rpc_pipe_open_np_state
*state
= tevent_req_data(
3966 req
, struct rpc_pipe_open_np_state
);
3969 if (tevent_req_is_nterror(req
, &status
)) {
3970 tevent_req_received(req
);
3973 *_result
= talloc_move(mem_ctx
, &state
->result
);
3974 tevent_req_received(req
);
3975 return NT_STATUS_OK
;
3978 /****************************************************************************
3979 Open a pipe to a remote server.
3980 ****************************************************************************/
3982 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3983 enum dcerpc_transport_t transport
,
3984 const struct ndr_interface_table
*table
,
3985 const char *remote_name
,
3986 const struct sockaddr_storage
*remote_sockaddr
,
3987 struct rpc_pipe_client
**presult
)
3989 TALLOC_CTX
*frame
= talloc_stackframe();
3990 struct samba_sockaddr saddr
= { .sa_socklen
= 0, };
3991 struct rpc_client_association
*assoc
= NULL
;
3992 struct rpc_client_connection
*conn
= NULL
;
3993 struct rpc_pipe_client
*result
= NULL
;
3994 char _tcp_endpoint
[6] = { 0, };
3995 const char *endpoint
= NULL
;
3998 if (cli
!= NULL
&& remote_name
== NULL
) {
3999 remote_name
= smbXcli_conn_remote_name(cli
->conn
);
4001 if (cli
!= NULL
&& remote_sockaddr
== NULL
) {
4002 remote_sockaddr
= smbXcli_conn_remote_sockaddr(cli
->conn
);
4005 if (remote_sockaddr
!= NULL
) {
4006 saddr
.u
.ss
= *remote_sockaddr
;
4010 ok
= resolve_name(remote_name
,
4016 return NT_STATUS_NOT_FOUND
;
4020 endpoint
= dcerpc_default_transport_endpoint(frame
,
4023 if (endpoint
== NULL
) {
4026 if (transport
!= NCACN_IP_TCP
) {
4028 return NT_STATUS_RPC_NO_ENDPOINT_FOUND
;
4031 status
= rpc_pipe_get_tcp_port(remote_name
,
4035 if (!NT_STATUS_IS_OK(status
)) {
4040 snprintf(_tcp_endpoint
, sizeof(_tcp_endpoint
), "%u", port
);
4041 endpoint
= _tcp_endpoint
;
4044 status
= rpc_client_association_create(NULL
,
4045 default_bt_features
,
4046 DCERPC_PROPOSE_HEADER_SIGNING
,
4052 if (!NT_STATUS_IS_OK(status
)) {
4056 talloc_steal(frame
, assoc
);
4058 switch (transport
) {
4060 status
= rpc_pipe_open_tcp_port(NULL
,
4063 if (!NT_STATUS_IS_OK(status
)) {
4067 talloc_steal(frame
, conn
);
4070 status
= rpc_client_connection_np(cli
,
4073 if (!NT_STATUS_IS_OK(status
)) {
4077 talloc_steal(frame
, conn
);
4081 return NT_STATUS_NOT_IMPLEMENTED
;
4083 status
= rpc_pipe_wrap_create(table
,
4089 if (!NT_STATUS_IS_OK(status
)) {
4096 return NT_STATUS_OK
;
4099 static NTSTATUS
cli_rpc_pipe_client_reconnect(struct rpc_pipe_client
*p
)
4101 enum dcerpc_transport_t transport
=
4102 dcerpc_binding_get_transport(p
->assoc
->binding
);
4105 switch (transport
) {
4107 status
= rpc_pipe_open_tcp_port(p
,
4110 if (!NT_STATUS_IS_OK(status
)) {
4115 status
= rpc_client_connection_np(p
->np_cli
,
4118 if (!NT_STATUS_IS_OK(status
)) {
4121 talloc_steal(p
, p
->conn
);
4124 return NT_STATUS_NOT_IMPLEMENTED
;
4127 return NT_STATUS_OK
;
4130 NTSTATUS
cli_rpc_pipe_client_prepare_alter(struct rpc_pipe_client
*p
,
4131 bool new_auth_context
,
4132 const struct ndr_interface_table
*table
,
4133 bool new_pres_context
)
4135 uint32_t f
= p
->assoc
->features
.negotiated
;
4138 if (!new_auth_context
&& !new_pres_context
) {
4139 return NT_STATUS_INVALID_PARAMETER_MIX
;
4142 TALLOC_FREE(p
->binding_handle
);
4144 if (new_auth_context
) {
4148 if (new_auth_context
&&
4149 !(f
& DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
))
4152 * new auth context without
4153 * security context multiplexing.
4155 * We need to create a new transport
4156 * connection is the same association
4159 * We need to keep the old connection alive
4160 * in order to connect to the existing association
4161 * group..., so no TALLOC_FREE(p->conn)
4164 status
= cli_rpc_pipe_client_reconnect(p
);
4165 if (!NT_STATUS_IS_OK(status
)) {
4170 if (new_pres_context
) {
4171 /* rpc_pipe_bind_send should allocate an id... */
4172 p
->pres_context_id
= UINT16_MAX
;
4174 p
->transfer_syntax
= ndr_transfer_syntax_ndr
;
4177 return NT_STATUS_OK
;
4180 /****************************************************************************
4181 Open a named pipe to an SMB server and bind anonymously.
4182 ****************************************************************************/
4184 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
4185 enum dcerpc_transport_t transport
,
4186 const struct ndr_interface_table
*table
,
4187 const char *remote_name
,
4188 const struct sockaddr_storage
*remote_sockaddr
,
4189 struct rpc_pipe_client
**presult
)
4191 struct rpc_pipe_client
*result
;
4192 struct pipe_auth_data
*auth
;
4195 status
= cli_rpc_pipe_open(cli
,
4201 if (!NT_STATUS_IS_OK(status
)) {
4205 status
= rpccli_anon_bind_data(result
, &auth
);
4206 if (!NT_STATUS_IS_OK(status
)) {
4207 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
4208 nt_errstr(status
)));
4209 TALLOC_FREE(result
);
4213 status
= rpc_pipe_bind(result
, auth
);
4214 if (!NT_STATUS_IS_OK(status
)) {
4216 if (ndr_syntax_id_equal(&table
->syntax_id
,
4217 &ndr_table_dssetup
.syntax_id
)) {
4218 /* non AD domains just don't have this pipe, avoid
4219 * level 0 statement in that case - gd */
4222 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
4223 "%s failed with error %s\n",
4225 nt_errstr(status
) ));
4226 TALLOC_FREE(result
);
4230 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
4231 "%s and bound anonymously.\n",
4236 return NT_STATUS_OK
;
4239 /****************************************************************************
4240 ****************************************************************************/
4242 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
4243 const struct ndr_interface_table
*table
,
4244 struct rpc_pipe_client
**presult
)
4246 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
4247 const struct sockaddr_storage
*remote_sockaddr
=
4248 smbXcli_conn_remote_sockaddr(cli
->conn
);
4250 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
4257 /****************************************************************************
4258 Open a named pipe to an SMB server and bind using the mech specified
4260 This routine references the creds pointer that is passed in
4261 ****************************************************************************/
4263 NTSTATUS
cli_rpc_pipe_open_with_creds(struct cli_state
*cli
,
4264 const struct ndr_interface_table
*table
,
4265 enum dcerpc_transport_t transport
,
4266 enum dcerpc_AuthType auth_type
,
4267 enum dcerpc_AuthLevel auth_level
,
4268 const char *target_service
,
4269 const char *target_hostname
,
4270 const struct sockaddr_storage
*remote_sockaddr
,
4271 struct cli_credentials
*creds
,
4272 struct rpc_pipe_client
**presult
)
4274 struct rpc_pipe_client
*result
;
4275 struct pipe_auth_data
*auth
= NULL
;
4278 if (target_service
== NULL
) {
4279 target_service
= table
->authservices
->names
[0];
4282 status
= cli_rpc_pipe_open(cli
,
4288 if (!NT_STATUS_IS_OK(status
)) {
4292 status
= rpccli_generic_bind_data_from_creds(result
,
4299 if (!NT_STATUS_IS_OK(status
)) {
4300 DBG_ERR("rpccli_generic_bind_data_from_creds returned %s\n",
4305 status
= rpc_pipe_bind(result
, auth
);
4306 if (!NT_STATUS_IS_OK(status
)) {
4307 DBG_ERR("cli_rpc_pipe_bind failed with error %s\n",
4312 DBG_DEBUG("opened pipe %s to machine %s and bound as user %s.\n",
4315 cli_credentials_get_unparsed_name(creds
, talloc_tos()));
4318 return NT_STATUS_OK
;
4322 TALLOC_FREE(result
);
4326 NTSTATUS
cli_rpc_pipe_client_auth_schannel(
4327 struct rpc_pipe_client
*rpccli
,
4328 const struct ndr_interface_table
*table
,
4329 struct netlogon_creds_cli_context
*netlogon_creds
)
4331 TALLOC_CTX
*frame
= talloc_stackframe();
4332 struct pipe_auth_data
*rpcauth
= NULL
;
4333 const char *target_service
= table
->authservices
->names
[0];
4334 struct cli_credentials
*cli_creds
= NULL
;
4335 enum dcerpc_AuthLevel auth_level
;
4338 auth_level
= netlogon_creds_cli_auth_level(netlogon_creds
);
4340 status
= netlogon_creds_bind_cli_credentials(netlogon_creds
,
4343 if (!NT_STATUS_IS_OK(status
)) {
4344 DBG_DEBUG("netlogon_creds_bind_cli_credentials failed: %s\n",
4350 status
= rpccli_generic_bind_data_from_creds(rpccli
,
4351 DCERPC_AUTH_TYPE_SCHANNEL
,
4357 if (!NT_STATUS_IS_OK(status
)) {
4358 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
4359 nt_errstr(status
)));
4364 status
= rpc_pipe_bind(rpccli
, rpcauth
);
4365 if (!NT_STATUS_IS_OK(status
)) {
4366 DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
4373 return NT_STATUS_OK
;
4376 NTSTATUS
cli_rpc_pipe_open_bind_schannel(
4377 struct cli_state
*cli
,
4378 const struct ndr_interface_table
*table
,
4379 enum dcerpc_transport_t transport
,
4380 struct netlogon_creds_cli_context
*netlogon_creds
,
4381 const char *remote_name
,
4382 const struct sockaddr_storage
*remote_sockaddr
,
4383 struct rpc_pipe_client
**_rpccli
)
4385 struct rpc_pipe_client
*rpccli
= NULL
;
4388 status
= cli_rpc_pipe_open(cli
,
4394 if (!NT_STATUS_IS_OK(status
)) {
4398 status
= cli_rpc_pipe_client_auth_schannel(rpccli
,
4401 if (!NT_STATUS_IS_OK(status
)) {
4402 DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
4404 TALLOC_FREE(rpccli
);
4410 return NT_STATUS_OK
;
4413 NTSTATUS
cli_rpc_pipe_open_schannel_with_creds(struct cli_state
*cli
,
4414 const struct ndr_interface_table
*table
,
4415 enum dcerpc_transport_t transport
,
4416 struct netlogon_creds_cli_context
*netlogon_creds
,
4417 const char *remote_name
,
4418 const struct sockaddr_storage
*remote_sockaddr
,
4419 struct rpc_pipe_client
**_rpccli
)
4421 TALLOC_CTX
*frame
= talloc_stackframe();
4422 struct rpc_pipe_client
*rpccli
;
4423 struct netlogon_creds_cli_lck
*lck
;
4426 status
= netlogon_creds_cli_lck(
4427 netlogon_creds
, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE
,
4429 if (!NT_STATUS_IS_OK(status
)) {
4430 DBG_WARNING("netlogon_creds_cli_lck returned %s\n",
4436 status
= cli_rpc_pipe_open_bind_schannel(cli
,
4443 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
4444 netlogon_creds_cli_delete_lck(netlogon_creds
);
4446 if (!NT_STATUS_IS_OK(status
)) {
4447 DBG_DEBUG("cli_rpc_pipe_open_bind_schannel failed: %s\n",
4453 if (ndr_syntax_id_equal(&table
->syntax_id
,
4454 &ndr_table_netlogon
.syntax_id
)) {
4455 status
= netlogon_creds_cli_check(netlogon_creds
,
4456 rpccli
->binding_handle
,
4458 if (!NT_STATUS_IS_OK(status
)) {
4459 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
4460 nt_errstr(status
)));
4466 DBG_DEBUG("opened pipe %s to machine %s with key %s "
4467 "and bound using schannel.\n",
4468 table
->name
, rpccli
->desthost
,
4469 netlogon_creds_cli_debug_string(netlogon_creds
, lck
));
4474 return NT_STATUS_OK
;