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
;
85 assoc
= talloc_zero(mem_ctx
, struct rpc_client_association
);
87 return NT_STATUS_NO_MEMORY
;
89 assoc
->features
.client
= client_features
;
90 if (client_features
== 0) {
92 * Without requested features there
93 * is no point in trying to negotiate
94 * something, so we are done...
96 assoc
->features
.negotiation_done
= true;
99 status
= dcerpc_parse_binding(assoc
, "", &bd
);
100 if (!NT_STATUS_IS_OK(status
)) {
104 status
= dcerpc_binding_set_transport(bd
, transport
);
105 if (!NT_STATUS_IS_OK(status
)) {
109 status
= dcerpc_binding_set_string_option(bd
,
112 if (!NT_STATUS_IS_OK(status
)) {
116 status
= dcerpc_binding_set_string_option(bd
,
119 if (!NT_STATUS_IS_OK(status
)) {
123 status
= dcerpc_binding_set_string_option(bd
,
126 if (!NT_STATUS_IS_OK(status
)) {
130 status
= dcerpc_binding_set_flags(bd
, flags
, 0);
131 if (!NT_STATUS_IS_OK(status
)) {
143 struct rpc_client_connection
{
144 DATA_BLOB transport_session_key
;
145 struct rpc_cli_transport
*transport
;
148 uint16_t max_xmit_frag
;
149 uint16_t max_recv_frag
;
150 bool client_hdr_signing
;
155 uint32_t next_auth_context_id
;
156 uint16_t next_pres_context_id
;
159 static NTSTATUS
rpc_client_connection_create(TALLOC_CTX
*mem_ctx
,
160 const struct rpc_client_association
*assoc
,
162 struct rpc_client_connection
**pconn
)
164 struct rpc_client_connection
*conn
= NULL
;
165 uint32_t flags
= dcerpc_binding_get_flags(assoc
->binding
);
166 bool client_hdr_signing
= (flags
& DCERPC_PROPOSE_HEADER_SIGNING
);
168 conn
= talloc_zero(mem_ctx
, struct rpc_client_connection
);
170 return NT_STATUS_NO_MEMORY
;
172 conn
->features
.max_xmit_frag
= max_frag
;
173 conn
->features
.max_recv_frag
= max_frag
;
174 conn
->features
.client_hdr_signing
= client_hdr_signing
;
180 static int rpc_pipe_client_wrap_destructor(struct rpc_pipe_client
*p
)
182 if (p
->np_cli
!= NULL
) {
183 DLIST_REMOVE(p
->np_cli
->pipe_list
, p
);
190 static NTSTATUS
rpc_pipe_wrap_create(
191 const struct ndr_interface_table
*table
,
192 struct cli_state
*np_cli
,
193 struct rpc_client_association
**passoc
,
194 struct rpc_client_connection
**pconn
,
196 struct rpc_pipe_client
**presult
)
198 struct rpc_pipe_client
*result
= NULL
;
199 const char *hostname
= NULL
;
201 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
202 if (result
== NULL
) {
203 return NT_STATUS_NO_MEMORY
;
205 talloc_set_destructor(result
, rpc_pipe_client_wrap_destructor
);
207 result
->assoc
= talloc_move(result
, passoc
);
208 result
->conn
= talloc_move(result
, pconn
);
210 /* rpc_pipe_bind_send should allocate an id... */
211 result
->pres_context_id
= UINT16_MAX
;
212 result
->table
= table
;
213 result
->transfer_syntax
= ndr_transfer_syntax_ndr
;
215 hostname
= dcerpc_binding_get_string_option(result
->assoc
->binding
,
217 result
->desthost
= talloc_strdup(result
, hostname
);
218 if (result
->desthost
== NULL
) {
220 return NT_STATUS_NO_MEMORY
;
223 result
->srv_name_slash
= talloc_asprintf_strupper_m(
224 result
, "\\\\%s", result
->desthost
);
225 if (result
->srv_name_slash
== NULL
) {
227 return NT_STATUS_NO_MEMORY
;
230 if (np_cli
!= NULL
) {
231 result
->np_cli
= np_cli
;
232 DLIST_ADD_END(np_cli
->pipe_list
, result
);
239 /********************************************************************
240 Pipe description for a DEBUG
241 ********************************************************************/
242 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
243 struct rpc_pipe_client
*cli
)
245 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
246 if (result
== NULL
) {
252 /*******************************************************************
253 Use SMBreadX to get rest of one fragment's worth of rpc data.
254 Reads the whole size or give an error message
255 ********************************************************************/
257 struct rpc_read_state
{
258 struct tevent_context
*ev
;
259 struct rpc_cli_transport
*transport
;
265 static void rpc_read_done(struct tevent_req
*subreq
);
267 static struct tevent_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
268 struct tevent_context
*ev
,
269 struct rpc_cli_transport
*transport
,
270 uint8_t *data
, size_t size
)
272 struct tevent_req
*req
, *subreq
;
273 struct rpc_read_state
*state
;
275 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_read_state
);
280 state
->transport
= transport
;
285 DBG_INFO("data_to_read: %zu\n", size
);
287 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
289 if (subreq
== NULL
) {
292 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
300 static void rpc_read_done(struct tevent_req
*subreq
)
302 struct tevent_req
*req
= tevent_req_callback_data(
303 subreq
, struct tevent_req
);
304 struct rpc_read_state
*state
= tevent_req_data(
305 req
, struct rpc_read_state
);
309 status
= state
->transport
->read_recv(subreq
, &received
);
311 if (tevent_req_nterror(req
, status
)) {
315 state
->num_read
+= received
;
316 if (state
->num_read
== state
->size
) {
317 tevent_req_done(req
);
321 subreq
= state
->transport
->read_send(state
, state
->ev
,
322 state
->data
+ state
->num_read
,
323 state
->size
- state
->num_read
,
324 state
->transport
->priv
);
325 if (tevent_req_nomem(subreq
, req
)) {
328 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
331 static NTSTATUS
rpc_read_recv(struct tevent_req
*req
)
333 return tevent_req_simple_recv_ntstatus(req
);
336 struct rpc_write_state
{
337 struct tevent_context
*ev
;
338 struct rpc_cli_transport
*transport
;
344 static void rpc_write_done(struct tevent_req
*subreq
);
346 static struct tevent_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
347 struct tevent_context
*ev
,
348 struct rpc_cli_transport
*transport
,
349 const uint8_t *data
, size_t size
)
351 struct tevent_req
*req
, *subreq
;
352 struct rpc_write_state
*state
;
354 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_write_state
);
359 state
->transport
= transport
;
362 state
->num_written
= 0;
364 DBG_INFO("data_to_write: %zu\n", size
);
366 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
367 if (tevent_req_nomem(subreq
, req
)) {
368 return tevent_req_post(req
, ev
);
370 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
374 static void rpc_write_done(struct tevent_req
*subreq
)
376 struct tevent_req
*req
= tevent_req_callback_data(
377 subreq
, struct tevent_req
);
378 struct rpc_write_state
*state
= tevent_req_data(
379 req
, struct rpc_write_state
);
383 status
= state
->transport
->write_recv(subreq
, &written
);
385 if (tevent_req_nterror(req
, status
)) {
389 state
->num_written
+= written
;
391 if (state
->num_written
== state
->size
) {
392 tevent_req_done(req
);
396 subreq
= state
->transport
->write_send(state
, state
->ev
,
397 state
->data
+ state
->num_written
,
398 state
->size
- state
->num_written
,
399 state
->transport
->priv
);
400 if (tevent_req_nomem(subreq
, req
)) {
403 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
406 static NTSTATUS
rpc_write_recv(struct tevent_req
*req
)
408 return tevent_req_simple_recv_ntstatus(req
);
412 /****************************************************************************
413 Try and get a PDU's worth of data from current_pdu. If not, then read more
415 ****************************************************************************/
417 struct get_complete_frag_state
{
418 struct tevent_context
*ev
;
419 struct rpc_pipe_client
*cli
;
424 static void get_complete_frag_got_header(struct tevent_req
*subreq
);
425 static void get_complete_frag_got_rest(struct tevent_req
*subreq
);
427 static struct tevent_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
428 struct tevent_context
*ev
,
429 struct rpc_pipe_client
*cli
,
432 struct tevent_req
*req
, *subreq
;
433 struct get_complete_frag_state
*state
;
436 req
= tevent_req_create(mem_ctx
, &state
,
437 struct get_complete_frag_state
);
443 state
->frag_len
= RPC_HEADER_LEN
;
446 received
= pdu
->length
;
447 if (received
< RPC_HEADER_LEN
) {
448 if (!data_blob_realloc(mem_ctx
, pdu
, RPC_HEADER_LEN
)) {
450 return tevent_req_post(req
, ev
);
452 subreq
= rpc_read_send(state
, state
->ev
,
453 state
->cli
->conn
->transport
,
454 pdu
->data
+ received
,
455 RPC_HEADER_LEN
- received
);
456 if (tevent_req_nomem(subreq
, req
)) {
457 return tevent_req_post(req
, ev
);
459 tevent_req_set_callback(subreq
, get_complete_frag_got_header
,
464 state
->frag_len
= dcerpc_get_frag_length(pdu
);
465 if (state
->frag_len
< RPC_HEADER_LEN
) {
466 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
467 return tevent_req_post(req
, ev
);
470 if (received
>= state
->frag_len
) {
472 * Got the whole fragment
474 tevent_req_done(req
);
475 return tevent_req_post(req
, ev
);
478 if (!data_blob_realloc(NULL
, pdu
, state
->frag_len
)) {
480 return tevent_req_post(req
, ev
);
483 subreq
= rpc_read_send(
486 state
->cli
->conn
->transport
,
487 pdu
->data
+ received
,
488 state
->frag_len
- received
);
489 if (tevent_req_nomem(subreq
, req
)) {
490 return tevent_req_post(req
, ev
);
492 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
496 static void get_complete_frag_got_header(struct tevent_req
*subreq
)
498 struct tevent_req
*req
= tevent_req_callback_data(
499 subreq
, struct tevent_req
);
500 struct get_complete_frag_state
*state
= tevent_req_data(
501 req
, struct get_complete_frag_state
);
504 status
= rpc_read_recv(subreq
);
506 if (tevent_req_nterror(req
, status
)) {
510 state
->frag_len
= dcerpc_get_frag_length(state
->pdu
);
511 if (state
->frag_len
< RPC_HEADER_LEN
) {
512 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
516 if (!data_blob_realloc(NULL
, state
->pdu
, state
->frag_len
)) {
522 * We're here in this piece of code because we've read exactly
523 * RPC_HEADER_LEN bytes into state->pdu.
526 subreq
= rpc_read_send(state
, state
->ev
,
527 state
->cli
->conn
->transport
,
528 state
->pdu
->data
+ RPC_HEADER_LEN
,
529 state
->frag_len
- RPC_HEADER_LEN
);
530 if (tevent_req_nomem(subreq
, req
)) {
533 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
536 static void get_complete_frag_got_rest(struct tevent_req
*subreq
)
538 NTSTATUS status
= rpc_read_recv(subreq
);
539 return tevent_req_simple_finish_ntstatus(subreq
, status
);
542 static NTSTATUS
get_complete_frag_recv(struct tevent_req
*req
)
544 return tevent_req_simple_recv_ntstatus(req
);
547 /****************************************************************************
548 Do basic authentication checks on an incoming pdu.
549 ****************************************************************************/
551 static NTSTATUS
cli_pipe_validate_current_pdu(TALLOC_CTX
*mem_ctx
,
552 struct rpc_pipe_client
*cli
,
553 struct ncacn_packet
*pkt
,
555 uint8_t expected_pkt_type
,
558 DATA_BLOB
*reply_pdu
)
560 const struct dcerpc_response
*r
= NULL
;
561 DATA_BLOB tmp_stub
= { .data
= NULL
};
565 * Point the return values at the real data including the RPC
566 * header. Just in case the caller wants it.
570 if ((pkt
->ptype
== DCERPC_PKT_BIND_ACK
) &&
571 !(pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
573 * TODO: do we still need this hack which was introduced
574 * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
576 * I don't even know what AS/U might be...
578 DEBUG(5, (__location__
": bug in server (AS/U?), setting "
579 "fragment first/last ON.\n"));
580 pkt
->pfc_flags
|= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
583 /* Ensure we have the correct type. */
584 switch (pkt
->ptype
) {
585 case DCERPC_PKT_BIND_NAK
:
586 DEBUG(1, (__location__
": Bind NACK received from %s!\n",
587 rpccli_pipe_txt(talloc_tos(), cli
)));
589 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
591 0, /* max_auth_info */
592 DCERPC_PFC_FLAG_FIRST
|
593 DCERPC_PFC_FLAG_LAST
,
594 0); /* optional flags */
595 if (!NT_STATUS_IS_OK(ret
)) {
596 DEBUG(1, (__location__
": Connection to %s got an unexpected "
597 "RPC packet type - %u, expected %u: %s\n",
598 rpccli_pipe_txt(talloc_tos(), cli
),
599 pkt
->ptype
, expected_pkt_type
,
601 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
605 /* Use this for now... */
606 return NT_STATUS_NETWORK_ACCESS_DENIED
;
608 case DCERPC_PKT_BIND_ACK
:
609 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
611 pkt
->u
.bind_ack
.auth_info
.length
,
612 DCERPC_PFC_FLAG_FIRST
|
613 DCERPC_PFC_FLAG_LAST
,
614 DCERPC_PFC_FLAG_CONC_MPX
|
615 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
616 if (!NT_STATUS_IS_OK(ret
)) {
617 DEBUG(1, (__location__
": Connection to %s got an unexpected "
618 "RPC packet type - %u, expected %u: %s\n",
619 rpccli_pipe_txt(talloc_tos(), cli
),
620 pkt
->ptype
, expected_pkt_type
,
622 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
628 case DCERPC_PKT_ALTER_RESP
:
629 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
631 pkt
->u
.alter_resp
.auth_info
.length
,
632 DCERPC_PFC_FLAG_FIRST
|
633 DCERPC_PFC_FLAG_LAST
,
634 DCERPC_PFC_FLAG_CONC_MPX
|
635 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
);
636 if (!NT_STATUS_IS_OK(ret
)) {
637 DEBUG(1, (__location__
": Connection to %s got an unexpected "
638 "RPC packet type - %u, expected %u: %s\n",
639 rpccli_pipe_txt(talloc_tos(), cli
),
640 pkt
->ptype
, expected_pkt_type
,
642 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
648 case DCERPC_PKT_RESPONSE
:
650 r
= &pkt
->u
.response
;
652 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
654 r
->stub_and_verifier
.length
,
655 0, /* required_flags */
656 DCERPC_PFC_FLAG_FIRST
|
657 DCERPC_PFC_FLAG_LAST
);
658 if (!NT_STATUS_IS_OK(ret
)) {
659 DEBUG(1, (__location__
": Connection to %s got an unexpected "
660 "RPC packet type - %u, expected %u: %s\n",
661 rpccli_pipe_txt(talloc_tos(), cli
),
662 pkt
->ptype
, expected_pkt_type
,
664 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
668 tmp_stub
.data
= r
->stub_and_verifier
.data
;
669 tmp_stub
.length
= r
->stub_and_verifier
.length
;
671 /* Here's where we deal with incoming sign/seal. */
672 ret
= dcerpc_check_auth(cli
->auth
, pkt
,
674 DCERPC_RESPONSE_LENGTH
,
676 if (!NT_STATUS_IS_OK(ret
)) {
677 DEBUG(1, (__location__
": Connection to %s got an unexpected "
678 "RPC packet type - %u, expected %u: %s\n",
679 rpccli_pipe_txt(talloc_tos(), cli
),
680 pkt
->ptype
, expected_pkt_type
,
682 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
686 /* Point the return values at the NDR data. */
689 DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
690 (long unsigned int)pdu
->length
,
691 (long unsigned int)rdata
->length
));
694 * If this is the first reply, and the allocation hint is
695 * reasonable, try and set up the reply_pdu DATA_BLOB to the
699 if ((reply_pdu
->length
== 0) &&
700 r
->alloc_hint
&& (r
->alloc_hint
< 15*1024*1024)) {
701 if (!data_blob_realloc(mem_ctx
, reply_pdu
,
703 DEBUG(0, ("reply alloc hint %d too "
704 "large to allocate\n",
705 (int)r
->alloc_hint
));
706 return NT_STATUS_NO_MEMORY
;
712 case DCERPC_PKT_FAULT
:
714 ret
= dcerpc_verify_ncacn_packet_header(pkt
,
716 0, /* max_auth_info */
717 DCERPC_PFC_FLAG_FIRST
|
718 DCERPC_PFC_FLAG_LAST
,
719 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
720 if (!NT_STATUS_IS_OK(ret
)) {
721 DEBUG(1, (__location__
": Connection to %s got an unexpected "
722 "RPC packet type - %u, expected %u: %s\n",
723 rpccli_pipe_txt(talloc_tos(), cli
),
724 pkt
->ptype
, expected_pkt_type
,
726 NDR_PRINT_DEBUG(ncacn_packet
, pkt
);
730 DEBUG(1, (__location__
": RPC fault code %s received "
732 dcerpc_errstr(talloc_tos(),
733 pkt
->u
.fault
.status
),
734 rpccli_pipe_txt(talloc_tos(), cli
)));
736 return dcerpc_fault_to_nt_status(pkt
->u
.fault
.status
);
739 DEBUG(0, (__location__
"Unknown packet type %u received "
741 (unsigned int)pkt
->ptype
,
742 rpccli_pipe_txt(talloc_tos(), cli
)));
743 return NT_STATUS_RPC_PROTOCOL_ERROR
;
747 if (pkt
->call_id
!= call_id
) {
748 DEBUG(3, (__location__
": Connection to %s got an unexpected "
749 "RPC call_id - %u, not %u\n",
750 rpccli_pipe_txt(talloc_tos(), cli
),
751 pkt
->call_id
, call_id
));
752 return NT_STATUS_RPC_PROTOCOL_ERROR
;
758 /****************************************************************************
759 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
760 ****************************************************************************/
762 struct cli_api_pipe_state
{
763 struct tevent_context
*ev
;
764 struct rpc_cli_transport
*transport
;
769 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
);
770 static void cli_api_pipe_write_done(struct tevent_req
*subreq
);
771 static void cli_api_pipe_read_done(struct tevent_req
*subreq
);
773 static struct tevent_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
774 struct tevent_context
*ev
,
775 struct rpc_cli_transport
*transport
,
776 uint8_t *data
, size_t data_len
,
777 uint32_t max_rdata_len
)
779 struct tevent_req
*req
, *subreq
;
780 struct cli_api_pipe_state
*state
;
782 req
= tevent_req_create(mem_ctx
, &state
, struct cli_api_pipe_state
);
787 state
->transport
= transport
;
789 if (max_rdata_len
< RPC_HEADER_LEN
) {
791 * For a RPC reply we always need at least RPC_HEADER_LEN
792 * bytes. We check this here because we will receive
793 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
795 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
796 return tevent_req_post(req
, ev
);
799 if (transport
->trans_send
!= NULL
) {
800 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
801 max_rdata_len
, transport
->priv
);
802 if (tevent_req_nomem(subreq
, req
)) {
803 return tevent_req_post(req
, ev
);
805 tevent_req_set_callback(subreq
, cli_api_pipe_trans_done
, req
);
810 * If the transport does not provide a "trans" routine, i.e. for
811 * example the ncacn_ip_tcp transport, do the write/read step here.
814 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
815 if (tevent_req_nomem(subreq
, req
)) {
816 return tevent_req_post(req
, ev
);
818 tevent_req_set_callback(subreq
, cli_api_pipe_write_done
, req
);
822 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
)
824 struct tevent_req
*req
= tevent_req_callback_data(
825 subreq
, struct tevent_req
);
826 struct cli_api_pipe_state
*state
= tevent_req_data(
827 req
, struct cli_api_pipe_state
);
830 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
833 if (tevent_req_nterror(req
, status
)) {
836 tevent_req_done(req
);
839 static void cli_api_pipe_write_done(struct tevent_req
*subreq
)
841 struct tevent_req
*req
= tevent_req_callback_data(
842 subreq
, struct tevent_req
);
843 struct cli_api_pipe_state
*state
= tevent_req_data(
844 req
, struct cli_api_pipe_state
);
847 status
= rpc_write_recv(subreq
);
849 if (tevent_req_nterror(req
, status
)) {
853 state
->rdata
= talloc_array(state
, uint8_t, RPC_HEADER_LEN
);
854 if (tevent_req_nomem(state
->rdata
, req
)) {
859 * We don't need to use rpc_read_send here, the upper layer will cope
860 * with a short read, transport->trans_send could also return less
861 * than state->max_rdata_len.
863 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
865 state
->transport
->priv
);
866 if (tevent_req_nomem(subreq
, req
)) {
869 tevent_req_set_callback(subreq
, cli_api_pipe_read_done
, req
);
872 static void cli_api_pipe_read_done(struct tevent_req
*subreq
)
874 struct tevent_req
*req
= tevent_req_callback_data(
875 subreq
, struct tevent_req
);
876 struct cli_api_pipe_state
*state
= tevent_req_data(
877 req
, struct cli_api_pipe_state
);
881 status
= state
->transport
->read_recv(subreq
, &received
);
883 if (tevent_req_nterror(req
, status
)) {
886 state
->rdata_len
= received
;
887 tevent_req_done(req
);
890 static NTSTATUS
cli_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
891 uint8_t **prdata
, uint32_t *prdata_len
)
893 struct cli_api_pipe_state
*state
= tevent_req_data(
894 req
, struct cli_api_pipe_state
);
897 if (tevent_req_is_nterror(req
, &status
)) {
901 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
902 *prdata_len
= state
->rdata_len
;
906 /****************************************************************************
907 Send data on an rpc pipe via trans. The data must be the last
908 pdu fragment of an NDR data stream.
910 Receive response data from an rpc pipe, which may be large...
912 Read the first fragment: unfortunately have to use SMBtrans for the first
913 bit, then SMBreadX for subsequent bits.
915 If first fragment received also wasn't the last fragment, continue
916 getting fragments until we _do_ receive the last fragment.
918 Request/Response PDU's look like the following...
920 |<------------------PDU len----------------------------------------------->|
921 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
923 +------------+-----------------+-------------+---------------+-------------+
924 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
925 +------------+-----------------+-------------+---------------+-------------+
927 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
928 signing & sealing being negotiated.
930 ****************************************************************************/
932 struct rpc_api_pipe_state
{
933 struct tevent_context
*ev
;
934 struct rpc_pipe_client
*cli
;
935 uint8_t expected_pkt_type
;
938 DATA_BLOB incoming_frag
;
939 struct ncacn_packet
*pkt
;
943 size_t reply_pdu_offset
;
947 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
);
948 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
);
949 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
);
951 static struct tevent_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
952 struct tevent_context
*ev
,
953 struct rpc_pipe_client
*cli
,
954 DATA_BLOB
*data
, /* Outgoing PDU */
955 uint8_t expected_pkt_type
,
958 struct tevent_req
*req
, *subreq
;
959 struct rpc_api_pipe_state
*state
;
960 uint16_t max_recv_frag
;
962 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_api_pipe_state
);
968 state
->expected_pkt_type
= expected_pkt_type
;
969 state
->call_id
= call_id
;
970 state
->endianness
= DCERPC_DREP_LE
;
973 * Ensure we're not sending too much.
975 if (data
->length
> cli
->conn
->features
.max_xmit_frag
) {
976 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
977 return tevent_req_post(req
, ev
);
980 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli
)));
982 if (state
->expected_pkt_type
== DCERPC_PKT_AUTH3
) {
983 subreq
= rpc_write_send(state
, ev
, cli
->conn
->transport
,
984 data
->data
, data
->length
);
985 if (tevent_req_nomem(subreq
, req
)) {
986 return tevent_req_post(req
, ev
);
988 tevent_req_set_callback(subreq
, rpc_api_pipe_auth3_done
, req
);
992 /* get the header first, then fetch the rest once we have
993 * the frag_length available */
994 max_recv_frag
= RPC_HEADER_LEN
;
996 subreq
= cli_api_pipe_send(state
, ev
, cli
->conn
->transport
,
997 data
->data
, data
->length
, max_recv_frag
);
998 if (tevent_req_nomem(subreq
, req
)) {
999 return tevent_req_post(req
, ev
);
1001 tevent_req_set_callback(subreq
, rpc_api_pipe_trans_done
, req
);
1005 static void rpc_api_pipe_auth3_done(struct tevent_req
*subreq
)
1007 NTSTATUS status
= rpc_write_recv(subreq
);
1008 return tevent_req_simple_finish_ntstatus(subreq
, status
);
1011 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
)
1013 struct tevent_req
*req
= tevent_req_callback_data(
1014 subreq
, struct tevent_req
);
1015 struct rpc_api_pipe_state
*state
= tevent_req_data(
1016 req
, struct rpc_api_pipe_state
);
1018 uint8_t *rdata
= NULL
;
1019 uint32_t rdata_len
= 0;
1021 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
1022 TALLOC_FREE(subreq
);
1023 if (tevent_req_nterror(req
, status
)) {;
1024 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
1028 if (rdata
== NULL
) {
1029 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1030 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1031 tevent_req_done(req
);
1036 * Move data on state->incoming_frag.
1038 state
->incoming_frag
.data
= talloc_move(state
, &rdata
);
1039 state
->incoming_frag
.length
= rdata_len
;
1040 if (!state
->incoming_frag
.data
) {
1041 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1045 /* Ensure we have enough data for a pdu. */
1046 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1047 &state
->incoming_frag
);
1048 if (tevent_req_nomem(subreq
, req
)) {
1051 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1054 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
)
1056 struct tevent_req
*req
= tevent_req_callback_data(
1057 subreq
, struct tevent_req
);
1058 struct rpc_api_pipe_state
*state
= tevent_req_data(
1059 req
, struct rpc_api_pipe_state
);
1061 DATA_BLOB rdata
= { .data
= NULL
};
1063 status
= get_complete_frag_recv(subreq
);
1064 TALLOC_FREE(subreq
);
1065 if (tevent_req_nterror(req
, status
)) {
1066 DEBUG(5, ("get_complete_frag failed: %s\n",
1067 nt_errstr(status
)));
1071 state
->pkt
= talloc(state
, struct ncacn_packet
);
1074 * TODO: do a real async disconnect ...
1076 * For now do it sync...
1078 TALLOC_FREE(state
->cli
->conn
);
1079 tevent_req_oom(req
);
1083 status
= dcerpc_pull_ncacn_packet(state
->pkt
,
1084 &state
->incoming_frag
,
1086 if (tevent_req_nterror(req
, status
)) {
1088 * TODO: do a real async disconnect ...
1090 * For now do it sync...
1092 TALLOC_FREE(state
->cli
->conn
);
1096 if (DEBUGLEVEL
>= 10) {
1097 NDR_PRINT_DEBUG(ncacn_packet
, state
->pkt
);
1100 status
= cli_pipe_validate_current_pdu(state
,
1101 state
->cli
, state
->pkt
,
1102 &state
->incoming_frag
,
1103 state
->expected_pkt_type
,
1108 DBG_DEBUG("got frag len of %zu at offset %zu: %s\n",
1109 state
->incoming_frag
.length
,
1110 state
->reply_pdu_offset
,
1113 if (state
->pkt
->ptype
!= DCERPC_PKT_FAULT
&& !NT_STATUS_IS_OK(status
)) {
1115 * TODO: do a real async disconnect ...
1117 * For now do it sync...
1119 TALLOC_FREE(state
->cli
->conn
);
1120 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
1122 * TODO: do a real async disconnect ...
1124 * For now do it sync...
1126 TALLOC_FREE(state
->cli
->conn
);
1127 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
)) {
1129 * TODO: do a real async disconnect ...
1131 * For now do it sync...
1133 TALLOC_FREE(state
->cli
->conn
);
1135 if (tevent_req_nterror(req
, status
)) {
1139 if ((state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_FIRST
)
1140 && (state
->pkt
->drep
[0] != DCERPC_DREP_LE
)) {
1142 * Set the data type correctly for big-endian data on the
1145 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1147 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1148 state
->endianness
= 0x00; /* BIG ENDIAN */
1151 * Check endianness on subsequent packets.
1153 if (state
->endianness
!= state
->pkt
->drep
[0]) {
1154 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1156 state
->endianness
?"little":"big",
1157 state
->pkt
->drep
[0]?"little":"big"));
1159 * TODO: do a real async disconnect ...
1161 * For now do it sync...
1163 TALLOC_FREE(state
->cli
->conn
);
1164 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1168 if (state
->reply_pdu_offset
+ rdata
.length
> MAX_RPC_DATA_SIZE
) {
1170 * TODO: do a real async disconnect ...
1172 * For now do it sync...
1174 TALLOC_FREE(state
->cli
->conn
);
1175 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
1179 /* Now copy the data portion out of the pdu into rbuf. */
1180 if (state
->reply_pdu
.length
< state
->reply_pdu_offset
+ rdata
.length
) {
1181 if (!data_blob_realloc(NULL
, &state
->reply_pdu
,
1182 state
->reply_pdu_offset
+ rdata
.length
)) {
1184 * TODO: do a real async disconnect ...
1186 * For now do it sync...
1188 TALLOC_FREE(state
->cli
->conn
);
1189 tevent_req_oom(req
);
1194 memcpy(state
->reply_pdu
.data
+ state
->reply_pdu_offset
,
1195 rdata
.data
, rdata
.length
);
1196 state
->reply_pdu_offset
+= rdata
.length
;
1198 /* reset state->incoming_frag, there is no need to free it,
1199 * it will be reallocated to the right size the next time
1201 state
->incoming_frag
.length
= 0;
1203 if (state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
) {
1204 /* make sure the pdu length is right now that we
1205 * have all the data available (alloc hint may
1206 * have allocated more than was actually used) */
1207 state
->reply_pdu
.length
= state
->reply_pdu_offset
;
1208 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1209 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1210 (unsigned)state
->reply_pdu
.length
));
1211 tevent_req_done(req
);
1215 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1216 &state
->incoming_frag
);
1217 if (subreq
== NULL
) {
1219 * TODO: do a real async disconnect ...
1221 * For now do it sync...
1223 TALLOC_FREE(state
->cli
->conn
);
1225 if (tevent_req_nomem(subreq
, req
)) {
1228 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1231 static NTSTATUS
rpc_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1232 struct ncacn_packet
**pkt
,
1233 DATA_BLOB
*reply_pdu
)
1235 struct rpc_api_pipe_state
*state
= tevent_req_data(
1236 req
, struct rpc_api_pipe_state
);
1239 if (tevent_req_is_nterror(req
, &status
)) {
1243 /* return data to caller and assign it ownership of memory */
1245 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1246 reply_pdu
->length
= state
->reply_pdu
.length
;
1247 state
->reply_pdu
.length
= 0;
1249 data_blob_free(&state
->reply_pdu
);
1253 *pkt
= talloc_steal(mem_ctx
, state
->pkt
);
1256 return NT_STATUS_OK
;
1259 /*******************************************************************
1260 Creates NTLMSSP auth bind.
1261 ********************************************************************/
1263 static NTSTATUS
create_generic_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1264 TALLOC_CTX
*mem_ctx
,
1265 DATA_BLOB
*auth_token
)
1267 struct gensec_security
*gensec_security
;
1268 DATA_BLOB null_blob
= { .data
= NULL
};
1271 gensec_security
= cli
->auth
->auth_ctx
;
1273 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1274 status
= gensec_update(gensec_security
, mem_ctx
, null_blob
, auth_token
);
1276 if (!NT_STATUS_IS_OK(status
) &&
1277 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1285 /*******************************************************************
1286 Creates the internals of a DCE/RPC bind request or alter context PDU.
1287 ********************************************************************/
1289 static NTSTATUS
create_bind_or_alt_ctx_internal(TALLOC_CTX
*mem_ctx
,
1290 enum dcerpc_pkt_type ptype
,
1291 uint32_t rpc_call_id
,
1292 struct rpc_client_association
*assoc
,
1293 struct rpc_client_connection
*conn
,
1294 uint16_t pres_context_id
,
1295 const struct ndr_syntax_id
*abstract
,
1296 const struct ndr_syntax_id
*transfer
,
1297 const DATA_BLOB
*auth_info
,
1300 uint16_t auth_len
= auth_info
->length
;
1302 struct ndr_syntax_id bind_time_features
= dcerpc_construct_bind_time_features(
1303 assoc
->features
.client
);
1304 struct dcerpc_ctx_list ctx_list
[2] = {
1306 .context_id
= pres_context_id
,
1307 .num_transfer_syntaxes
= 1,
1308 .abstract_syntax
= *abstract
,
1309 .transfer_syntaxes
= (struct ndr_syntax_id
*)discard_const(transfer
),
1313 * For now we assume pres_context_id is 0
1314 * because bind time feature negotiation
1315 * only happens once per association,
1316 * with the first DCERPC Bind.
1318 * With that we use pres_context_id + 1,
1319 * but only consume it from conn->next_pres_context_id
1320 * in check_bind_response().
1322 .context_id
= pres_context_id
+ 1,
1323 .num_transfer_syntaxes
= 1,
1324 .abstract_syntax
= *abstract
,
1325 .transfer_syntaxes
= &bind_time_features
,
1328 uint32_t assoc_group_id
=
1329 dcerpc_binding_get_assoc_group_id(assoc
->binding
);
1330 union dcerpc_payload u
= {
1331 .bind
.max_xmit_frag
= conn
->features
.max_xmit_frag
,
1332 .bind
.max_recv_frag
= conn
->features
.max_recv_frag
,
1333 .bind
.assoc_group_id
= assoc_group_id
,
1334 .bind
.num_contexts
= assoc
->features
.negotiation_done
? 1 : 2,
1335 .bind
.ctx_list
= ctx_list
,
1336 .bind
.auth_info
= *auth_info
,
1338 uint8_t pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
1340 if (conn
->features
.client_hdr_signing
&&
1342 !conn
->features
.hdr_signing
)
1345 * The first authenticated bind or alter_context
1346 * negotiates header signing
1348 pfc_flags
|= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
;
1352 auth_len
-= DCERPC_AUTH_TRAILER_LENGTH
;
1355 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1361 if (!NT_STATUS_IS_OK(status
)) {
1362 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1366 return NT_STATUS_OK
;
1369 /*******************************************************************
1370 Creates a DCE/RPC bind request.
1371 ********************************************************************/
1373 static NTSTATUS
create_rpc_bind_req(TALLOC_CTX
*mem_ctx
,
1374 struct rpc_pipe_client
*cli
,
1375 struct pipe_auth_data
*auth
,
1376 uint32_t rpc_call_id
,
1377 const struct ndr_syntax_id
*abstract
,
1378 const struct ndr_syntax_id
*transfer
,
1381 enum dcerpc_pkt_type ptype
= DCERPC_PKT_BIND
;
1382 DATA_BLOB auth_token
= { .data
= NULL
};
1383 DATA_BLOB auth_info
= { .data
= NULL
};
1386 if (cli
->conn
->features
.bind_done
) {
1387 ptype
= DCERPC_PKT_ALTER
;
1390 if (auth
->auth_type
!= DCERPC_AUTH_TYPE_NONE
) {
1391 ret
= create_generic_auth_rpc_bind_req(
1392 cli
, mem_ctx
, &auth_token
);
1394 if (!NT_STATUS_IS_OK(ret
) &&
1395 !NT_STATUS_EQUAL(ret
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1400 if (auth_token
.length
!= 0) {
1401 ret
= dcerpc_push_dcerpc_auth(cli
,
1404 0, /* auth_pad_length */
1405 auth
->auth_context_id
,
1408 if (!NT_STATUS_IS_OK(ret
)) {
1411 data_blob_free(&auth_token
);
1414 ret
= create_bind_or_alt_ctx_internal(mem_ctx
,
1419 cli
->pres_context_id
,
1424 data_blob_free(&auth_info
);
1429 /*******************************************************************
1431 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1432 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1433 and deals with signing/sealing details.
1434 ********************************************************************/
1436 struct rpc_api_pipe_req_state
{
1437 struct tevent_context
*ev
;
1438 struct rpc_pipe_client
*cli
;
1441 const DATA_BLOB
*req_data
;
1442 const struct GUID
*object_uuid
;
1443 uint32_t req_data_sent
;
1444 DATA_BLOB req_trailer
;
1445 uint32_t req_trailer_sent
;
1446 bool verify_bitmask1
;
1447 bool verify_pcontext
;
1449 DATA_BLOB reply_pdu
;
1452 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
1453 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
1454 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
);
1455 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1456 bool *is_last_frag
);
1458 static struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
1459 struct tevent_context
*ev
,
1460 struct rpc_pipe_client
*cli
,
1462 const struct GUID
*object_uuid
,
1463 const DATA_BLOB
*req_data
)
1465 struct tevent_req
*req
, *subreq
;
1466 struct rpc_api_pipe_req_state
*state
;
1470 req
= tevent_req_create(mem_ctx
, &state
,
1471 struct rpc_api_pipe_req_state
);
1477 state
->op_num
= op_num
;
1478 state
->object_uuid
= object_uuid
;
1479 state
->req_data
= req_data
;
1480 state
->call_id
= ++cli
->assoc
->next_call_id
;
1482 if (cli
->conn
->features
.max_xmit_frag
< DCERPC_REQUEST_LENGTH
1483 + RPC_MAX_SIGN_SIZE
) {
1484 /* Server is screwed up ! */
1485 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1486 return tevent_req_post(req
, ev
);
1489 status
= prepare_verification_trailer(state
);
1490 if (tevent_req_nterror(req
, status
)) {
1491 return tevent_req_post(req
, ev
);
1494 status
= prepare_next_frag(state
, &is_last_frag
);
1495 if (tevent_req_nterror(req
, status
)) {
1496 return tevent_req_post(req
, ev
);
1500 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
1502 DCERPC_PKT_RESPONSE
,
1504 if (tevent_req_nomem(subreq
, req
)) {
1505 return tevent_req_post(req
, ev
);
1507 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1509 subreq
= rpc_write_send(state
, ev
, cli
->conn
->transport
,
1510 state
->rpc_out
.data
,
1511 state
->rpc_out
.length
);
1512 if (tevent_req_nomem(subreq
, req
)) {
1513 return tevent_req_post(req
, ev
);
1515 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1521 static NTSTATUS
prepare_verification_trailer(struct rpc_api_pipe_req_state
*state
)
1523 struct pipe_auth_data
*a
= state
->cli
->auth
;
1524 struct dcerpc_sec_verification_trailer
*t
;
1525 struct ndr_push
*ndr
= NULL
;
1526 enum ndr_err_code ndr_err
;
1531 return NT_STATUS_OK
;
1534 if (a
->auth_level
< DCERPC_AUTH_LEVEL_PACKET
) {
1535 return NT_STATUS_OK
;
1538 t
= talloc_zero(state
, struct dcerpc_sec_verification_trailer
);
1540 return NT_STATUS_NO_MEMORY
;
1543 if (!a
->verified_bitmask1
) {
1544 t
->commands
= talloc_realloc(t
, t
->commands
,
1545 struct dcerpc_sec_vt
,
1546 t
->count
.count
+ 1);
1547 if (t
->commands
== NULL
) {
1548 return NT_STATUS_NO_MEMORY
;
1550 t
->commands
[t
->count
.count
++] = (struct dcerpc_sec_vt
) {
1551 .command
= DCERPC_SEC_VT_COMMAND_BITMASK1
,
1552 .u
.bitmask1
= (state
->cli
->conn
->features
.client_hdr_signing
) ?
1553 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING
:
1556 state
->verify_bitmask1
= true;
1559 if (!state
->cli
->verified_pcontext
) {
1560 t
->commands
= talloc_realloc(t
, t
->commands
,
1561 struct dcerpc_sec_vt
,
1562 t
->count
.count
+ 1);
1563 if (t
->commands
== NULL
) {
1564 return NT_STATUS_NO_MEMORY
;
1566 t
->commands
[t
->count
.count
++] = (struct dcerpc_sec_vt
) {
1567 .command
= DCERPC_SEC_VT_COMMAND_PCONTEXT
,
1568 .u
.pcontext
.abstract_syntax
=
1569 state
->cli
->table
->syntax_id
,
1570 .u
.pcontext
.transfer_syntax
=
1571 state
->cli
->transfer_syntax
,
1573 state
->verify_pcontext
= true;
1576 if (!a
->hdr_signing
) {
1577 t
->commands
= talloc_realloc(t
, t
->commands
,
1578 struct dcerpc_sec_vt
,
1579 t
->count
.count
+ 1);
1580 if (t
->commands
== NULL
) {
1581 return NT_STATUS_NO_MEMORY
;
1583 t
->commands
[t
->count
.count
++] = (struct dcerpc_sec_vt
) {
1584 .command
= DCERPC_SEC_VT_COMMAND_HEADER2
,
1585 .u
.header2
.ptype
= DCERPC_PKT_REQUEST
,
1586 .u
.header2
.drep
[0] = DCERPC_DREP_LE
,
1587 .u
.header2
.call_id
= state
->call_id
,
1588 .u
.header2
.context_id
= state
->cli
->pres_context_id
,
1589 .u
.header2
.opnum
= state
->op_num
,
1593 if (t
->count
.count
== 0) {
1595 return NT_STATUS_OK
;
1598 t
->commands
[t
->count
.count
- 1].command
|= DCERPC_SEC_VT_COMMAND_END
;
1600 if (DEBUGLEVEL
>= 10) {
1601 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer
, t
);
1604 ndr
= ndr_push_init_ctx(state
);
1606 return NT_STATUS_NO_MEMORY
;
1609 ndr_err
= ndr_push_dcerpc_sec_verification_trailer(ndr
,
1610 NDR_SCALARS
| NDR_BUFFERS
,
1613 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1614 return ndr_map_error2ntstatus(ndr_err
);
1616 state
->req_trailer
= ndr_push_blob(ndr
);
1618 align
= state
->req_data
->length
& 0x3;
1625 const uint8_t zeros
[4] = { 0, };
1627 ok
= data_blob_append(ndr
, &state
->req_trailer
, zeros
, pad
);
1629 return NT_STATUS_NO_MEMORY
;
1632 /* move the padding to the start */
1633 p
= state
->req_trailer
.data
;
1634 memmove(p
+ pad
, p
, state
->req_trailer
.length
- pad
);
1638 return NT_STATUS_OK
;
1641 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1649 size_t data_thistime
;
1650 size_t trailer_left
;
1651 size_t trailer_thistime
= 0;
1653 size_t total_thistime
;
1656 union dcerpc_payload u
;
1658 data_left
= state
->req_data
->length
- state
->req_data_sent
;
1659 trailer_left
= state
->req_trailer
.length
- state
->req_trailer_sent
;
1660 total_left
= data_left
+ trailer_left
;
1661 if ((total_left
< data_left
) || (total_left
< trailer_left
)) {
1665 return NT_STATUS_INVALID_PARAMETER_MIX
;
1668 status
= dcerpc_guess_sizes(state
->cli
->auth
,
1669 DCERPC_REQUEST_LENGTH
, total_left
,
1670 state
->cli
->conn
->features
.max_xmit_frag
,
1672 &frag_len
, &auth_len
, &pad_len
);
1673 if (!NT_STATUS_IS_OK(status
)) {
1677 if (state
->req_data_sent
== 0) {
1678 flags
= DCERPC_PFC_FLAG_FIRST
;
1681 if (total_thistime
== total_left
) {
1682 flags
|= DCERPC_PFC_FLAG_LAST
;
1685 data_thistime
= MIN(total_thistime
, data_left
);
1686 if (data_thistime
< total_thistime
) {
1687 trailer_thistime
= total_thistime
- data_thistime
;
1690 data_blob_free(&state
->rpc_out
);
1692 u
= (union dcerpc_payload
) {
1693 .request
.alloc_hint
= total_left
,
1694 .request
.context_id
= state
->cli
->pres_context_id
,
1695 .request
.opnum
= state
->op_num
,
1698 if (state
->object_uuid
) {
1699 flags
|= DCERPC_PFC_FLAG_OBJECT_UUID
;
1700 u
.request
.object
.object
= *state
->object_uuid
;
1701 frag_len
+= ndr_size_GUID(state
->object_uuid
, 0);
1704 status
= dcerpc_push_ncacn_packet(state
,
1711 if (!NT_STATUS_IS_OK(status
)) {
1715 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1716 * compute it right for requests because the auth trailer is missing
1718 dcerpc_set_frag_length(&state
->rpc_out
, frag_len
);
1720 if (data_thistime
> 0) {
1721 /* Copy in the data. */
1722 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1723 state
->req_data
->data
+ state
->req_data_sent
,
1726 return NT_STATUS_NO_MEMORY
;
1728 state
->req_data_sent
+= data_thistime
;
1731 if (trailer_thistime
> 0) {
1732 /* Copy in the verification trailer. */
1733 ok
= data_blob_append(NULL
, &state
->rpc_out
,
1734 state
->req_trailer
.data
+ state
->req_trailer_sent
,
1737 return NT_STATUS_NO_MEMORY
;
1739 state
->req_trailer_sent
+= trailer_thistime
;
1742 switch (state
->cli
->auth
->auth_level
) {
1743 case DCERPC_AUTH_LEVEL_NONE
:
1744 case DCERPC_AUTH_LEVEL_CONNECT
:
1746 case DCERPC_AUTH_LEVEL_PACKET
:
1747 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1748 case DCERPC_AUTH_LEVEL_PRIVACY
:
1749 status
= dcerpc_add_auth_footer(state
->cli
->auth
, pad_len
,
1751 if (!NT_STATUS_IS_OK(status
)) {
1756 return NT_STATUS_INVALID_PARAMETER
;
1759 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
1764 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
1766 struct tevent_req
*req
= tevent_req_callback_data(
1767 subreq
, struct tevent_req
);
1768 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1769 req
, struct rpc_api_pipe_req_state
);
1773 status
= rpc_write_recv(subreq
);
1774 TALLOC_FREE(subreq
);
1775 if (tevent_req_nterror(req
, status
)) {
1779 status
= prepare_next_frag(state
, &is_last_frag
);
1780 if (tevent_req_nterror(req
, status
)) {
1785 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
1787 DCERPC_PKT_RESPONSE
,
1789 if (tevent_req_nomem(subreq
, req
)) {
1792 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1794 subreq
= rpc_write_send(state
, state
->ev
,
1795 state
->cli
->conn
->transport
,
1796 state
->rpc_out
.data
,
1797 state
->rpc_out
.length
);
1798 if (tevent_req_nomem(subreq
, req
)) {
1801 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1806 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
1808 struct tevent_req
*req
= tevent_req_callback_data(
1809 subreq
, struct tevent_req
);
1810 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1811 req
, struct rpc_api_pipe_req_state
);
1814 status
= rpc_api_pipe_recv(subreq
, state
, NULL
, &state
->reply_pdu
);
1815 TALLOC_FREE(subreq
);
1816 if (tevent_req_nterror(req
, status
)) {
1820 if (state
->cli
->auth
== NULL
) {
1821 tevent_req_done(req
);
1825 if (state
->verify_bitmask1
) {
1826 state
->cli
->auth
->verified_bitmask1
= true;
1829 if (state
->verify_pcontext
) {
1830 state
->cli
->verified_pcontext
= true;
1833 tevent_req_done(req
);
1836 static NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1837 DATA_BLOB
*reply_pdu
)
1839 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1840 req
, struct rpc_api_pipe_req_state
);
1843 if (tevent_req_is_nterror(req
, &status
)) {
1845 * We always have to initialize to reply pdu, even if there is
1846 * none. The rpccli_* caller routines expect this.
1848 *reply_pdu
= data_blob_null
;
1852 /* return data to caller and assign it ownership of memory */
1853 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1854 reply_pdu
->length
= state
->reply_pdu
.length
;
1855 state
->reply_pdu
.length
= 0;
1857 return NT_STATUS_OK
;
1860 /****************************************************************************
1861 Check the rpc bind acknowledge response.
1862 ****************************************************************************/
1864 static bool check_bind_response(const struct dcerpc_bind_ack
*r
,
1865 struct rpc_pipe_client
*cli
)
1867 const struct ndr_syntax_id
*transfer
= &cli
->transfer_syntax
;
1868 uint32_t assoc_group_id
=
1869 dcerpc_binding_get_assoc_group_id(cli
->assoc
->binding
);
1870 struct dcerpc_ack_ctx ctx
;
1873 if (r
->secondary_address_size
== 0) {
1874 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)\n"));
1877 if (assoc_group_id
== 0) {
1881 * We only capture the first assoc_group_id we're
1884 * Current samba releases may ignore the client value
1885 * and return a different assoc_group_id if the
1886 * client given one is not found in the preforked
1887 * process. This applies to the source4 netlogon,
1888 * which uses DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED.
1891 status
= dcerpc_binding_set_assoc_group_id(cli
->assoc
->binding
,
1893 if (!NT_STATUS_IS_OK(status
)) {
1898 if (!cli
->conn
->features
.bind_done
) {
1900 * DCE-RPC 1.1 (c706) specifies
1901 * CONST_MUST_RCV_FRAG_SIZE as 1432
1904 if (r
->max_xmit_frag
< 1432) {
1907 if (r
->max_recv_frag
< 1432) {
1911 cli
->conn
->features
.max_xmit_frag
=
1912 MIN(cli
->conn
->features
.max_xmit_frag
, r
->max_xmit_frag
);
1913 cli
->conn
->features
.max_recv_frag
=
1914 MIN(cli
->conn
->features
.max_recv_frag
, r
->max_recv_frag
);
1916 cli
->conn
->features
.bind_done
= true;
1919 if (r
->num_results
< 1 || !r
->ctx_list
) {
1923 ctx
= r
->ctx_list
[0];
1925 /* check the transfer syntax */
1926 equal
= ndr_syntax_id_equal(&ctx
.syntax
, transfer
);
1928 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1932 if (ctx
.result
!= DCERPC_BIND_ACK_RESULT_ACCEPTANCE
) {
1933 DBG_NOTICE("bind denied result: %d reason: %x\n",
1934 ctx
.result
, ctx
.reason
.value
);
1938 if (r
->num_results
>= 2) {
1939 const struct dcerpc_ack_ctx
*neg
= &r
->ctx_list
[1];
1941 if (neg
->result
== DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK
) {
1942 cli
->assoc
->features
.negotiated
= neg
->reason
.negotiate
;
1943 cli
->assoc
->features
.negotiation_done
= true;
1945 * consume presentation context used for bind time
1946 * feature negotiation
1948 cli
->conn
->next_pres_context_id
++;
1950 DBG_DEBUG("bind_time_feature failed - "
1951 "result: %d reason %x\n",
1952 neg
->result
, neg
->reason
.value
);
1956 DEBUG(5,("check_bind_response: accepted!\n"));
1960 /*******************************************************************
1961 Creates a DCE/RPC bind authentication response.
1962 This is the packet that is sent back to the server once we
1963 have received a BIND-ACK, to finish the third leg of
1964 the authentication handshake.
1965 ********************************************************************/
1967 static NTSTATUS
create_rpc_bind_auth3(TALLOC_CTX
*mem_ctx
,
1968 struct rpc_pipe_client
*cli
,
1969 struct pipe_auth_data
*auth
,
1970 uint32_t rpc_call_id
,
1971 DATA_BLOB
*pauth_blob
,
1975 union dcerpc_payload u
= { .auth3
._pad
= 0, };
1977 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
1980 0, /* auth_pad_length */
1981 auth
->auth_context_id
,
1983 &u
.auth3
.auth_info
);
1984 if (!NT_STATUS_IS_OK(status
)) {
1988 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1990 DCERPC_PFC_FLAG_FIRST
|
1991 DCERPC_PFC_FLAG_LAST
,
1996 data_blob_free(&u
.auth3
.auth_info
);
1997 if (!NT_STATUS_IS_OK(status
)) {
1998 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2002 return NT_STATUS_OK
;
2005 /*******************************************************************
2006 Creates a DCE/RPC bind alter context authentication request which
2007 may contain a spnego auth blob
2008 ********************************************************************/
2010 static NTSTATUS
create_rpc_alter_context(TALLOC_CTX
*mem_ctx
,
2011 struct pipe_auth_data
*auth
,
2012 uint32_t rpc_call_id
,
2013 struct rpc_client_association
*assoc
,
2014 struct rpc_client_connection
*conn
,
2015 uint16_t pres_context_id
,
2016 const struct ndr_syntax_id
*abstract
,
2017 const struct ndr_syntax_id
*transfer
,
2018 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
2021 DATA_BLOB auth_info
;
2024 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
2027 0, /* auth_pad_length */
2028 auth
->auth_context_id
,
2031 if (!NT_STATUS_IS_OK(status
)) {
2035 status
= create_bind_or_alt_ctx_internal(mem_ctx
,
2045 data_blob_free(&auth_info
);
2049 /****************************************************************************
2051 ****************************************************************************/
2053 struct rpc_pipe_bind_state
{
2054 struct tevent_context
*ev
;
2055 struct rpc_pipe_client
*cli
;
2058 uint32_t rpc_call_id
;
2061 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
2062 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
2063 struct rpc_pipe_bind_state
*state
,
2064 DATA_BLOB
*credentials
);
2065 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
2066 struct rpc_pipe_bind_state
*state
,
2067 DATA_BLOB
*credentials
);
2069 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
2070 struct tevent_context
*ev
,
2071 struct rpc_pipe_client
*cli
,
2072 struct pipe_auth_data
*auth
)
2074 struct tevent_req
*req
, *subreq
;
2075 struct rpc_pipe_bind_state
*state
;
2076 struct cli_credentials
*creds
= NULL
;
2077 const char *username
= NULL
;
2078 enum dcerpc_pkt_type rep_ptype
= DCERPC_PKT_BIND_ACK
;
2081 if (cli
->conn
->features
.bind_done
) {
2082 rep_ptype
= DCERPC_PKT_ALTER_RESP
;
2085 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
2090 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2091 rpccli_pipe_txt(talloc_tos(), cli
),
2092 (unsigned int)auth
->auth_type
,
2093 (unsigned int)auth
->auth_level
));
2097 state
->rpc_call_id
= ++cli
->assoc
->next_call_id
;
2099 cli
->auth
= talloc_move(cli
, &auth
);
2100 if (cli
->auth
->auth_context_id
== UINT32_MAX
) {
2101 if (cli
->conn
->next_auth_context_id
== UINT32_MAX
) {
2102 tevent_req_nterror(req
, NT_STATUS_RPC_NO_MORE_BINDINGS
);
2103 return tevent_req_post(req
, ev
);
2105 cli
->auth
->auth_context_id
= cli
->conn
->next_auth_context_id
++;
2107 if (cli
->pres_context_id
== UINT16_MAX
) {
2108 if (cli
->conn
->next_pres_context_id
== UINT16_MAX
) {
2109 tevent_req_nterror(req
, NT_STATUS_RPC_NO_MORE_BINDINGS
);
2110 return tevent_req_post(req
, ev
);
2112 cli
->pres_context_id
= cli
->conn
->next_pres_context_id
++;
2115 cli
->binding_handle
= rpccli_bh_create(cli
, NULL
, cli
->table
);
2116 if (tevent_req_nomem(cli
->binding_handle
, req
)) {
2117 return tevent_req_post(req
, ev
);
2120 creds
= gensec_get_credentials(cli
->auth
->auth_ctx
);
2121 username
= cli_credentials_get_username(creds
);
2122 cli
->printer_username
= talloc_strdup(cli
, username
);
2123 if (tevent_req_nomem(cli
->printer_username
, req
)) {
2124 return tevent_req_post(req
, ev
);
2127 /* Marshall the outgoing data. */
2128 status
= create_rpc_bind_req(state
, cli
,
2131 &cli
->table
->syntax_id
,
2132 &cli
->transfer_syntax
,
2135 if (!NT_STATUS_IS_OK(status
) &&
2136 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2137 tevent_req_nterror(req
, status
);
2138 return tevent_req_post(req
, ev
);
2141 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
2142 rep_ptype
, state
->rpc_call_id
);
2143 if (tevent_req_nomem(subreq
, req
)) {
2144 return tevent_req_post(req
, ev
);
2146 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2150 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
2152 struct tevent_req
*req
= tevent_req_callback_data(
2153 subreq
, struct tevent_req
);
2154 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2155 req
, struct rpc_pipe_bind_state
);
2156 struct pipe_auth_data
*pauth
= state
->cli
->auth
;
2157 struct gensec_security
*gensec_security
;
2158 struct ncacn_packet
*pkt
= NULL
;
2159 struct dcerpc_auth auth
;
2160 DATA_BLOB auth_token
= { .data
= NULL
};
2163 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, NULL
);
2164 TALLOC_FREE(subreq
);
2165 if (tevent_req_nterror(req
, status
)) {
2166 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2167 rpccli_pipe_txt(talloc_tos(), state
->cli
),
2168 nt_errstr(status
)));
2173 tevent_req_done(req
);
2177 if (!check_bind_response(&pkt
->u
.bind_ack
, state
->cli
)) {
2178 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2179 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2183 if (state
->cli
->conn
->features
.client_hdr_signing
&&
2184 pkt
->pfc_flags
& DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
)
2186 state
->cli
->conn
->features
.hdr_signing
= true;
2189 if (pauth
->auth_type
== DCERPC_AUTH_TYPE_NONE
) {
2190 /* Bind complete. */
2191 tevent_req_done(req
);
2195 if (pkt
->auth_length
== 0) {
2196 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2200 pauth
->hdr_signing
= state
->cli
->conn
->features
.hdr_signing
;
2202 /* get auth credentials */
2203 status
= dcerpc_pull_auth_trailer(pkt
, talloc_tos(),
2204 &pkt
->u
.bind_ack
.auth_info
,
2206 if (tevent_req_nterror(req
, status
)) {
2207 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2208 nt_errstr(status
)));
2212 if (auth
.auth_type
!= pauth
->auth_type
) {
2213 DBG_ERR("Auth type %u mismatch expected %u.\n",
2214 auth
.auth_type
, pauth
->auth_type
);
2215 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2219 if (auth
.auth_level
!= pauth
->auth_level
) {
2220 DBG_ERR("Auth level %u mismatch expected %u.\n",
2221 auth
.auth_level
, pauth
->auth_level
);
2222 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2226 if (auth
.auth_context_id
!= pauth
->auth_context_id
) {
2227 DBG_ERR("Auth context id %"PRIu32
" mismatch "
2228 "expected %"PRIu32
".\n",
2229 auth
.auth_context_id
,
2230 pauth
->auth_context_id
);
2231 tevent_req_nterror(req
, NT_STATUS_RPC_PROTOCOL_ERROR
);
2236 * For authenticated binds we may need to do 3 or 4 leg binds.
2239 if (pauth
->auth_type
== DCERPC_AUTH_TYPE_NONE
) {
2240 /* Bind complete. */
2241 tevent_req_done(req
);
2245 gensec_security
= pauth
->auth_ctx
;
2247 status
= gensec_update(gensec_security
, state
,
2248 auth
.credentials
, &auth_token
);
2249 if (NT_STATUS_EQUAL(status
,
2250 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2251 status
= rpc_bind_next_send(req
, state
,
2253 } else if (NT_STATUS_IS_OK(status
)) {
2254 if (pauth
->hdr_signing
) {
2255 gensec_want_feature(gensec_security
,
2256 GENSEC_FEATURE_SIGN_PKT_HEADER
);
2259 if (auth_token
.length
== 0) {
2260 /* Bind complete. */
2261 tevent_req_done(req
);
2264 status
= rpc_bind_finish_send(req
, state
,
2268 if (!NT_STATUS_IS_OK(status
)) {
2269 tevent_req_nterror(req
, status
);
2274 static NTSTATUS
rpc_bind_next_send(struct tevent_req
*req
,
2275 struct rpc_pipe_bind_state
*state
,
2276 DATA_BLOB
*auth_token
)
2278 struct pipe_auth_data
*auth
= state
->cli
->auth
;
2279 struct tevent_req
*subreq
;
2282 /* Now prepare the alter context pdu. */
2283 data_blob_free(&state
->rpc_out
);
2285 status
= create_rpc_alter_context(state
, auth
,
2289 state
->cli
->pres_context_id
,
2290 &state
->cli
->table
->syntax_id
,
2291 &state
->cli
->transfer_syntax
,
2294 if (!NT_STATUS_IS_OK(status
)) {
2298 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2299 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
,
2300 state
->rpc_call_id
);
2301 if (subreq
== NULL
) {
2302 return NT_STATUS_NO_MEMORY
;
2304 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2305 return NT_STATUS_OK
;
2308 static NTSTATUS
rpc_bind_finish_send(struct tevent_req
*req
,
2309 struct rpc_pipe_bind_state
*state
,
2310 DATA_BLOB
*auth_token
)
2312 struct pipe_auth_data
*auth
= state
->cli
->auth
;
2313 struct tevent_req
*subreq
;
2316 state
->auth3
= true;
2318 /* Now prepare the auth3 context pdu. */
2319 data_blob_free(&state
->rpc_out
);
2321 status
= create_rpc_bind_auth3(state
, state
->cli
, auth
,
2325 if (!NT_STATUS_IS_OK(status
)) {
2329 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2330 &state
->rpc_out
, DCERPC_PKT_AUTH3
,
2331 state
->rpc_call_id
);
2332 if (subreq
== NULL
) {
2333 return NT_STATUS_NO_MEMORY
;
2335 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2336 return NT_STATUS_OK
;
2339 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
2341 return tevent_req_simple_recv_ntstatus(req
);
2344 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2345 struct pipe_auth_data
*auth
)
2347 TALLOC_CTX
*frame
= talloc_stackframe();
2348 struct tevent_context
*ev
;
2349 struct tevent_req
*req
;
2350 NTSTATUS status
= NT_STATUS_OK
;
2352 ev
= samba_tevent_context_init(frame
);
2354 status
= NT_STATUS_NO_MEMORY
;
2358 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
2360 status
= NT_STATUS_NO_MEMORY
;
2364 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2368 status
= rpc_pipe_bind_recv(req
);
2374 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2376 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
2377 unsigned int timeout
)
2379 if (rpc_cli
== NULL
) {
2380 return RPCCLI_DEFAULT_TIMEOUT
;
2383 if (rpc_cli
->binding_handle
== NULL
) {
2384 return RPCCLI_DEFAULT_TIMEOUT
;
2387 return dcerpc_binding_handle_set_timeout(rpc_cli
->binding_handle
,
2391 bool rpccli_is_connected(struct rpc_pipe_client
*rpc_cli
)
2393 if (rpc_cli
== NULL
) {
2397 if (rpc_cli
->binding_handle
== NULL
) {
2401 return dcerpc_binding_handle_is_connected(rpc_cli
->binding_handle
);
2404 struct rpccli_bh_state
{
2405 struct rpc_pipe_client
*rpc_cli
;
2406 struct dcerpc_binding
*binding
;
2409 static const struct dcerpc_binding
*rpccli_bh_get_binding(struct dcerpc_binding_handle
*h
)
2411 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2412 struct rpccli_bh_state
);
2417 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle
*h
)
2419 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2420 struct rpccli_bh_state
);
2421 struct rpc_cli_transport
*transport
= NULL
;
2423 if (hs
->rpc_cli
== NULL
) {
2427 if (hs
->rpc_cli
->conn
== NULL
) {
2431 transport
= hs
->rpc_cli
->conn
->transport
;
2432 if (transport
== NULL
) {
2436 if (transport
->is_connected
== NULL
) {
2440 return transport
->is_connected(transport
->priv
);
2443 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle
*h
,
2446 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2447 struct rpccli_bh_state
);
2448 struct rpc_cli_transport
*transport
= NULL
;
2451 if (hs
->rpc_cli
->conn
== NULL
) {
2452 return RPCCLI_DEFAULT_TIMEOUT
;
2455 transport
= hs
->rpc_cli
->conn
->transport
;
2456 if (transport
== NULL
) {
2457 return RPCCLI_DEFAULT_TIMEOUT
;
2460 if (transport
->set_timeout
== NULL
) {
2461 return RPCCLI_DEFAULT_TIMEOUT
;
2464 old
= transport
->set_timeout(transport
->priv
, timeout
);
2466 return RPCCLI_DEFAULT_TIMEOUT
;
2472 static NTSTATUS
rpccli_bh_transport_session_key(struct dcerpc_binding_handle
*h
,
2473 TALLOC_CTX
*mem_ctx
,
2474 DATA_BLOB
*session_key
)
2476 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2477 struct rpccli_bh_state
);
2478 DATA_BLOB sk
= { .length
= 0, };
2480 if (hs
->rpc_cli
== NULL
) {
2481 return NT_STATUS_NO_USER_SESSION_KEY
;
2484 if (hs
->rpc_cli
->conn
== NULL
) {
2485 return NT_STATUS_NO_USER_SESSION_KEY
;
2488 if (hs
->rpc_cli
->conn
->transport_session_key
.length
== 0) {
2489 return NT_STATUS_NO_USER_SESSION_KEY
;
2492 sk
= hs
->rpc_cli
->conn
->transport_session_key
;
2493 sk
.length
= MIN(sk
.length
, 16);
2495 *session_key
= data_blob_dup_talloc(mem_ctx
, sk
);
2496 if (session_key
->length
!= sk
.length
) {
2497 return NT_STATUS_NO_MEMORY
;
2499 talloc_keep_secret(session_key
->data
);
2500 return NT_STATUS_OK
;
2503 static void rpccli_bh_auth_info(struct dcerpc_binding_handle
*h
,
2504 enum dcerpc_AuthType
*auth_type
,
2505 enum dcerpc_AuthLevel
*auth_level
)
2507 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2508 struct rpccli_bh_state
);
2510 if (hs
->rpc_cli
== NULL
) {
2514 if (hs
->rpc_cli
->auth
== NULL
) {
2518 *auth_type
= hs
->rpc_cli
->auth
->auth_type
;
2519 *auth_level
= hs
->rpc_cli
->auth
->auth_level
;
2522 static NTSTATUS
rpccli_bh_auth_session_key(struct dcerpc_binding_handle
*h
,
2523 TALLOC_CTX
*mem_ctx
,
2524 DATA_BLOB
*session_key
)
2526 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2527 struct rpccli_bh_state
);
2528 struct pipe_auth_data
*auth
= NULL
;
2531 if (hs
->rpc_cli
== NULL
) {
2532 return NT_STATUS_NO_USER_SESSION_KEY
;
2535 if (hs
->rpc_cli
->auth
== NULL
) {
2536 return NT_STATUS_NO_USER_SESSION_KEY
;
2539 auth
= hs
->rpc_cli
->auth
;
2541 if (auth
->auth_type
== DCERPC_AUTH_TYPE_NONE
) {
2542 return NT_STATUS_NO_USER_SESSION_KEY
;
2545 if (auth
->auth_ctx
== NULL
) {
2546 return NT_STATUS_NO_USER_SESSION_KEY
;
2549 status
= gensec_session_key(auth
->auth_ctx
,
2552 if (!NT_STATUS_IS_OK(status
)) {
2556 talloc_keep_secret(session_key
->data
);
2557 return NT_STATUS_OK
;
2560 struct rpccli_bh_raw_call_state
{
2566 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
);
2568 static struct tevent_req
*rpccli_bh_raw_call_send(TALLOC_CTX
*mem_ctx
,
2569 struct tevent_context
*ev
,
2570 struct dcerpc_binding_handle
*h
,
2571 const struct GUID
*object
,
2574 const uint8_t *in_data
,
2577 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2578 struct rpccli_bh_state
);
2579 struct tevent_req
*req
;
2580 struct rpccli_bh_raw_call_state
*state
;
2582 struct tevent_req
*subreq
;
2584 req
= tevent_req_create(mem_ctx
, &state
,
2585 struct rpccli_bh_raw_call_state
);
2589 state
->in_data
.data
= discard_const_p(uint8_t, in_data
);
2590 state
->in_data
.length
= in_length
;
2592 ok
= rpccli_bh_is_connected(h
);
2594 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2595 return tevent_req_post(req
, ev
);
2598 subreq
= rpc_api_pipe_req_send(state
, ev
, hs
->rpc_cli
,
2599 opnum
, object
, &state
->in_data
);
2600 if (tevent_req_nomem(subreq
, req
)) {
2601 return tevent_req_post(req
, ev
);
2603 tevent_req_set_callback(subreq
, rpccli_bh_raw_call_done
, req
);
2608 static void rpccli_bh_raw_call_done(struct tevent_req
*subreq
)
2610 struct tevent_req
*req
=
2611 tevent_req_callback_data(subreq
,
2613 struct rpccli_bh_raw_call_state
*state
=
2614 tevent_req_data(req
,
2615 struct rpccli_bh_raw_call_state
);
2618 state
->out_flags
= 0;
2620 /* TODO: support bigendian responses */
2622 status
= rpc_api_pipe_req_recv(subreq
, state
, &state
->out_data
);
2623 TALLOC_FREE(subreq
);
2624 if (tevent_req_nterror(req
, status
)) {
2628 tevent_req_done(req
);
2631 static NTSTATUS
rpccli_bh_raw_call_recv(struct tevent_req
*req
,
2632 TALLOC_CTX
*mem_ctx
,
2635 uint32_t *out_flags
)
2637 struct rpccli_bh_raw_call_state
*state
=
2638 tevent_req_data(req
,
2639 struct rpccli_bh_raw_call_state
);
2642 if (tevent_req_is_nterror(req
, &status
)) {
2643 tevent_req_received(req
);
2647 *out_data
= talloc_move(mem_ctx
, &state
->out_data
.data
);
2648 *out_length
= state
->out_data
.length
;
2649 *out_flags
= state
->out_flags
;
2650 tevent_req_received(req
);
2651 return NT_STATUS_OK
;
2654 struct rpccli_bh_disconnect_state
{
2658 static struct tevent_req
*rpccli_bh_disconnect_send(TALLOC_CTX
*mem_ctx
,
2659 struct tevent_context
*ev
,
2660 struct dcerpc_binding_handle
*h
)
2662 struct rpccli_bh_state
*hs
= dcerpc_binding_handle_data(h
,
2663 struct rpccli_bh_state
);
2664 struct tevent_req
*req
;
2665 struct rpccli_bh_disconnect_state
*state
;
2668 req
= tevent_req_create(mem_ctx
, &state
,
2669 struct rpccli_bh_disconnect_state
);
2674 ok
= rpccli_bh_is_connected(h
);
2676 tevent_req_nterror(req
, NT_STATUS_CONNECTION_DISCONNECTED
);
2677 return tevent_req_post(req
, ev
);
2681 * TODO: do a real async disconnect ...
2683 * For now we do it sync...
2685 TALLOC_FREE(hs
->rpc_cli
->conn
);
2688 tevent_req_done(req
);
2689 return tevent_req_post(req
, ev
);
2692 static NTSTATUS
rpccli_bh_disconnect_recv(struct tevent_req
*req
)
2694 return tevent_req_simple_recv_ntstatus(req
);
2697 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle
*h
)
2702 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle
*h
,
2703 ndr_flags_type ndr_flags
,
2704 const void *_struct_ptr
,
2705 const struct ndr_interface_call
*call
)
2707 void *struct_ptr
= discard_const(_struct_ptr
);
2709 if (DEBUGLEVEL
< 10) {
2713 if (ndr_flags
& NDR_IN
) {
2714 ndr_print_function_debug(call
->ndr_print
,
2719 if (ndr_flags
& NDR_OUT
) {
2720 ndr_print_function_debug(call
->ndr_print
,
2727 static const struct dcerpc_binding_handle_ops rpccli_bh_ops
= {
2729 .get_binding
= rpccli_bh_get_binding
,
2730 .is_connected
= rpccli_bh_is_connected
,
2731 .set_timeout
= rpccli_bh_set_timeout
,
2732 .transport_session_key
= rpccli_bh_transport_session_key
,
2733 .auth_info
= rpccli_bh_auth_info
,
2734 .auth_session_key
= rpccli_bh_auth_session_key
,
2735 .raw_call_send
= rpccli_bh_raw_call_send
,
2736 .raw_call_recv
= rpccli_bh_raw_call_recv
,
2737 .disconnect_send
= rpccli_bh_disconnect_send
,
2738 .disconnect_recv
= rpccli_bh_disconnect_recv
,
2740 .ref_alloc
= rpccli_bh_ref_alloc
,
2741 .do_ndr_print
= rpccli_bh_do_ndr_print
,
2744 /* initialise a rpc_pipe_client binding handle */
2745 struct dcerpc_binding_handle
*rpccli_bh_create(struct rpc_pipe_client
*c
,
2746 const struct GUID
*object
,
2747 const struct ndr_interface_table
*table
)
2749 struct dcerpc_binding_handle
*h
= NULL
;
2750 struct rpccli_bh_state
*hs
= NULL
;
2751 struct dcerpc_binding
*b
= NULL
;
2752 uint32_t a_flags
= 0;
2753 uint32_t c_flags
= 0;
2756 if (c
->conn
->features
.hdr_signing
) {
2757 a_flags
|= DCERPC_HEADER_SIGNING
;
2759 c_flags
|= DCERPC_HEADER_SIGNING
;
2762 switch (c
->auth
->auth_type
) {
2763 case DCERPC_AUTH_TYPE_KRB5
:
2764 a_flags
|= DCERPC_AUTH_KRB5
;
2765 c_flags
|= DCERPC_AUTH_NTLM
;
2766 c_flags
|= DCERPC_AUTH_SPNEGO
;
2767 c_flags
|= DCERPC_SCHANNEL
;
2769 case DCERPC_AUTH_TYPE_NTLMSSP
:
2770 c_flags
|= DCERPC_AUTH_KRB5
;
2771 a_flags
|= DCERPC_AUTH_NTLM
;
2772 c_flags
|= DCERPC_AUTH_SPNEGO
;
2773 c_flags
|= DCERPC_SCHANNEL
;
2775 case DCERPC_AUTH_TYPE_SPNEGO
:
2776 c_flags
|= DCERPC_AUTH_KRB5
;
2777 c_flags
|= DCERPC_AUTH_NTLM
;
2778 a_flags
|= DCERPC_AUTH_SPNEGO
;
2779 c_flags
|= DCERPC_SCHANNEL
;
2781 case DCERPC_AUTH_TYPE_SCHANNEL
:
2782 c_flags
|= DCERPC_AUTH_KRB5
;
2783 c_flags
|= DCERPC_AUTH_NTLM
;
2784 c_flags
|= DCERPC_AUTH_SPNEGO
;
2785 a_flags
|= DCERPC_SCHANNEL
;
2788 c_flags
|= DCERPC_AUTH_KRB5
;
2789 c_flags
|= DCERPC_AUTH_NTLM
;
2790 c_flags
|= DCERPC_AUTH_SPNEGO
;
2791 c_flags
|= DCERPC_SCHANNEL
;
2795 if (c
->auth
->auth_level
>= DCERPC_AUTH_LEVEL_PRIVACY
) {
2796 a_flags
|= DCERPC_SEAL
;
2797 c_flags
|= DCERPC_SIGN
;
2798 c_flags
|= DCERPC_CONNECT
;
2799 } else if (c
->auth
->auth_level
>= DCERPC_AUTH_LEVEL_INTEGRITY
) {
2800 c_flags
|= DCERPC_SEAL
;
2801 a_flags
|= DCERPC_SIGN
;
2802 c_flags
|= DCERPC_CONNECT
;
2803 } else if (c
->auth
->auth_level
>= DCERPC_AUTH_LEVEL_CONNECT
) {
2804 c_flags
|= DCERPC_SEAL
;
2805 c_flags
|= DCERPC_SIGN
;
2806 a_flags
|= DCERPC_CONNECT
;
2808 c_flags
|= DCERPC_SEAL
;
2809 c_flags
|= DCERPC_SIGN
;
2810 c_flags
|= DCERPC_CONNECT
;
2813 h
= dcerpc_binding_handle_create(c
,
2818 struct rpccli_bh_state
,
2825 b
= dcerpc_binding_dup(h
, c
->assoc
->binding
);
2830 status
= dcerpc_binding_set_abstract_syntax(b
, &table
->syntax_id
);
2831 if (!NT_STATUS_IS_OK(status
)) {
2835 status
= dcerpc_binding_set_flags(b
, a_flags
, c_flags
);
2836 if (!NT_STATUS_IS_OK(status
)) {
2846 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
2847 struct pipe_auth_data
**presult
)
2849 struct pipe_auth_data
*result
;
2850 struct auth_generic_state
*auth_generic_ctx
;
2853 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2854 if (result
== NULL
) {
2855 return NT_STATUS_NO_MEMORY
;
2858 result
->auth_type
= DCERPC_AUTH_TYPE_NONE
;
2859 result
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
2860 /* rpc_pipe_bind_send should allocate an id... */
2861 result
->auth_context_id
= UINT32_MAX
;
2863 status
= auth_generic_client_prepare(result
,
2865 if (!NT_STATUS_IS_OK(status
)) {
2866 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2867 nt_errstr(status
)));
2870 status
= auth_generic_set_username(auth_generic_ctx
, "");
2871 if (!NT_STATUS_IS_OK(status
)) {
2872 DEBUG(1, ("Failed to set username: %s\n",
2873 nt_errstr(status
)));
2876 status
= auth_generic_set_domain(auth_generic_ctx
, "");
2877 if (!NT_STATUS_IS_OK(status
)) {
2878 DEBUG(1, ("Failed to set domain: %s\n",
2879 nt_errstr(status
)));
2883 status
= gensec_set_credentials(auth_generic_ctx
->gensec_security
,
2884 auth_generic_ctx
->credentials
);
2885 if (!NT_STATUS_IS_OK(status
)) {
2886 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2887 nt_errstr(status
)));
2890 talloc_unlink(auth_generic_ctx
, auth_generic_ctx
->credentials
);
2891 auth_generic_ctx
->credentials
= NULL
;
2893 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2894 talloc_free(auth_generic_ctx
);
2896 return NT_STATUS_OK
;
2899 static NTSTATUS
rpccli_generic_bind_data(TALLOC_CTX
*mem_ctx
,
2900 enum dcerpc_AuthType auth_type
,
2901 enum dcerpc_AuthLevel auth_level
,
2903 const char *target_service
,
2905 const char *username
,
2906 const char *password
,
2907 enum credentials_use_kerberos use_kerberos
,
2908 struct netlogon_creds_CredentialState
*creds
,
2909 struct pipe_auth_data
**presult
)
2911 struct auth_generic_state
*auth_generic_ctx
;
2912 struct pipe_auth_data
*result
;
2915 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2916 if (result
== NULL
) {
2917 return NT_STATUS_NO_MEMORY
;
2920 result
->auth_type
= auth_type
;
2921 result
->auth_level
= auth_level
;
2922 /* rpc_pipe_bind_send should allocate an id... */
2923 result
->auth_context_id
= UINT32_MAX
;
2925 status
= auth_generic_client_prepare(result
,
2927 if (!NT_STATUS_IS_OK(status
)) {
2931 status
= auth_generic_set_username(auth_generic_ctx
, username
);
2932 if (!NT_STATUS_IS_OK(status
)) {
2936 status
= auth_generic_set_domain(auth_generic_ctx
, domain
);
2937 if (!NT_STATUS_IS_OK(status
)) {
2941 status
= auth_generic_set_password(auth_generic_ctx
, password
);
2942 if (!NT_STATUS_IS_OK(status
)) {
2946 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
2947 if (!NT_STATUS_IS_OK(status
)) {
2951 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
2952 if (!NT_STATUS_IS_OK(status
)) {
2956 cli_credentials_set_kerberos_state(auth_generic_ctx
->credentials
,
2959 cli_credentials_set_netlogon_creds(auth_generic_ctx
->credentials
, creds
);
2961 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
2962 if (!NT_STATUS_IS_OK(status
)) {
2966 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
2967 talloc_free(auth_generic_ctx
);
2969 return NT_STATUS_OK
;
2972 TALLOC_FREE(result
);
2976 /* This routine steals the creds pointer that is passed in */
2977 static NTSTATUS
rpccli_generic_bind_data_from_creds(TALLOC_CTX
*mem_ctx
,
2978 enum dcerpc_AuthType auth_type
,
2979 enum dcerpc_AuthLevel auth_level
,
2981 const char *target_service
,
2982 struct cli_credentials
*creds
,
2983 struct pipe_auth_data
**presult
)
2985 struct auth_generic_state
*auth_generic_ctx
;
2986 struct pipe_auth_data
*result
;
2989 result
= talloc_zero(mem_ctx
, struct pipe_auth_data
);
2990 if (result
== NULL
) {
2991 return NT_STATUS_NO_MEMORY
;
2994 result
->auth_type
= auth_type
;
2995 result
->auth_level
= auth_level
;
2996 /* rpc_pipe_bind_send should allocate an id... */
2997 result
->auth_context_id
= UINT32_MAX
;
2999 status
= auth_generic_client_prepare(result
,
3001 if (!NT_STATUS_IS_OK(status
)) {
3005 status
= auth_generic_set_creds(auth_generic_ctx
, creds
);
3006 if (!NT_STATUS_IS_OK(status
)) {
3010 status
= gensec_set_target_service(auth_generic_ctx
->gensec_security
, target_service
);
3011 if (!NT_STATUS_IS_OK(status
)) {
3015 status
= gensec_set_target_hostname(auth_generic_ctx
->gensec_security
, server
);
3016 if (!NT_STATUS_IS_OK(status
)) {
3020 status
= auth_generic_client_start_by_authtype(auth_generic_ctx
, auth_type
, auth_level
);
3021 if (!NT_STATUS_IS_OK(status
)) {
3025 result
->auth_ctx
= talloc_move(result
, &auth_generic_ctx
->gensec_security
);
3026 talloc_free(auth_generic_ctx
);
3028 return NT_STATUS_OK
;
3031 TALLOC_FREE(result
);
3035 NTSTATUS
rpccli_ncalrpc_bind_data(TALLOC_CTX
*mem_ctx
,
3036 struct pipe_auth_data
**presult
)
3038 return rpccli_generic_bind_data(mem_ctx
,
3039 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
,
3040 DCERPC_AUTH_LEVEL_CONNECT
,
3042 "host", /* target_service */
3043 NAME_NT_AUTHORITY
, /* domain */
3045 NULL
, /* password */
3046 CRED_USE_KERBEROS_DISABLED
,
3047 NULL
, /* netlogon_creds_CredentialState */
3052 * Create an rpc pipe client struct, connecting to a tcp port.
3054 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
,
3055 const struct rpc_client_association
*assoc
,
3056 struct rpc_client_connection
**pconn
)
3058 struct rpc_client_connection
*conn
= NULL
;
3059 enum dcerpc_transport_t transport
;
3060 const char *endpoint
= NULL
;
3065 transport
= dcerpc_binding_get_transport(assoc
->binding
);
3066 if (transport
!= NCACN_IP_TCP
) {
3067 return NT_STATUS_RPC_WRONG_KIND_OF_BINDING
;
3070 endpoint
= dcerpc_binding_get_string_option(assoc
->binding
,
3072 if (endpoint
== NULL
) {
3073 return NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT
;
3075 port
= (uint16_t)atoi(endpoint
);
3077 return NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT
;
3080 status
= rpc_client_connection_create(mem_ctx
,
3082 DCERPC_FRAG_MAX_SIZE
,
3084 if (!NT_STATUS_IS_OK(status
)) {
3088 status
= open_socket_out(&assoc
->addr
.u
.ss
, port
, 60*1000, &fd
);
3089 if (!NT_STATUS_IS_OK(status
)) {
3093 set_socket_options(fd
, lp_socket_options());
3095 status
= rpc_transport_sock_init(conn
, fd
, &conn
->transport
);
3096 if (!NT_STATUS_IS_OK(status
)) {
3102 conn
->transport
->transport
= NCACN_IP_TCP
;
3105 return NT_STATUS_OK
;
3108 static NTSTATUS
rpccli_epm_map_binding(
3109 struct dcerpc_binding_handle
*epm_connection
,
3110 struct dcerpc_binding
*binding
,
3111 TALLOC_CTX
*mem_ctx
,
3114 TALLOC_CTX
*frame
= talloc_stackframe();
3115 enum dcerpc_transport_t transport
=
3116 dcerpc_binding_get_transport(binding
);
3117 enum dcerpc_transport_t res_transport
;
3118 struct dcerpc_binding
*res_binding
= NULL
;
3119 struct epm_twr_t
*map_tower
= NULL
;
3120 struct epm_twr_p_t res_towers
= { .twr
= NULL
};
3121 struct policy_handle
*entry_handle
= NULL
;
3122 uint32_t num_towers
= 0;
3123 const uint32_t max_towers
= 1;
3124 const char *endpoint
= NULL
;
3129 map_tower
= talloc_zero(frame
, struct epm_twr_t
);
3130 if (map_tower
== NULL
) {
3134 status
= dcerpc_binding_build_tower(
3135 frame
, binding
, &(map_tower
->tower
));
3136 if (!NT_STATUS_IS_OK(status
)) {
3137 DBG_DEBUG("dcerpc_binding_build_tower failed: %s\n",
3142 res_towers
.twr
= talloc_array(frame
, struct epm_twr_t
, max_towers
);
3143 if (res_towers
.twr
== NULL
) {
3147 entry_handle
= talloc_zero(frame
, struct policy_handle
);
3148 if (entry_handle
== NULL
) {
3152 status
= dcerpc_epm_Map(
3163 if (!NT_STATUS_IS_OK(status
)) {
3164 DBG_DEBUG("dcerpc_epm_Map failed: %s\n", nt_errstr(status
));
3168 if (result
!= EPMAPPER_STATUS_OK
) {
3169 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32
"\n", result
);
3170 status
= NT_STATUS_NOT_FOUND
;
3174 if (num_towers
!= 1) {
3175 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32
" towers\n",
3177 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
3181 status
= dcerpc_binding_from_tower(
3182 frame
, &(res_towers
.twr
->tower
), &res_binding
);
3183 if (!NT_STATUS_IS_OK(status
)) {
3184 DBG_DEBUG("dcerpc_binding_from_tower failed: %s\n",
3189 res_transport
= dcerpc_binding_get_transport(res_binding
);
3190 if (res_transport
!= transport
) {
3191 DBG_DEBUG("dcerpc_epm_Map returned transport %d, "
3195 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
3199 endpoint
= dcerpc_binding_get_string_option(res_binding
, "endpoint");
3200 if (endpoint
== NULL
) {
3201 DBG_DEBUG("dcerpc_epm_Map returned no endpoint\n");
3202 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
3206 tmp
= talloc_strdup(mem_ctx
, endpoint
);
3212 status
= NT_STATUS_OK
;
3216 status
= NT_STATUS_NO_MEMORY
;
3222 static NTSTATUS
rpccli_epm_map_interface(
3223 struct dcerpc_binding_handle
*epm_connection
,
3224 enum dcerpc_transport_t transport
,
3225 const struct ndr_syntax_id
*iface
,
3226 TALLOC_CTX
*mem_ctx
,
3229 struct dcerpc_binding
*binding
= NULL
;
3230 char *endpoint
= NULL
;
3233 status
= dcerpc_parse_binding(mem_ctx
, "", &binding
);
3234 if (!NT_STATUS_IS_OK(status
)) {
3235 DBG_DEBUG("dcerpc_parse_binding failed: %s\n",
3240 status
= dcerpc_binding_set_transport(binding
, transport
);
3241 if (!NT_STATUS_IS_OK(status
)) {
3242 DBG_DEBUG("dcerpc_binding_set_transport failed: %s\n",
3247 status
= dcerpc_binding_set_abstract_syntax(binding
, iface
);
3248 if (!NT_STATUS_IS_OK(status
)) {
3249 DBG_DEBUG("dcerpc_binding_set_abstract_syntax failed: %s\n",
3254 status
= rpccli_epm_map_binding(
3255 epm_connection
, binding
, mem_ctx
, &endpoint
);
3256 if (!NT_STATUS_IS_OK(status
)) {
3257 DBG_DEBUG("rpccli_epm_map_binding failed: %s\n",
3261 *pendpoint
= endpoint
;
3264 TALLOC_FREE(binding
);
3269 * Determine the tcp port on which a dcerpc interface is listening
3270 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3273 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
3274 const struct samba_sockaddr
*saddr
,
3275 const struct ndr_interface_table
*table
,
3278 TALLOC_CTX
*frame
= talloc_stackframe();
3279 const char *epm_ep
= NULL
;
3280 struct rpc_client_association
*epm_assoc
= NULL
;
3281 struct rpc_client_connection
*epm_conn
= NULL
;
3282 struct rpc_pipe_client
*epm_pipe
= NULL
;
3283 struct pipe_auth_data
*epm_auth
= NULL
;
3284 char *endpoint
= NULL
;
3288 endpoint
= dcerpc_default_transport_endpoint(frame
,
3291 if (endpoint
!= NULL
) {
3292 port
= (uint16_t)atoi(endpoint
);
3298 return NT_STATUS_OK
;
3301 epm_ep
= dcerpc_default_transport_endpoint(frame
,
3303 &ndr_table_epmapper
);
3304 if (epm_ep
== NULL
) {
3306 return NT_STATUS_RPC_INTERNAL_ERROR
;
3309 status
= rpc_client_association_create(frame
,
3310 default_bt_features
,
3311 DCERPC_PROPOSE_HEADER_SIGNING
,
3317 if (!NT_STATUS_IS_OK(status
)) {
3322 /* open the connection to the endpoint mapper */
3323 status
= rpc_pipe_open_tcp_port(frame
, epm_assoc
, &epm_conn
);
3324 if (!NT_STATUS_IS_OK(status
)) {
3329 status
= rpccli_anon_bind_data(frame
, &epm_auth
);
3330 if (!NT_STATUS_IS_OK(status
)) {
3335 status
= rpc_pipe_wrap_create(&ndr_table_epmapper
,
3341 if (!NT_STATUS_IS_OK(status
)) {
3346 status
= rpc_pipe_bind(epm_pipe
, epm_auth
);
3347 if (!NT_STATUS_IS_OK(status
)) {
3352 status
= rpccli_epm_map_interface(
3353 epm_pipe
->binding_handle
,
3358 if (!NT_STATUS_IS_OK(status
)) {
3359 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
3365 *pport
= (uint16_t)atoi(endpoint
);
3367 return NT_STATUS_OK
;
3370 static NTSTATUS
rpc_pipe_get_ncalrpc_name(
3371 const struct ndr_syntax_id
*iface
,
3372 TALLOC_CTX
*mem_ctx
,
3373 char **psocket_name
)
3375 TALLOC_CTX
*frame
= talloc_stackframe();
3376 struct rpc_pipe_client
*epm_pipe
= NULL
;
3377 struct pipe_auth_data
*auth
= NULL
;
3378 NTSTATUS status
= NT_STATUS_OK
;
3381 is_epm
= ndr_syntax_id_equal(iface
, &ndr_table_epmapper
.syntax_id
);
3383 char *endpoint
= talloc_strdup(mem_ctx
, "EPMAPPER");
3384 if (endpoint
== NULL
) {
3385 status
= NT_STATUS_NO_MEMORY
;
3388 *psocket_name
= endpoint
;
3392 status
= rpc_pipe_open_ncalrpc(
3393 frame
, &ndr_table_epmapper
, &epm_pipe
);
3394 if (!NT_STATUS_IS_OK(status
)) {
3395 DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
3400 status
= rpccli_anon_bind_data(epm_pipe
, &auth
);
3401 if (!NT_STATUS_IS_OK(status
)) {
3402 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3407 status
= rpc_pipe_bind(epm_pipe
, auth
);
3408 if (!NT_STATUS_IS_OK(status
)) {
3409 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status
));
3413 status
= rpccli_epm_map_interface(
3414 epm_pipe
->binding_handle
,
3419 if (!NT_STATUS_IS_OK(status
)) {
3420 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
3429 /********************************************************************
3430 Create a rpc pipe client struct, connecting to a unix domain socket
3431 ********************************************************************/
3432 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
,
3433 const struct ndr_interface_table
*table
,
3434 struct rpc_pipe_client
**presult
)
3436 TALLOC_CTX
*frame
= talloc_stackframe();
3437 char *myname
= NULL
;
3438 char *socket_name
= NULL
;
3439 struct samba_sockaddr saddr
= {
3440 .sa_socklen
= sizeof(struct sockaddr_un
),
3443 .sun_family
= AF_UNIX
,
3447 struct rpc_client_association
*assoc
= NULL
;
3448 struct rpc_client_connection
*conn
= NULL
;
3449 struct rpc_pipe_client
*result
= NULL
;
3454 myname
= get_myname(frame
);
3455 if (myname
== NULL
) {
3457 return NT_STATUS_NO_MEMORY
;
3460 status
= rpc_pipe_get_ncalrpc_name(&table
->syntax_id
,
3463 if (!NT_STATUS_IS_OK(status
)) {
3464 DBG_DEBUG("rpc_pipe_get_ncalrpc_name failed: %s\n",
3471 saddr
.u
.un
.sun_path
,
3472 sizeof(saddr
.u
.un
.sun_path
),
3476 if ((pathlen
< 0) || ((size_t)pathlen
>= sizeof(saddr
.u
.un
.sun_path
))) {
3477 DBG_DEBUG("socket_path for %s too long\n", socket_name
);
3479 return NT_STATUS_NAME_TOO_LONG
;
3481 TALLOC_FREE(socket_name
);
3483 status
= rpc_client_association_create(mem_ctx
,
3484 0, /* no client_features */
3491 if (!NT_STATUS_IS_OK(status
)) {
3495 talloc_steal(frame
, assoc
);
3497 status
= rpc_client_connection_create(mem_ctx
,
3499 DCERPC_FRAG_MAX_SIZE
,
3501 if (!NT_STATUS_IS_OK(status
)) {
3505 talloc_steal(frame
, conn
);
3507 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3509 status
= map_nt_error_from_unix(errno
);
3514 if (connect(fd
, &saddr
.u
.sa
, saddr
.sa_socklen
) == -1) {
3515 status
= map_nt_error_from_unix(errno
);
3517 DBG_WARNING("connect(%s) failed: %s - %s\n",
3518 saddr
.u
.un
.sun_path
,
3519 strerror(errno
), nt_errstr(status
));
3524 status
= rpc_transport_sock_init(conn
, fd
, &conn
->transport
);
3525 if (!NT_STATUS_IS_OK(status
)) {
3532 conn
->transport
->transport
= NCALRPC
;
3534 status
= rpc_pipe_wrap_create(table
,
3540 if (!NT_STATUS_IS_OK(status
)) {
3547 return NT_STATUS_OK
;
3550 NTSTATUS
rpc_pipe_open_local_np(
3551 TALLOC_CTX
*mem_ctx
,
3552 const struct ndr_interface_table
*table
,
3553 const char *remote_client_name
,
3554 const struct tsocket_address
*remote_client_addr
,
3555 const char *local_server_name
,
3556 const struct tsocket_address
*local_server_addr
,
3557 const struct auth_session_info
*session_info
,
3558 struct rpc_pipe_client
**presult
)
3560 TALLOC_CTX
*frame
= talloc_stackframe();
3561 struct rpc_client_association
*assoc
= NULL
;
3562 struct rpc_client_connection
*conn
= NULL
;
3563 struct rpc_pipe_client
*result
= NULL
;
3564 struct pipe_auth_data
*auth
= NULL
;
3565 struct samba_sockaddr saddr
= { .sa_socklen
= 0, };
3566 const char *pipe_name
= NULL
;
3567 struct tstream_context
*npa_stream
= NULL
;
3568 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3571 pipe_name
= dcerpc_default_transport_endpoint(frame
,
3574 if (pipe_name
== NULL
) {
3575 DBG_DEBUG("dcerpc_default_transport_endpoint failed\n");
3577 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3580 if (local_server_name
== NULL
) {
3581 local_server_name
= get_myname(result
);
3584 if (local_server_addr
!= NULL
) {
3585 saddr
.sa_socklen
= tsocket_address_bsd_sockaddr(local_server_addr
,
3587 sizeof(saddr
.u
.ss
));
3588 if (saddr
.sa_socklen
== -1) {
3589 status
= map_nt_error_from_unix(errno
);
3595 status
= rpc_client_association_create(mem_ctx
,
3596 0, /* no client_features */
3603 if (!NT_STATUS_IS_OK(status
)) {
3607 talloc_steal(frame
, assoc
);
3609 status
= rpc_client_connection_create(mem_ctx
,
3611 DCERPC_FRAG_MAX_SIZE
,
3613 if (!NT_STATUS_IS_OK(status
)) {
3617 talloc_steal(frame
, conn
);
3619 ret
= local_np_connect(
3631 DBG_DEBUG("local_np_connect for %s and "
3632 "user %s\\%s failed: %s\n",
3634 session_info
->info
->domain_name
,
3635 session_info
->info
->account_name
,
3637 status
= map_nt_error_from_unix(ret
);
3642 status
= rpc_transport_tstream_init(conn
,
3645 if (!NT_STATUS_IS_OK(status
)) {
3646 DBG_DEBUG("rpc_transport_tstream_init failed: %s\n",
3651 conn
->transport
->transport
= NCACN_NP
;
3653 status
= rpc_pipe_wrap_create(table
,
3659 if (!NT_STATUS_IS_OK(status
)) {
3663 talloc_steal(frame
, result
);
3665 status
= rpccli_anon_bind_data(result
, &auth
);
3666 if (!NT_STATUS_IS_OK(status
)) {
3667 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3673 status
= rpc_pipe_bind(result
, auth
);
3674 if (!NT_STATUS_IS_OK(status
)) {
3675 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status
));
3680 *presult
= talloc_move(mem_ctx
, &result
);
3682 return NT_STATUS_OK
;
3685 struct rpc_client_connection_np_state
{
3686 struct cli_state
*cli
;
3687 const char *pipe_name
;
3688 struct rpc_client_connection
*conn
;
3691 static void rpc_client_connection_np_done(struct tevent_req
*subreq
);
3693 static struct tevent_req
*rpc_client_connection_np_send(
3694 TALLOC_CTX
*mem_ctx
,
3695 struct tevent_context
*ev
,
3696 struct cli_state
*cli
,
3697 const struct rpc_client_association
*assoc
)
3699 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
3700 struct rpc_client_connection_np_state
*state
= NULL
;
3701 enum dcerpc_transport_t transport
;
3702 const char *endpoint
= NULL
;
3703 struct smbXcli_session
*session
= NULL
;
3706 req
= tevent_req_create(mem_ctx
, &state
,
3707 struct rpc_client_connection_np_state
);
3712 transport
= dcerpc_binding_get_transport(assoc
->binding
);
3713 if (transport
!= NCACN_NP
) {
3714 tevent_req_nterror(req
, NT_STATUS_RPC_WRONG_KIND_OF_BINDING
);
3715 return tevent_req_post(req
, ev
);
3718 endpoint
= dcerpc_binding_get_string_option(assoc
->binding
,
3720 if (endpoint
== NULL
) {
3721 tevent_req_nterror(req
, NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT
);
3722 return tevent_req_post(req
, ev
);
3725 status
= rpc_client_connection_create(state
,
3727 TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE
,
3729 if (tevent_req_nterror(req
, status
)) {
3730 return tevent_req_post(req
, ev
);
3733 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
3734 session
= cli
->smb2
.session
;
3736 session
= cli
->smb1
.session
;
3739 status
= smbXcli_session_application_key(session
, state
->conn
,
3740 &state
->conn
->transport_session_key
);
3741 if (!NT_STATUS_IS_OK(status
)) {
3742 state
->conn
->transport_session_key
= data_blob_null
;
3745 subreq
= rpc_transport_np_init_send(state
, ev
, cli
, endpoint
);
3746 if (tevent_req_nomem(subreq
, req
)) {
3747 return tevent_req_post(req
, ev
);
3749 tevent_req_set_callback(subreq
, rpc_client_connection_np_done
, req
);
3753 static void rpc_client_connection_np_done(struct tevent_req
*subreq
)
3755 struct tevent_req
*req
= tevent_req_callback_data(
3756 subreq
, struct tevent_req
);
3757 struct rpc_client_connection_np_state
*state
= tevent_req_data(
3758 req
, struct rpc_client_connection_np_state
);
3761 status
= rpc_transport_np_init_recv(subreq
,
3763 &state
->conn
->transport
);
3764 TALLOC_FREE(subreq
);
3765 if (tevent_req_nterror(req
, status
)) {
3769 state
->conn
->transport
->transport
= NCACN_NP
;
3771 tevent_req_done(req
);
3774 static NTSTATUS
rpc_client_connection_np_recv(
3775 struct tevent_req
*req
,
3776 TALLOC_CTX
*mem_ctx
,
3777 struct rpc_client_connection
**pconn
)
3779 struct rpc_client_connection_np_state
*state
= tevent_req_data(
3780 req
, struct rpc_client_connection_np_state
);
3783 if (tevent_req_is_nterror(req
, &status
)) {
3784 tevent_req_received(req
);
3787 *pconn
= talloc_move(mem_ctx
, &state
->conn
);
3788 tevent_req_received(req
);
3789 return NT_STATUS_OK
;
3792 static NTSTATUS
rpc_client_connection_np(struct cli_state
*cli
,
3793 const struct rpc_client_association
*assoc
,
3794 struct rpc_client_connection
**pconn
)
3796 struct tevent_context
*ev
= NULL
;
3797 struct tevent_req
*req
= NULL
;
3798 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3800 ev
= samba_tevent_context_init(cli
);
3804 req
= rpc_client_connection_np_send(ev
, ev
, cli
, assoc
);
3808 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3811 status
= rpc_client_connection_np_recv(req
, NULL
, pconn
);
3818 struct rpc_pipe_open_np_state
{
3819 struct cli_state
*cli
;
3820 const struct ndr_interface_table
*table
;
3821 struct rpc_client_association
*assoc
;
3822 struct rpc_client_connection
*conn
;
3823 struct rpc_pipe_client
*result
;
3826 static void rpc_pipe_open_np_done(struct tevent_req
*subreq
);
3828 struct tevent_req
*rpc_pipe_open_np_send(
3829 TALLOC_CTX
*mem_ctx
,
3830 struct tevent_context
*ev
,
3831 struct cli_state
*cli
,
3832 const struct ndr_interface_table
*table
)
3834 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
3835 struct rpc_pipe_open_np_state
*state
= NULL
;
3836 const char *remote_name
= NULL
;
3837 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
3838 struct samba_sockaddr saddr
= { .sa_socklen
= 0, };
3839 const char *pipe_name
= NULL
;
3842 req
= tevent_req_create(
3843 mem_ctx
, &state
, struct rpc_pipe_open_np_state
);
3848 state
->table
= table
;
3850 remote_name
= smbXcli_conn_remote_name(cli
->conn
);
3851 remote_sockaddr
= smbXcli_conn_remote_sockaddr(cli
->conn
);
3852 saddr
.u
.ss
= *remote_sockaddr
;
3854 pipe_name
= dcerpc_default_transport_endpoint(state
,
3857 if (tevent_req_nomem(pipe_name
, req
)) {
3858 return tevent_req_post(req
, ev
);
3861 status
= rpc_client_association_create(state
,
3862 default_bt_features
,
3863 DCERPC_PROPOSE_HEADER_SIGNING
,
3869 if (tevent_req_nterror(req
, status
)) {
3870 return tevent_req_post(req
, ev
);
3873 subreq
= rpc_client_connection_np_send(state
, ev
, cli
, state
->assoc
);
3874 if (tevent_req_nomem(subreq
, req
)) {
3875 return tevent_req_post(req
, ev
);
3877 tevent_req_set_callback(subreq
, rpc_pipe_open_np_done
, req
);
3881 static void rpc_pipe_open_np_done(struct tevent_req
*subreq
)
3883 struct tevent_req
*req
= tevent_req_callback_data(
3884 subreq
, struct tevent_req
);
3885 struct rpc_pipe_open_np_state
*state
= tevent_req_data(
3886 req
, struct rpc_pipe_open_np_state
);
3889 status
= rpc_client_connection_np_recv(subreq
,
3892 TALLOC_FREE(subreq
);
3893 if (tevent_req_nterror(req
, status
)) {
3897 status
= rpc_pipe_wrap_create(state
->table
,
3903 if (tevent_req_nterror(req
, status
)) {
3907 tevent_req_done(req
);
3910 NTSTATUS
rpc_pipe_open_np_recv(
3911 struct tevent_req
*req
,
3912 TALLOC_CTX
*mem_ctx
,
3913 struct rpc_pipe_client
**_result
)
3915 struct rpc_pipe_open_np_state
*state
= tevent_req_data(
3916 req
, struct rpc_pipe_open_np_state
);
3919 if (tevent_req_is_nterror(req
, &status
)) {
3920 tevent_req_received(req
);
3923 *_result
= talloc_move(mem_ctx
, &state
->result
);
3924 tevent_req_received(req
);
3925 return NT_STATUS_OK
;
3928 /****************************************************************************
3929 Open a pipe to a remote server.
3930 ****************************************************************************/
3932 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3933 enum dcerpc_transport_t transport
,
3934 const struct ndr_interface_table
*table
,
3935 const char *remote_name
,
3936 const struct sockaddr_storage
*remote_sockaddr
,
3937 struct rpc_pipe_client
**presult
)
3939 TALLOC_CTX
*frame
= talloc_stackframe();
3940 struct samba_sockaddr saddr
= { .sa_socklen
= 0, };
3941 struct rpc_client_association
*assoc
= NULL
;
3942 struct rpc_client_connection
*conn
= NULL
;
3943 struct rpc_pipe_client
*result
= NULL
;
3944 char _tcp_endpoint
[6] = { 0, };
3945 const char *endpoint
= NULL
;
3948 if (cli
!= NULL
&& remote_name
== NULL
) {
3949 remote_name
= smbXcli_conn_remote_name(cli
->conn
);
3951 if (cli
!= NULL
&& remote_sockaddr
== NULL
) {
3952 remote_sockaddr
= smbXcli_conn_remote_sockaddr(cli
->conn
);
3955 if (remote_sockaddr
!= NULL
) {
3956 saddr
.u
.ss
= *remote_sockaddr
;
3960 ok
= resolve_name(remote_name
,
3966 return NT_STATUS_NOT_FOUND
;
3970 endpoint
= dcerpc_default_transport_endpoint(frame
,
3973 if (endpoint
== NULL
) {
3976 if (transport
!= NCACN_IP_TCP
) {
3978 return NT_STATUS_RPC_NO_ENDPOINT_FOUND
;
3981 status
= rpc_pipe_get_tcp_port(remote_name
,
3985 if (!NT_STATUS_IS_OK(status
)) {
3990 snprintf(_tcp_endpoint
, sizeof(_tcp_endpoint
), "%u", port
);
3991 endpoint
= _tcp_endpoint
;
3994 status
= rpc_client_association_create(NULL
,
3995 default_bt_features
,
3996 DCERPC_PROPOSE_HEADER_SIGNING
,
4002 if (!NT_STATUS_IS_OK(status
)) {
4006 talloc_steal(frame
, assoc
);
4008 switch (transport
) {
4010 status
= rpc_pipe_open_tcp_port(NULL
,
4013 if (!NT_STATUS_IS_OK(status
)) {
4017 talloc_steal(frame
, conn
);
4020 status
= rpc_client_connection_np(cli
,
4023 if (!NT_STATUS_IS_OK(status
)) {
4027 talloc_steal(frame
, conn
);
4031 return NT_STATUS_NOT_IMPLEMENTED
;
4033 status
= rpc_pipe_wrap_create(table
,
4039 if (!NT_STATUS_IS_OK(status
)) {
4046 return NT_STATUS_OK
;
4049 static NTSTATUS
cli_rpc_pipe_client_reconnect(struct rpc_pipe_client
*p
)
4051 enum dcerpc_transport_t transport
=
4052 dcerpc_binding_get_transport(p
->assoc
->binding
);
4055 switch (transport
) {
4057 status
= rpc_pipe_open_tcp_port(p
,
4060 if (!NT_STATUS_IS_OK(status
)) {
4065 status
= rpc_client_connection_np(p
->np_cli
,
4068 if (!NT_STATUS_IS_OK(status
)) {
4071 talloc_steal(p
, p
->conn
);
4074 return NT_STATUS_NOT_IMPLEMENTED
;
4077 return NT_STATUS_OK
;
4080 NTSTATUS
cli_rpc_pipe_client_prepare_alter(struct rpc_pipe_client
*p
,
4081 bool new_auth_context
,
4082 const struct ndr_interface_table
*table
,
4083 bool new_pres_context
)
4085 uint32_t f
= p
->assoc
->features
.negotiated
;
4088 if (!new_auth_context
&& !new_pres_context
) {
4089 return NT_STATUS_INVALID_PARAMETER_MIX
;
4092 TALLOC_FREE(p
->binding_handle
);
4094 if (new_auth_context
) {
4098 if (new_auth_context
&&
4099 !(f
& DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
))
4102 * new auth context without
4103 * security context multiplexing.
4105 * We need to create a new transport
4106 * connection is the same association
4109 * We need to keep the old connection alive
4110 * in order to connect to the existing association
4111 * group..., so no TALLOC_FREE(p->conn)
4114 status
= cli_rpc_pipe_client_reconnect(p
);
4115 if (!NT_STATUS_IS_OK(status
)) {
4120 if (new_pres_context
) {
4121 /* rpc_pipe_bind_send should allocate an id... */
4122 p
->pres_context_id
= UINT16_MAX
;
4124 p
->transfer_syntax
= ndr_transfer_syntax_ndr
;
4127 return NT_STATUS_OK
;
4130 /****************************************************************************
4131 Open a named pipe to an SMB server and bind anonymously.
4132 ****************************************************************************/
4134 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
4135 enum dcerpc_transport_t transport
,
4136 const struct ndr_interface_table
*table
,
4137 const char *remote_name
,
4138 const struct sockaddr_storage
*remote_sockaddr
,
4139 struct rpc_pipe_client
**presult
)
4141 struct rpc_pipe_client
*result
;
4142 struct pipe_auth_data
*auth
;
4145 status
= cli_rpc_pipe_open(cli
,
4151 if (!NT_STATUS_IS_OK(status
)) {
4155 status
= rpccli_anon_bind_data(result
, &auth
);
4156 if (!NT_STATUS_IS_OK(status
)) {
4157 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
4158 nt_errstr(status
)));
4159 TALLOC_FREE(result
);
4163 status
= rpc_pipe_bind(result
, auth
);
4164 if (!NT_STATUS_IS_OK(status
)) {
4166 if (ndr_syntax_id_equal(&table
->syntax_id
,
4167 &ndr_table_dssetup
.syntax_id
)) {
4168 /* non AD domains just don't have this pipe, avoid
4169 * level 0 statement in that case - gd */
4172 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
4173 "%s failed with error %s\n",
4175 nt_errstr(status
) ));
4176 TALLOC_FREE(result
);
4180 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
4181 "%s and bound anonymously.\n",
4186 return NT_STATUS_OK
;
4189 /****************************************************************************
4190 ****************************************************************************/
4192 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
4193 const struct ndr_interface_table
*table
,
4194 struct rpc_pipe_client
**presult
)
4196 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
4197 const struct sockaddr_storage
*remote_sockaddr
=
4198 smbXcli_conn_remote_sockaddr(cli
->conn
);
4200 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
4207 /****************************************************************************
4208 Open a named pipe to an SMB server and bind using the mech specified
4210 This routine references the creds pointer that is passed in
4211 ****************************************************************************/
4213 NTSTATUS
cli_rpc_pipe_open_with_creds(struct cli_state
*cli
,
4214 const struct ndr_interface_table
*table
,
4215 enum dcerpc_transport_t transport
,
4216 enum dcerpc_AuthType auth_type
,
4217 enum dcerpc_AuthLevel auth_level
,
4219 const struct sockaddr_storage
*remote_sockaddr
,
4220 struct cli_credentials
*creds
,
4221 struct rpc_pipe_client
**presult
)
4223 struct rpc_pipe_client
*result
;
4224 struct pipe_auth_data
*auth
= NULL
;
4225 const char *target_service
= table
->authservices
->names
[0];
4228 status
= cli_rpc_pipe_open(cli
,
4234 if (!NT_STATUS_IS_OK(status
)) {
4238 status
= rpccli_generic_bind_data_from_creds(result
,
4239 auth_type
, auth_level
,
4240 server
, target_service
,
4243 if (!NT_STATUS_IS_OK(status
)) {
4244 DBG_ERR("rpccli_generic_bind_data_from_creds returned %s\n",
4249 status
= rpc_pipe_bind(result
, auth
);
4250 if (!NT_STATUS_IS_OK(status
)) {
4251 DBG_ERR("cli_rpc_pipe_bind failed with error %s\n",
4256 DBG_DEBUG("opened pipe %s to machine %s and bound as user %s.\n",
4259 cli_credentials_get_unparsed_name(creds
, talloc_tos()));
4262 return NT_STATUS_OK
;
4266 TALLOC_FREE(result
);
4270 NTSTATUS
cli_rpc_pipe_client_auth_schannel(
4271 struct rpc_pipe_client
*rpccli
,
4272 const struct ndr_interface_table
*table
,
4273 struct netlogon_creds_cli_context
*netlogon_creds
)
4275 TALLOC_CTX
*frame
= talloc_stackframe();
4276 struct pipe_auth_data
*rpcauth
= NULL
;
4277 const char *target_service
= table
->authservices
->names
[0];
4278 struct cli_credentials
*cli_creds
= NULL
;
4279 enum dcerpc_AuthLevel auth_level
;
4282 auth_level
= netlogon_creds_cli_auth_level(netlogon_creds
);
4284 status
= netlogon_creds_bind_cli_credentials(netlogon_creds
,
4287 if (!NT_STATUS_IS_OK(status
)) {
4288 DBG_DEBUG("netlogon_creds_bind_cli_credentials failed: %s\n",
4294 status
= rpccli_generic_bind_data_from_creds(rpccli
,
4295 DCERPC_AUTH_TYPE_SCHANNEL
,
4301 if (!NT_STATUS_IS_OK(status
)) {
4302 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
4303 nt_errstr(status
)));
4308 status
= rpc_pipe_bind(rpccli
, rpcauth
);
4309 if (!NT_STATUS_IS_OK(status
)) {
4310 DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
4317 return NT_STATUS_OK
;
4320 NTSTATUS
cli_rpc_pipe_open_bind_schannel(
4321 struct cli_state
*cli
,
4322 const struct ndr_interface_table
*table
,
4323 enum dcerpc_transport_t transport
,
4324 struct netlogon_creds_cli_context
*netlogon_creds
,
4325 const char *remote_name
,
4326 const struct sockaddr_storage
*remote_sockaddr
,
4327 struct rpc_pipe_client
**_rpccli
)
4329 struct rpc_pipe_client
*rpccli
= NULL
;
4332 status
= cli_rpc_pipe_open(cli
,
4338 if (!NT_STATUS_IS_OK(status
)) {
4342 status
= cli_rpc_pipe_client_auth_schannel(rpccli
,
4345 if (!NT_STATUS_IS_OK(status
)) {
4346 DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
4348 TALLOC_FREE(rpccli
);
4354 return NT_STATUS_OK
;
4357 NTSTATUS
cli_rpc_pipe_open_schannel_with_creds(struct cli_state
*cli
,
4358 const struct ndr_interface_table
*table
,
4359 enum dcerpc_transport_t transport
,
4360 struct netlogon_creds_cli_context
*netlogon_creds
,
4361 const char *remote_name
,
4362 const struct sockaddr_storage
*remote_sockaddr
,
4363 struct rpc_pipe_client
**_rpccli
)
4365 TALLOC_CTX
*frame
= talloc_stackframe();
4366 struct rpc_pipe_client
*rpccli
;
4367 struct netlogon_creds_cli_lck
*lck
;
4370 status
= netlogon_creds_cli_lck(
4371 netlogon_creds
, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE
,
4373 if (!NT_STATUS_IS_OK(status
)) {
4374 DBG_WARNING("netlogon_creds_cli_lck returned %s\n",
4380 status
= cli_rpc_pipe_open_bind_schannel(cli
,
4387 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
4388 netlogon_creds_cli_delete_lck(netlogon_creds
);
4390 if (!NT_STATUS_IS_OK(status
)) {
4391 DBG_DEBUG("cli_rpc_pipe_open_bind_schannel failed: %s\n",
4397 if (ndr_syntax_id_equal(&table
->syntax_id
,
4398 &ndr_table_netlogon
.syntax_id
)) {
4399 status
= netlogon_creds_cli_check(netlogon_creds
,
4400 rpccli
->binding_handle
,
4402 if (!NT_STATUS_IS_OK(status
)) {
4403 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
4404 nt_errstr(status
)));
4410 DBG_DEBUG("opened pipe %s to machine %s with key %s "
4411 "and bound using schannel.\n",
4412 table
->name
, rpccli
->desthost
,
4413 netlogon_creds_cli_debug_string(netlogon_creds
, lck
));
4418 return NT_STATUS_OK
;