2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../librpc/gen_ndr/ndr_dssetup.h"
24 #include "../librpc/gen_ndr/ndr_netlogon.h"
25 #include "../libcli/auth/schannel.h"
26 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "ntlmssp_wrap.h"
30 #include "rpc_client/cli_netlogon.h"
31 #include "librpc/gen_ndr/ndr_dcerpc.h"
32 #include "librpc/rpc/dcerpc.h"
35 #define DBGC_CLASS DBGC_RPC_CLI
37 /********************************************************************
38 Pipe description for a DEBUG
39 ********************************************************************/
40 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
41 struct rpc_pipe_client
*cli
)
43 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
50 /********************************************************************
52 ********************************************************************/
54 static uint32
get_rpc_call_id(void)
56 static uint32 call_id
= 0;
60 /*******************************************************************
61 Use SMBreadX to get rest of one fragment's worth of rpc data.
62 Reads the whole size or give an error message
63 ********************************************************************/
65 struct rpc_read_state
{
66 struct event_context
*ev
;
67 struct rpc_cli_transport
*transport
;
73 static void rpc_read_done(struct tevent_req
*subreq
);
75 static struct tevent_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
76 struct event_context
*ev
,
77 struct rpc_cli_transport
*transport
,
78 uint8_t *data
, size_t size
)
80 struct tevent_req
*req
, *subreq
;
81 struct rpc_read_state
*state
;
83 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_read_state
);
88 state
->transport
= transport
;
93 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size
));
95 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
100 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
108 static void rpc_read_done(struct tevent_req
*subreq
)
110 struct tevent_req
*req
= tevent_req_callback_data(
111 subreq
, struct tevent_req
);
112 struct rpc_read_state
*state
= tevent_req_data(
113 req
, struct rpc_read_state
);
117 status
= state
->transport
->read_recv(subreq
, &received
);
119 if (!NT_STATUS_IS_OK(status
)) {
120 tevent_req_nterror(req
, status
);
124 state
->num_read
+= received
;
125 if (state
->num_read
== state
->size
) {
126 tevent_req_done(req
);
130 subreq
= state
->transport
->read_send(state
, state
->ev
,
131 state
->data
+ state
->num_read
,
132 state
->size
- state
->num_read
,
133 state
->transport
->priv
);
134 if (tevent_req_nomem(subreq
, req
)) {
137 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
140 static NTSTATUS
rpc_read_recv(struct tevent_req
*req
)
142 return tevent_req_simple_recv_ntstatus(req
);
145 struct rpc_write_state
{
146 struct event_context
*ev
;
147 struct rpc_cli_transport
*transport
;
153 static void rpc_write_done(struct tevent_req
*subreq
);
155 static struct tevent_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
156 struct event_context
*ev
,
157 struct rpc_cli_transport
*transport
,
158 const uint8_t *data
, size_t size
)
160 struct tevent_req
*req
, *subreq
;
161 struct rpc_write_state
*state
;
163 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_write_state
);
168 state
->transport
= transport
;
171 state
->num_written
= 0;
173 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size
));
175 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
176 if (subreq
== NULL
) {
179 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
186 static void rpc_write_done(struct tevent_req
*subreq
)
188 struct tevent_req
*req
= tevent_req_callback_data(
189 subreq
, struct tevent_req
);
190 struct rpc_write_state
*state
= tevent_req_data(
191 req
, struct rpc_write_state
);
195 status
= state
->transport
->write_recv(subreq
, &written
);
197 if (!NT_STATUS_IS_OK(status
)) {
198 tevent_req_nterror(req
, status
);
202 state
->num_written
+= written
;
204 if (state
->num_written
== state
->size
) {
205 tevent_req_done(req
);
209 subreq
= state
->transport
->write_send(state
, state
->ev
,
210 state
->data
+ state
->num_written
,
211 state
->size
- state
->num_written
,
212 state
->transport
->priv
);
213 if (tevent_req_nomem(subreq
, req
)) {
216 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
219 static NTSTATUS
rpc_write_recv(struct tevent_req
*req
)
221 return tevent_req_simple_recv_ntstatus(req
);
225 /****************************************************************************
226 Try and get a PDU's worth of data from current_pdu. If not, then read more
228 ****************************************************************************/
230 struct get_complete_frag_state
{
231 struct event_context
*ev
;
232 struct rpc_pipe_client
*cli
;
237 static void get_complete_frag_got_header(struct tevent_req
*subreq
);
238 static void get_complete_frag_got_rest(struct tevent_req
*subreq
);
240 static struct tevent_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
241 struct event_context
*ev
,
242 struct rpc_pipe_client
*cli
,
245 struct tevent_req
*req
, *subreq
;
246 struct get_complete_frag_state
*state
;
250 req
= tevent_req_create(mem_ctx
, &state
,
251 struct get_complete_frag_state
);
257 state
->frag_len
= RPC_HEADER_LEN
;
260 received
= pdu
->length
;
261 if (received
< RPC_HEADER_LEN
) {
262 if (!data_blob_realloc(mem_ctx
, pdu
, RPC_HEADER_LEN
)) {
263 status
= NT_STATUS_NO_MEMORY
;
266 subreq
= rpc_read_send(state
, state
->ev
,
267 state
->cli
->transport
,
268 pdu
->data
+ received
,
269 RPC_HEADER_LEN
- received
);
270 if (subreq
== NULL
) {
271 status
= NT_STATUS_NO_MEMORY
;
274 tevent_req_set_callback(subreq
, get_complete_frag_got_header
,
279 state
->frag_len
= dcerpc_get_frag_length(pdu
);
282 * Ensure we have frag_len bytes of data.
284 if (received
< state
->frag_len
) {
285 if (!data_blob_realloc(NULL
, pdu
, state
->frag_len
)) {
286 status
= NT_STATUS_NO_MEMORY
;
289 subreq
= rpc_read_send(state
, state
->ev
,
290 state
->cli
->transport
,
291 pdu
->data
+ received
,
292 state
->frag_len
- received
);
293 if (subreq
== NULL
) {
294 status
= NT_STATUS_NO_MEMORY
;
297 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
,
302 status
= NT_STATUS_OK
;
304 if (NT_STATUS_IS_OK(status
)) {
305 tevent_req_done(req
);
307 tevent_req_nterror(req
, status
);
309 return tevent_req_post(req
, ev
);
312 static void get_complete_frag_got_header(struct tevent_req
*subreq
)
314 struct tevent_req
*req
= tevent_req_callback_data(
315 subreq
, struct tevent_req
);
316 struct get_complete_frag_state
*state
= tevent_req_data(
317 req
, struct get_complete_frag_state
);
320 status
= rpc_read_recv(subreq
);
322 if (!NT_STATUS_IS_OK(status
)) {
323 tevent_req_nterror(req
, status
);
327 state
->frag_len
= dcerpc_get_frag_length(state
->pdu
);
329 if (!data_blob_realloc(NULL
, state
->pdu
, state
->frag_len
)) {
330 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
335 * We're here in this piece of code because we've read exactly
336 * RPC_HEADER_LEN bytes into state->pdu.
339 subreq
= rpc_read_send(state
, state
->ev
, state
->cli
->transport
,
340 state
->pdu
->data
+ RPC_HEADER_LEN
,
341 state
->frag_len
- RPC_HEADER_LEN
);
342 if (tevent_req_nomem(subreq
, req
)) {
345 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
348 static void get_complete_frag_got_rest(struct tevent_req
*subreq
)
350 struct tevent_req
*req
= tevent_req_callback_data(
351 subreq
, struct tevent_req
);
354 status
= rpc_read_recv(subreq
);
356 if (!NT_STATUS_IS_OK(status
)) {
357 tevent_req_nterror(req
, status
);
360 tevent_req_done(req
);
363 static NTSTATUS
get_complete_frag_recv(struct tevent_req
*req
)
365 return tevent_req_simple_recv_ntstatus(req
);
368 /****************************************************************************
369 NTLMSSP specific sign/seal.
370 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
371 In fact I should probably abstract these into identical pieces of code... JRA.
372 ****************************************************************************/
374 static NTSTATUS
cli_pipe_verify_ntlmssp(struct rpc_pipe_client
*cli
,
375 struct ncacn_packet
*pkt
,
377 uint8
*p_ss_padding_len
)
379 struct dcerpc_auth auth_info
;
383 if (cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_NONE
384 || cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_CONNECT
) {
388 if (!cli
->auth
->a_u
.auth_ntlmssp_state
) {
389 return NT_STATUS_INVALID_PARAMETER
;
392 /* Ensure there's enough data for an authenticated response. */
393 if ((pkt
->auth_length
> RPC_MAX_PDU_FRAG_LEN
) ||
394 (pkt
->frag_length
< DCERPC_RESPONSE_LENGTH
395 + DCERPC_AUTH_TRAILER_LENGTH
396 + pkt
->auth_length
)) {
397 DEBUG(0, ("auth_len %u is too long.\n",
398 (unsigned int)pkt
->auth_length
));
399 return NT_STATUS_BUFFER_TOO_SMALL
;
402 /* get the auth blob at the end of the packet */
403 blob
= data_blob_const(pdu
->data
+ pkt
->frag_length
404 - DCERPC_AUTH_TRAILER_LENGTH
406 DCERPC_AUTH_TRAILER_LENGTH
409 status
= dcerpc_pull_dcerpc_auth(cli
, &blob
, &auth_info
, false);
410 if (!NT_STATUS_IS_OK(status
)) {
411 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
415 /* Ensure auth_pad_len fits into the packet. */
416 if (pkt
->frag_length
< DCERPC_RESPONSE_LENGTH
417 + auth_info
.auth_pad_length
418 + DCERPC_AUTH_TRAILER_LENGTH
419 + pkt
->auth_length
) {
420 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
421 "too large (%u), auth_len (%u), frag_len = (%u).\n",
422 (unsigned int)auth_info
.auth_pad_length
,
423 (unsigned int)pkt
->auth_length
,
424 (unsigned int)pkt
->frag_length
));
425 return NT_STATUS_BUFFER_TOO_SMALL
;
429 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
430 * after the RPC header.
431 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
432 * functions as NTLMv2 checks the rpc headers also.
435 switch (cli
->auth
->auth_level
) {
436 case DCERPC_AUTH_LEVEL_PRIVACY
:
437 /* Data is encrypted. */
438 status
= auth_ntlmssp_unseal_packet(
439 cli
->auth
->a_u
.auth_ntlmssp_state
,
440 pdu
->data
+ DCERPC_RESPONSE_LENGTH
,
442 - DCERPC_RESPONSE_LENGTH
443 - DCERPC_AUTH_TRAILER_LENGTH
446 pkt
->frag_length
- pkt
->auth_length
,
447 &auth_info
.credentials
);
448 if (!NT_STATUS_IS_OK(status
)) {
449 DEBUG(0, ("failed to unseal packet from %s."
451 rpccli_pipe_txt(talloc_tos(), cli
),
457 case DCERPC_AUTH_LEVEL_INTEGRITY
:
458 /* Data is signed. */
459 status
= auth_ntlmssp_check_packet(
460 cli
->auth
->a_u
.auth_ntlmssp_state
,
461 pdu
->data
+ DCERPC_RESPONSE_LENGTH
,
463 - DCERPC_RESPONSE_LENGTH
464 - DCERPC_AUTH_TRAILER_LENGTH
467 pkt
->frag_length
- pkt
->auth_length
,
468 &auth_info
.credentials
);
469 if (!NT_STATUS_IS_OK(status
)) {
470 DEBUG(0, ("check signing failed on packet from %s."
472 rpccli_pipe_txt(talloc_tos(), cli
),
479 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
480 "auth level %d\n", cli
->auth
->auth_level
));
481 return NT_STATUS_INVALID_INFO_CLASS
;
485 * Remember the padding length. We must remove it from the real data
486 * stream once the sign/seal is done.
489 *p_ss_padding_len
= auth_info
.auth_pad_length
;
494 /****************************************************************************
495 schannel specific sign/seal.
496 ****************************************************************************/
498 static NTSTATUS
cli_pipe_verify_schannel(struct rpc_pipe_client
*cli
,
499 struct ncacn_packet
*pkt
,
501 uint8
*p_ss_padding_len
)
503 struct dcerpc_auth auth_info
;
507 if (cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_NONE
508 || cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_CONNECT
) {
512 if (pkt
->auth_length
< NL_AUTH_SIGNATURE_SIZE
) {
513 DEBUG(0, ("auth_len %u.\n", (unsigned int)pkt
->auth_length
));
514 return NT_STATUS_INVALID_PARAMETER
;
517 if (!cli
->auth
->a_u
.schannel_auth
) {
518 return NT_STATUS_INVALID_PARAMETER
;
521 /* Ensure there's enough data for an authenticated response. */
522 if ((pkt
->auth_length
> RPC_MAX_PDU_FRAG_LEN
) ||
523 (pkt
->frag_length
< DCERPC_RESPONSE_LENGTH
524 + DCERPC_AUTH_TRAILER_LENGTH
525 + pkt
->auth_length
)) {
526 DEBUG(0, ("auth_len %u is too long.\n",
527 (unsigned int)pkt
->auth_length
));
528 return NT_STATUS_INVALID_PARAMETER
;
531 /* get the auth blob at the end of the packet */
532 blob
= data_blob_const(pdu
->data
+ pkt
->frag_length
533 - DCERPC_AUTH_TRAILER_LENGTH
535 DCERPC_AUTH_TRAILER_LENGTH
539 status
= dcerpc_pull_dcerpc_auth(cli
, &blob
, &auth_info
, false);
540 if (!NT_STATUS_IS_OK(status
)) {
541 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
545 /* Ensure auth_pad_len fits into the packet. */
546 if (pkt
->frag_length
< DCERPC_RESPONSE_LENGTH
547 + auth_info
.auth_pad_length
548 + DCERPC_AUTH_TRAILER_LENGTH
549 + pkt
->auth_length
) {
550 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
551 "too large (%u), auth_len (%u), frag_len = (%u).\n",
552 (unsigned int)auth_info
.auth_pad_length
,
553 (unsigned int)pkt
->auth_length
,
554 (unsigned int)pkt
->frag_length
));
555 return NT_STATUS_BUFFER_TOO_SMALL
;
558 if (auth_info
.auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
) {
559 DEBUG(0, ("Invalid auth info %d on schannel\n",
560 auth_info
.auth_type
));
561 return NT_STATUS_BUFFER_TOO_SMALL
;
564 if (DEBUGLEVEL
>= 10) {
565 dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_info
.credentials
);
568 switch (cli
->auth
->auth_level
) {
569 case DCERPC_AUTH_LEVEL_PRIVACY
:
570 status
= netsec_incoming_packet(
571 cli
->auth
->a_u
.schannel_auth
,
574 pdu
->data
+ DCERPC_RESPONSE_LENGTH
,
576 - DCERPC_RESPONSE_LENGTH
577 - DCERPC_AUTH_TRAILER_LENGTH
579 &auth_info
.credentials
);
581 case DCERPC_AUTH_LEVEL_INTEGRITY
:
582 status
= netsec_incoming_packet(
583 cli
->auth
->a_u
.schannel_auth
,
586 pdu
->data
+ DCERPC_RESPONSE_LENGTH
,
588 - DCERPC_RESPONSE_LENGTH
589 - DCERPC_AUTH_TRAILER_LENGTH
591 &auth_info
.credentials
);
594 status
= NT_STATUS_INTERNAL_ERROR
;
598 if (!NT_STATUS_IS_OK(status
)) {
599 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
600 "Connection to %s (%s).\n",
601 rpccli_pipe_txt(talloc_tos(), cli
),
603 return NT_STATUS_INVALID_PARAMETER
;
607 * Remember the padding length. We must remove it from the real data
608 * stream once the sign/seal is done.
611 *p_ss_padding_len
= auth_info
.auth_pad_length
;
616 /****************************************************************************
617 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
618 ****************************************************************************/
620 static NTSTATUS
cli_pipe_validate_rpc_response(struct rpc_pipe_client
*cli
,
621 struct ncacn_packet
*pkt
,
623 uint8
*p_ss_padding_len
)
625 NTSTATUS ret
= NT_STATUS_OK
;
627 /* Paranioa checks for auth_len. */
628 if (pkt
->auth_length
) {
629 if (pkt
->auth_length
> pkt
->frag_length
) {
630 return NT_STATUS_INVALID_PARAMETER
;
633 if ((pkt
->auth_length
634 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
635 < pkt
->auth_length
) ||
637 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
638 < (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
)) {
639 /* Integer wrap attempt. */
640 return NT_STATUS_INVALID_PARAMETER
;
645 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
648 switch(cli
->auth
->auth_type
) {
649 case PIPE_AUTH_TYPE_NONE
:
650 if (pkt
->auth_length
) {
651 DEBUG(3, ("cli_pipe_validate_rpc_response: "
652 "Connection to %s - got non-zero "
654 rpccli_pipe_txt(talloc_tos(), cli
),
655 (unsigned int)pkt
->auth_length
));
656 return NT_STATUS_INVALID_PARAMETER
;
660 case PIPE_AUTH_TYPE_NTLMSSP
:
661 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
662 ret
= cli_pipe_verify_ntlmssp(cli
, pkt
, pdu
,
664 if (!NT_STATUS_IS_OK(ret
)) {
669 case PIPE_AUTH_TYPE_SCHANNEL
:
670 ret
= cli_pipe_verify_schannel(cli
, pkt
, pdu
,
672 if (!NT_STATUS_IS_OK(ret
)) {
677 case PIPE_AUTH_TYPE_KRB5
:
678 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
680 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
681 "to %s - unknown internal auth type %u.\n",
682 rpccli_pipe_txt(talloc_tos(), cli
),
683 cli
->auth
->auth_type
));
684 return NT_STATUS_INVALID_INFO_CLASS
;
690 /****************************************************************************
691 Do basic authentication checks on an incoming pdu.
692 ****************************************************************************/
694 static NTSTATUS
cli_pipe_validate_current_pdu(TALLOC_CTX
*mem_ctx
,
695 struct rpc_pipe_client
*cli
,
696 struct ncacn_packet
*pkt
,
698 uint8_t expected_pkt_type
,
700 DATA_BLOB
*reply_pdu
)
702 NTSTATUS ret
= NT_STATUS_OK
;
703 uint8 ss_padding_len
= 0;
705 ret
= dcerpc_pull_ncacn_packet(cli
, pdu
, pkt
, false);
706 if (!NT_STATUS_IS_OK(ret
)) {
710 if (pdu
->length
!= pkt
->frag_length
) {
711 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
712 (unsigned int)pdu
->length
,
713 (unsigned int)pkt
->frag_length
));
714 return NT_STATUS_INVALID_PARAMETER
;
718 * Point the return values at the real data including the RPC
719 * header. Just in case the caller wants it.
723 /* Ensure we have the correct type. */
724 switch (pkt
->ptype
) {
725 case DCERPC_PKT_ALTER_RESP
:
726 case DCERPC_PKT_BIND_ACK
:
728 /* Alter context and bind ack share the same packet definitions. */
732 case DCERPC_PKT_RESPONSE
:
734 /* Here's where we deal with incoming sign/seal. */
735 ret
= cli_pipe_validate_rpc_response(cli
, pkt
, pdu
,
737 if (!NT_STATUS_IS_OK(ret
)) {
741 /* Point the return values at the NDR data.
742 * Remember to remove any ss padding. */
743 rdata
->data
= pdu
->data
+ DCERPC_RESPONSE_LENGTH
;
745 if (pdu
->length
< DCERPC_RESPONSE_LENGTH
+ ss_padding_len
) {
746 return NT_STATUS_BUFFER_TOO_SMALL
;
749 rdata
->length
= pdu
->length
750 - DCERPC_RESPONSE_LENGTH
753 /* Remember to remove the auth footer. */
754 if (pkt
->auth_length
) {
755 /* We've already done integer wrap tests on auth_len in
756 cli_pipe_validate_rpc_response(). */
757 if (rdata
->length
< DCERPC_AUTH_TRAILER_LENGTH
758 + pkt
->auth_length
) {
759 return NT_STATUS_BUFFER_TOO_SMALL
;
761 rdata
->length
-= (DCERPC_AUTH_TRAILER_LENGTH
765 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
766 (long unsigned int)pdu
->length
,
767 (long unsigned int)rdata
->length
,
768 (unsigned int)ss_padding_len
));
771 * If this is the first reply, and the allocation hint is
772 * reasonable, try and set up the reply_pdu DATA_BLOB to the
776 if ((reply_pdu
->length
== 0) &&
777 pkt
->u
.response
.alloc_hint
&&
778 (pkt
->u
.response
.alloc_hint
< 15*1024*1024)) {
779 if (!data_blob_realloc(mem_ctx
, reply_pdu
,
780 pkt
->u
.response
.alloc_hint
)) {
781 DEBUG(0, ("reply alloc hint %d too "
782 "large to allocate\n",
783 (int)pkt
->u
.response
.alloc_hint
));
784 return NT_STATUS_NO_MEMORY
;
790 case DCERPC_PKT_BIND_NAK
:
791 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
792 "received from %s!\n",
793 rpccli_pipe_txt(talloc_tos(), cli
)));
794 /* Use this for now... */
795 return NT_STATUS_NETWORK_ACCESS_DENIED
;
797 case DCERPC_PKT_FAULT
:
799 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
800 "code %s received from %s!\n",
801 dcerpc_errstr(talloc_tos(),
802 pkt
->u
.fault
.status
),
803 rpccli_pipe_txt(talloc_tos(), cli
)));
805 if (NT_STATUS_IS_OK(NT_STATUS(pkt
->u
.fault
.status
))) {
806 return NT_STATUS_UNSUCCESSFUL
;
808 return NT_STATUS(pkt
->u
.fault
.status
);
812 DEBUG(0, ("Unknown packet type %u received from %s!\n",
813 (unsigned int)pkt
->ptype
,
814 rpccli_pipe_txt(talloc_tos(), cli
)));
815 return NT_STATUS_INVALID_INFO_CLASS
;
818 if (pkt
->ptype
!= expected_pkt_type
) {
819 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
820 "got an unexpected RPC packet type - %u, not %u\n",
821 rpccli_pipe_txt(talloc_tos(), cli
),
824 return NT_STATUS_INVALID_INFO_CLASS
;
827 /* Do this just before return - we don't want to modify any rpc header
828 data before now as we may have needed to do cryptographic actions on
831 if ((pkt
->ptype
== DCERPC_PKT_BIND_ACK
) &&
832 !(pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
833 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
834 "setting fragment first/last ON.\n"));
835 pkt
->pfc_flags
|= DCERPC_PFC_FLAG_FIRST
|
836 DCERPC_PFC_FLAG_LAST
;
842 /****************************************************************************
843 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
844 ****************************************************************************/
846 struct cli_api_pipe_state
{
847 struct event_context
*ev
;
848 struct rpc_cli_transport
*transport
;
853 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
);
854 static void cli_api_pipe_write_done(struct tevent_req
*subreq
);
855 static void cli_api_pipe_read_done(struct tevent_req
*subreq
);
857 static struct tevent_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
858 struct event_context
*ev
,
859 struct rpc_cli_transport
*transport
,
860 uint8_t *data
, size_t data_len
,
861 uint32_t max_rdata_len
)
863 struct tevent_req
*req
, *subreq
;
864 struct cli_api_pipe_state
*state
;
867 req
= tevent_req_create(mem_ctx
, &state
, struct cli_api_pipe_state
);
872 state
->transport
= transport
;
874 if (max_rdata_len
< RPC_HEADER_LEN
) {
876 * For a RPC reply we always need at least RPC_HEADER_LEN
877 * bytes. We check this here because we will receive
878 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
880 status
= NT_STATUS_INVALID_PARAMETER
;
884 if (transport
->trans_send
!= NULL
) {
885 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
886 max_rdata_len
, transport
->priv
);
887 if (subreq
== NULL
) {
890 tevent_req_set_callback(subreq
, cli_api_pipe_trans_done
, req
);
895 * If the transport does not provide a "trans" routine, i.e. for
896 * example the ncacn_ip_tcp transport, do the write/read step here.
899 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
900 if (subreq
== NULL
) {
903 tevent_req_set_callback(subreq
, cli_api_pipe_write_done
, req
);
907 tevent_req_nterror(req
, status
);
908 return tevent_req_post(req
, ev
);
914 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
)
916 struct tevent_req
*req
= tevent_req_callback_data(
917 subreq
, struct tevent_req
);
918 struct cli_api_pipe_state
*state
= tevent_req_data(
919 req
, struct cli_api_pipe_state
);
922 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
925 if (!NT_STATUS_IS_OK(status
)) {
926 tevent_req_nterror(req
, status
);
929 tevent_req_done(req
);
932 static void cli_api_pipe_write_done(struct tevent_req
*subreq
)
934 struct tevent_req
*req
= tevent_req_callback_data(
935 subreq
, struct tevent_req
);
936 struct cli_api_pipe_state
*state
= tevent_req_data(
937 req
, struct cli_api_pipe_state
);
940 status
= rpc_write_recv(subreq
);
942 if (!NT_STATUS_IS_OK(status
)) {
943 tevent_req_nterror(req
, status
);
947 state
->rdata
= TALLOC_ARRAY(state
, uint8_t, RPC_HEADER_LEN
);
948 if (tevent_req_nomem(state
->rdata
, req
)) {
953 * We don't need to use rpc_read_send here, the upper layer will cope
954 * with a short read, transport->trans_send could also return less
955 * than state->max_rdata_len.
957 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
959 state
->transport
->priv
);
960 if (tevent_req_nomem(subreq
, req
)) {
963 tevent_req_set_callback(subreq
, cli_api_pipe_read_done
, req
);
966 static void cli_api_pipe_read_done(struct tevent_req
*subreq
)
968 struct tevent_req
*req
= tevent_req_callback_data(
969 subreq
, struct tevent_req
);
970 struct cli_api_pipe_state
*state
= tevent_req_data(
971 req
, struct cli_api_pipe_state
);
975 status
= state
->transport
->read_recv(subreq
, &received
);
977 if (!NT_STATUS_IS_OK(status
)) {
978 tevent_req_nterror(req
, status
);
981 state
->rdata_len
= received
;
982 tevent_req_done(req
);
985 static NTSTATUS
cli_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
986 uint8_t **prdata
, uint32_t *prdata_len
)
988 struct cli_api_pipe_state
*state
= tevent_req_data(
989 req
, struct cli_api_pipe_state
);
992 if (tevent_req_is_nterror(req
, &status
)) {
996 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
997 *prdata_len
= state
->rdata_len
;
1001 /****************************************************************************
1002 Send data on an rpc pipe via trans. The data must be the last
1003 pdu fragment of an NDR data stream.
1005 Receive response data from an rpc pipe, which may be large...
1007 Read the first fragment: unfortunately have to use SMBtrans for the first
1008 bit, then SMBreadX for subsequent bits.
1010 If first fragment received also wasn't the last fragment, continue
1011 getting fragments until we _do_ receive the last fragment.
1013 Request/Response PDU's look like the following...
1015 |<------------------PDU len----------------------------------------------->|
1016 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1018 +------------+-----------------+-------------+---------------+-------------+
1019 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1020 +------------+-----------------+-------------+---------------+-------------+
1022 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1023 signing & sealing being negotiated.
1025 ****************************************************************************/
1027 struct rpc_api_pipe_state
{
1028 struct event_context
*ev
;
1029 struct rpc_pipe_client
*cli
;
1030 uint8_t expected_pkt_type
;
1032 DATA_BLOB incoming_frag
;
1033 struct ncacn_packet
*pkt
;
1035 /* Incoming reply */
1036 DATA_BLOB reply_pdu
;
1037 size_t reply_pdu_offset
;
1041 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
);
1042 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
);
1044 static struct tevent_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
1045 struct event_context
*ev
,
1046 struct rpc_pipe_client
*cli
,
1047 DATA_BLOB
*data
, /* Outgoing PDU */
1048 uint8_t expected_pkt_type
)
1050 struct tevent_req
*req
, *subreq
;
1051 struct rpc_api_pipe_state
*state
;
1052 uint16_t max_recv_frag
;
1055 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_api_pipe_state
);
1061 state
->expected_pkt_type
= expected_pkt_type
;
1062 state
->incoming_frag
= data_blob_null
;
1063 state
->reply_pdu
= data_blob_null
;
1064 state
->reply_pdu_offset
= 0;
1065 state
->endianess
= DCERPC_DREP_LE
;
1068 * Ensure we're not sending too much.
1070 if (data
->length
> cli
->max_xmit_frag
) {
1071 status
= NT_STATUS_INVALID_PARAMETER
;
1075 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli
)));
1077 /* get the header first, then fetch the rest once we have
1078 * the frag_length available */
1079 max_recv_frag
= RPC_HEADER_LEN
;
1081 subreq
= cli_api_pipe_send(state
, ev
, cli
->transport
,
1082 data
->data
, data
->length
, max_recv_frag
);
1083 if (subreq
== NULL
) {
1086 tevent_req_set_callback(subreq
, rpc_api_pipe_trans_done
, req
);
1090 tevent_req_nterror(req
, status
);
1091 return tevent_req_post(req
, ev
);
1097 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
)
1099 struct tevent_req
*req
= tevent_req_callback_data(
1100 subreq
, struct tevent_req
);
1101 struct rpc_api_pipe_state
*state
= tevent_req_data(
1102 req
, struct rpc_api_pipe_state
);
1104 uint8_t *rdata
= NULL
;
1105 uint32_t rdata_len
= 0;
1107 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
1108 TALLOC_FREE(subreq
);
1109 if (!NT_STATUS_IS_OK(status
)) {
1110 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
1111 tevent_req_nterror(req
, status
);
1115 if (rdata
== NULL
) {
1116 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1117 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1118 tevent_req_done(req
);
1123 * Move data on state->incoming_frag.
1125 state
->incoming_frag
.data
= talloc_move(state
, &rdata
);
1126 state
->incoming_frag
.length
= rdata_len
;
1127 if (!state
->incoming_frag
.data
) {
1128 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1132 /* Ensure we have enough data for a pdu. */
1133 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1134 &state
->incoming_frag
);
1135 if (tevent_req_nomem(subreq
, req
)) {
1138 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1141 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
)
1143 struct tevent_req
*req
= tevent_req_callback_data(
1144 subreq
, struct tevent_req
);
1145 struct rpc_api_pipe_state
*state
= tevent_req_data(
1146 req
, struct rpc_api_pipe_state
);
1148 DATA_BLOB rdata
= data_blob_null
;
1150 status
= get_complete_frag_recv(subreq
);
1151 TALLOC_FREE(subreq
);
1152 if (!NT_STATUS_IS_OK(status
)) {
1153 DEBUG(5, ("get_complete_frag failed: %s\n",
1154 nt_errstr(status
)));
1155 tevent_req_nterror(req
, status
);
1159 state
->pkt
= talloc(state
, struct ncacn_packet
);
1161 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1165 status
= cli_pipe_validate_current_pdu(state
,
1166 state
->cli
, state
->pkt
,
1167 &state
->incoming_frag
,
1168 state
->expected_pkt_type
,
1172 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1173 (unsigned)state
->incoming_frag
.length
,
1174 (unsigned)state
->reply_pdu_offset
,
1175 nt_errstr(status
)));
1177 if (!NT_STATUS_IS_OK(status
)) {
1178 tevent_req_nterror(req
, status
);
1182 if ((state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_FIRST
)
1183 && (state
->pkt
->drep
[0] != DCERPC_DREP_LE
)) {
1185 * Set the data type correctly for big-endian data on the
1188 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1190 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1191 state
->endianess
= 0x00; /* BIG ENDIAN */
1194 * Check endianness on subsequent packets.
1196 if (state
->endianess
!= state
->pkt
->drep
[0]) {
1197 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1199 state
->endianess
?"little":"big",
1200 state
->pkt
->drep
[0]?"little":"big"));
1201 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1205 /* Now copy the data portion out of the pdu into rbuf. */
1206 if (state
->reply_pdu
.length
< state
->reply_pdu_offset
+ rdata
.length
) {
1207 if (!data_blob_realloc(NULL
, &state
->reply_pdu
,
1208 state
->reply_pdu_offset
+ rdata
.length
)) {
1209 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1214 memcpy(state
->reply_pdu
.data
+ state
->reply_pdu_offset
,
1215 rdata
.data
, rdata
.length
);
1216 state
->reply_pdu_offset
+= rdata
.length
;
1218 /* reset state->incoming_frag, there is no need to free it,
1219 * it will be reallocated to the right size the next time
1221 state
->incoming_frag
.length
= 0;
1223 if (state
->pkt
->pfc_flags
& DCERPC_PFC_FLAG_LAST
) {
1224 /* make sure the pdu length is right now that we
1225 * have all the data available (alloc hint may
1226 * have allocated more than was actually used) */
1227 state
->reply_pdu
.length
= state
->reply_pdu_offset
;
1228 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1229 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1230 (unsigned)state
->reply_pdu
.length
));
1231 tevent_req_done(req
);
1235 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1236 &state
->incoming_frag
);
1237 if (tevent_req_nomem(subreq
, req
)) {
1240 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1243 static NTSTATUS
rpc_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1244 struct ncacn_packet
**pkt
,
1245 DATA_BLOB
*reply_pdu
)
1247 struct rpc_api_pipe_state
*state
= tevent_req_data(
1248 req
, struct rpc_api_pipe_state
);
1251 if (tevent_req_is_nterror(req
, &status
)) {
1255 /* return data to caller and assign it ownership of memory */
1257 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
1258 reply_pdu
->length
= state
->reply_pdu
.length
;
1259 state
->reply_pdu
.length
= 0;
1261 data_blob_free(&state
->reply_pdu
);
1265 *pkt
= talloc_steal(mem_ctx
, state
->pkt
);
1268 return NT_STATUS_OK
;
1271 /*******************************************************************
1272 Creates krb5 auth bind.
1273 ********************************************************************/
1275 static NTSTATUS
create_krb5_auth_bind_req(struct rpc_pipe_client
*cli
,
1276 enum dcerpc_AuthLevel auth_level
,
1277 DATA_BLOB
*auth_info
)
1282 struct kerberos_auth_struct
*a
= cli
->auth
->a_u
.kerberos_auth
;
1283 DATA_BLOB tkt
= data_blob_null
;
1284 DATA_BLOB tkt_wrapped
= data_blob_null
;
1286 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1287 a
->service_principal
));
1289 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1291 ret
= cli_krb5_get_ticket(a
, a
->service_principal
, 0,
1292 &tkt
, &a
->session_key
,
1293 AP_OPTS_MUTUAL_REQUIRED
, NULL
,
1297 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1299 a
->service_principal
,
1300 error_message(ret
) ));
1302 data_blob_free(&tkt
);
1303 return NT_STATUS_INVALID_PARAMETER
;
1306 /* wrap that up in a nice GSS-API wrapping */
1307 tkt_wrapped
= spnego_gen_krb5_wrap(talloc_tos(), tkt
, TOK_ID_KRB_AP_REQ
);
1309 data_blob_free(&tkt
);
1311 status
= dcerpc_push_dcerpc_auth(cli
,
1312 DCERPC_AUTH_TYPE_KRB5
,
1314 0, /* auth_pad_length */
1315 1, /* auth_context_id */
1318 if (!NT_STATUS_IS_OK(status
)) {
1319 data_blob_free(&tkt_wrapped
);
1323 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1324 dump_data(5, tkt_wrapped
.data
, tkt_wrapped
.length
);
1326 return NT_STATUS_OK
;
1328 return NT_STATUS_INVALID_PARAMETER
;
1332 /*******************************************************************
1333 Creates SPNEGO NTLMSSP auth bind.
1334 ********************************************************************/
1336 static NTSTATUS
create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1337 enum dcerpc_AuthLevel auth_level
,
1338 DATA_BLOB
*auth_info
)
1341 DATA_BLOB null_blob
= data_blob_null
;
1342 DATA_BLOB request
= data_blob_null
;
1343 DATA_BLOB spnego_msg
= data_blob_null
;
1344 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1346 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1347 status
= auth_ntlmssp_update(cli
->auth
->a_u
.auth_ntlmssp_state
,
1351 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1352 data_blob_free(&request
);
1356 /* Wrap this in SPNEGO. */
1357 spnego_msg
= spnego_gen_negTokenInit(talloc_tos(), OIDs_ntlm
, &request
, NULL
);
1359 data_blob_free(&request
);
1361 status
= dcerpc_push_dcerpc_auth(cli
,
1362 DCERPC_AUTH_TYPE_SPNEGO
,
1364 0, /* auth_pad_length */
1365 1, /* auth_context_id */
1369 if (!NT_STATUS_IS_OK(status
)) {
1370 data_blob_free(&spnego_msg
);
1374 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1375 dump_data(5, spnego_msg
.data
, spnego_msg
.length
);
1376 data_blob_free(&spnego_msg
);
1378 return NT_STATUS_OK
;
1381 /*******************************************************************
1382 Creates NTLMSSP auth bind.
1383 ********************************************************************/
1385 static NTSTATUS
create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1386 enum dcerpc_AuthLevel auth_level
,
1387 DATA_BLOB
*auth_info
)
1390 DATA_BLOB null_blob
= data_blob_null
;
1391 DATA_BLOB request
= data_blob_null
;
1393 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1394 status
= auth_ntlmssp_update(cli
->auth
->a_u
.auth_ntlmssp_state
,
1398 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1399 data_blob_free(&request
);
1403 status
= dcerpc_push_dcerpc_auth(cli
,
1404 DCERPC_AUTH_TYPE_NTLMSSP
,
1406 0, /* auth_pad_length */
1407 1, /* auth_context_id */
1410 if (!NT_STATUS_IS_OK(status
)) {
1411 data_blob_free(&request
);
1415 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1416 dump_data(5, request
.data
, request
.length
);
1418 return NT_STATUS_OK
;
1421 /*******************************************************************
1422 Creates schannel auth bind.
1423 ********************************************************************/
1425 static NTSTATUS
create_schannel_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1426 enum dcerpc_AuthLevel auth_level
,
1427 DATA_BLOB
*auth_info
)
1430 struct NL_AUTH_MESSAGE r
;
1431 DATA_BLOB schannel_blob
;
1433 /* Use lp_workgroup() if domain not specified */
1435 if (!cli
->auth
->domain
|| !cli
->auth
->domain
[0]) {
1436 cli
->auth
->domain
= talloc_strdup(cli
, lp_workgroup());
1437 if (cli
->auth
->domain
== NULL
) {
1438 return NT_STATUS_NO_MEMORY
;
1443 * Now marshall the data into the auth parse_struct.
1446 r
.MessageType
= NL_NEGOTIATE_REQUEST
;
1447 r
.Flags
= NL_FLAG_OEM_NETBIOS_DOMAIN_NAME
|
1448 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME
;
1449 r
.oem_netbios_domain
.a
= cli
->auth
->domain
;
1450 r
.oem_netbios_computer
.a
= global_myname();
1452 status
= dcerpc_push_schannel_bind(cli
, &r
, &schannel_blob
);
1453 if (!NT_STATUS_IS_OK(status
)) {
1457 status
= dcerpc_push_dcerpc_auth(cli
,
1458 DCERPC_AUTH_TYPE_SCHANNEL
,
1460 0, /* auth_pad_length */
1461 1, /* auth_context_id */
1464 if (!NT_STATUS_IS_OK(status
)) {
1468 return NT_STATUS_OK
;
1471 /*******************************************************************
1472 Creates the internals of a DCE/RPC bind request or alter context PDU.
1473 ********************************************************************/
1475 static NTSTATUS
create_bind_or_alt_ctx_internal(TALLOC_CTX
*mem_ctx
,
1476 enum dcerpc_pkt_type ptype
,
1478 const struct ndr_syntax_id
*abstract
,
1479 const struct ndr_syntax_id
*transfer
,
1480 const DATA_BLOB
*auth_info
,
1483 uint16 auth_len
= auth_info
->length
;
1485 union dcerpc_payload u
;
1486 struct dcerpc_ctx_list ctx_list
;
1489 auth_len
-= DCERPC_AUTH_TRAILER_LENGTH
;
1492 ctx_list
.context_id
= 0;
1493 ctx_list
.num_transfer_syntaxes
= 1;
1494 ctx_list
.abstract_syntax
= *abstract
;
1495 ctx_list
.transfer_syntaxes
= (struct ndr_syntax_id
*)discard_const(transfer
);
1497 u
.bind
.max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
1498 u
.bind
.max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
1499 u
.bind
.assoc_group_id
= 0x0;
1500 u
.bind
.num_contexts
= 1;
1501 u
.bind
.ctx_list
= &ctx_list
;
1502 u
.bind
.auth_info
= *auth_info
;
1504 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1506 DCERPC_PFC_FLAG_FIRST
|
1507 DCERPC_PFC_FLAG_LAST
,
1512 if (!NT_STATUS_IS_OK(status
)) {
1513 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1517 return NT_STATUS_OK
;
1520 /*******************************************************************
1521 Creates a DCE/RPC bind request.
1522 ********************************************************************/
1524 static NTSTATUS
create_rpc_bind_req(TALLOC_CTX
*mem_ctx
,
1525 struct rpc_pipe_client
*cli
,
1527 const struct ndr_syntax_id
*abstract
,
1528 const struct ndr_syntax_id
*transfer
,
1529 enum pipe_auth_type auth_type
,
1530 enum dcerpc_AuthLevel auth_level
,
1533 DATA_BLOB auth_info
= data_blob_null
;
1534 NTSTATUS ret
= NT_STATUS_OK
;
1536 switch (auth_type
) {
1537 case PIPE_AUTH_TYPE_SCHANNEL
:
1538 ret
= create_schannel_auth_rpc_bind_req(cli
, auth_level
, &auth_info
);
1539 if (!NT_STATUS_IS_OK(ret
)) {
1544 case PIPE_AUTH_TYPE_NTLMSSP
:
1545 ret
= create_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &auth_info
);
1546 if (!NT_STATUS_IS_OK(ret
)) {
1551 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1552 ret
= create_spnego_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &auth_info
);
1553 if (!NT_STATUS_IS_OK(ret
)) {
1558 case PIPE_AUTH_TYPE_KRB5
:
1559 ret
= create_krb5_auth_bind_req(cli
, auth_level
, &auth_info
);
1560 if (!NT_STATUS_IS_OK(ret
)) {
1565 case PIPE_AUTH_TYPE_NONE
:
1569 /* "Can't" happen. */
1570 return NT_STATUS_INVALID_INFO_CLASS
;
1573 ret
= create_bind_or_alt_ctx_internal(mem_ctx
,
1583 /*******************************************************************
1584 Create and add the NTLMSSP sign/seal auth header and data.
1585 ********************************************************************/
1587 static NTSTATUS
add_ntlmssp_auth_footer(struct rpc_pipe_client
*cli
,
1588 uint32 ss_padding_len
,
1591 DATA_BLOB auth_info
;
1593 DATA_BLOB auth_blob
= data_blob_null
;
1594 uint16_t data_and_pad_len
= rpc_out
->length
- DCERPC_RESPONSE_LENGTH
;
1596 if (!cli
->auth
->a_u
.auth_ntlmssp_state
) {
1597 return NT_STATUS_INVALID_PARAMETER
;
1600 /* marshall the dcerpc_auth with an actually empty auth_blob.
1601 * this is needed because the ntmlssp signature includes the
1603 status
= dcerpc_push_dcerpc_auth(rpc_out
->data
,
1604 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
->auth_type
),
1605 cli
->auth
->auth_level
,
1607 1 /* context id. */,
1610 if (!NT_STATUS_IS_OK(status
)) {
1614 /* append the header */
1615 if (!data_blob_append(NULL
, rpc_out
,
1616 auth_info
.data
, auth_info
.length
)) {
1617 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1618 (unsigned int)auth_info
.length
));
1619 return NT_STATUS_NO_MEMORY
;
1621 data_blob_free(&auth_info
);
1623 switch (cli
->auth
->auth_level
) {
1624 case DCERPC_AUTH_LEVEL_PRIVACY
:
1625 /* Data portion is encrypted. */
1626 status
= auth_ntlmssp_seal_packet(cli
->auth
->a_u
.auth_ntlmssp_state
,
1629 + DCERPC_RESPONSE_LENGTH
,
1634 if (!NT_STATUS_IS_OK(status
)) {
1639 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1640 /* Data is signed. */
1641 status
= auth_ntlmssp_sign_packet(cli
->auth
->a_u
.auth_ntlmssp_state
,
1644 + DCERPC_RESPONSE_LENGTH
,
1649 if (!NT_STATUS_IS_OK(status
)) {
1656 smb_panic("bad auth level");
1658 return NT_STATUS_INVALID_PARAMETER
;
1661 /* Finally attach the blob. */
1662 if (!data_blob_append(NULL
, rpc_out
,
1663 auth_blob
.data
, auth_blob
.length
)) {
1664 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1665 (unsigned int)auth_info
.length
));
1666 return NT_STATUS_NO_MEMORY
;
1668 data_blob_free(&auth_blob
);
1670 return NT_STATUS_OK
;
1673 /*******************************************************************
1674 Create and add the schannel sign/seal auth header and data.
1675 ********************************************************************/
1677 static NTSTATUS
add_schannel_auth_footer(struct rpc_pipe_client
*cli
,
1678 uint32 ss_padding_len
,
1681 DATA_BLOB auth_info
;
1682 struct schannel_state
*sas
= cli
->auth
->a_u
.schannel_auth
;
1683 uint8_t *data_p
= rpc_out
->data
+ DCERPC_RESPONSE_LENGTH
;
1684 size_t data_and_pad_len
= rpc_out
->length
1685 - DCERPC_RESPONSE_LENGTH
;
1690 return NT_STATUS_INVALID_PARAMETER
;
1693 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1696 switch (cli
->auth
->auth_level
) {
1697 case DCERPC_AUTH_LEVEL_PRIVACY
:
1698 status
= netsec_outgoing_packet(sas
,
1705 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1706 status
= netsec_outgoing_packet(sas
,
1714 status
= NT_STATUS_INTERNAL_ERROR
;
1718 if (!NT_STATUS_IS_OK(status
)) {
1719 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1720 nt_errstr(status
)));
1724 if (DEBUGLEVEL
>= 10) {
1725 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob
);
1728 /* Finally marshall the blob. */
1729 status
= dcerpc_push_dcerpc_auth(rpc_out
->data
,
1730 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
->auth_type
),
1731 cli
->auth
->auth_level
,
1733 1 /* context id. */,
1736 if (!NT_STATUS_IS_OK(status
)) {
1739 data_blob_free(&blob
);
1741 if (!data_blob_append(NULL
, rpc_out
,
1742 auth_info
.data
, auth_info
.length
)) {
1743 return NT_STATUS_NO_MEMORY
;
1745 data_blob_free(&auth_info
);
1747 return NT_STATUS_OK
;
1750 /*******************************************************************
1751 Calculate how much data we're going to send in this packet, also
1752 work out any sign/seal padding length.
1753 ********************************************************************/
1755 static uint32
calculate_data_len_tosend(struct rpc_pipe_client
*cli
,
1759 uint32
*p_ss_padding
)
1761 uint32 data_space
, data_len
;
1764 if ((data_left
> 0) && (sys_random() % 2)) {
1765 data_left
= MAX(data_left
/2, 1);
1769 switch (cli
->auth
->auth_level
) {
1770 case DCERPC_AUTH_LEVEL_NONE
:
1771 case DCERPC_AUTH_LEVEL_CONNECT
:
1772 data_space
= cli
->max_xmit_frag
- DCERPC_REQUEST_LENGTH
;
1773 data_len
= MIN(data_space
, data_left
);
1776 *p_frag_len
= DCERPC_REQUEST_LENGTH
+ data_len
;
1779 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1780 case DCERPC_AUTH_LEVEL_PRIVACY
:
1781 /* Treat the same for all authenticated rpc requests. */
1782 switch(cli
->auth
->auth_type
) {
1783 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1784 case PIPE_AUTH_TYPE_NTLMSSP
:
1785 *p_auth_len
= NTLMSSP_SIG_SIZE
;
1787 case PIPE_AUTH_TYPE_SCHANNEL
:
1788 *p_auth_len
= NL_AUTH_SIGNATURE_SIZE
;
1791 smb_panic("bad auth type");
1795 data_space
= cli
->max_xmit_frag
1796 - DCERPC_REQUEST_LENGTH
1797 - DCERPC_AUTH_TRAILER_LENGTH
1800 data_len
= MIN(data_space
, data_left
);
1802 if (data_len
% CLIENT_NDR_PADDING_SIZE
) {
1803 *p_ss_padding
= CLIENT_NDR_PADDING_SIZE
- (data_len
% CLIENT_NDR_PADDING_SIZE
);
1805 *p_frag_len
= DCERPC_REQUEST_LENGTH
1806 + data_len
+ *p_ss_padding
1807 + DCERPC_AUTH_TRAILER_LENGTH
1812 smb_panic("bad auth level");
1818 /*******************************************************************
1820 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1821 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1822 and deals with signing/sealing details.
1823 ********************************************************************/
1825 struct rpc_api_pipe_req_state
{
1826 struct event_context
*ev
;
1827 struct rpc_pipe_client
*cli
;
1830 DATA_BLOB
*req_data
;
1831 uint32_t req_data_sent
;
1833 DATA_BLOB reply_pdu
;
1836 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
1837 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
1838 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1839 bool *is_last_frag
);
1841 struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
1842 struct event_context
*ev
,
1843 struct rpc_pipe_client
*cli
,
1845 DATA_BLOB
*req_data
)
1847 struct tevent_req
*req
, *subreq
;
1848 struct rpc_api_pipe_req_state
*state
;
1852 req
= tevent_req_create(mem_ctx
, &state
,
1853 struct rpc_api_pipe_req_state
);
1859 state
->op_num
= op_num
;
1860 state
->req_data
= req_data
;
1861 state
->req_data_sent
= 0;
1862 state
->call_id
= get_rpc_call_id();
1863 state
->reply_pdu
= data_blob_null
;
1864 state
->rpc_out
= data_blob_null
;
1866 if (cli
->max_xmit_frag
< DCERPC_REQUEST_LENGTH
1867 + RPC_MAX_SIGN_SIZE
) {
1868 /* Server is screwed up ! */
1869 status
= NT_STATUS_INVALID_PARAMETER
;
1873 status
= prepare_next_frag(state
, &is_last_frag
);
1874 if (!NT_STATUS_IS_OK(status
)) {
1879 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
1881 DCERPC_PKT_RESPONSE
);
1882 if (subreq
== NULL
) {
1885 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1887 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
1888 state
->rpc_out
.data
,
1889 state
->rpc_out
.length
);
1890 if (subreq
== NULL
) {
1893 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1899 tevent_req_nterror(req
, status
);
1900 return tevent_req_post(req
, ev
);
1906 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1909 uint32_t data_sent_thistime
;
1913 uint32_t ss_padding
;
1915 char pad
[8] = { 0, };
1917 union dcerpc_payload u
;
1919 data_left
= state
->req_data
->length
- state
->req_data_sent
;
1921 data_sent_thistime
= calculate_data_len_tosend(
1922 state
->cli
, data_left
, &frag_len
, &auth_len
, &ss_padding
);
1924 if (state
->req_data_sent
== 0) {
1925 flags
= DCERPC_PFC_FLAG_FIRST
;
1928 if (data_sent_thistime
== data_left
) {
1929 flags
|= DCERPC_PFC_FLAG_LAST
;
1932 data_blob_free(&state
->rpc_out
);
1934 ZERO_STRUCT(u
.request
);
1936 u
.request
.alloc_hint
= state
->req_data
->length
;
1937 u
.request
.context_id
= 0;
1938 u
.request
.opnum
= state
->op_num
;
1940 status
= dcerpc_push_ncacn_packet(state
,
1947 if (!NT_STATUS_IS_OK(status
)) {
1951 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1952 * compute it right for requests */
1953 dcerpc_set_frag_length(&state
->rpc_out
, frag_len
);
1955 /* Copy in the data, plus any ss padding. */
1956 if (!data_blob_append(NULL
, &state
->rpc_out
,
1957 state
->req_data
->data
+ state
->req_data_sent
,
1958 data_sent_thistime
)) {
1959 return NT_STATUS_NO_MEMORY
;
1963 /* Copy the sign/seal padding data. */
1964 if (!data_blob_append(NULL
, &state
->rpc_out
,
1966 return NT_STATUS_NO_MEMORY
;
1970 /* Generate any auth sign/seal and add the auth footer. */
1971 switch (state
->cli
->auth
->auth_type
) {
1972 case PIPE_AUTH_TYPE_NONE
:
1973 status
= NT_STATUS_OK
;
1975 case PIPE_AUTH_TYPE_NTLMSSP
:
1976 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1977 status
= add_ntlmssp_auth_footer(state
->cli
, ss_padding
,
1980 case PIPE_AUTH_TYPE_SCHANNEL
:
1981 status
= add_schannel_auth_footer(state
->cli
, ss_padding
,
1985 status
= NT_STATUS_INVALID_PARAMETER
;
1989 state
->req_data_sent
+= data_sent_thistime
;
1990 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
1995 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
1997 struct tevent_req
*req
= tevent_req_callback_data(
1998 subreq
, struct tevent_req
);
1999 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2000 req
, struct rpc_api_pipe_req_state
);
2004 status
= rpc_write_recv(subreq
);
2005 TALLOC_FREE(subreq
);
2006 if (!NT_STATUS_IS_OK(status
)) {
2007 tevent_req_nterror(req
, status
);
2011 status
= prepare_next_frag(state
, &is_last_frag
);
2012 if (!NT_STATUS_IS_OK(status
)) {
2013 tevent_req_nterror(req
, status
);
2018 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2020 DCERPC_PKT_RESPONSE
);
2021 if (tevent_req_nomem(subreq
, req
)) {
2024 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
2026 subreq
= rpc_write_send(state
, state
->ev
,
2027 state
->cli
->transport
,
2028 state
->rpc_out
.data
,
2029 state
->rpc_out
.length
);
2030 if (tevent_req_nomem(subreq
, req
)) {
2033 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
2038 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
2040 struct tevent_req
*req
= tevent_req_callback_data(
2041 subreq
, struct tevent_req
);
2042 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2043 req
, struct rpc_api_pipe_req_state
);
2046 status
= rpc_api_pipe_recv(subreq
, state
, NULL
, &state
->reply_pdu
);
2047 TALLOC_FREE(subreq
);
2048 if (!NT_STATUS_IS_OK(status
)) {
2049 tevent_req_nterror(req
, status
);
2052 tevent_req_done(req
);
2055 NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2056 DATA_BLOB
*reply_pdu
)
2058 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2059 req
, struct rpc_api_pipe_req_state
);
2062 if (tevent_req_is_nterror(req
, &status
)) {
2064 * We always have to initialize to reply pdu, even if there is
2065 * none. The rpccli_* caller routines expect this.
2067 *reply_pdu
= data_blob_null
;
2071 /* return data to caller and assign it ownership of memory */
2072 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
2073 reply_pdu
->length
= state
->reply_pdu
.length
;
2074 state
->reply_pdu
.length
= 0;
2076 return NT_STATUS_OK
;
2080 /****************************************************************************
2081 Set the handle state.
2082 ****************************************************************************/
2084 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client
*cli
,
2085 const char *pipe_name
, uint16 device_state
)
2087 bool state_set
= False
;
2089 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
2090 char *rparam
= NULL
;
2092 uint32 rparam_len
, rdata_len
;
2094 if (pipe_name
== NULL
)
2097 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2098 cli
->fnum
, pipe_name
, device_state
));
2100 /* create parameters: device state */
2101 SSVAL(param
, 0, device_state
);
2103 /* create setup parameters. */
2105 setup
[1] = cli
->fnum
; /* pipe file handle. got this from an SMBOpenX. */
2107 /* send the data on \PIPE\ */
2108 if (cli_api_pipe(cli
->cli
, "\\PIPE\\",
2109 setup
, 2, 0, /* setup, length, max */
2110 param
, 2, 0, /* param, length, max */
2111 NULL
, 0, 1024, /* data, length, max */
2112 &rparam
, &rparam_len
, /* return param, length */
2113 &rdata
, &rdata_len
)) /* return data, length */
2115 DEBUG(5, ("Set Handle state: return OK\n"));
2126 /****************************************************************************
2127 Check the rpc bind acknowledge response.
2128 ****************************************************************************/
2130 static bool check_bind_response(const struct dcerpc_bind_ack
*r
,
2131 const struct ndr_syntax_id
*transfer
)
2133 struct dcerpc_ack_ctx ctx
;
2135 if (r
->secondary_address_size
== 0) {
2136 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2139 if (r
->num_results
< 1 || !r
->ctx_list
) {
2143 ctx
= r
->ctx_list
[0];
2145 /* check the transfer syntax */
2146 if ((ctx
.syntax
.if_version
!= transfer
->if_version
) ||
2147 (memcmp(&ctx
.syntax
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
2148 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2152 if (r
->num_results
!= 0x1 || ctx
.result
!= 0) {
2153 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2154 r
->num_results
, ctx
.reason
));
2157 DEBUG(5,("check_bind_response: accepted!\n"));
2161 /*******************************************************************
2162 Creates a DCE/RPC bind authentication response.
2163 This is the packet that is sent back to the server once we
2164 have received a BIND-ACK, to finish the third leg of
2165 the authentication handshake.
2166 ********************************************************************/
2168 static NTSTATUS
create_rpc_bind_auth3(TALLOC_CTX
*mem_ctx
,
2169 struct rpc_pipe_client
*cli
,
2171 enum pipe_auth_type auth_type
,
2172 enum dcerpc_AuthLevel auth_level
,
2173 DATA_BLOB
*pauth_blob
,
2177 union dcerpc_payload u
;
2181 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
2182 map_pipe_auth_type_to_rpc_auth_type(auth_type
),
2184 0, /* auth_pad_length */
2185 1, /* auth_context_id */
2187 &u
.auth3
.auth_info
);
2188 if (!NT_STATUS_IS_OK(status
)) {
2192 status
= dcerpc_push_ncacn_packet(mem_ctx
,
2194 DCERPC_PFC_FLAG_FIRST
|
2195 DCERPC_PFC_FLAG_LAST
,
2200 data_blob_free(&u
.auth3
.auth_info
);
2201 if (!NT_STATUS_IS_OK(status
)) {
2202 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2206 return NT_STATUS_OK
;
2209 /*******************************************************************
2210 Creates a DCE/RPC bind alter context authentication request which
2211 may contain a spnego auth blobl
2212 ********************************************************************/
2214 static NTSTATUS
create_rpc_alter_context(TALLOC_CTX
*mem_ctx
,
2216 const struct ndr_syntax_id
*abstract
,
2217 const struct ndr_syntax_id
*transfer
,
2218 enum dcerpc_AuthLevel auth_level
,
2219 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
2222 DATA_BLOB auth_info
;
2225 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
2226 DCERPC_AUTH_TYPE_SPNEGO
,
2228 0, /* auth_pad_length */
2229 1, /* auth_context_id */
2232 if (!NT_STATUS_IS_OK(status
)) {
2236 status
= create_bind_or_alt_ctx_internal(mem_ctx
,
2243 data_blob_free(&auth_info
);
2247 /****************************************************************************
2249 ****************************************************************************/
2251 struct rpc_pipe_bind_state
{
2252 struct event_context
*ev
;
2253 struct rpc_pipe_client
*cli
;
2255 uint32_t rpc_call_id
;
2258 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
2259 static NTSTATUS
rpc_finish_auth3_bind_send(struct tevent_req
*req
,
2260 struct rpc_pipe_bind_state
*state
,
2261 struct ncacn_packet
*r
);
2262 static void rpc_bind_auth3_write_done(struct tevent_req
*subreq
);
2263 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req
*req
,
2264 struct rpc_pipe_bind_state
*state
,
2265 struct ncacn_packet
*r
,
2266 DATA_BLOB
*reply_pdu
);
2267 static void rpc_bind_ntlmssp_api_done(struct tevent_req
*subreq
);
2269 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
2270 struct event_context
*ev
,
2271 struct rpc_pipe_client
*cli
,
2272 struct pipe_auth_data
*auth
)
2274 struct tevent_req
*req
, *subreq
;
2275 struct rpc_pipe_bind_state
*state
;
2278 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
2283 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2284 rpccli_pipe_txt(talloc_tos(), cli
),
2285 (unsigned int)auth
->auth_type
,
2286 (unsigned int)auth
->auth_level
));
2290 state
->rpc_call_id
= get_rpc_call_id();
2291 state
->rpc_out
= data_blob_null
;
2293 cli
->auth
= talloc_move(cli
, &auth
);
2295 /* Marshall the outgoing data. */
2296 status
= create_rpc_bind_req(state
, cli
,
2298 &cli
->abstract_syntax
,
2299 &cli
->transfer_syntax
,
2300 cli
->auth
->auth_type
,
2301 cli
->auth
->auth_level
,
2304 if (!NT_STATUS_IS_OK(status
)) {
2308 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
2309 DCERPC_PKT_BIND_ACK
);
2310 if (subreq
== NULL
) {
2313 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2317 tevent_req_nterror(req
, status
);
2318 return tevent_req_post(req
, ev
);
2324 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
2326 struct tevent_req
*req
= tevent_req_callback_data(
2327 subreq
, struct tevent_req
);
2328 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2329 req
, struct rpc_pipe_bind_state
);
2330 DATA_BLOB reply_pdu
;
2331 struct ncacn_packet
*pkt
;
2334 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, &reply_pdu
);
2335 TALLOC_FREE(subreq
);
2336 if (!NT_STATUS_IS_OK(status
)) {
2337 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2338 rpccli_pipe_txt(talloc_tos(), state
->cli
),
2339 nt_errstr(status
)));
2340 tevent_req_nterror(req
, status
);
2344 if (!check_bind_response(&pkt
->u
.bind_ack
, &state
->cli
->transfer_syntax
)) {
2345 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2346 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2350 state
->cli
->max_xmit_frag
= pkt
->u
.bind_ack
.max_xmit_frag
;
2351 state
->cli
->max_recv_frag
= pkt
->u
.bind_ack
.max_recv_frag
;
2354 * For authenticated binds we may need to do 3 or 4 leg binds.
2357 switch(state
->cli
->auth
->auth_type
) {
2359 case PIPE_AUTH_TYPE_NONE
:
2360 case PIPE_AUTH_TYPE_SCHANNEL
:
2361 /* Bind complete. */
2362 tevent_req_done(req
);
2365 case PIPE_AUTH_TYPE_NTLMSSP
:
2366 /* Need to send AUTH3 packet - no reply. */
2367 status
= rpc_finish_auth3_bind_send(req
, state
, pkt
);
2368 if (!NT_STATUS_IS_OK(status
)) {
2369 tevent_req_nterror(req
, status
);
2373 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2374 /* Need to send alter context request and reply. */
2375 status
= rpc_finish_spnego_ntlmssp_bind_send(req
, state
, pkt
,
2377 if (!NT_STATUS_IS_OK(status
)) {
2378 tevent_req_nterror(req
, status
);
2382 case PIPE_AUTH_TYPE_KRB5
:
2386 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2387 (unsigned int)state
->cli
->auth
->auth_type
));
2388 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2392 static NTSTATUS
rpc_finish_auth3_bind_send(struct tevent_req
*req
,
2393 struct rpc_pipe_bind_state
*state
,
2394 struct ncacn_packet
*r
)
2396 DATA_BLOB client_reply
= data_blob_null
;
2397 struct dcerpc_auth auth
;
2398 struct tevent_req
*subreq
;
2401 if ((r
->auth_length
== 0)
2402 || (r
->frag_length
< DCERPC_AUTH_TRAILER_LENGTH
2403 + r
->auth_length
)) {
2404 return NT_STATUS_INVALID_PARAMETER
;
2407 status
= dcerpc_pull_dcerpc_auth(talloc_tos(),
2408 &r
->u
.bind_ack
.auth_info
,
2410 if (!NT_STATUS_IS_OK(status
)) {
2411 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2412 nt_errstr(status
)));
2416 /* TODO - check auth_type/auth_level match. */
2418 status
= auth_ntlmssp_update(state
->cli
->auth
->a_u
.auth_ntlmssp_state
,
2419 auth
.credentials
, &client_reply
);
2421 if (!NT_STATUS_IS_OK(status
)) {
2422 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2423 "blob failed: %s.\n", nt_errstr(status
)));
2427 data_blob_free(&state
->rpc_out
);
2429 status
= create_rpc_bind_auth3(state
,
2430 state
->cli
, state
->rpc_call_id
,
2431 state
->cli
->auth
->auth_type
,
2432 state
->cli
->auth
->auth_level
,
2433 &client_reply
, &state
->rpc_out
);
2434 data_blob_free(&client_reply
);
2436 if (!NT_STATUS_IS_OK(status
)) {
2440 subreq
= rpc_write_send(state
, state
->ev
, state
->cli
->transport
,
2441 state
->rpc_out
.data
, state
->rpc_out
.length
);
2442 if (subreq
== NULL
) {
2443 return NT_STATUS_NO_MEMORY
;
2445 tevent_req_set_callback(subreq
, rpc_bind_auth3_write_done
, req
);
2446 return NT_STATUS_OK
;
2449 static void rpc_bind_auth3_write_done(struct tevent_req
*subreq
)
2451 struct tevent_req
*req
= tevent_req_callback_data(
2452 subreq
, struct tevent_req
);
2455 status
= rpc_write_recv(subreq
);
2456 TALLOC_FREE(subreq
);
2457 if (!NT_STATUS_IS_OK(status
)) {
2458 tevent_req_nterror(req
, status
);
2461 tevent_req_done(req
);
2464 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req
*req
,
2465 struct rpc_pipe_bind_state
*state
,
2466 struct ncacn_packet
*r
,
2467 DATA_BLOB
*reply_pdu
)
2469 DATA_BLOB server_ntlm_response
= data_blob_null
;
2470 DATA_BLOB client_reply
= data_blob_null
;
2471 DATA_BLOB tmp_blob
= data_blob_null
;
2472 struct dcerpc_auth auth_info
;
2473 DATA_BLOB auth_blob
;
2474 struct tevent_req
*subreq
;
2477 if ((r
->auth_length
== 0)
2478 || (r
->frag_length
< DCERPC_AUTH_TRAILER_LENGTH
2479 + r
->auth_length
)) {
2480 return NT_STATUS_INVALID_PARAMETER
;
2483 /* Process the returned NTLMSSP blob first. */
2484 auth_blob
= data_blob_const(reply_pdu
->data
2486 - DCERPC_AUTH_TRAILER_LENGTH
2488 DCERPC_AUTH_TRAILER_LENGTH
2491 status
= dcerpc_pull_dcerpc_auth(state
, &auth_blob
, &auth_info
, false);
2492 if (!NT_STATUS_IS_OK(status
)) {
2493 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
2498 * The server might give us back two challenges - tmp_blob is for the
2501 if (!spnego_parse_challenge(state
, auth_info
.credentials
,
2502 &server_ntlm_response
, &tmp_blob
)) {
2503 data_blob_free(&server_ntlm_response
);
2504 data_blob_free(&tmp_blob
);
2505 return NT_STATUS_INVALID_PARAMETER
;
2508 /* We're finished with the server spnego response and the tmp_blob. */
2509 data_blob_free(&tmp_blob
);
2511 status
= auth_ntlmssp_update(state
->cli
->auth
->a_u
.auth_ntlmssp_state
,
2512 server_ntlm_response
, &client_reply
);
2514 /* Finished with the server_ntlm response */
2515 data_blob_free(&server_ntlm_response
);
2517 if (!NT_STATUS_IS_OK(status
)) {
2518 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2519 "using server blob failed.\n"));
2520 data_blob_free(&client_reply
);
2524 /* SPNEGO wrap the client reply. */
2525 tmp_blob
= spnego_gen_auth(state
, client_reply
);
2526 data_blob_free(&client_reply
);
2527 client_reply
= tmp_blob
;
2528 tmp_blob
= data_blob_null
;
2530 /* Now prepare the alter context pdu. */
2531 data_blob_free(&state
->rpc_out
);
2533 status
= create_rpc_alter_context(state
,
2535 &state
->cli
->abstract_syntax
,
2536 &state
->cli
->transfer_syntax
,
2537 state
->cli
->auth
->auth_level
,
2540 data_blob_free(&client_reply
);
2542 if (!NT_STATUS_IS_OK(status
)) {
2546 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2547 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
);
2548 if (subreq
== NULL
) {
2549 return NT_STATUS_NO_MEMORY
;
2551 tevent_req_set_callback(subreq
, rpc_bind_ntlmssp_api_done
, req
);
2552 return NT_STATUS_OK
;
2555 static void rpc_bind_ntlmssp_api_done(struct tevent_req
*subreq
)
2557 struct tevent_req
*req
= tevent_req_callback_data(
2558 subreq
, struct tevent_req
);
2559 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2560 req
, struct rpc_pipe_bind_state
);
2561 DATA_BLOB tmp_blob
= data_blob_null
;
2562 struct ncacn_packet
*pkt
;
2563 struct dcerpc_auth auth
;
2566 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, NULL
);
2567 TALLOC_FREE(subreq
);
2568 if (!NT_STATUS_IS_OK(status
)) {
2569 tevent_req_nterror(req
, status
);
2573 status
= dcerpc_pull_dcerpc_auth(pkt
,
2574 &pkt
->u
.alter_resp
.auth_info
,
2576 if (!NT_STATUS_IS_OK(status
)) {
2577 tevent_req_nterror(req
, status
);
2581 /* Check we got a valid auth response. */
2582 if (!spnego_parse_auth_response(talloc_tos(), auth
.credentials
,
2584 OID_NTLMSSP
, &tmp_blob
)) {
2585 data_blob_free(&tmp_blob
);
2586 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2590 data_blob_free(&tmp_blob
);
2592 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2593 "%s.\n", rpccli_pipe_txt(talloc_tos(), state
->cli
)));
2594 tevent_req_done(req
);
2597 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
2599 return tevent_req_simple_recv_ntstatus(req
);
2602 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2603 struct pipe_auth_data
*auth
)
2605 TALLOC_CTX
*frame
= talloc_stackframe();
2606 struct event_context
*ev
;
2607 struct tevent_req
*req
;
2608 NTSTATUS status
= NT_STATUS_OK
;
2610 ev
= event_context_init(frame
);
2612 status
= NT_STATUS_NO_MEMORY
;
2616 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
2618 status
= NT_STATUS_NO_MEMORY
;
2622 if (!tevent_req_poll(req
, ev
)) {
2623 status
= map_nt_error_from_unix(errno
);
2627 status
= rpc_pipe_bind_recv(req
);
2633 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2635 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
2636 unsigned int timeout
)
2640 if (rpc_cli
->transport
== NULL
) {
2641 return RPCCLI_DEFAULT_TIMEOUT
;
2644 if (rpc_cli
->transport
->set_timeout
== NULL
) {
2645 return RPCCLI_DEFAULT_TIMEOUT
;
2648 old
= rpc_cli
->transport
->set_timeout(rpc_cli
->transport
->priv
, timeout
);
2650 return RPCCLI_DEFAULT_TIMEOUT
;
2656 bool rpccli_is_connected(struct rpc_pipe_client
*rpc_cli
)
2658 if (rpc_cli
== NULL
) {
2662 if (rpc_cli
->transport
== NULL
) {
2666 return rpc_cli
->transport
->is_connected(rpc_cli
->transport
->priv
);
2669 bool rpccli_get_pwd_hash(struct rpc_pipe_client
*rpc_cli
, uint8_t nt_hash
[16])
2671 struct cli_state
*cli
;
2673 if ((rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_NTLMSSP
)
2674 || (rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
)) {
2675 memcpy(nt_hash
, auth_ntlmssp_get_nt_hash(rpc_cli
->auth
->a_u
.auth_ntlmssp_state
), 16);
2679 cli
= rpc_pipe_np_smb_conn(rpc_cli
);
2683 E_md4hash(cli
->password
? cli
->password
: "", nt_hash
);
2687 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
2688 struct pipe_auth_data
**presult
)
2690 struct pipe_auth_data
*result
;
2692 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2693 if (result
== NULL
) {
2694 return NT_STATUS_NO_MEMORY
;
2697 result
->auth_type
= PIPE_AUTH_TYPE_NONE
;
2698 result
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
2700 result
->user_name
= talloc_strdup(result
, "");
2701 result
->domain
= talloc_strdup(result
, "");
2702 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2703 TALLOC_FREE(result
);
2704 return NT_STATUS_NO_MEMORY
;
2708 return NT_STATUS_OK
;
2711 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data
*auth
)
2713 TALLOC_FREE(auth
->a_u
.auth_ntlmssp_state
);
2717 static NTSTATUS
rpccli_ntlmssp_bind_data(TALLOC_CTX
*mem_ctx
,
2718 enum pipe_auth_type auth_type
,
2719 enum dcerpc_AuthLevel auth_level
,
2721 const char *username
,
2722 const char *password
,
2723 struct pipe_auth_data
**presult
)
2725 struct pipe_auth_data
*result
;
2728 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2729 if (result
== NULL
) {
2730 return NT_STATUS_NO_MEMORY
;
2733 result
->auth_type
= auth_type
;
2734 result
->auth_level
= auth_level
;
2736 result
->user_name
= talloc_strdup(result
, username
);
2737 result
->domain
= talloc_strdup(result
, domain
);
2738 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2739 status
= NT_STATUS_NO_MEMORY
;
2743 status
= auth_ntlmssp_client_start(NULL
,
2746 lp_client_ntlmv2_auth(),
2747 &result
->a_u
.auth_ntlmssp_state
);
2748 if (!NT_STATUS_IS_OK(status
)) {
2752 talloc_set_destructor(result
, cli_auth_ntlmssp_data_destructor
);
2754 status
= auth_ntlmssp_set_username(result
->a_u
.auth_ntlmssp_state
,
2756 if (!NT_STATUS_IS_OK(status
)) {
2760 status
= auth_ntlmssp_set_domain(result
->a_u
.auth_ntlmssp_state
,
2762 if (!NT_STATUS_IS_OK(status
)) {
2766 status
= auth_ntlmssp_set_password(result
->a_u
.auth_ntlmssp_state
,
2768 if (!NT_STATUS_IS_OK(status
)) {
2773 * Turn off sign+seal to allow selected auth level to turn it back on.
2775 auth_ntlmssp_and_flags(result
->a_u
.auth_ntlmssp_state
,
2776 ~(NTLMSSP_NEGOTIATE_SIGN
|
2777 NTLMSSP_NEGOTIATE_SEAL
));
2779 if (auth_level
== DCERPC_AUTH_LEVEL_INTEGRITY
) {
2780 auth_ntlmssp_or_flags(result
->a_u
.auth_ntlmssp_state
,
2781 NTLMSSP_NEGOTIATE_SIGN
);
2782 } else if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
2783 auth_ntlmssp_or_flags(result
->a_u
.auth_ntlmssp_state
,
2784 NTLMSSP_NEGOTIATE_SEAL
|
2785 NTLMSSP_NEGOTIATE_SIGN
);
2789 return NT_STATUS_OK
;
2792 TALLOC_FREE(result
);
2796 NTSTATUS
rpccli_schannel_bind_data(TALLOC_CTX
*mem_ctx
, const char *domain
,
2797 enum dcerpc_AuthLevel auth_level
,
2798 struct netlogon_creds_CredentialState
*creds
,
2799 struct pipe_auth_data
**presult
)
2801 struct pipe_auth_data
*result
;
2803 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2804 if (result
== NULL
) {
2805 return NT_STATUS_NO_MEMORY
;
2808 result
->auth_type
= PIPE_AUTH_TYPE_SCHANNEL
;
2809 result
->auth_level
= auth_level
;
2811 result
->user_name
= talloc_strdup(result
, "");
2812 result
->domain
= talloc_strdup(result
, domain
);
2813 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2817 result
->a_u
.schannel_auth
= talloc(result
, struct schannel_state
);
2818 if (result
->a_u
.schannel_auth
== NULL
) {
2822 result
->a_u
.schannel_auth
->state
= SCHANNEL_STATE_START
;
2823 result
->a_u
.schannel_auth
->seq_num
= 0;
2824 result
->a_u
.schannel_auth
->initiator
= true;
2825 result
->a_u
.schannel_auth
->creds
= creds
;
2828 return NT_STATUS_OK
;
2831 TALLOC_FREE(result
);
2832 return NT_STATUS_NO_MEMORY
;
2836 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct
*auth
)
2838 data_blob_free(&auth
->session_key
);
2843 static NTSTATUS
rpccli_kerberos_bind_data(TALLOC_CTX
*mem_ctx
,
2844 enum dcerpc_AuthLevel auth_level
,
2845 const char *service_princ
,
2846 const char *username
,
2847 const char *password
,
2848 struct pipe_auth_data
**presult
)
2851 struct pipe_auth_data
*result
;
2853 if ((username
!= NULL
) && (password
!= NULL
)) {
2854 int ret
= kerberos_kinit_password(username
, password
, 0, NULL
);
2856 return NT_STATUS_ACCESS_DENIED
;
2860 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2861 if (result
== NULL
) {
2862 return NT_STATUS_NO_MEMORY
;
2865 result
->auth_type
= PIPE_AUTH_TYPE_KRB5
;
2866 result
->auth_level
= auth_level
;
2869 * Username / domain need fixing!
2871 result
->user_name
= talloc_strdup(result
, "");
2872 result
->domain
= talloc_strdup(result
, "");
2873 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2877 result
->a_u
.kerberos_auth
= TALLOC_ZERO_P(
2878 result
, struct kerberos_auth_struct
);
2879 if (result
->a_u
.kerberos_auth
== NULL
) {
2882 talloc_set_destructor(result
->a_u
.kerberos_auth
,
2883 cli_auth_kerberos_data_destructor
);
2885 result
->a_u
.kerberos_auth
->service_principal
= talloc_strdup(
2886 result
, service_princ
);
2887 if (result
->a_u
.kerberos_auth
->service_principal
== NULL
) {
2892 return NT_STATUS_OK
;
2895 TALLOC_FREE(result
);
2896 return NT_STATUS_NO_MEMORY
;
2898 return NT_STATUS_NOT_SUPPORTED
;
2903 * Create an rpc pipe client struct, connecting to a tcp port.
2905 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
2907 const struct ndr_syntax_id
*abstract_syntax
,
2908 struct rpc_pipe_client
**presult
)
2910 struct rpc_pipe_client
*result
;
2911 struct sockaddr_storage addr
;
2915 result
= TALLOC_ZERO_P(mem_ctx
, struct rpc_pipe_client
);
2916 if (result
== NULL
) {
2917 return NT_STATUS_NO_MEMORY
;
2920 result
->abstract_syntax
= *abstract_syntax
;
2921 result
->transfer_syntax
= ndr_transfer_syntax
;
2922 result
->dispatch
= cli_do_rpc_ndr
;
2923 result
->dispatch_send
= cli_do_rpc_ndr_send
;
2924 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
2926 result
->desthost
= talloc_strdup(result
, host
);
2927 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2928 result
, "\\\\%s", result
->desthost
);
2929 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2930 status
= NT_STATUS_NO_MEMORY
;
2934 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2935 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
2937 if (!resolve_name(host
, &addr
, 0, false)) {
2938 status
= NT_STATUS_NOT_FOUND
;
2942 status
= open_socket_out(&addr
, port
, 60, &fd
);
2943 if (!NT_STATUS_IS_OK(status
)) {
2946 set_socket_options(fd
, lp_socket_options());
2948 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
2949 if (!NT_STATUS_IS_OK(status
)) {
2954 result
->transport
->transport
= NCACN_IP_TCP
;
2957 return NT_STATUS_OK
;
2960 TALLOC_FREE(result
);
2965 * Determine the tcp port on which a dcerpc interface is listening
2966 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2969 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
2970 const struct ndr_syntax_id
*abstract_syntax
,
2974 struct rpc_pipe_client
*epm_pipe
= NULL
;
2975 struct pipe_auth_data
*auth
= NULL
;
2976 struct dcerpc_binding
*map_binding
= NULL
;
2977 struct dcerpc_binding
*res_binding
= NULL
;
2978 struct epm_twr_t
*map_tower
= NULL
;
2979 struct epm_twr_t
*res_towers
= NULL
;
2980 struct policy_handle
*entry_handle
= NULL
;
2981 uint32_t num_towers
= 0;
2982 uint32_t max_towers
= 1;
2983 struct epm_twr_p_t towers
;
2984 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2986 if (pport
== NULL
) {
2987 status
= NT_STATUS_INVALID_PARAMETER
;
2991 /* open the connection to the endpoint mapper */
2992 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, 135,
2993 &ndr_table_epmapper
.syntax_id
,
2996 if (!NT_STATUS_IS_OK(status
)) {
3000 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
3001 if (!NT_STATUS_IS_OK(status
)) {
3005 status
= rpc_pipe_bind(epm_pipe
, auth
);
3006 if (!NT_STATUS_IS_OK(status
)) {
3010 /* create tower for asking the epmapper */
3012 map_binding
= TALLOC_ZERO_P(tmp_ctx
, struct dcerpc_binding
);
3013 if (map_binding
== NULL
) {
3014 status
= NT_STATUS_NO_MEMORY
;
3018 map_binding
->transport
= NCACN_IP_TCP
;
3019 map_binding
->object
= *abstract_syntax
;
3020 map_binding
->host
= host
; /* needed? */
3021 map_binding
->endpoint
= "0"; /* correct? needed? */
3023 map_tower
= TALLOC_ZERO_P(tmp_ctx
, struct epm_twr_t
);
3024 if (map_tower
== NULL
) {
3025 status
= NT_STATUS_NO_MEMORY
;
3029 status
= dcerpc_binding_build_tower(tmp_ctx
, map_binding
,
3030 &(map_tower
->tower
));
3031 if (!NT_STATUS_IS_OK(status
)) {
3035 /* allocate further parameters for the epm_Map call */
3037 res_towers
= TALLOC_ARRAY(tmp_ctx
, struct epm_twr_t
, max_towers
);
3038 if (res_towers
== NULL
) {
3039 status
= NT_STATUS_NO_MEMORY
;
3042 towers
.twr
= res_towers
;
3044 entry_handle
= TALLOC_ZERO_P(tmp_ctx
, struct policy_handle
);
3045 if (entry_handle
== NULL
) {
3046 status
= NT_STATUS_NO_MEMORY
;
3050 /* ask the endpoint mapper for the port */
3052 status
= rpccli_epm_Map(epm_pipe
,
3054 CONST_DISCARD(struct GUID
*,
3055 &(abstract_syntax
->uuid
)),
3062 if (!NT_STATUS_IS_OK(status
)) {
3066 if (num_towers
!= 1) {
3067 status
= NT_STATUS_UNSUCCESSFUL
;
3071 /* extract the port from the answer */
3073 status
= dcerpc_binding_from_tower(tmp_ctx
,
3074 &(towers
.twr
->tower
),
3076 if (!NT_STATUS_IS_OK(status
)) {
3080 /* are further checks here necessary? */
3081 if (res_binding
->transport
!= NCACN_IP_TCP
) {
3082 status
= NT_STATUS_UNSUCCESSFUL
;
3086 *pport
= (uint16_t)atoi(res_binding
->endpoint
);
3089 TALLOC_FREE(tmp_ctx
);
3094 * Create a rpc pipe client struct, connecting to a host via tcp.
3095 * The port is determined by asking the endpoint mapper on the given
3098 NTSTATUS
rpc_pipe_open_tcp(TALLOC_CTX
*mem_ctx
, const char *host
,
3099 const struct ndr_syntax_id
*abstract_syntax
,
3100 struct rpc_pipe_client
**presult
)
3105 status
= rpc_pipe_get_tcp_port(host
, abstract_syntax
, &port
);
3106 if (!NT_STATUS_IS_OK(status
)) {
3110 return rpc_pipe_open_tcp_port(mem_ctx
, host
, port
,
3111 abstract_syntax
, presult
);
3114 /********************************************************************
3115 Create a rpc pipe client struct, connecting to a unix domain socket
3116 ********************************************************************/
3117 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
, const char *socket_path
,
3118 const struct ndr_syntax_id
*abstract_syntax
,
3119 struct rpc_pipe_client
**presult
)
3121 struct rpc_pipe_client
*result
;
3122 struct sockaddr_un addr
;
3126 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
3127 if (result
== NULL
) {
3128 return NT_STATUS_NO_MEMORY
;
3131 result
->abstract_syntax
= *abstract_syntax
;
3132 result
->transfer_syntax
= ndr_transfer_syntax
;
3133 result
->dispatch
= cli_do_rpc_ndr
;
3134 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3135 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3137 result
->desthost
= get_myname(result
);
3138 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3139 result
, "\\\\%s", result
->desthost
);
3140 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3141 status
= NT_STATUS_NO_MEMORY
;
3145 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3146 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3148 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3150 status
= map_nt_error_from_unix(errno
);
3155 addr
.sun_family
= AF_UNIX
;
3156 strncpy(addr
.sun_path
, socket_path
, sizeof(addr
.sun_path
));
3158 if (sys_connect(fd
, (struct sockaddr
*)(void *)&addr
) == -1) {
3159 DEBUG(0, ("connect(%s) failed: %s\n", socket_path
,
3162 return map_nt_error_from_unix(errno
);
3165 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
3166 if (!NT_STATUS_IS_OK(status
)) {
3171 result
->transport
->transport
= NCALRPC
;
3174 return NT_STATUS_OK
;
3177 TALLOC_FREE(result
);
3181 struct rpc_pipe_client_np_ref
{
3182 struct cli_state
*cli
;
3183 struct rpc_pipe_client
*pipe
;
3186 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref
*np_ref
)
3188 DLIST_REMOVE(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3192 /****************************************************************************
3193 Open a named pipe over SMB to a remote server.
3195 * CAVEAT CALLER OF THIS FUNCTION:
3196 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3197 * so be sure that this function is called AFTER any structure (vs pointer)
3198 * assignment of the cli. In particular, libsmbclient does structure
3199 * assignments of cli, which invalidates the data in the returned
3200 * rpc_pipe_client if this function is called before the structure assignment
3203 ****************************************************************************/
3205 static NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
3206 const struct ndr_syntax_id
*abstract_syntax
,
3207 struct rpc_pipe_client
**presult
)
3209 struct rpc_pipe_client
*result
;
3211 struct rpc_pipe_client_np_ref
*np_ref
;
3213 /* sanity check to protect against crashes */
3216 return NT_STATUS_INVALID_HANDLE
;
3219 result
= TALLOC_ZERO_P(NULL
, struct rpc_pipe_client
);
3220 if (result
== NULL
) {
3221 return NT_STATUS_NO_MEMORY
;
3224 result
->abstract_syntax
= *abstract_syntax
;
3225 result
->transfer_syntax
= ndr_transfer_syntax
;
3226 result
->dispatch
= cli_do_rpc_ndr
;
3227 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3228 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3229 result
->desthost
= talloc_strdup(result
, cli
->desthost
);
3230 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3231 result
, "\\\\%s", result
->desthost
);
3233 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3234 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3236 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3237 TALLOC_FREE(result
);
3238 return NT_STATUS_NO_MEMORY
;
3241 status
= rpc_transport_np_init(result
, cli
, abstract_syntax
,
3242 &result
->transport
);
3243 if (!NT_STATUS_IS_OK(status
)) {
3244 TALLOC_FREE(result
);
3248 result
->transport
->transport
= NCACN_NP
;
3250 np_ref
= talloc(result
->transport
, struct rpc_pipe_client_np_ref
);
3251 if (np_ref
== NULL
) {
3252 TALLOC_FREE(result
);
3253 return NT_STATUS_NO_MEMORY
;
3256 np_ref
->pipe
= result
;
3258 DLIST_ADD(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3259 talloc_set_destructor(np_ref
, rpc_pipe_client_np_ref_destructor
);
3262 return NT_STATUS_OK
;
3265 NTSTATUS
rpc_pipe_open_local(TALLOC_CTX
*mem_ctx
,
3266 struct rpc_cli_smbd_conn
*conn
,
3267 const struct ndr_syntax_id
*syntax
,
3268 struct rpc_pipe_client
**presult
)
3270 struct rpc_pipe_client
*result
;
3271 struct pipe_auth_data
*auth
;
3274 result
= talloc(mem_ctx
, struct rpc_pipe_client
);
3275 if (result
== NULL
) {
3276 return NT_STATUS_NO_MEMORY
;
3278 result
->abstract_syntax
= *syntax
;
3279 result
->transfer_syntax
= ndr_transfer_syntax
;
3280 result
->dispatch
= cli_do_rpc_ndr
;
3281 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3282 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3283 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3284 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3286 result
->desthost
= talloc_strdup(result
, global_myname());
3287 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3288 result
, "\\\\%s", global_myname());
3289 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3290 TALLOC_FREE(result
);
3291 return NT_STATUS_NO_MEMORY
;
3294 status
= rpc_transport_smbd_init(result
, conn
, syntax
,
3295 &result
->transport
);
3296 if (!NT_STATUS_IS_OK(status
)) {
3297 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3298 nt_errstr(status
)));
3299 TALLOC_FREE(result
);
3303 status
= rpccli_anon_bind_data(result
, &auth
);
3304 if (!NT_STATUS_IS_OK(status
)) {
3305 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3306 nt_errstr(status
)));
3307 TALLOC_FREE(result
);
3311 status
= rpc_pipe_bind(result
, auth
);
3312 if (!NT_STATUS_IS_OK(status
)) {
3313 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status
)));
3314 TALLOC_FREE(result
);
3318 result
->transport
->transport
= NCACN_INTERNAL
;
3321 return NT_STATUS_OK
;
3324 /****************************************************************************
3325 Open a pipe to a remote server.
3326 ****************************************************************************/
3328 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3329 enum dcerpc_transport_t transport
,
3330 const struct ndr_syntax_id
*interface
,
3331 struct rpc_pipe_client
**presult
)
3333 switch (transport
) {
3335 return rpc_pipe_open_tcp(NULL
, cli
->desthost
, interface
,
3338 return rpc_pipe_open_np(cli
, interface
, presult
);
3340 return NT_STATUS_NOT_IMPLEMENTED
;
3344 /****************************************************************************
3345 Open a named pipe to an SMB server and bind anonymously.
3346 ****************************************************************************/
3348 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
3349 enum dcerpc_transport_t transport
,
3350 const struct ndr_syntax_id
*interface
,
3351 struct rpc_pipe_client
**presult
)
3353 struct rpc_pipe_client
*result
;
3354 struct pipe_auth_data
*auth
;
3357 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3358 if (!NT_STATUS_IS_OK(status
)) {
3362 status
= rpccli_anon_bind_data(result
, &auth
);
3363 if (!NT_STATUS_IS_OK(status
)) {
3364 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3365 nt_errstr(status
)));
3366 TALLOC_FREE(result
);
3371 * This is a bit of an abstraction violation due to the fact that an
3372 * anonymous bind on an authenticated SMB inherits the user/domain
3373 * from the enclosing SMB creds
3376 TALLOC_FREE(auth
->user_name
);
3377 TALLOC_FREE(auth
->domain
);
3379 auth
->user_name
= talloc_strdup(auth
, cli
->user_name
);
3380 auth
->domain
= talloc_strdup(auth
, cli
->domain
);
3381 auth
->user_session_key
= data_blob_talloc(auth
,
3382 cli
->user_session_key
.data
,
3383 cli
->user_session_key
.length
);
3385 if ((auth
->user_name
== NULL
) || (auth
->domain
== NULL
)) {
3386 TALLOC_FREE(result
);
3387 return NT_STATUS_NO_MEMORY
;
3390 status
= rpc_pipe_bind(result
, auth
);
3391 if (!NT_STATUS_IS_OK(status
)) {
3393 if (ndr_syntax_id_equal(interface
,
3394 &ndr_table_dssetup
.syntax_id
)) {
3395 /* non AD domains just don't have this pipe, avoid
3396 * level 0 statement in that case - gd */
3399 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3400 "%s failed with error %s\n",
3401 get_pipe_name_from_syntax(talloc_tos(), interface
),
3402 nt_errstr(status
) ));
3403 TALLOC_FREE(result
);
3407 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3408 "%s and bound anonymously.\n",
3409 get_pipe_name_from_syntax(talloc_tos(), interface
),
3413 return NT_STATUS_OK
;
3416 /****************************************************************************
3417 ****************************************************************************/
3419 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
3420 const struct ndr_syntax_id
*interface
,
3421 struct rpc_pipe_client
**presult
)
3423 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
3424 interface
, presult
);
3427 /****************************************************************************
3428 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3429 ****************************************************************************/
3431 static NTSTATUS
cli_rpc_pipe_open_ntlmssp_internal(struct cli_state
*cli
,
3432 const struct ndr_syntax_id
*interface
,
3433 enum dcerpc_transport_t transport
,
3434 enum pipe_auth_type auth_type
,
3435 enum dcerpc_AuthLevel auth_level
,
3437 const char *username
,
3438 const char *password
,
3439 struct rpc_pipe_client
**presult
)
3441 struct rpc_pipe_client
*result
;
3442 struct pipe_auth_data
*auth
;
3445 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3446 if (!NT_STATUS_IS_OK(status
)) {
3450 status
= rpccli_ntlmssp_bind_data(
3451 result
, auth_type
, auth_level
, domain
, username
,
3453 if (!NT_STATUS_IS_OK(status
)) {
3454 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3455 nt_errstr(status
)));
3459 status
= rpc_pipe_bind(result
, auth
);
3460 if (!NT_STATUS_IS_OK(status
)) {
3461 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3462 nt_errstr(status
) ));
3466 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3467 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3468 get_pipe_name_from_syntax(talloc_tos(), interface
),
3469 cli
->desthost
, domain
, username
));
3472 return NT_STATUS_OK
;
3476 TALLOC_FREE(result
);
3480 /****************************************************************************
3482 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3483 ****************************************************************************/
3485 NTSTATUS
cli_rpc_pipe_open_ntlmssp(struct cli_state
*cli
,
3486 const struct ndr_syntax_id
*interface
,
3487 enum dcerpc_transport_t transport
,
3488 enum dcerpc_AuthLevel auth_level
,
3490 const char *username
,
3491 const char *password
,
3492 struct rpc_pipe_client
**presult
)
3494 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3497 PIPE_AUTH_TYPE_NTLMSSP
,
3505 /****************************************************************************
3507 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3508 ****************************************************************************/
3510 NTSTATUS
cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state
*cli
,
3511 const struct ndr_syntax_id
*interface
,
3512 enum dcerpc_transport_t transport
,
3513 enum dcerpc_AuthLevel auth_level
,
3515 const char *username
,
3516 const char *password
,
3517 struct rpc_pipe_client
**presult
)
3519 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3522 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
,
3530 /****************************************************************************
3531 Get a the schannel session key out of an already opened netlogon pipe.
3532 ****************************************************************************/
3533 static NTSTATUS
get_schannel_session_key_common(struct rpc_pipe_client
*netlogon_pipe
,
3534 struct cli_state
*cli
,
3538 enum netr_SchannelType sec_chan_type
= 0;
3539 unsigned char machine_pwd
[16];
3540 const char *machine_account
;
3543 /* Get the machine account credentials from secrets.tdb. */
3544 if (!get_trust_pw_hash(domain
, machine_pwd
, &machine_account
,
3547 DEBUG(0, ("get_schannel_session_key: could not fetch "
3548 "trust account password for domain '%s'\n",
3550 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3553 status
= rpccli_netlogon_setup_creds(netlogon_pipe
,
3554 cli
->desthost
, /* server name */
3555 domain
, /* domain */
3556 global_myname(), /* client name */
3557 machine_account
, /* machine account name */
3562 if (!NT_STATUS_IS_OK(status
)) {
3563 DEBUG(3, ("get_schannel_session_key_common: "
3564 "rpccli_netlogon_setup_creds failed with result %s "
3565 "to server %s, domain %s, machine account %s.\n",
3566 nt_errstr(status
), cli
->desthost
, domain
,
3571 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
3572 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3574 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3577 return NT_STATUS_OK
;;
3580 /****************************************************************************
3581 Open a netlogon pipe and get the schannel session key.
3582 Now exposed to external callers.
3583 ****************************************************************************/
3586 NTSTATUS
get_schannel_session_key(struct cli_state
*cli
,
3589 struct rpc_pipe_client
**presult
)
3591 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3594 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
.syntax_id
,
3596 if (!NT_STATUS_IS_OK(status
)) {
3600 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
3602 if (!NT_STATUS_IS_OK(status
)) {
3603 TALLOC_FREE(netlogon_pipe
);
3607 *presult
= netlogon_pipe
;
3608 return NT_STATUS_OK
;
3611 /****************************************************************************
3613 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3614 using session_key. sign and seal.
3616 The *pdc will be stolen onto this new pipe
3617 ****************************************************************************/
3619 NTSTATUS
cli_rpc_pipe_open_schannel_with_key(struct cli_state
*cli
,
3620 const struct ndr_syntax_id
*interface
,
3621 enum dcerpc_transport_t transport
,
3622 enum dcerpc_AuthLevel auth_level
,
3624 struct netlogon_creds_CredentialState
**pdc
,
3625 struct rpc_pipe_client
**presult
)
3627 struct rpc_pipe_client
*result
;
3628 struct pipe_auth_data
*auth
;
3631 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3632 if (!NT_STATUS_IS_OK(status
)) {
3636 status
= rpccli_schannel_bind_data(result
, domain
, auth_level
,
3638 if (!NT_STATUS_IS_OK(status
)) {
3639 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3640 nt_errstr(status
)));
3641 TALLOC_FREE(result
);
3645 status
= rpc_pipe_bind(result
, auth
);
3646 if (!NT_STATUS_IS_OK(status
)) {
3647 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3648 "cli_rpc_pipe_bind failed with error %s\n",
3649 nt_errstr(status
) ));
3650 TALLOC_FREE(result
);
3655 * The credentials on a new netlogon pipe are the ones we are passed
3656 * in - reference them in
3658 result
->dc
= talloc_move(result
, pdc
);
3660 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3661 "for domain %s and bound using schannel.\n",
3662 get_pipe_name_from_syntax(talloc_tos(), interface
),
3663 cli
->desthost
, domain
));
3666 return NT_STATUS_OK
;
3669 /****************************************************************************
3670 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3671 Fetch the session key ourselves using a temporary netlogon pipe. This
3672 version uses an ntlmssp auth bound netlogon pipe to get the key.
3673 ****************************************************************************/
3675 static NTSTATUS
get_schannel_session_key_auth_ntlmssp(struct cli_state
*cli
,
3677 const char *username
,
3678 const char *password
,
3680 struct rpc_pipe_client
**presult
)
3682 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3685 status
= cli_rpc_pipe_open_spnego_ntlmssp(
3686 cli
, &ndr_table_netlogon
.syntax_id
, NCACN_NP
,
3687 DCERPC_AUTH_LEVEL_PRIVACY
,
3688 domain
, username
, password
, &netlogon_pipe
);
3689 if (!NT_STATUS_IS_OK(status
)) {
3693 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
3695 if (!NT_STATUS_IS_OK(status
)) {
3696 TALLOC_FREE(netlogon_pipe
);
3700 *presult
= netlogon_pipe
;
3701 return NT_STATUS_OK
;
3704 /****************************************************************************
3705 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3706 Fetch the session key ourselves using a temporary netlogon pipe. This version
3707 uses an ntlmssp bind to get the session key.
3708 ****************************************************************************/
3710 NTSTATUS
cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
*cli
,
3711 const struct ndr_syntax_id
*interface
,
3712 enum dcerpc_transport_t transport
,
3713 enum dcerpc_AuthLevel auth_level
,
3715 const char *username
,
3716 const char *password
,
3717 struct rpc_pipe_client
**presult
)
3719 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
3720 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3721 struct rpc_pipe_client
*result
= NULL
;
3724 status
= get_schannel_session_key_auth_ntlmssp(
3725 cli
, domain
, username
, password
, &neg_flags
, &netlogon_pipe
);
3726 if (!NT_STATUS_IS_OK(status
)) {
3727 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3728 "key from server %s for domain %s.\n",
3729 cli
->desthost
, domain
));
3733 status
= cli_rpc_pipe_open_schannel_with_key(
3734 cli
, interface
, transport
, auth_level
, domain
, &netlogon_pipe
->dc
,
3737 /* Now we've bound using the session key we can close the netlog pipe. */
3738 TALLOC_FREE(netlogon_pipe
);
3740 if (NT_STATUS_IS_OK(status
)) {
3746 /****************************************************************************
3747 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3748 Fetch the session key ourselves using a temporary netlogon pipe.
3749 ****************************************************************************/
3751 NTSTATUS
cli_rpc_pipe_open_schannel(struct cli_state
*cli
,
3752 const struct ndr_syntax_id
*interface
,
3753 enum dcerpc_transport_t transport
,
3754 enum dcerpc_AuthLevel auth_level
,
3756 struct rpc_pipe_client
**presult
)
3758 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
3759 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3760 struct rpc_pipe_client
*result
= NULL
;
3763 status
= get_schannel_session_key(cli
, domain
, &neg_flags
,
3765 if (!NT_STATUS_IS_OK(status
)) {
3766 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3767 "key from server %s for domain %s.\n",
3768 cli
->desthost
, domain
));
3772 status
= cli_rpc_pipe_open_schannel_with_key(
3773 cli
, interface
, transport
, auth_level
, domain
, &netlogon_pipe
->dc
,
3776 /* Now we've bound using the session key we can close the netlog pipe. */
3777 TALLOC_FREE(netlogon_pipe
);
3779 if (NT_STATUS_IS_OK(status
)) {
3786 /****************************************************************************
3787 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3788 The idea is this can be called with service_princ, username and password all
3789 NULL so long as the caller has a TGT.
3790 ****************************************************************************/
3792 NTSTATUS
cli_rpc_pipe_open_krb5(struct cli_state
*cli
,
3793 const struct ndr_syntax_id
*interface
,
3794 enum dcerpc_AuthLevel auth_level
,
3795 const char *service_princ
,
3796 const char *username
,
3797 const char *password
,
3798 struct rpc_pipe_client
**presult
)
3801 struct rpc_pipe_client
*result
;
3802 struct pipe_auth_data
*auth
;
3805 status
= cli_rpc_pipe_open(cli
, NCACN_NP
, interface
, &result
);
3806 if (!NT_STATUS_IS_OK(status
)) {
3810 status
= rpccli_kerberos_bind_data(result
, auth_level
, service_princ
,
3811 username
, password
, &auth
);
3812 if (!NT_STATUS_IS_OK(status
)) {
3813 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3814 nt_errstr(status
)));
3815 TALLOC_FREE(result
);
3819 status
= rpc_pipe_bind(result
, auth
);
3820 if (!NT_STATUS_IS_OK(status
)) {
3821 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3822 "with error %s\n", nt_errstr(status
)));
3823 TALLOC_FREE(result
);
3828 return NT_STATUS_OK
;
3830 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3831 return NT_STATUS_NOT_IMPLEMENTED
;
3835 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
3836 struct rpc_pipe_client
*cli
,
3837 DATA_BLOB
*session_key
)
3839 struct pipe_auth_data
*a
= cli
->auth
;
3842 if (!session_key
|| !cli
) {
3843 return NT_STATUS_INVALID_PARAMETER
;
3847 return NT_STATUS_INVALID_PARAMETER
;
3850 switch (cli
->auth
->auth_type
) {
3851 case PIPE_AUTH_TYPE_SCHANNEL
:
3852 sk
= data_blob_const(a
->a_u
.schannel_auth
->creds
->session_key
,
3855 case PIPE_AUTH_TYPE_NTLMSSP
:
3856 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
3857 sk
= auth_ntlmssp_get_session_key(a
->a_u
.auth_ntlmssp_state
);
3859 case PIPE_AUTH_TYPE_KRB5
:
3860 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
3861 sk
= data_blob_const(a
->a_u
.kerberos_auth
->session_key
.data
,
3862 a
->a_u
.kerberos_auth
->session_key
.length
);
3864 case PIPE_AUTH_TYPE_NONE
:
3865 sk
= data_blob_const(a
->user_session_key
.data
,
3866 a
->user_session_key
.length
);
3869 return NT_STATUS_NO_USER_SESSION_KEY
;
3872 *session_key
= data_blob_dup_talloc(mem_ctx
, &sk
);
3873 return NT_STATUS_OK
;