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
->service_principal
, 0, &tkt
,
1292 &a
->session_key
, (uint32
)AP_OPTS_MUTUAL_REQUIRED
, NULL
, NULL
, NULL
);
1295 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1297 a
->service_principal
,
1298 error_message(ret
) ));
1300 data_blob_free(&tkt
);
1301 return NT_STATUS_INVALID_PARAMETER
;
1304 /* wrap that up in a nice GSS-API wrapping */
1305 tkt_wrapped
= spnego_gen_krb5_wrap(tkt
, TOK_ID_KRB_AP_REQ
);
1307 data_blob_free(&tkt
);
1309 status
= dcerpc_push_dcerpc_auth(cli
,
1310 DCERPC_AUTH_TYPE_KRB5
,
1312 0, /* auth_pad_length */
1313 1, /* auth_context_id */
1316 if (!NT_STATUS_IS_OK(status
)) {
1317 data_blob_free(&tkt_wrapped
);
1321 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1322 dump_data(5, tkt_wrapped
.data
, tkt_wrapped
.length
);
1324 return NT_STATUS_OK
;
1326 return NT_STATUS_INVALID_PARAMETER
;
1330 /*******************************************************************
1331 Creates SPNEGO NTLMSSP auth bind.
1332 ********************************************************************/
1334 static NTSTATUS
create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1335 enum dcerpc_AuthLevel auth_level
,
1336 DATA_BLOB
*auth_info
)
1339 DATA_BLOB null_blob
= data_blob_null
;
1340 DATA_BLOB request
= data_blob_null
;
1341 DATA_BLOB spnego_msg
= data_blob_null
;
1342 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1344 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1345 status
= auth_ntlmssp_update(cli
->auth
->a_u
.auth_ntlmssp_state
,
1349 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1350 data_blob_free(&request
);
1354 /* Wrap this in SPNEGO. */
1355 spnego_msg
= spnego_gen_negTokenInit(talloc_tos(), OIDs_ntlm
, &request
, NULL
);
1357 data_blob_free(&request
);
1359 status
= dcerpc_push_dcerpc_auth(cli
,
1360 DCERPC_AUTH_TYPE_SPNEGO
,
1362 0, /* auth_pad_length */
1363 1, /* auth_context_id */
1367 if (!NT_STATUS_IS_OK(status
)) {
1368 data_blob_free(&spnego_msg
);
1372 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1373 dump_data(5, spnego_msg
.data
, spnego_msg
.length
);
1374 data_blob_free(&spnego_msg
);
1376 return NT_STATUS_OK
;
1379 /*******************************************************************
1380 Creates NTLMSSP auth bind.
1381 ********************************************************************/
1383 static NTSTATUS
create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1384 enum dcerpc_AuthLevel auth_level
,
1385 DATA_BLOB
*auth_info
)
1388 DATA_BLOB null_blob
= data_blob_null
;
1389 DATA_BLOB request
= data_blob_null
;
1391 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1392 status
= auth_ntlmssp_update(cli
->auth
->a_u
.auth_ntlmssp_state
,
1396 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1397 data_blob_free(&request
);
1401 status
= dcerpc_push_dcerpc_auth(cli
,
1402 DCERPC_AUTH_TYPE_NTLMSSP
,
1404 0, /* auth_pad_length */
1405 1, /* auth_context_id */
1408 if (!NT_STATUS_IS_OK(status
)) {
1409 data_blob_free(&request
);
1413 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1414 dump_data(5, request
.data
, request
.length
);
1416 return NT_STATUS_OK
;
1419 /*******************************************************************
1420 Creates schannel auth bind.
1421 ********************************************************************/
1423 static NTSTATUS
create_schannel_auth_rpc_bind_req(struct rpc_pipe_client
*cli
,
1424 enum dcerpc_AuthLevel auth_level
,
1425 DATA_BLOB
*auth_info
)
1428 struct NL_AUTH_MESSAGE r
;
1429 DATA_BLOB schannel_blob
;
1431 /* Use lp_workgroup() if domain not specified */
1433 if (!cli
->auth
->domain
|| !cli
->auth
->domain
[0]) {
1434 cli
->auth
->domain
= talloc_strdup(cli
, lp_workgroup());
1435 if (cli
->auth
->domain
== NULL
) {
1436 return NT_STATUS_NO_MEMORY
;
1441 * Now marshall the data into the auth parse_struct.
1444 r
.MessageType
= NL_NEGOTIATE_REQUEST
;
1445 r
.Flags
= NL_FLAG_OEM_NETBIOS_DOMAIN_NAME
|
1446 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME
;
1447 r
.oem_netbios_domain
.a
= cli
->auth
->domain
;
1448 r
.oem_netbios_computer
.a
= global_myname();
1450 status
= dcerpc_push_schannel_bind(cli
, &r
, &schannel_blob
);
1451 if (!NT_STATUS_IS_OK(status
)) {
1455 status
= dcerpc_push_dcerpc_auth(cli
,
1456 DCERPC_AUTH_TYPE_SCHANNEL
,
1458 0, /* auth_pad_length */
1459 1, /* auth_context_id */
1462 if (!NT_STATUS_IS_OK(status
)) {
1466 return NT_STATUS_OK
;
1469 /*******************************************************************
1470 Creates the internals of a DCE/RPC bind request or alter context PDU.
1471 ********************************************************************/
1473 static NTSTATUS
create_bind_or_alt_ctx_internal(TALLOC_CTX
*mem_ctx
,
1474 enum dcerpc_pkt_type ptype
,
1476 const struct ndr_syntax_id
*abstract
,
1477 const struct ndr_syntax_id
*transfer
,
1478 const DATA_BLOB
*auth_info
,
1481 uint16 auth_len
= auth_info
->length
;
1483 union dcerpc_payload u
;
1484 struct dcerpc_ctx_list ctx_list
;
1487 auth_len
-= DCERPC_AUTH_TRAILER_LENGTH
;
1490 ctx_list
.context_id
= 0;
1491 ctx_list
.num_transfer_syntaxes
= 1;
1492 ctx_list
.abstract_syntax
= *abstract
;
1493 ctx_list
.transfer_syntaxes
= (struct ndr_syntax_id
*)discard_const(transfer
);
1495 u
.bind
.max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
1496 u
.bind
.max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
1497 u
.bind
.assoc_group_id
= 0x0;
1498 u
.bind
.num_contexts
= 1;
1499 u
.bind
.ctx_list
= &ctx_list
;
1500 u
.bind
.auth_info
= *auth_info
;
1502 status
= dcerpc_push_ncacn_packet(mem_ctx
,
1504 DCERPC_PFC_FLAG_FIRST
|
1505 DCERPC_PFC_FLAG_LAST
,
1510 if (!NT_STATUS_IS_OK(status
)) {
1511 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1515 return NT_STATUS_OK
;
1518 /*******************************************************************
1519 Creates a DCE/RPC bind request.
1520 ********************************************************************/
1522 static NTSTATUS
create_rpc_bind_req(TALLOC_CTX
*mem_ctx
,
1523 struct rpc_pipe_client
*cli
,
1525 const struct ndr_syntax_id
*abstract
,
1526 const struct ndr_syntax_id
*transfer
,
1527 enum pipe_auth_type auth_type
,
1528 enum dcerpc_AuthLevel auth_level
,
1531 DATA_BLOB auth_info
= data_blob_null
;
1532 NTSTATUS ret
= NT_STATUS_OK
;
1534 switch (auth_type
) {
1535 case PIPE_AUTH_TYPE_SCHANNEL
:
1536 ret
= create_schannel_auth_rpc_bind_req(cli
, auth_level
, &auth_info
);
1537 if (!NT_STATUS_IS_OK(ret
)) {
1542 case PIPE_AUTH_TYPE_NTLMSSP
:
1543 ret
= create_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &auth_info
);
1544 if (!NT_STATUS_IS_OK(ret
)) {
1549 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1550 ret
= create_spnego_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &auth_info
);
1551 if (!NT_STATUS_IS_OK(ret
)) {
1556 case PIPE_AUTH_TYPE_KRB5
:
1557 ret
= create_krb5_auth_bind_req(cli
, auth_level
, &auth_info
);
1558 if (!NT_STATUS_IS_OK(ret
)) {
1563 case PIPE_AUTH_TYPE_NONE
:
1567 /* "Can't" happen. */
1568 return NT_STATUS_INVALID_INFO_CLASS
;
1571 ret
= create_bind_or_alt_ctx_internal(mem_ctx
,
1581 /*******************************************************************
1582 Create and add the NTLMSSP sign/seal auth header and data.
1583 ********************************************************************/
1585 static NTSTATUS
add_ntlmssp_auth_footer(struct rpc_pipe_client
*cli
,
1586 uint32 ss_padding_len
,
1589 DATA_BLOB auth_info
;
1591 DATA_BLOB auth_blob
= data_blob_null
;
1592 uint16_t data_and_pad_len
= rpc_out
->length
- DCERPC_RESPONSE_LENGTH
;
1594 if (!cli
->auth
->a_u
.auth_ntlmssp_state
) {
1595 return NT_STATUS_INVALID_PARAMETER
;
1598 /* marshall the dcerpc_auth with an actually empty auth_blob.
1599 * this is needed because the ntmlssp signature includes the
1601 status
= dcerpc_push_dcerpc_auth(rpc_out
->data
,
1602 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
->auth_type
),
1603 cli
->auth
->auth_level
,
1605 1 /* context id. */,
1608 if (!NT_STATUS_IS_OK(status
)) {
1612 /* append the header */
1613 if (!data_blob_append(NULL
, rpc_out
,
1614 auth_info
.data
, auth_info
.length
)) {
1615 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1616 (unsigned int)auth_info
.length
));
1617 return NT_STATUS_NO_MEMORY
;
1619 data_blob_free(&auth_info
);
1621 switch (cli
->auth
->auth_level
) {
1622 case DCERPC_AUTH_LEVEL_PRIVACY
:
1623 /* Data portion is encrypted. */
1624 status
= auth_ntlmssp_seal_packet(cli
->auth
->a_u
.auth_ntlmssp_state
,
1627 + DCERPC_RESPONSE_LENGTH
,
1632 if (!NT_STATUS_IS_OK(status
)) {
1637 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1638 /* Data is signed. */
1639 status
= auth_ntlmssp_sign_packet(cli
->auth
->a_u
.auth_ntlmssp_state
,
1642 + DCERPC_RESPONSE_LENGTH
,
1647 if (!NT_STATUS_IS_OK(status
)) {
1654 smb_panic("bad auth level");
1656 return NT_STATUS_INVALID_PARAMETER
;
1659 /* Finally attach the blob. */
1660 if (!data_blob_append(NULL
, rpc_out
,
1661 auth_blob
.data
, auth_blob
.length
)) {
1662 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1663 (unsigned int)auth_info
.length
));
1664 return NT_STATUS_NO_MEMORY
;
1666 data_blob_free(&auth_blob
);
1668 return NT_STATUS_OK
;
1671 /*******************************************************************
1672 Create and add the schannel sign/seal auth header and data.
1673 ********************************************************************/
1675 static NTSTATUS
add_schannel_auth_footer(struct rpc_pipe_client
*cli
,
1676 uint32 ss_padding_len
,
1679 DATA_BLOB auth_info
;
1680 struct schannel_state
*sas
= cli
->auth
->a_u
.schannel_auth
;
1681 uint8_t *data_p
= rpc_out
->data
+ DCERPC_RESPONSE_LENGTH
;
1682 size_t data_and_pad_len
= rpc_out
->length
1683 - DCERPC_RESPONSE_LENGTH
;
1688 return NT_STATUS_INVALID_PARAMETER
;
1691 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1694 switch (cli
->auth
->auth_level
) {
1695 case DCERPC_AUTH_LEVEL_PRIVACY
:
1696 status
= netsec_outgoing_packet(sas
,
1703 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1704 status
= netsec_outgoing_packet(sas
,
1712 status
= NT_STATUS_INTERNAL_ERROR
;
1716 if (!NT_STATUS_IS_OK(status
)) {
1717 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1718 nt_errstr(status
)));
1722 if (DEBUGLEVEL
>= 10) {
1723 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob
);
1726 /* Finally marshall the blob. */
1727 status
= dcerpc_push_dcerpc_auth(rpc_out
->data
,
1728 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
->auth_type
),
1729 cli
->auth
->auth_level
,
1731 1 /* context id. */,
1734 if (!NT_STATUS_IS_OK(status
)) {
1737 data_blob_free(&blob
);
1739 if (!data_blob_append(NULL
, rpc_out
,
1740 auth_info
.data
, auth_info
.length
)) {
1741 return NT_STATUS_NO_MEMORY
;
1743 data_blob_free(&auth_info
);
1745 return NT_STATUS_OK
;
1748 /*******************************************************************
1749 Calculate how much data we're going to send in this packet, also
1750 work out any sign/seal padding length.
1751 ********************************************************************/
1753 static uint32
calculate_data_len_tosend(struct rpc_pipe_client
*cli
,
1757 uint32
*p_ss_padding
)
1759 uint32 data_space
, data_len
;
1762 if ((data_left
> 0) && (sys_random() % 2)) {
1763 data_left
= MAX(data_left
/2, 1);
1767 switch (cli
->auth
->auth_level
) {
1768 case DCERPC_AUTH_LEVEL_NONE
:
1769 case DCERPC_AUTH_LEVEL_CONNECT
:
1770 data_space
= cli
->max_xmit_frag
- DCERPC_REQUEST_LENGTH
;
1771 data_len
= MIN(data_space
, data_left
);
1774 *p_frag_len
= DCERPC_REQUEST_LENGTH
+ data_len
;
1777 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1778 case DCERPC_AUTH_LEVEL_PRIVACY
:
1779 /* Treat the same for all authenticated rpc requests. */
1780 switch(cli
->auth
->auth_type
) {
1781 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1782 case PIPE_AUTH_TYPE_NTLMSSP
:
1783 *p_auth_len
= NTLMSSP_SIG_SIZE
;
1785 case PIPE_AUTH_TYPE_SCHANNEL
:
1786 *p_auth_len
= NL_AUTH_SIGNATURE_SIZE
;
1789 smb_panic("bad auth type");
1793 data_space
= cli
->max_xmit_frag
1794 - DCERPC_REQUEST_LENGTH
1795 - DCERPC_AUTH_TRAILER_LENGTH
1798 data_len
= MIN(data_space
, data_left
);
1800 if (data_len
% CLIENT_NDR_PADDING_SIZE
) {
1801 *p_ss_padding
= CLIENT_NDR_PADDING_SIZE
- (data_len
% CLIENT_NDR_PADDING_SIZE
);
1803 *p_frag_len
= DCERPC_REQUEST_LENGTH
1804 + data_len
+ *p_ss_padding
1805 + DCERPC_AUTH_TRAILER_LENGTH
1810 smb_panic("bad auth level");
1816 /*******************************************************************
1818 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1819 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1820 and deals with signing/sealing details.
1821 ********************************************************************/
1823 struct rpc_api_pipe_req_state
{
1824 struct event_context
*ev
;
1825 struct rpc_pipe_client
*cli
;
1828 DATA_BLOB
*req_data
;
1829 uint32_t req_data_sent
;
1831 DATA_BLOB reply_pdu
;
1834 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
1835 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
1836 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1837 bool *is_last_frag
);
1839 struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
1840 struct event_context
*ev
,
1841 struct rpc_pipe_client
*cli
,
1843 DATA_BLOB
*req_data
)
1845 struct tevent_req
*req
, *subreq
;
1846 struct rpc_api_pipe_req_state
*state
;
1850 req
= tevent_req_create(mem_ctx
, &state
,
1851 struct rpc_api_pipe_req_state
);
1857 state
->op_num
= op_num
;
1858 state
->req_data
= req_data
;
1859 state
->req_data_sent
= 0;
1860 state
->call_id
= get_rpc_call_id();
1861 state
->reply_pdu
= data_blob_null
;
1862 state
->rpc_out
= data_blob_null
;
1864 if (cli
->max_xmit_frag
< DCERPC_REQUEST_LENGTH
1865 + RPC_MAX_SIGN_SIZE
) {
1866 /* Server is screwed up ! */
1867 status
= NT_STATUS_INVALID_PARAMETER
;
1871 status
= prepare_next_frag(state
, &is_last_frag
);
1872 if (!NT_STATUS_IS_OK(status
)) {
1877 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
1879 DCERPC_PKT_RESPONSE
);
1880 if (subreq
== NULL
) {
1883 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
1885 subreq
= rpc_write_send(state
, ev
, cli
->transport
,
1886 state
->rpc_out
.data
,
1887 state
->rpc_out
.length
);
1888 if (subreq
== NULL
) {
1891 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
1897 tevent_req_nterror(req
, status
);
1898 return tevent_req_post(req
, ev
);
1904 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
1907 uint32_t data_sent_thistime
;
1911 uint32_t ss_padding
;
1913 char pad
[8] = { 0, };
1915 union dcerpc_payload u
;
1917 data_left
= state
->req_data
->length
- state
->req_data_sent
;
1919 data_sent_thistime
= calculate_data_len_tosend(
1920 state
->cli
, data_left
, &frag_len
, &auth_len
, &ss_padding
);
1922 if (state
->req_data_sent
== 0) {
1923 flags
= DCERPC_PFC_FLAG_FIRST
;
1926 if (data_sent_thistime
== data_left
) {
1927 flags
|= DCERPC_PFC_FLAG_LAST
;
1930 data_blob_free(&state
->rpc_out
);
1932 ZERO_STRUCT(u
.request
);
1934 u
.request
.alloc_hint
= state
->req_data
->length
;
1935 u
.request
.context_id
= 0;
1936 u
.request
.opnum
= state
->op_num
;
1938 status
= dcerpc_push_ncacn_packet(state
,
1945 if (!NT_STATUS_IS_OK(status
)) {
1949 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1950 * compute it right for requests */
1951 dcerpc_set_frag_length(&state
->rpc_out
, frag_len
);
1953 /* Copy in the data, plus any ss padding. */
1954 if (!data_blob_append(NULL
, &state
->rpc_out
,
1955 state
->req_data
->data
+ state
->req_data_sent
,
1956 data_sent_thistime
)) {
1957 return NT_STATUS_NO_MEMORY
;
1961 /* Copy the sign/seal padding data. */
1962 if (!data_blob_append(NULL
, &state
->rpc_out
,
1964 return NT_STATUS_NO_MEMORY
;
1968 /* Generate any auth sign/seal and add the auth footer. */
1969 switch (state
->cli
->auth
->auth_type
) {
1970 case PIPE_AUTH_TYPE_NONE
:
1971 status
= NT_STATUS_OK
;
1973 case PIPE_AUTH_TYPE_NTLMSSP
:
1974 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1975 status
= add_ntlmssp_auth_footer(state
->cli
, ss_padding
,
1978 case PIPE_AUTH_TYPE_SCHANNEL
:
1979 status
= add_schannel_auth_footer(state
->cli
, ss_padding
,
1983 status
= NT_STATUS_INVALID_PARAMETER
;
1987 state
->req_data_sent
+= data_sent_thistime
;
1988 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
1993 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
1995 struct tevent_req
*req
= tevent_req_callback_data(
1996 subreq
, struct tevent_req
);
1997 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
1998 req
, struct rpc_api_pipe_req_state
);
2002 status
= rpc_write_recv(subreq
);
2003 TALLOC_FREE(subreq
);
2004 if (!NT_STATUS_IS_OK(status
)) {
2005 tevent_req_nterror(req
, status
);
2009 status
= prepare_next_frag(state
, &is_last_frag
);
2010 if (!NT_STATUS_IS_OK(status
)) {
2011 tevent_req_nterror(req
, status
);
2016 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2018 DCERPC_PKT_RESPONSE
);
2019 if (tevent_req_nomem(subreq
, req
)) {
2022 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
2024 subreq
= rpc_write_send(state
, state
->ev
,
2025 state
->cli
->transport
,
2026 state
->rpc_out
.data
,
2027 state
->rpc_out
.length
);
2028 if (tevent_req_nomem(subreq
, req
)) {
2031 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
2036 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
2038 struct tevent_req
*req
= tevent_req_callback_data(
2039 subreq
, struct tevent_req
);
2040 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2041 req
, struct rpc_api_pipe_req_state
);
2044 status
= rpc_api_pipe_recv(subreq
, state
, NULL
, &state
->reply_pdu
);
2045 TALLOC_FREE(subreq
);
2046 if (!NT_STATUS_IS_OK(status
)) {
2047 tevent_req_nterror(req
, status
);
2050 tevent_req_done(req
);
2053 NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2054 DATA_BLOB
*reply_pdu
)
2056 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2057 req
, struct rpc_api_pipe_req_state
);
2060 if (tevent_req_is_nterror(req
, &status
)) {
2062 * We always have to initialize to reply pdu, even if there is
2063 * none. The rpccli_* caller routines expect this.
2065 *reply_pdu
= data_blob_null
;
2069 /* return data to caller and assign it ownership of memory */
2070 reply_pdu
->data
= talloc_move(mem_ctx
, &state
->reply_pdu
.data
);
2071 reply_pdu
->length
= state
->reply_pdu
.length
;
2072 state
->reply_pdu
.length
= 0;
2074 return NT_STATUS_OK
;
2078 /****************************************************************************
2079 Set the handle state.
2080 ****************************************************************************/
2082 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client
*cli
,
2083 const char *pipe_name
, uint16 device_state
)
2085 bool state_set
= False
;
2087 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
2088 char *rparam
= NULL
;
2090 uint32 rparam_len
, rdata_len
;
2092 if (pipe_name
== NULL
)
2095 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2096 cli
->fnum
, pipe_name
, device_state
));
2098 /* create parameters: device state */
2099 SSVAL(param
, 0, device_state
);
2101 /* create setup parameters. */
2103 setup
[1] = cli
->fnum
; /* pipe file handle. got this from an SMBOpenX. */
2105 /* send the data on \PIPE\ */
2106 if (cli_api_pipe(cli
->cli
, "\\PIPE\\",
2107 setup
, 2, 0, /* setup, length, max */
2108 param
, 2, 0, /* param, length, max */
2109 NULL
, 0, 1024, /* data, length, max */
2110 &rparam
, &rparam_len
, /* return param, length */
2111 &rdata
, &rdata_len
)) /* return data, length */
2113 DEBUG(5, ("Set Handle state: return OK\n"));
2124 /****************************************************************************
2125 Check the rpc bind acknowledge response.
2126 ****************************************************************************/
2128 static bool check_bind_response(const struct dcerpc_bind_ack
*r
,
2129 const struct ndr_syntax_id
*transfer
)
2131 struct dcerpc_ack_ctx ctx
;
2133 if (r
->secondary_address_size
== 0) {
2134 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2137 if (r
->num_results
< 1 || !r
->ctx_list
) {
2141 ctx
= r
->ctx_list
[0];
2143 /* check the transfer syntax */
2144 if ((ctx
.syntax
.if_version
!= transfer
->if_version
) ||
2145 (memcmp(&ctx
.syntax
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
2146 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2150 if (r
->num_results
!= 0x1 || ctx
.result
!= 0) {
2151 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2152 r
->num_results
, ctx
.reason
));
2155 DEBUG(5,("check_bind_response: accepted!\n"));
2159 /*******************************************************************
2160 Creates a DCE/RPC bind authentication response.
2161 This is the packet that is sent back to the server once we
2162 have received a BIND-ACK, to finish the third leg of
2163 the authentication handshake.
2164 ********************************************************************/
2166 static NTSTATUS
create_rpc_bind_auth3(TALLOC_CTX
*mem_ctx
,
2167 struct rpc_pipe_client
*cli
,
2169 enum pipe_auth_type auth_type
,
2170 enum dcerpc_AuthLevel auth_level
,
2171 DATA_BLOB
*pauth_blob
,
2175 union dcerpc_payload u
;
2179 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
2180 map_pipe_auth_type_to_rpc_auth_type(auth_type
),
2182 0, /* auth_pad_length */
2183 1, /* auth_context_id */
2185 &u
.auth3
.auth_info
);
2186 if (!NT_STATUS_IS_OK(status
)) {
2190 status
= dcerpc_push_ncacn_packet(mem_ctx
,
2192 DCERPC_PFC_FLAG_FIRST
|
2193 DCERPC_PFC_FLAG_LAST
,
2198 data_blob_free(&u
.auth3
.auth_info
);
2199 if (!NT_STATUS_IS_OK(status
)) {
2200 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2204 return NT_STATUS_OK
;
2207 /*******************************************************************
2208 Creates a DCE/RPC bind alter context authentication request which
2209 may contain a spnego auth blobl
2210 ********************************************************************/
2212 static NTSTATUS
create_rpc_alter_context(TALLOC_CTX
*mem_ctx
,
2214 const struct ndr_syntax_id
*abstract
,
2215 const struct ndr_syntax_id
*transfer
,
2216 enum dcerpc_AuthLevel auth_level
,
2217 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
2220 DATA_BLOB auth_info
;
2223 status
= dcerpc_push_dcerpc_auth(mem_ctx
,
2224 DCERPC_AUTH_TYPE_SPNEGO
,
2226 0, /* auth_pad_length */
2227 1, /* auth_context_id */
2230 if (!NT_STATUS_IS_OK(status
)) {
2234 status
= create_bind_or_alt_ctx_internal(mem_ctx
,
2241 data_blob_free(&auth_info
);
2245 /****************************************************************************
2247 ****************************************************************************/
2249 struct rpc_pipe_bind_state
{
2250 struct event_context
*ev
;
2251 struct rpc_pipe_client
*cli
;
2253 uint32_t rpc_call_id
;
2256 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
2257 static NTSTATUS
rpc_finish_auth3_bind_send(struct tevent_req
*req
,
2258 struct rpc_pipe_bind_state
*state
,
2259 struct ncacn_packet
*r
);
2260 static void rpc_bind_auth3_write_done(struct tevent_req
*subreq
);
2261 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req
*req
,
2262 struct rpc_pipe_bind_state
*state
,
2263 struct ncacn_packet
*r
,
2264 DATA_BLOB
*reply_pdu
);
2265 static void rpc_bind_ntlmssp_api_done(struct tevent_req
*subreq
);
2267 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
2268 struct event_context
*ev
,
2269 struct rpc_pipe_client
*cli
,
2270 struct pipe_auth_data
*auth
)
2272 struct tevent_req
*req
, *subreq
;
2273 struct rpc_pipe_bind_state
*state
;
2276 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
2281 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2282 rpccli_pipe_txt(talloc_tos(), cli
),
2283 (unsigned int)auth
->auth_type
,
2284 (unsigned int)auth
->auth_level
));
2288 state
->rpc_call_id
= get_rpc_call_id();
2289 state
->rpc_out
= data_blob_null
;
2291 cli
->auth
= talloc_move(cli
, &auth
);
2293 /* Marshall the outgoing data. */
2294 status
= create_rpc_bind_req(state
, cli
,
2296 &cli
->abstract_syntax
,
2297 &cli
->transfer_syntax
,
2298 cli
->auth
->auth_type
,
2299 cli
->auth
->auth_level
,
2302 if (!NT_STATUS_IS_OK(status
)) {
2306 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
2307 DCERPC_PKT_BIND_ACK
);
2308 if (subreq
== NULL
) {
2311 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2315 tevent_req_nterror(req
, status
);
2316 return tevent_req_post(req
, ev
);
2322 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
2324 struct tevent_req
*req
= tevent_req_callback_data(
2325 subreq
, struct tevent_req
);
2326 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2327 req
, struct rpc_pipe_bind_state
);
2328 DATA_BLOB reply_pdu
;
2329 struct ncacn_packet
*pkt
;
2332 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, &reply_pdu
);
2333 TALLOC_FREE(subreq
);
2334 if (!NT_STATUS_IS_OK(status
)) {
2335 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2336 rpccli_pipe_txt(talloc_tos(), state
->cli
),
2337 nt_errstr(status
)));
2338 tevent_req_nterror(req
, status
);
2342 if (!check_bind_response(&pkt
->u
.bind_ack
, &state
->cli
->transfer_syntax
)) {
2343 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2344 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2348 state
->cli
->max_xmit_frag
= pkt
->u
.bind_ack
.max_xmit_frag
;
2349 state
->cli
->max_recv_frag
= pkt
->u
.bind_ack
.max_recv_frag
;
2352 * For authenticated binds we may need to do 3 or 4 leg binds.
2355 switch(state
->cli
->auth
->auth_type
) {
2357 case PIPE_AUTH_TYPE_NONE
:
2358 case PIPE_AUTH_TYPE_SCHANNEL
:
2359 /* Bind complete. */
2360 tevent_req_done(req
);
2363 case PIPE_AUTH_TYPE_NTLMSSP
:
2364 /* Need to send AUTH3 packet - no reply. */
2365 status
= rpc_finish_auth3_bind_send(req
, state
, pkt
);
2366 if (!NT_STATUS_IS_OK(status
)) {
2367 tevent_req_nterror(req
, status
);
2371 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2372 /* Need to send alter context request and reply. */
2373 status
= rpc_finish_spnego_ntlmssp_bind_send(req
, state
, pkt
,
2375 if (!NT_STATUS_IS_OK(status
)) {
2376 tevent_req_nterror(req
, status
);
2380 case PIPE_AUTH_TYPE_KRB5
:
2384 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2385 (unsigned int)state
->cli
->auth
->auth_type
));
2386 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2390 static NTSTATUS
rpc_finish_auth3_bind_send(struct tevent_req
*req
,
2391 struct rpc_pipe_bind_state
*state
,
2392 struct ncacn_packet
*r
)
2394 DATA_BLOB client_reply
= data_blob_null
;
2395 struct dcerpc_auth auth
;
2396 struct tevent_req
*subreq
;
2399 if ((r
->auth_length
== 0)
2400 || (r
->frag_length
< DCERPC_AUTH_TRAILER_LENGTH
2401 + r
->auth_length
)) {
2402 return NT_STATUS_INVALID_PARAMETER
;
2405 status
= dcerpc_pull_dcerpc_auth(talloc_tos(),
2406 &r
->u
.bind_ack
.auth_info
,
2408 if (!NT_STATUS_IS_OK(status
)) {
2409 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2410 nt_errstr(status
)));
2414 /* TODO - check auth_type/auth_level match. */
2416 status
= auth_ntlmssp_update(state
->cli
->auth
->a_u
.auth_ntlmssp_state
,
2417 auth
.credentials
, &client_reply
);
2419 if (!NT_STATUS_IS_OK(status
)) {
2420 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2421 "blob failed: %s.\n", nt_errstr(status
)));
2425 data_blob_free(&state
->rpc_out
);
2427 status
= create_rpc_bind_auth3(state
,
2428 state
->cli
, state
->rpc_call_id
,
2429 state
->cli
->auth
->auth_type
,
2430 state
->cli
->auth
->auth_level
,
2431 &client_reply
, &state
->rpc_out
);
2432 data_blob_free(&client_reply
);
2434 if (!NT_STATUS_IS_OK(status
)) {
2438 subreq
= rpc_write_send(state
, state
->ev
, state
->cli
->transport
,
2439 state
->rpc_out
.data
, state
->rpc_out
.length
);
2440 if (subreq
== NULL
) {
2441 return NT_STATUS_NO_MEMORY
;
2443 tevent_req_set_callback(subreq
, rpc_bind_auth3_write_done
, req
);
2444 return NT_STATUS_OK
;
2447 static void rpc_bind_auth3_write_done(struct tevent_req
*subreq
)
2449 struct tevent_req
*req
= tevent_req_callback_data(
2450 subreq
, struct tevent_req
);
2453 status
= rpc_write_recv(subreq
);
2454 TALLOC_FREE(subreq
);
2455 if (!NT_STATUS_IS_OK(status
)) {
2456 tevent_req_nterror(req
, status
);
2459 tevent_req_done(req
);
2462 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req
*req
,
2463 struct rpc_pipe_bind_state
*state
,
2464 struct ncacn_packet
*r
,
2465 DATA_BLOB
*reply_pdu
)
2467 DATA_BLOB server_ntlm_response
= data_blob_null
;
2468 DATA_BLOB client_reply
= data_blob_null
;
2469 DATA_BLOB tmp_blob
= data_blob_null
;
2470 struct dcerpc_auth auth_info
;
2471 DATA_BLOB auth_blob
;
2472 struct tevent_req
*subreq
;
2475 if ((r
->auth_length
== 0)
2476 || (r
->frag_length
< DCERPC_AUTH_TRAILER_LENGTH
2477 + r
->auth_length
)) {
2478 return NT_STATUS_INVALID_PARAMETER
;
2481 /* Process the returned NTLMSSP blob first. */
2482 auth_blob
= data_blob_const(reply_pdu
->data
2484 - DCERPC_AUTH_TRAILER_LENGTH
2486 DCERPC_AUTH_TRAILER_LENGTH
2489 status
= dcerpc_pull_dcerpc_auth(state
, &auth_blob
, &auth_info
, false);
2490 if (!NT_STATUS_IS_OK(status
)) {
2491 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
2496 * The server might give us back two challenges - tmp_blob is for the
2499 if (!spnego_parse_challenge(auth_info
.credentials
,
2500 &server_ntlm_response
, &tmp_blob
)) {
2501 data_blob_free(&server_ntlm_response
);
2502 data_blob_free(&tmp_blob
);
2503 return NT_STATUS_INVALID_PARAMETER
;
2506 /* We're finished with the server spnego response and the tmp_blob. */
2507 data_blob_free(&tmp_blob
);
2509 status
= auth_ntlmssp_update(state
->cli
->auth
->a_u
.auth_ntlmssp_state
,
2510 server_ntlm_response
, &client_reply
);
2512 /* Finished with the server_ntlm response */
2513 data_blob_free(&server_ntlm_response
);
2515 if (!NT_STATUS_IS_OK(status
)) {
2516 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2517 "using server blob failed.\n"));
2518 data_blob_free(&client_reply
);
2522 /* SPNEGO wrap the client reply. */
2523 tmp_blob
= spnego_gen_auth(client_reply
);
2524 data_blob_free(&client_reply
);
2525 client_reply
= tmp_blob
;
2526 tmp_blob
= data_blob_null
;
2528 /* Now prepare the alter context pdu. */
2529 data_blob_free(&state
->rpc_out
);
2531 status
= create_rpc_alter_context(state
,
2533 &state
->cli
->abstract_syntax
,
2534 &state
->cli
->transfer_syntax
,
2535 state
->cli
->auth
->auth_level
,
2538 data_blob_free(&client_reply
);
2540 if (!NT_STATUS_IS_OK(status
)) {
2544 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2545 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
);
2546 if (subreq
== NULL
) {
2547 return NT_STATUS_NO_MEMORY
;
2549 tevent_req_set_callback(subreq
, rpc_bind_ntlmssp_api_done
, req
);
2550 return NT_STATUS_OK
;
2553 static void rpc_bind_ntlmssp_api_done(struct tevent_req
*subreq
)
2555 struct tevent_req
*req
= tevent_req_callback_data(
2556 subreq
, struct tevent_req
);
2557 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2558 req
, struct rpc_pipe_bind_state
);
2559 DATA_BLOB tmp_blob
= data_blob_null
;
2560 struct ncacn_packet
*pkt
;
2561 struct dcerpc_auth auth
;
2564 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &pkt
, NULL
);
2565 TALLOC_FREE(subreq
);
2566 if (!NT_STATUS_IS_OK(status
)) {
2567 tevent_req_nterror(req
, status
);
2571 status
= dcerpc_pull_dcerpc_auth(pkt
,
2572 &pkt
->u
.alter_resp
.auth_info
,
2574 if (!NT_STATUS_IS_OK(status
)) {
2575 tevent_req_nterror(req
, status
);
2579 /* Check we got a valid auth response. */
2580 if (!spnego_parse_auth_response(auth
.credentials
,
2582 OID_NTLMSSP
, &tmp_blob
)) {
2583 data_blob_free(&tmp_blob
);
2584 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2588 data_blob_free(&tmp_blob
);
2590 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2591 "%s.\n", rpccli_pipe_txt(talloc_tos(), state
->cli
)));
2592 tevent_req_done(req
);
2595 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
2597 return tevent_req_simple_recv_ntstatus(req
);
2600 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2601 struct pipe_auth_data
*auth
)
2603 TALLOC_CTX
*frame
= talloc_stackframe();
2604 struct event_context
*ev
;
2605 struct tevent_req
*req
;
2606 NTSTATUS status
= NT_STATUS_OK
;
2608 ev
= event_context_init(frame
);
2610 status
= NT_STATUS_NO_MEMORY
;
2614 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
2616 status
= NT_STATUS_NO_MEMORY
;
2620 if (!tevent_req_poll(req
, ev
)) {
2621 status
= map_nt_error_from_unix(errno
);
2625 status
= rpc_pipe_bind_recv(req
);
2631 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2633 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
2634 unsigned int timeout
)
2638 if (rpc_cli
->transport
== NULL
) {
2639 return RPCCLI_DEFAULT_TIMEOUT
;
2642 if (rpc_cli
->transport
->set_timeout
== NULL
) {
2643 return RPCCLI_DEFAULT_TIMEOUT
;
2646 old
= rpc_cli
->transport
->set_timeout(rpc_cli
->transport
->priv
, timeout
);
2648 return RPCCLI_DEFAULT_TIMEOUT
;
2654 bool rpccli_is_connected(struct rpc_pipe_client
*rpc_cli
)
2656 if (rpc_cli
== NULL
) {
2660 if (rpc_cli
->transport
== NULL
) {
2664 return rpc_cli
->transport
->is_connected(rpc_cli
->transport
->priv
);
2667 bool rpccli_get_pwd_hash(struct rpc_pipe_client
*rpc_cli
, uint8_t nt_hash
[16])
2669 struct cli_state
*cli
;
2671 if ((rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_NTLMSSP
)
2672 || (rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
)) {
2673 memcpy(nt_hash
, auth_ntlmssp_get_nt_hash(rpc_cli
->auth
->a_u
.auth_ntlmssp_state
), 16);
2677 cli
= rpc_pipe_np_smb_conn(rpc_cli
);
2681 E_md4hash(cli
->password
? cli
->password
: "", nt_hash
);
2685 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
2686 struct pipe_auth_data
**presult
)
2688 struct pipe_auth_data
*result
;
2690 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2691 if (result
== NULL
) {
2692 return NT_STATUS_NO_MEMORY
;
2695 result
->auth_type
= PIPE_AUTH_TYPE_NONE
;
2696 result
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
2698 result
->user_name
= talloc_strdup(result
, "");
2699 result
->domain
= talloc_strdup(result
, "");
2700 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2701 TALLOC_FREE(result
);
2702 return NT_STATUS_NO_MEMORY
;
2706 return NT_STATUS_OK
;
2709 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data
*auth
)
2711 TALLOC_FREE(auth
->a_u
.auth_ntlmssp_state
);
2715 static NTSTATUS
rpccli_ntlmssp_bind_data(TALLOC_CTX
*mem_ctx
,
2716 enum pipe_auth_type auth_type
,
2717 enum dcerpc_AuthLevel auth_level
,
2719 const char *username
,
2720 const char *password
,
2721 struct pipe_auth_data
**presult
)
2723 struct pipe_auth_data
*result
;
2726 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2727 if (result
== NULL
) {
2728 return NT_STATUS_NO_MEMORY
;
2731 result
->auth_type
= auth_type
;
2732 result
->auth_level
= auth_level
;
2734 result
->user_name
= talloc_strdup(result
, username
);
2735 result
->domain
= talloc_strdup(result
, domain
);
2736 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2737 status
= NT_STATUS_NO_MEMORY
;
2741 status
= auth_ntlmssp_client_start(NULL
,
2744 lp_client_ntlmv2_auth(),
2745 &result
->a_u
.auth_ntlmssp_state
);
2746 if (!NT_STATUS_IS_OK(status
)) {
2750 talloc_set_destructor(result
, cli_auth_ntlmssp_data_destructor
);
2752 status
= auth_ntlmssp_set_username(result
->a_u
.auth_ntlmssp_state
,
2754 if (!NT_STATUS_IS_OK(status
)) {
2758 status
= auth_ntlmssp_set_domain(result
->a_u
.auth_ntlmssp_state
,
2760 if (!NT_STATUS_IS_OK(status
)) {
2764 status
= auth_ntlmssp_set_password(result
->a_u
.auth_ntlmssp_state
,
2766 if (!NT_STATUS_IS_OK(status
)) {
2771 * Turn off sign+seal to allow selected auth level to turn it back on.
2773 auth_ntlmssp_and_flags(result
->a_u
.auth_ntlmssp_state
,
2774 ~(NTLMSSP_NEGOTIATE_SIGN
|
2775 NTLMSSP_NEGOTIATE_SEAL
));
2777 if (auth_level
== DCERPC_AUTH_LEVEL_INTEGRITY
) {
2778 auth_ntlmssp_or_flags(result
->a_u
.auth_ntlmssp_state
,
2779 NTLMSSP_NEGOTIATE_SIGN
);
2780 } else if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
2781 auth_ntlmssp_or_flags(result
->a_u
.auth_ntlmssp_state
,
2782 NTLMSSP_NEGOTIATE_SEAL
|
2783 NTLMSSP_NEGOTIATE_SIGN
);
2787 return NT_STATUS_OK
;
2790 TALLOC_FREE(result
);
2794 NTSTATUS
rpccli_schannel_bind_data(TALLOC_CTX
*mem_ctx
, const char *domain
,
2795 enum dcerpc_AuthLevel auth_level
,
2796 struct netlogon_creds_CredentialState
*creds
,
2797 struct pipe_auth_data
**presult
)
2799 struct pipe_auth_data
*result
;
2801 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2802 if (result
== NULL
) {
2803 return NT_STATUS_NO_MEMORY
;
2806 result
->auth_type
= PIPE_AUTH_TYPE_SCHANNEL
;
2807 result
->auth_level
= auth_level
;
2809 result
->user_name
= talloc_strdup(result
, "");
2810 result
->domain
= talloc_strdup(result
, domain
);
2811 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2815 result
->a_u
.schannel_auth
= talloc(result
, struct schannel_state
);
2816 if (result
->a_u
.schannel_auth
== NULL
) {
2820 result
->a_u
.schannel_auth
->state
= SCHANNEL_STATE_START
;
2821 result
->a_u
.schannel_auth
->seq_num
= 0;
2822 result
->a_u
.schannel_auth
->initiator
= true;
2823 result
->a_u
.schannel_auth
->creds
= creds
;
2826 return NT_STATUS_OK
;
2829 TALLOC_FREE(result
);
2830 return NT_STATUS_NO_MEMORY
;
2834 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct
*auth
)
2836 data_blob_free(&auth
->session_key
);
2841 static NTSTATUS
rpccli_kerberos_bind_data(TALLOC_CTX
*mem_ctx
,
2842 enum dcerpc_AuthLevel auth_level
,
2843 const char *service_princ
,
2844 const char *username
,
2845 const char *password
,
2846 struct pipe_auth_data
**presult
)
2849 struct pipe_auth_data
*result
;
2851 if ((username
!= NULL
) && (password
!= NULL
)) {
2852 int ret
= kerberos_kinit_password(username
, password
, 0, NULL
);
2854 return NT_STATUS_ACCESS_DENIED
;
2858 result
= talloc(mem_ctx
, struct pipe_auth_data
);
2859 if (result
== NULL
) {
2860 return NT_STATUS_NO_MEMORY
;
2863 result
->auth_type
= PIPE_AUTH_TYPE_KRB5
;
2864 result
->auth_level
= auth_level
;
2867 * Username / domain need fixing!
2869 result
->user_name
= talloc_strdup(result
, "");
2870 result
->domain
= talloc_strdup(result
, "");
2871 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2875 result
->a_u
.kerberos_auth
= TALLOC_ZERO_P(
2876 result
, struct kerberos_auth_struct
);
2877 if (result
->a_u
.kerberos_auth
== NULL
) {
2880 talloc_set_destructor(result
->a_u
.kerberos_auth
,
2881 cli_auth_kerberos_data_destructor
);
2883 result
->a_u
.kerberos_auth
->service_principal
= talloc_strdup(
2884 result
, service_princ
);
2885 if (result
->a_u
.kerberos_auth
->service_principal
== NULL
) {
2890 return NT_STATUS_OK
;
2893 TALLOC_FREE(result
);
2894 return NT_STATUS_NO_MEMORY
;
2896 return NT_STATUS_NOT_SUPPORTED
;
2901 * Create an rpc pipe client struct, connecting to a tcp port.
2903 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
2905 const struct ndr_syntax_id
*abstract_syntax
,
2906 struct rpc_pipe_client
**presult
)
2908 struct rpc_pipe_client
*result
;
2909 struct sockaddr_storage addr
;
2913 result
= TALLOC_ZERO_P(mem_ctx
, struct rpc_pipe_client
);
2914 if (result
== NULL
) {
2915 return NT_STATUS_NO_MEMORY
;
2918 result
->abstract_syntax
= *abstract_syntax
;
2919 result
->transfer_syntax
= ndr_transfer_syntax
;
2920 result
->dispatch
= cli_do_rpc_ndr
;
2921 result
->dispatch_send
= cli_do_rpc_ndr_send
;
2922 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
2924 result
->desthost
= talloc_strdup(result
, host
);
2925 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2926 result
, "\\\\%s", result
->desthost
);
2927 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2928 status
= NT_STATUS_NO_MEMORY
;
2932 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2933 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
2935 if (!resolve_name(host
, &addr
, 0, false)) {
2936 status
= NT_STATUS_NOT_FOUND
;
2940 status
= open_socket_out(&addr
, port
, 60, &fd
);
2941 if (!NT_STATUS_IS_OK(status
)) {
2944 set_socket_options(fd
, lp_socket_options());
2946 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
2947 if (!NT_STATUS_IS_OK(status
)) {
2952 result
->transport
->transport
= NCACN_IP_TCP
;
2955 return NT_STATUS_OK
;
2958 TALLOC_FREE(result
);
2963 * Determine the tcp port on which a dcerpc interface is listening
2964 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2967 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
2968 const struct ndr_syntax_id
*abstract_syntax
,
2972 struct rpc_pipe_client
*epm_pipe
= NULL
;
2973 struct pipe_auth_data
*auth
= NULL
;
2974 struct dcerpc_binding
*map_binding
= NULL
;
2975 struct dcerpc_binding
*res_binding
= NULL
;
2976 struct epm_twr_t
*map_tower
= NULL
;
2977 struct epm_twr_t
*res_towers
= NULL
;
2978 struct policy_handle
*entry_handle
= NULL
;
2979 uint32_t num_towers
= 0;
2980 uint32_t max_towers
= 1;
2981 struct epm_twr_p_t towers
;
2982 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2984 if (pport
== NULL
) {
2985 status
= NT_STATUS_INVALID_PARAMETER
;
2989 /* open the connection to the endpoint mapper */
2990 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, 135,
2991 &ndr_table_epmapper
.syntax_id
,
2994 if (!NT_STATUS_IS_OK(status
)) {
2998 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
2999 if (!NT_STATUS_IS_OK(status
)) {
3003 status
= rpc_pipe_bind(epm_pipe
, auth
);
3004 if (!NT_STATUS_IS_OK(status
)) {
3008 /* create tower for asking the epmapper */
3010 map_binding
= TALLOC_ZERO_P(tmp_ctx
, struct dcerpc_binding
);
3011 if (map_binding
== NULL
) {
3012 status
= NT_STATUS_NO_MEMORY
;
3016 map_binding
->transport
= NCACN_IP_TCP
;
3017 map_binding
->object
= *abstract_syntax
;
3018 map_binding
->host
= host
; /* needed? */
3019 map_binding
->endpoint
= "0"; /* correct? needed? */
3021 map_tower
= TALLOC_ZERO_P(tmp_ctx
, struct epm_twr_t
);
3022 if (map_tower
== NULL
) {
3023 status
= NT_STATUS_NO_MEMORY
;
3027 status
= dcerpc_binding_build_tower(tmp_ctx
, map_binding
,
3028 &(map_tower
->tower
));
3029 if (!NT_STATUS_IS_OK(status
)) {
3033 /* allocate further parameters for the epm_Map call */
3035 res_towers
= TALLOC_ARRAY(tmp_ctx
, struct epm_twr_t
, max_towers
);
3036 if (res_towers
== NULL
) {
3037 status
= NT_STATUS_NO_MEMORY
;
3040 towers
.twr
= res_towers
;
3042 entry_handle
= TALLOC_ZERO_P(tmp_ctx
, struct policy_handle
);
3043 if (entry_handle
== NULL
) {
3044 status
= NT_STATUS_NO_MEMORY
;
3048 /* ask the endpoint mapper for the port */
3050 status
= rpccli_epm_Map(epm_pipe
,
3052 CONST_DISCARD(struct GUID
*,
3053 &(abstract_syntax
->uuid
)),
3060 if (!NT_STATUS_IS_OK(status
)) {
3064 if (num_towers
!= 1) {
3065 status
= NT_STATUS_UNSUCCESSFUL
;
3069 /* extract the port from the answer */
3071 status
= dcerpc_binding_from_tower(tmp_ctx
,
3072 &(towers
.twr
->tower
),
3074 if (!NT_STATUS_IS_OK(status
)) {
3078 /* are further checks here necessary? */
3079 if (res_binding
->transport
!= NCACN_IP_TCP
) {
3080 status
= NT_STATUS_UNSUCCESSFUL
;
3084 *pport
= (uint16_t)atoi(res_binding
->endpoint
);
3087 TALLOC_FREE(tmp_ctx
);
3092 * Create a rpc pipe client struct, connecting to a host via tcp.
3093 * The port is determined by asking the endpoint mapper on the given
3096 NTSTATUS
rpc_pipe_open_tcp(TALLOC_CTX
*mem_ctx
, const char *host
,
3097 const struct ndr_syntax_id
*abstract_syntax
,
3098 struct rpc_pipe_client
**presult
)
3103 status
= rpc_pipe_get_tcp_port(host
, abstract_syntax
, &port
);
3104 if (!NT_STATUS_IS_OK(status
)) {
3108 return rpc_pipe_open_tcp_port(mem_ctx
, host
, port
,
3109 abstract_syntax
, presult
);
3112 /********************************************************************
3113 Create a rpc pipe client struct, connecting to a unix domain socket
3114 ********************************************************************/
3115 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
, const char *socket_path
,
3116 const struct ndr_syntax_id
*abstract_syntax
,
3117 struct rpc_pipe_client
**presult
)
3119 struct rpc_pipe_client
*result
;
3120 struct sockaddr_un addr
;
3124 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
3125 if (result
== NULL
) {
3126 return NT_STATUS_NO_MEMORY
;
3129 result
->abstract_syntax
= *abstract_syntax
;
3130 result
->transfer_syntax
= ndr_transfer_syntax
;
3131 result
->dispatch
= cli_do_rpc_ndr
;
3132 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3133 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3135 result
->desthost
= get_myname(result
);
3136 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3137 result
, "\\\\%s", result
->desthost
);
3138 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3139 status
= NT_STATUS_NO_MEMORY
;
3143 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3144 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3146 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3148 status
= map_nt_error_from_unix(errno
);
3153 addr
.sun_family
= AF_UNIX
;
3154 strncpy(addr
.sun_path
, socket_path
, sizeof(addr
.sun_path
));
3156 if (sys_connect(fd
, (struct sockaddr
*)(void *)&addr
) == -1) {
3157 DEBUG(0, ("connect(%s) failed: %s\n", socket_path
,
3160 return map_nt_error_from_unix(errno
);
3163 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
3164 if (!NT_STATUS_IS_OK(status
)) {
3169 result
->transport
->transport
= NCALRPC
;
3172 return NT_STATUS_OK
;
3175 TALLOC_FREE(result
);
3179 struct rpc_pipe_client_np_ref
{
3180 struct cli_state
*cli
;
3181 struct rpc_pipe_client
*pipe
;
3184 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref
*np_ref
)
3186 DLIST_REMOVE(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3190 /****************************************************************************
3191 Open a named pipe over SMB to a remote server.
3193 * CAVEAT CALLER OF THIS FUNCTION:
3194 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3195 * so be sure that this function is called AFTER any structure (vs pointer)
3196 * assignment of the cli. In particular, libsmbclient does structure
3197 * assignments of cli, which invalidates the data in the returned
3198 * rpc_pipe_client if this function is called before the structure assignment
3201 ****************************************************************************/
3203 static NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
3204 const struct ndr_syntax_id
*abstract_syntax
,
3205 struct rpc_pipe_client
**presult
)
3207 struct rpc_pipe_client
*result
;
3209 struct rpc_pipe_client_np_ref
*np_ref
;
3211 /* sanity check to protect against crashes */
3214 return NT_STATUS_INVALID_HANDLE
;
3217 result
= TALLOC_ZERO_P(NULL
, struct rpc_pipe_client
);
3218 if (result
== NULL
) {
3219 return NT_STATUS_NO_MEMORY
;
3222 result
->abstract_syntax
= *abstract_syntax
;
3223 result
->transfer_syntax
= ndr_transfer_syntax
;
3224 result
->dispatch
= cli_do_rpc_ndr
;
3225 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3226 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3227 result
->desthost
= talloc_strdup(result
, cli
->desthost
);
3228 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3229 result
, "\\\\%s", result
->desthost
);
3231 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3232 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3234 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3235 TALLOC_FREE(result
);
3236 return NT_STATUS_NO_MEMORY
;
3239 status
= rpc_transport_np_init(result
, cli
, abstract_syntax
,
3240 &result
->transport
);
3241 if (!NT_STATUS_IS_OK(status
)) {
3242 TALLOC_FREE(result
);
3246 result
->transport
->transport
= NCACN_NP
;
3248 np_ref
= talloc(result
->transport
, struct rpc_pipe_client_np_ref
);
3249 if (np_ref
== NULL
) {
3250 TALLOC_FREE(result
);
3251 return NT_STATUS_NO_MEMORY
;
3254 np_ref
->pipe
= result
;
3256 DLIST_ADD(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3257 talloc_set_destructor(np_ref
, rpc_pipe_client_np_ref_destructor
);
3260 return NT_STATUS_OK
;
3263 NTSTATUS
rpc_pipe_open_local(TALLOC_CTX
*mem_ctx
,
3264 struct rpc_cli_smbd_conn
*conn
,
3265 const struct ndr_syntax_id
*syntax
,
3266 struct rpc_pipe_client
**presult
)
3268 struct rpc_pipe_client
*result
;
3269 struct pipe_auth_data
*auth
;
3272 result
= talloc(mem_ctx
, struct rpc_pipe_client
);
3273 if (result
== NULL
) {
3274 return NT_STATUS_NO_MEMORY
;
3276 result
->abstract_syntax
= *syntax
;
3277 result
->transfer_syntax
= ndr_transfer_syntax
;
3278 result
->dispatch
= cli_do_rpc_ndr
;
3279 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3280 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3281 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3282 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3284 result
->desthost
= talloc_strdup(result
, global_myname());
3285 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3286 result
, "\\\\%s", global_myname());
3287 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3288 TALLOC_FREE(result
);
3289 return NT_STATUS_NO_MEMORY
;
3292 status
= rpc_transport_smbd_init(result
, conn
, syntax
,
3293 &result
->transport
);
3294 if (!NT_STATUS_IS_OK(status
)) {
3295 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3296 nt_errstr(status
)));
3297 TALLOC_FREE(result
);
3301 status
= rpccli_anon_bind_data(result
, &auth
);
3302 if (!NT_STATUS_IS_OK(status
)) {
3303 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3304 nt_errstr(status
)));
3305 TALLOC_FREE(result
);
3309 status
= rpc_pipe_bind(result
, auth
);
3310 if (!NT_STATUS_IS_OK(status
)) {
3311 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status
)));
3312 TALLOC_FREE(result
);
3316 result
->transport
->transport
= NCACN_INTERNAL
;
3319 return NT_STATUS_OK
;
3322 /****************************************************************************
3323 Open a pipe to a remote server.
3324 ****************************************************************************/
3326 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3327 enum dcerpc_transport_t transport
,
3328 const struct ndr_syntax_id
*interface
,
3329 struct rpc_pipe_client
**presult
)
3331 switch (transport
) {
3333 return rpc_pipe_open_tcp(NULL
, cli
->desthost
, interface
,
3336 return rpc_pipe_open_np(cli
, interface
, presult
);
3338 return NT_STATUS_NOT_IMPLEMENTED
;
3342 /****************************************************************************
3343 Open a named pipe to an SMB server and bind anonymously.
3344 ****************************************************************************/
3346 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
3347 enum dcerpc_transport_t transport
,
3348 const struct ndr_syntax_id
*interface
,
3349 struct rpc_pipe_client
**presult
)
3351 struct rpc_pipe_client
*result
;
3352 struct pipe_auth_data
*auth
;
3355 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3356 if (!NT_STATUS_IS_OK(status
)) {
3360 status
= rpccli_anon_bind_data(result
, &auth
);
3361 if (!NT_STATUS_IS_OK(status
)) {
3362 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3363 nt_errstr(status
)));
3364 TALLOC_FREE(result
);
3369 * This is a bit of an abstraction violation due to the fact that an
3370 * anonymous bind on an authenticated SMB inherits the user/domain
3371 * from the enclosing SMB creds
3374 TALLOC_FREE(auth
->user_name
);
3375 TALLOC_FREE(auth
->domain
);
3377 auth
->user_name
= talloc_strdup(auth
, cli
->user_name
);
3378 auth
->domain
= talloc_strdup(auth
, cli
->domain
);
3379 auth
->user_session_key
= data_blob_talloc(auth
,
3380 cli
->user_session_key
.data
,
3381 cli
->user_session_key
.length
);
3383 if ((auth
->user_name
== NULL
) || (auth
->domain
== NULL
)) {
3384 TALLOC_FREE(result
);
3385 return NT_STATUS_NO_MEMORY
;
3388 status
= rpc_pipe_bind(result
, auth
);
3389 if (!NT_STATUS_IS_OK(status
)) {
3391 if (ndr_syntax_id_equal(interface
,
3392 &ndr_table_dssetup
.syntax_id
)) {
3393 /* non AD domains just don't have this pipe, avoid
3394 * level 0 statement in that case - gd */
3397 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3398 "%s failed with error %s\n",
3399 get_pipe_name_from_syntax(talloc_tos(), interface
),
3400 nt_errstr(status
) ));
3401 TALLOC_FREE(result
);
3405 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3406 "%s and bound anonymously.\n",
3407 get_pipe_name_from_syntax(talloc_tos(), interface
),
3411 return NT_STATUS_OK
;
3414 /****************************************************************************
3415 ****************************************************************************/
3417 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
3418 const struct ndr_syntax_id
*interface
,
3419 struct rpc_pipe_client
**presult
)
3421 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
3422 interface
, presult
);
3425 /****************************************************************************
3426 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3427 ****************************************************************************/
3429 static NTSTATUS
cli_rpc_pipe_open_ntlmssp_internal(struct cli_state
*cli
,
3430 const struct ndr_syntax_id
*interface
,
3431 enum dcerpc_transport_t transport
,
3432 enum pipe_auth_type auth_type
,
3433 enum dcerpc_AuthLevel auth_level
,
3435 const char *username
,
3436 const char *password
,
3437 struct rpc_pipe_client
**presult
)
3439 struct rpc_pipe_client
*result
;
3440 struct pipe_auth_data
*auth
;
3443 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3444 if (!NT_STATUS_IS_OK(status
)) {
3448 status
= rpccli_ntlmssp_bind_data(
3449 result
, auth_type
, auth_level
, domain
, username
,
3451 if (!NT_STATUS_IS_OK(status
)) {
3452 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3453 nt_errstr(status
)));
3457 status
= rpc_pipe_bind(result
, auth
);
3458 if (!NT_STATUS_IS_OK(status
)) {
3459 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3460 nt_errstr(status
) ));
3464 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3465 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3466 get_pipe_name_from_syntax(talloc_tos(), interface
),
3467 cli
->desthost
, domain
, username
));
3470 return NT_STATUS_OK
;
3474 TALLOC_FREE(result
);
3478 /****************************************************************************
3480 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3481 ****************************************************************************/
3483 NTSTATUS
cli_rpc_pipe_open_ntlmssp(struct cli_state
*cli
,
3484 const struct ndr_syntax_id
*interface
,
3485 enum dcerpc_transport_t transport
,
3486 enum dcerpc_AuthLevel auth_level
,
3488 const char *username
,
3489 const char *password
,
3490 struct rpc_pipe_client
**presult
)
3492 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3495 PIPE_AUTH_TYPE_NTLMSSP
,
3503 /****************************************************************************
3505 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3506 ****************************************************************************/
3508 NTSTATUS
cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state
*cli
,
3509 const struct ndr_syntax_id
*interface
,
3510 enum dcerpc_transport_t transport
,
3511 enum dcerpc_AuthLevel auth_level
,
3513 const char *username
,
3514 const char *password
,
3515 struct rpc_pipe_client
**presult
)
3517 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3520 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
,
3528 /****************************************************************************
3529 Get a the schannel session key out of an already opened netlogon pipe.
3530 ****************************************************************************/
3531 static NTSTATUS
get_schannel_session_key_common(struct rpc_pipe_client
*netlogon_pipe
,
3532 struct cli_state
*cli
,
3536 enum netr_SchannelType sec_chan_type
= 0;
3537 unsigned char machine_pwd
[16];
3538 const char *machine_account
;
3541 /* Get the machine account credentials from secrets.tdb. */
3542 if (!get_trust_pw_hash(domain
, machine_pwd
, &machine_account
,
3545 DEBUG(0, ("get_schannel_session_key: could not fetch "
3546 "trust account password for domain '%s'\n",
3548 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3551 status
= rpccli_netlogon_setup_creds(netlogon_pipe
,
3552 cli
->desthost
, /* server name */
3553 domain
, /* domain */
3554 global_myname(), /* client name */
3555 machine_account
, /* machine account name */
3560 if (!NT_STATUS_IS_OK(status
)) {
3561 DEBUG(3, ("get_schannel_session_key_common: "
3562 "rpccli_netlogon_setup_creds failed with result %s "
3563 "to server %s, domain %s, machine account %s.\n",
3564 nt_errstr(status
), cli
->desthost
, domain
,
3569 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
3570 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3572 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3575 return NT_STATUS_OK
;;
3578 /****************************************************************************
3579 Open a netlogon pipe and get the schannel session key.
3580 Now exposed to external callers.
3581 ****************************************************************************/
3584 NTSTATUS
get_schannel_session_key(struct cli_state
*cli
,
3587 struct rpc_pipe_client
**presult
)
3589 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3592 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
.syntax_id
,
3594 if (!NT_STATUS_IS_OK(status
)) {
3598 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
3600 if (!NT_STATUS_IS_OK(status
)) {
3601 TALLOC_FREE(netlogon_pipe
);
3605 *presult
= netlogon_pipe
;
3606 return NT_STATUS_OK
;
3609 /****************************************************************************
3611 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3612 using session_key. sign and seal.
3614 The *pdc will be stolen onto this new pipe
3615 ****************************************************************************/
3617 NTSTATUS
cli_rpc_pipe_open_schannel_with_key(struct cli_state
*cli
,
3618 const struct ndr_syntax_id
*interface
,
3619 enum dcerpc_transport_t transport
,
3620 enum dcerpc_AuthLevel auth_level
,
3622 struct netlogon_creds_CredentialState
**pdc
,
3623 struct rpc_pipe_client
**presult
)
3625 struct rpc_pipe_client
*result
;
3626 struct pipe_auth_data
*auth
;
3629 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3630 if (!NT_STATUS_IS_OK(status
)) {
3634 status
= rpccli_schannel_bind_data(result
, domain
, auth_level
,
3636 if (!NT_STATUS_IS_OK(status
)) {
3637 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3638 nt_errstr(status
)));
3639 TALLOC_FREE(result
);
3643 status
= rpc_pipe_bind(result
, auth
);
3644 if (!NT_STATUS_IS_OK(status
)) {
3645 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3646 "cli_rpc_pipe_bind failed with error %s\n",
3647 nt_errstr(status
) ));
3648 TALLOC_FREE(result
);
3653 * The credentials on a new netlogon pipe are the ones we are passed
3654 * in - reference them in
3656 result
->dc
= talloc_move(result
, pdc
);
3658 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3659 "for domain %s and bound using schannel.\n",
3660 get_pipe_name_from_syntax(talloc_tos(), interface
),
3661 cli
->desthost
, domain
));
3664 return NT_STATUS_OK
;
3667 /****************************************************************************
3668 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3669 Fetch the session key ourselves using a temporary netlogon pipe. This
3670 version uses an ntlmssp auth bound netlogon pipe to get the key.
3671 ****************************************************************************/
3673 static NTSTATUS
get_schannel_session_key_auth_ntlmssp(struct cli_state
*cli
,
3675 const char *username
,
3676 const char *password
,
3678 struct rpc_pipe_client
**presult
)
3680 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3683 status
= cli_rpc_pipe_open_spnego_ntlmssp(
3684 cli
, &ndr_table_netlogon
.syntax_id
, NCACN_NP
,
3685 DCERPC_AUTH_LEVEL_PRIVACY
,
3686 domain
, username
, password
, &netlogon_pipe
);
3687 if (!NT_STATUS_IS_OK(status
)) {
3691 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
3693 if (!NT_STATUS_IS_OK(status
)) {
3694 TALLOC_FREE(netlogon_pipe
);
3698 *presult
= netlogon_pipe
;
3699 return NT_STATUS_OK
;
3702 /****************************************************************************
3703 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3704 Fetch the session key ourselves using a temporary netlogon pipe. This version
3705 uses an ntlmssp bind to get the session key.
3706 ****************************************************************************/
3708 NTSTATUS
cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
*cli
,
3709 const struct ndr_syntax_id
*interface
,
3710 enum dcerpc_transport_t transport
,
3711 enum dcerpc_AuthLevel auth_level
,
3713 const char *username
,
3714 const char *password
,
3715 struct rpc_pipe_client
**presult
)
3717 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
3718 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3719 struct rpc_pipe_client
*result
= NULL
;
3722 status
= get_schannel_session_key_auth_ntlmssp(
3723 cli
, domain
, username
, password
, &neg_flags
, &netlogon_pipe
);
3724 if (!NT_STATUS_IS_OK(status
)) {
3725 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3726 "key from server %s for domain %s.\n",
3727 cli
->desthost
, domain
));
3731 status
= cli_rpc_pipe_open_schannel_with_key(
3732 cli
, interface
, transport
, auth_level
, domain
, &netlogon_pipe
->dc
,
3735 /* Now we've bound using the session key we can close the netlog pipe. */
3736 TALLOC_FREE(netlogon_pipe
);
3738 if (NT_STATUS_IS_OK(status
)) {
3744 /****************************************************************************
3745 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3746 Fetch the session key ourselves using a temporary netlogon pipe.
3747 ****************************************************************************/
3749 NTSTATUS
cli_rpc_pipe_open_schannel(struct cli_state
*cli
,
3750 const struct ndr_syntax_id
*interface
,
3751 enum dcerpc_transport_t transport
,
3752 enum dcerpc_AuthLevel auth_level
,
3754 struct rpc_pipe_client
**presult
)
3756 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
3757 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3758 struct rpc_pipe_client
*result
= NULL
;
3761 status
= get_schannel_session_key(cli
, domain
, &neg_flags
,
3763 if (!NT_STATUS_IS_OK(status
)) {
3764 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3765 "key from server %s for domain %s.\n",
3766 cli
->desthost
, domain
));
3770 status
= cli_rpc_pipe_open_schannel_with_key(
3771 cli
, interface
, transport
, auth_level
, domain
, &netlogon_pipe
->dc
,
3774 /* Now we've bound using the session key we can close the netlog pipe. */
3775 TALLOC_FREE(netlogon_pipe
);
3777 if (NT_STATUS_IS_OK(status
)) {
3784 /****************************************************************************
3785 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3786 The idea is this can be called with service_princ, username and password all
3787 NULL so long as the caller has a TGT.
3788 ****************************************************************************/
3790 NTSTATUS
cli_rpc_pipe_open_krb5(struct cli_state
*cli
,
3791 const struct ndr_syntax_id
*interface
,
3792 enum dcerpc_AuthLevel auth_level
,
3793 const char *service_princ
,
3794 const char *username
,
3795 const char *password
,
3796 struct rpc_pipe_client
**presult
)
3799 struct rpc_pipe_client
*result
;
3800 struct pipe_auth_data
*auth
;
3803 status
= cli_rpc_pipe_open(cli
, NCACN_NP
, interface
, &result
);
3804 if (!NT_STATUS_IS_OK(status
)) {
3808 status
= rpccli_kerberos_bind_data(result
, auth_level
, service_princ
,
3809 username
, password
, &auth
);
3810 if (!NT_STATUS_IS_OK(status
)) {
3811 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3812 nt_errstr(status
)));
3813 TALLOC_FREE(result
);
3817 status
= rpc_pipe_bind(result
, auth
);
3818 if (!NT_STATUS_IS_OK(status
)) {
3819 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3820 "with error %s\n", nt_errstr(status
)));
3821 TALLOC_FREE(result
);
3826 return NT_STATUS_OK
;
3828 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3829 return NT_STATUS_NOT_IMPLEMENTED
;
3833 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
3834 struct rpc_pipe_client
*cli
,
3835 DATA_BLOB
*session_key
)
3839 if (!session_key
|| !cli
) {
3840 return NT_STATUS_INVALID_PARAMETER
;
3844 return NT_STATUS_INVALID_PARAMETER
;
3847 switch (cli
->auth
->auth_type
) {
3848 case PIPE_AUTH_TYPE_SCHANNEL
:
3849 *session_key
= data_blob_talloc(mem_ctx
,
3850 cli
->auth
->a_u
.schannel_auth
->creds
->session_key
, 16);
3852 case PIPE_AUTH_TYPE_NTLMSSP
:
3853 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
3854 sk
= auth_ntlmssp_get_session_key(cli
->auth
->a_u
.auth_ntlmssp_state
);
3855 *session_key
= data_blob_dup_talloc(mem_ctx
, &sk
);
3857 case PIPE_AUTH_TYPE_KRB5
:
3858 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
3859 *session_key
= data_blob_talloc(mem_ctx
,
3860 cli
->auth
->a_u
.kerberos_auth
->session_key
.data
,
3861 cli
->auth
->a_u
.kerberos_auth
->session_key
.length
);
3863 case PIPE_AUTH_TYPE_NONE
:
3864 *session_key
= data_blob_talloc(mem_ctx
,
3865 cli
->auth
->user_session_key
.data
,
3866 cli
->auth
->user_session_key
.length
);
3869 return NT_STATUS_NO_USER_SESSION_KEY
;
3872 return NT_STATUS_OK
;