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 "../libcli/auth/schannel.h"
24 #include "../libcli/auth/spnego.h"
29 #define DBGC_CLASS DBGC_RPC_CLI
31 static const char *get_pipe_name_from_iface(
32 TALLOC_CTX
*mem_ctx
, const struct ndr_interface_table
*interface
)
35 const struct ndr_interface_string_array
*ep
= interface
->endpoints
;
38 for (i
=0; i
<ep
->count
; i
++) {
39 if (strncmp(ep
->names
[i
], "ncacn_np:[\\pipe\\", 16) == 0) {
48 * extract the pipe name without \\pipe from for example
49 * ncacn_np:[\\pipe\\epmapper]
51 p
= strchr(ep
->names
[i
]+15, ']');
55 return talloc_strndup(mem_ctx
, ep
->names
[i
]+15, p
- ep
->names
[i
] - 15);
58 static const struct ndr_interface_table
**interfaces
;
60 bool smb_register_ndr_interface(const struct ndr_interface_table
*interface
)
62 int num_interfaces
= talloc_array_length(interfaces
);
63 const struct ndr_interface_table
**tmp
;
66 for (i
=0; i
<num_interfaces
; i
++) {
67 if (ndr_syntax_id_equal(&interfaces
[i
]->syntax_id
,
68 &interface
->syntax_id
)) {
73 tmp
= talloc_realloc(NULL
, interfaces
,
74 const struct ndr_interface_table
*,
77 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
81 interfaces
[num_interfaces
] = interface
;
85 static bool initialize_interfaces(void)
87 if (!smb_register_ndr_interface(&ndr_table_lsarpc
)) {
90 if (!smb_register_ndr_interface(&ndr_table_dssetup
)) {
93 if (!smb_register_ndr_interface(&ndr_table_samr
)) {
96 if (!smb_register_ndr_interface(&ndr_table_netlogon
)) {
99 if (!smb_register_ndr_interface(&ndr_table_srvsvc
)) {
102 if (!smb_register_ndr_interface(&ndr_table_wkssvc
)) {
105 if (!smb_register_ndr_interface(&ndr_table_winreg
)) {
108 if (!smb_register_ndr_interface(&ndr_table_spoolss
)) {
111 if (!smb_register_ndr_interface(&ndr_table_netdfs
)) {
114 if (!smb_register_ndr_interface(&ndr_table_rpcecho
)) {
117 if (!smb_register_ndr_interface(&ndr_table_initshutdown
)) {
120 if (!smb_register_ndr_interface(&ndr_table_svcctl
)) {
123 if (!smb_register_ndr_interface(&ndr_table_eventlog
)) {
126 if (!smb_register_ndr_interface(&ndr_table_ntsvcs
)) {
129 if (!smb_register_ndr_interface(&ndr_table_epmapper
)) {
132 if (!smb_register_ndr_interface(&ndr_table_drsuapi
)) {
138 const struct ndr_interface_table
*get_iface_from_syntax(
139 const struct ndr_syntax_id
*syntax
)
144 if (interfaces
== NULL
) {
145 if (!initialize_interfaces()) {
149 num_interfaces
= talloc_array_length(interfaces
);
151 for (i
=0; i
<num_interfaces
; i
++) {
152 if (ndr_syntax_id_equal(&interfaces
[i
]->syntax_id
, syntax
)) {
153 return interfaces
[i
];
160 /****************************************************************************
161 Return the pipe name from the interface.
162 ****************************************************************************/
164 const char *get_pipe_name_from_syntax(TALLOC_CTX
*mem_ctx
,
165 const struct ndr_syntax_id
*syntax
)
167 const struct ndr_interface_table
*interface
;
171 interface
= get_iface_from_syntax(syntax
);
172 if (interface
!= NULL
) {
173 result
= get_pipe_name_from_iface(mem_ctx
, interface
);
174 if (result
!= NULL
) {
180 * Here we should ask \\epmapper, but for now our code is only
181 * interested in the known pipes mentioned in pipe_names[]
184 guid_str
= GUID_string(talloc_tos(), &syntax
->uuid
);
185 if (guid_str
== NULL
) {
188 result
= talloc_asprintf(mem_ctx
, "Interface %s.%d", guid_str
,
189 (int)syntax
->if_version
);
190 TALLOC_FREE(guid_str
);
192 if (result
== NULL
) {
198 /********************************************************************
199 Map internal value to wire value.
200 ********************************************************************/
202 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type
)
206 case PIPE_AUTH_TYPE_NONE
:
207 return DCERPC_AUTH_TYPE_NONE
;
209 case PIPE_AUTH_TYPE_NTLMSSP
:
210 return DCERPC_AUTH_TYPE_NTLMSSP
;
212 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
213 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
214 return DCERPC_AUTH_TYPE_SPNEGO
;
216 case PIPE_AUTH_TYPE_SCHANNEL
:
217 return DCERPC_AUTH_TYPE_SCHANNEL
;
219 case PIPE_AUTH_TYPE_KRB5
:
220 return DCERPC_AUTH_TYPE_KRB5
;
223 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
225 (unsigned int)auth_type
));
231 /********************************************************************
232 Pipe description for a DEBUG
233 ********************************************************************/
234 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
235 struct rpc_pipe_client
*cli
)
237 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
238 if (result
== NULL
) {
244 /********************************************************************
246 ********************************************************************/
248 static uint32
get_rpc_call_id(void)
250 static uint32 call_id
= 0;
255 * Realloc pdu to have a least "size" bytes
258 static bool rpc_grow_buffer(prs_struct
*pdu
, size_t size
)
262 if (prs_data_size(pdu
) >= size
) {
266 extra_size
= size
- prs_data_size(pdu
);
268 if (!prs_force_grow(pdu
, extra_size
)) {
269 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
270 "%d bytes.\n", (int)extra_size
));
274 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
275 (int)extra_size
, prs_data_size(pdu
)));
280 /*******************************************************************
281 Use SMBreadX to get rest of one fragment's worth of rpc data.
282 Reads the whole size or give an error message
283 ********************************************************************/
285 struct rpc_read_state
{
286 struct event_context
*ev
;
287 struct rpc_cli_transport
*transport
;
293 static void rpc_read_done(struct tevent_req
*subreq
);
295 static struct tevent_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
296 struct event_context
*ev
,
297 struct rpc_cli_transport
*transport
,
298 uint8_t *data
, size_t size
)
300 struct tevent_req
*req
, *subreq
;
301 struct rpc_read_state
*state
;
303 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_read_state
);
308 state
->transport
= transport
;
313 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size
));
315 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
317 if (subreq
== NULL
) {
320 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
328 static void rpc_read_done(struct tevent_req
*subreq
)
330 struct tevent_req
*req
= tevent_req_callback_data(
331 subreq
, struct tevent_req
);
332 struct rpc_read_state
*state
= tevent_req_data(
333 req
, struct rpc_read_state
);
337 status
= state
->transport
->read_recv(subreq
, &received
);
339 if (!NT_STATUS_IS_OK(status
)) {
340 tevent_req_nterror(req
, status
);
344 state
->num_read
+= received
;
345 if (state
->num_read
== state
->size
) {
346 tevent_req_done(req
);
350 subreq
= state
->transport
->read_send(state
, state
->ev
,
351 state
->data
+ state
->num_read
,
352 state
->size
- state
->num_read
,
353 state
->transport
->priv
);
354 if (tevent_req_nomem(subreq
, req
)) {
357 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
360 static NTSTATUS
rpc_read_recv(struct tevent_req
*req
)
362 return tevent_req_simple_recv_ntstatus(req
);
365 struct rpc_write_state
{
366 struct event_context
*ev
;
367 struct rpc_cli_transport
*transport
;
373 static void rpc_write_done(struct tevent_req
*subreq
);
375 static struct tevent_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
376 struct event_context
*ev
,
377 struct rpc_cli_transport
*transport
,
378 const uint8_t *data
, size_t size
)
380 struct tevent_req
*req
, *subreq
;
381 struct rpc_write_state
*state
;
383 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_write_state
);
388 state
->transport
= transport
;
391 state
->num_written
= 0;
393 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size
));
395 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
396 if (subreq
== NULL
) {
399 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
406 static void rpc_write_done(struct tevent_req
*subreq
)
408 struct tevent_req
*req
= tevent_req_callback_data(
409 subreq
, struct tevent_req
);
410 struct rpc_write_state
*state
= tevent_req_data(
411 req
, struct rpc_write_state
);
415 status
= state
->transport
->write_recv(subreq
, &written
);
417 if (!NT_STATUS_IS_OK(status
)) {
418 tevent_req_nterror(req
, status
);
422 state
->num_written
+= written
;
424 if (state
->num_written
== state
->size
) {
425 tevent_req_done(req
);
429 subreq
= state
->transport
->write_send(state
, state
->ev
,
430 state
->data
+ state
->num_written
,
431 state
->size
- state
->num_written
,
432 state
->transport
->priv
);
433 if (tevent_req_nomem(subreq
, req
)) {
436 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
439 static NTSTATUS
rpc_write_recv(struct tevent_req
*req
)
441 return tevent_req_simple_recv_ntstatus(req
);
445 static NTSTATUS
parse_rpc_header(struct rpc_pipe_client
*cli
,
446 struct rpc_hdr_info
*prhdr
,
450 * This next call sets the endian bit correctly in current_pdu. We
451 * will propagate this to rbuf later.
454 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr
, pdu
, 0)) {
455 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
456 return NT_STATUS_BUFFER_TOO_SMALL
;
459 if (prhdr
->frag_len
> cli
->max_recv_frag
) {
460 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
461 " we only allow %d\n", (int)prhdr
->frag_len
,
462 (int)cli
->max_recv_frag
));
463 return NT_STATUS_BUFFER_TOO_SMALL
;
469 /****************************************************************************
470 Try and get a PDU's worth of data from current_pdu. If not, then read more
472 ****************************************************************************/
474 struct get_complete_frag_state
{
475 struct event_context
*ev
;
476 struct rpc_pipe_client
*cli
;
477 struct rpc_hdr_info
*prhdr
;
481 static void get_complete_frag_got_header(struct tevent_req
*subreq
);
482 static void get_complete_frag_got_rest(struct tevent_req
*subreq
);
484 static struct tevent_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
485 struct event_context
*ev
,
486 struct rpc_pipe_client
*cli
,
487 struct rpc_hdr_info
*prhdr
,
490 struct tevent_req
*req
, *subreq
;
491 struct get_complete_frag_state
*state
;
495 req
= tevent_req_create(mem_ctx
, &state
,
496 struct get_complete_frag_state
);
502 state
->prhdr
= prhdr
;
505 pdu_len
= prs_data_size(pdu
);
506 if (pdu_len
< RPC_HEADER_LEN
) {
507 if (!rpc_grow_buffer(pdu
, RPC_HEADER_LEN
)) {
508 status
= NT_STATUS_NO_MEMORY
;
511 subreq
= rpc_read_send(
513 state
->cli
->transport
,
514 (uint8_t *)(prs_data_p(state
->pdu
) + pdu_len
),
515 RPC_HEADER_LEN
- pdu_len
);
516 if (subreq
== NULL
) {
517 status
= NT_STATUS_NO_MEMORY
;
520 tevent_req_set_callback(subreq
, get_complete_frag_got_header
,
525 status
= parse_rpc_header(cli
, prhdr
, pdu
);
526 if (!NT_STATUS_IS_OK(status
)) {
531 * Ensure we have frag_len bytes of data.
533 if (pdu_len
< prhdr
->frag_len
) {
534 if (!rpc_grow_buffer(pdu
, prhdr
->frag_len
)) {
535 status
= NT_STATUS_NO_MEMORY
;
538 subreq
= rpc_read_send(state
, state
->ev
,
539 state
->cli
->transport
,
540 (uint8_t *)(prs_data_p(pdu
) + pdu_len
),
541 prhdr
->frag_len
- pdu_len
);
542 if (subreq
== NULL
) {
543 status
= NT_STATUS_NO_MEMORY
;
546 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
,
551 status
= NT_STATUS_OK
;
553 if (NT_STATUS_IS_OK(status
)) {
554 tevent_req_done(req
);
556 tevent_req_nterror(req
, status
);
558 return tevent_req_post(req
, ev
);
561 static void get_complete_frag_got_header(struct tevent_req
*subreq
)
563 struct tevent_req
*req
= tevent_req_callback_data(
564 subreq
, struct tevent_req
);
565 struct get_complete_frag_state
*state
= tevent_req_data(
566 req
, struct get_complete_frag_state
);
569 status
= rpc_read_recv(subreq
);
571 if (!NT_STATUS_IS_OK(status
)) {
572 tevent_req_nterror(req
, status
);
576 status
= parse_rpc_header(state
->cli
, state
->prhdr
, state
->pdu
);
577 if (!NT_STATUS_IS_OK(status
)) {
578 tevent_req_nterror(req
, status
);
582 if (!rpc_grow_buffer(state
->pdu
, state
->prhdr
->frag_len
)) {
583 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
588 * We're here in this piece of code because we've read exactly
589 * RPC_HEADER_LEN bytes into state->pdu.
592 subreq
= rpc_read_send(
593 state
, state
->ev
, state
->cli
->transport
,
594 (uint8_t *)(prs_data_p(state
->pdu
) + RPC_HEADER_LEN
),
595 state
->prhdr
->frag_len
- RPC_HEADER_LEN
);
596 if (tevent_req_nomem(subreq
, req
)) {
599 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
602 static void get_complete_frag_got_rest(struct tevent_req
*subreq
)
604 struct tevent_req
*req
= tevent_req_callback_data(
605 subreq
, struct tevent_req
);
608 status
= rpc_read_recv(subreq
);
610 if (!NT_STATUS_IS_OK(status
)) {
611 tevent_req_nterror(req
, status
);
614 tevent_req_done(req
);
617 static NTSTATUS
get_complete_frag_recv(struct tevent_req
*req
)
619 return tevent_req_simple_recv_ntstatus(req
);
622 /****************************************************************************
623 NTLMSSP specific sign/seal.
624 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
625 In fact I should probably abstract these into identical pieces of code... JRA.
626 ****************************************************************************/
628 static NTSTATUS
cli_pipe_verify_ntlmssp(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
629 prs_struct
*current_pdu
,
630 uint8
*p_ss_padding_len
)
632 RPC_HDR_AUTH auth_info
;
633 uint32 save_offset
= prs_offset(current_pdu
);
634 uint32 auth_len
= prhdr
->auth_len
;
635 struct ntlmssp_state
*ntlmssp_state
= cli
->auth
->a_u
.ntlmssp_state
;
636 unsigned char *data
= NULL
;
638 unsigned char *full_packet_data
= NULL
;
639 size_t full_packet_data_len
;
643 if (cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_NONE
644 || cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_CONNECT
) {
648 if (!ntlmssp_state
) {
649 return NT_STATUS_INVALID_PARAMETER
;
652 /* Ensure there's enough data for an authenticated response. */
653 if (auth_len
> RPC_MAX_PDU_FRAG_LEN
||
654 prhdr
->frag_len
< RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+
655 RPC_HDR_AUTH_LEN
+ auth_len
) {
656 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
657 (unsigned int)auth_len
));
658 return NT_STATUS_BUFFER_TOO_SMALL
;
662 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
663 * after the RPC header.
664 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
665 * functions as NTLMv2 checks the rpc headers also.
668 data
= (unsigned char *)(prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
);
669 data_len
= (size_t)(prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
);
671 full_packet_data
= (unsigned char *)prs_data_p(current_pdu
);
672 full_packet_data_len
= prhdr
->frag_len
- auth_len
;
674 /* Pull the auth header and the following data into a blob. */
675 /* NB. The offset of the auth_header is relative to the *end*
676 * of the packet, not the start. */
677 if(!prs_set_offset(current_pdu
, prhdr
->frag_len
- RPC_HDR_AUTH_LEN
- auth_len
)) {
678 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
679 (unsigned int)RPC_HEADER_LEN
+ (unsigned int)RPC_HDR_RESP_LEN
+ (unsigned int)data_len
));
680 return NT_STATUS_BUFFER_TOO_SMALL
;
683 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
684 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
685 return NT_STATUS_BUFFER_TOO_SMALL
;
688 /* Ensure auth_pad_len fits into the packet. */
689 if (RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ auth_info
.auth_pad_len
+
690 RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
) {
691 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
692 "too large (%u), auth_len (%u), frag_len = (%u).\n",
693 (unsigned int)auth_info
.auth_pad_len
,
694 (unsigned int)auth_len
,
695 (unsigned int)prhdr
->frag_len
));
696 return NT_STATUS_BUFFER_TOO_SMALL
;
700 auth_blob
.data
= (unsigned char *)prs_data_p(current_pdu
) + prs_offset(current_pdu
);
701 auth_blob
.length
= auth_len
;
703 switch (cli
->auth
->auth_level
) {
704 case DCERPC_AUTH_LEVEL_PRIVACY
:
705 /* Data is encrypted. */
706 status
= ntlmssp_unseal_packet(ntlmssp_state
,
709 full_packet_data_len
,
711 if (!NT_STATUS_IS_OK(status
)) {
712 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
713 "packet from %s. Error was %s.\n",
714 rpccli_pipe_txt(talloc_tos(), cli
),
715 nt_errstr(status
) ));
719 case DCERPC_AUTH_LEVEL_INTEGRITY
:
720 /* Data is signed. */
721 status
= ntlmssp_check_packet(ntlmssp_state
,
724 full_packet_data_len
,
726 if (!NT_STATUS_IS_OK(status
)) {
727 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
728 "packet from %s. Error was %s.\n",
729 rpccli_pipe_txt(talloc_tos(), cli
),
730 nt_errstr(status
) ));
735 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
736 "auth level %d\n", cli
->auth
->auth_level
));
737 return NT_STATUS_INVALID_INFO_CLASS
;
741 * Return the current pointer to the data offset.
744 if(!prs_set_offset(current_pdu
, save_offset
)) {
745 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
746 (unsigned int)save_offset
));
747 return NT_STATUS_BUFFER_TOO_SMALL
;
751 * Remember the padding length. We must remove it from the real data
752 * stream once the sign/seal is done.
755 *p_ss_padding_len
= auth_info
.auth_pad_len
;
760 /****************************************************************************
761 schannel specific sign/seal.
762 ****************************************************************************/
764 static NTSTATUS
cli_pipe_verify_schannel(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
765 prs_struct
*current_pdu
,
766 uint8
*p_ss_padding_len
)
768 RPC_HDR_AUTH auth_info
;
769 uint32 auth_len
= prhdr
->auth_len
;
770 uint32 save_offset
= prs_offset(current_pdu
);
771 struct schannel_state
*schannel_auth
=
772 cli
->auth
->a_u
.schannel_auth
;
778 if (cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_NONE
779 || cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_CONNECT
) {
783 if (auth_len
< RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
) {
784 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len
));
785 return NT_STATUS_INVALID_PARAMETER
;
788 if (!schannel_auth
) {
789 return NT_STATUS_INVALID_PARAMETER
;
792 /* Ensure there's enough data for an authenticated response. */
793 if ((auth_len
> RPC_MAX_PDU_FRAG_LEN
) ||
794 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
795 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
796 (unsigned int)auth_len
));
797 return NT_STATUS_INVALID_PARAMETER
;
800 data_len
= prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
;
802 /* Pull the auth header and the following data into a blob. */
803 /* NB. The offset of the auth_header is relative to the *end*
804 * of the packet, not the start. */
805 if(!prs_set_offset(current_pdu
,
806 prhdr
->frag_len
- RPC_HDR_AUTH_LEN
- auth_len
)) {
807 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
809 (unsigned int)(prhdr
->frag_len
-
810 RPC_HDR_AUTH_LEN
- auth_len
) ));
811 return NT_STATUS_BUFFER_TOO_SMALL
;
814 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
815 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
816 return NT_STATUS_BUFFER_TOO_SMALL
;
819 /* Ensure auth_pad_len fits into the packet. */
820 if (RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ auth_info
.auth_pad_len
+
821 RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
) {
822 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
823 "too large (%u), auth_len (%u), frag_len = (%u).\n",
824 (unsigned int)auth_info
.auth_pad_len
,
825 (unsigned int)auth_len
,
826 (unsigned int)prhdr
->frag_len
));
827 return NT_STATUS_BUFFER_TOO_SMALL
;
830 if (auth_info
.auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
) {
831 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
832 auth_info
.auth_type
));
833 return NT_STATUS_BUFFER_TOO_SMALL
;
836 blob
= data_blob_const(prs_data_p(current_pdu
) + prs_offset(current_pdu
), auth_len
);
838 if (DEBUGLEVEL
>= 10) {
839 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob
);
842 data
= (uint8_t *)prs_data_p(current_pdu
)+RPC_HEADER_LEN
+RPC_HDR_RESP_LEN
;
844 switch (cli
->auth
->auth_level
) {
845 case DCERPC_AUTH_LEVEL_PRIVACY
:
846 status
= netsec_incoming_packet(schannel_auth
,
853 case DCERPC_AUTH_LEVEL_INTEGRITY
:
854 status
= netsec_incoming_packet(schannel_auth
,
862 status
= NT_STATUS_INTERNAL_ERROR
;
866 if (!NT_STATUS_IS_OK(status
)) {
867 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
868 "Connection to %s (%s).\n",
869 rpccli_pipe_txt(talloc_tos(), cli
),
871 return NT_STATUS_INVALID_PARAMETER
;
875 * Return the current pointer to the data offset.
878 if(!prs_set_offset(current_pdu
, save_offset
)) {
879 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
880 (unsigned int)save_offset
));
881 return NT_STATUS_BUFFER_TOO_SMALL
;
885 * Remember the padding length. We must remove it from the real data
886 * stream once the sign/seal is done.
889 *p_ss_padding_len
= auth_info
.auth_pad_len
;
894 /****************************************************************************
895 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
896 ****************************************************************************/
898 static NTSTATUS
cli_pipe_validate_rpc_response(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
899 prs_struct
*current_pdu
,
900 uint8
*p_ss_padding_len
)
902 NTSTATUS ret
= NT_STATUS_OK
;
904 /* Paranioa checks for auth_len. */
905 if (prhdr
->auth_len
) {
906 if (prhdr
->auth_len
> prhdr
->frag_len
) {
907 return NT_STATUS_INVALID_PARAMETER
;
910 if (prhdr
->auth_len
+ (unsigned int)RPC_HDR_AUTH_LEN
< prhdr
->auth_len
||
911 prhdr
->auth_len
+ (unsigned int)RPC_HDR_AUTH_LEN
< (unsigned int)RPC_HDR_AUTH_LEN
) {
912 /* Integer wrap attempt. */
913 return NT_STATUS_INVALID_PARAMETER
;
918 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
921 switch(cli
->auth
->auth_type
) {
922 case PIPE_AUTH_TYPE_NONE
:
923 if (prhdr
->auth_len
) {
924 DEBUG(3, ("cli_pipe_validate_rpc_response: "
925 "Connection to %s - got non-zero "
927 rpccli_pipe_txt(talloc_tos(), cli
),
928 (unsigned int)prhdr
->auth_len
));
929 return NT_STATUS_INVALID_PARAMETER
;
933 case PIPE_AUTH_TYPE_NTLMSSP
:
934 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
935 ret
= cli_pipe_verify_ntlmssp(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
936 if (!NT_STATUS_IS_OK(ret
)) {
941 case PIPE_AUTH_TYPE_SCHANNEL
:
942 ret
= cli_pipe_verify_schannel(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
943 if (!NT_STATUS_IS_OK(ret
)) {
948 case PIPE_AUTH_TYPE_KRB5
:
949 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
951 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
952 "to %s - unknown internal auth type %u.\n",
953 rpccli_pipe_txt(talloc_tos(), cli
),
954 cli
->auth
->auth_type
));
955 return NT_STATUS_INVALID_INFO_CLASS
;
961 /****************************************************************************
962 Do basic authentication checks on an incoming pdu.
963 ****************************************************************************/
965 static NTSTATUS
cli_pipe_validate_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
966 prs_struct
*current_pdu
,
967 uint8 expected_pkt_type
,
970 prs_struct
*return_data
)
973 NTSTATUS ret
= NT_STATUS_OK
;
974 uint32 current_pdu_len
= prs_data_size(current_pdu
);
976 if (current_pdu_len
!= prhdr
->frag_len
) {
977 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
978 (unsigned int)current_pdu_len
, (unsigned int)prhdr
->frag_len
));
979 return NT_STATUS_INVALID_PARAMETER
;
983 * Point the return values at the real data including the RPC
984 * header. Just in case the caller wants it.
986 *ppdata
= prs_data_p(current_pdu
);
987 *pdata_len
= current_pdu_len
;
989 /* Ensure we have the correct type. */
990 switch (prhdr
->pkt_type
) {
991 case DCERPC_PKT_ALTER_RESP
:
992 case DCERPC_PKT_BIND_ACK
:
994 /* Alter context and bind ack share the same packet definitions. */
998 case DCERPC_PKT_RESPONSE
:
1000 RPC_HDR_RESP rhdr_resp
;
1001 uint8 ss_padding_len
= 0;
1003 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
1004 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1005 return NT_STATUS_BUFFER_TOO_SMALL
;
1008 /* Here's where we deal with incoming sign/seal. */
1009 ret
= cli_pipe_validate_rpc_response(cli
, prhdr
,
1010 current_pdu
, &ss_padding_len
);
1011 if (!NT_STATUS_IS_OK(ret
)) {
1015 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1016 *ppdata
= prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
1018 if (current_pdu_len
< RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ ss_padding_len
) {
1019 return NT_STATUS_BUFFER_TOO_SMALL
;
1022 *pdata_len
= current_pdu_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- ss_padding_len
;
1024 /* Remember to remove the auth footer. */
1025 if (prhdr
->auth_len
) {
1026 /* We've already done integer wrap tests on auth_len in
1027 cli_pipe_validate_rpc_response(). */
1028 if (*pdata_len
< RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
) {
1029 return NT_STATUS_BUFFER_TOO_SMALL
;
1031 *pdata_len
-= (RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
);
1034 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1035 current_pdu_len
, *pdata_len
, ss_padding_len
));
1038 * If this is the first reply, and the allocation hint is reasonably, try and
1039 * set up the return_data parse_struct to the correct size.
1042 if ((prs_data_size(return_data
) == 0) && rhdr_resp
.alloc_hint
&& (rhdr_resp
.alloc_hint
< 15*1024*1024)) {
1043 if (!prs_set_buffer_size(return_data
, rhdr_resp
.alloc_hint
)) {
1044 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1045 "too large to allocate\n",
1046 (unsigned int)rhdr_resp
.alloc_hint
));
1047 return NT_STATUS_NO_MEMORY
;
1054 case DCERPC_PKT_BIND_NAK
:
1055 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1056 "received from %s!\n",
1057 rpccli_pipe_txt(talloc_tos(), cli
)));
1058 /* Use this for now... */
1059 return NT_STATUS_NETWORK_ACCESS_DENIED
;
1061 case DCERPC_PKT_FAULT
:
1063 RPC_HDR_RESP rhdr_resp
;
1064 RPC_HDR_FAULT fault_resp
;
1066 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
1067 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1068 return NT_STATUS_BUFFER_TOO_SMALL
;
1071 if(!smb_io_rpc_hdr_fault("fault", &fault_resp
, current_pdu
, 0)) {
1072 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
1073 return NT_STATUS_BUFFER_TOO_SMALL
;
1076 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1077 "code %s received from %s!\n",
1078 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp
.status
)),
1079 rpccli_pipe_txt(talloc_tos(), cli
)));
1080 if (NT_STATUS_IS_OK(fault_resp
.status
)) {
1081 return NT_STATUS_UNSUCCESSFUL
;
1083 return fault_resp
.status
;
1088 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1090 (unsigned int)prhdr
->pkt_type
,
1091 rpccli_pipe_txt(talloc_tos(), cli
)));
1092 return NT_STATUS_INVALID_INFO_CLASS
;
1095 if (prhdr
->pkt_type
!= expected_pkt_type
) {
1096 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1097 "got an unexpected RPC packet type - %u, not %u\n",
1098 rpccli_pipe_txt(talloc_tos(), cli
),
1100 expected_pkt_type
));
1101 return NT_STATUS_INVALID_INFO_CLASS
;
1104 /* Do this just before return - we don't want to modify any rpc header
1105 data before now as we may have needed to do cryptographic actions on
1108 if ((prhdr
->pkt_type
== DCERPC_PKT_BIND_ACK
) && !(prhdr
->flags
& DCERPC_PFC_FLAG_LAST
)) {
1109 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1110 "setting fragment first/last ON.\n"));
1111 prhdr
->flags
|= DCERPC_PFC_FLAG_FIRST
|DCERPC_PFC_FLAG_LAST
;
1114 return NT_STATUS_OK
;
1117 /****************************************************************************
1118 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1119 Normally the frag_len and buffer size will match, but on the first trans
1120 reply there is a theoretical chance that buffer size > frag_len, so we must
1122 ****************************************************************************/
1124 static NTSTATUS
cli_pipe_reset_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
, prs_struct
*current_pdu
)
1126 uint32 current_pdu_len
= prs_data_size(current_pdu
);
1128 if (current_pdu_len
< prhdr
->frag_len
) {
1129 return NT_STATUS_BUFFER_TOO_SMALL
;
1133 if (current_pdu_len
== (uint32
)prhdr
->frag_len
) {
1134 prs_mem_free(current_pdu
);
1135 prs_init_empty(current_pdu
, prs_get_mem_context(current_pdu
), UNMARSHALL
);
1136 /* Make current_pdu dynamic with no memory. */
1137 prs_give_memory(current_pdu
, 0, 0, True
);
1138 return NT_STATUS_OK
;
1142 * Oh no ! More data in buffer than we processed in current pdu.
1143 * Cheat. Move the data down and shrink the buffer.
1146 memcpy(prs_data_p(current_pdu
), prs_data_p(current_pdu
) + prhdr
->frag_len
,
1147 current_pdu_len
- prhdr
->frag_len
);
1149 /* Remember to set the read offset back to zero. */
1150 prs_set_offset(current_pdu
, 0);
1152 /* Shrink the buffer. */
1153 if (!prs_set_buffer_size(current_pdu
, current_pdu_len
- prhdr
->frag_len
)) {
1154 return NT_STATUS_BUFFER_TOO_SMALL
;
1157 return NT_STATUS_OK
;
1160 /****************************************************************************
1161 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1162 ****************************************************************************/
1164 struct cli_api_pipe_state
{
1165 struct event_context
*ev
;
1166 struct rpc_cli_transport
*transport
;
1171 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
);
1172 static void cli_api_pipe_write_done(struct tevent_req
*subreq
);
1173 static void cli_api_pipe_read_done(struct tevent_req
*subreq
);
1175 static struct tevent_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
1176 struct event_context
*ev
,
1177 struct rpc_cli_transport
*transport
,
1178 uint8_t *data
, size_t data_len
,
1179 uint32_t max_rdata_len
)
1181 struct tevent_req
*req
, *subreq
;
1182 struct cli_api_pipe_state
*state
;
1185 req
= tevent_req_create(mem_ctx
, &state
, struct cli_api_pipe_state
);
1190 state
->transport
= transport
;
1192 if (max_rdata_len
< RPC_HEADER_LEN
) {
1194 * For a RPC reply we always need at least RPC_HEADER_LEN
1195 * bytes. We check this here because we will receive
1196 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1198 status
= NT_STATUS_INVALID_PARAMETER
;
1202 if (transport
->trans_send
!= NULL
) {
1203 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
1204 max_rdata_len
, transport
->priv
);
1205 if (subreq
== NULL
) {
1208 tevent_req_set_callback(subreq
, cli_api_pipe_trans_done
, req
);
1213 * If the transport does not provide a "trans" routine, i.e. for
1214 * example the ncacn_ip_tcp transport, do the write/read step here.
1217 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
1218 if (subreq
== NULL
) {
1221 tevent_req_set_callback(subreq
, cli_api_pipe_write_done
, req
);
1224 status
= NT_STATUS_INVALID_PARAMETER
;
1227 tevent_req_nterror(req
, status
);
1228 return tevent_req_post(req
, ev
);
1234 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
)
1236 struct tevent_req
*req
= tevent_req_callback_data(
1237 subreq
, struct tevent_req
);
1238 struct cli_api_pipe_state
*state
= tevent_req_data(
1239 req
, struct cli_api_pipe_state
);
1242 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
1244 TALLOC_FREE(subreq
);
1245 if (!NT_STATUS_IS_OK(status
)) {
1246 tevent_req_nterror(req
, status
);
1249 tevent_req_done(req
);
1252 static void cli_api_pipe_write_done(struct tevent_req
*subreq
)
1254 struct tevent_req
*req
= tevent_req_callback_data(
1255 subreq
, struct tevent_req
);
1256 struct cli_api_pipe_state
*state
= tevent_req_data(
1257 req
, struct cli_api_pipe_state
);
1260 status
= rpc_write_recv(subreq
);
1261 TALLOC_FREE(subreq
);
1262 if (!NT_STATUS_IS_OK(status
)) {
1263 tevent_req_nterror(req
, status
);
1267 state
->rdata
= TALLOC_ARRAY(state
, uint8_t, RPC_HEADER_LEN
);
1268 if (tevent_req_nomem(state
->rdata
, req
)) {
1273 * We don't need to use rpc_read_send here, the upper layer will cope
1274 * with a short read, transport->trans_send could also return less
1275 * than state->max_rdata_len.
1277 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
1279 state
->transport
->priv
);
1280 if (tevent_req_nomem(subreq
, req
)) {
1283 tevent_req_set_callback(subreq
, cli_api_pipe_read_done
, req
);
1286 static void cli_api_pipe_read_done(struct tevent_req
*subreq
)
1288 struct tevent_req
*req
= tevent_req_callback_data(
1289 subreq
, struct tevent_req
);
1290 struct cli_api_pipe_state
*state
= tevent_req_data(
1291 req
, struct cli_api_pipe_state
);
1295 status
= state
->transport
->read_recv(subreq
, &received
);
1296 TALLOC_FREE(subreq
);
1297 if (!NT_STATUS_IS_OK(status
)) {
1298 tevent_req_nterror(req
, status
);
1301 state
->rdata_len
= received
;
1302 tevent_req_done(req
);
1305 static NTSTATUS
cli_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1306 uint8_t **prdata
, uint32_t *prdata_len
)
1308 struct cli_api_pipe_state
*state
= tevent_req_data(
1309 req
, struct cli_api_pipe_state
);
1312 if (tevent_req_is_nterror(req
, &status
)) {
1316 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
1317 *prdata_len
= state
->rdata_len
;
1318 return NT_STATUS_OK
;
1321 /****************************************************************************
1322 Send data on an rpc pipe via trans. The prs_struct data must be the last
1323 pdu fragment of an NDR data stream.
1325 Receive response data from an rpc pipe, which may be large...
1327 Read the first fragment: unfortunately have to use SMBtrans for the first
1328 bit, then SMBreadX for subsequent bits.
1330 If first fragment received also wasn't the last fragment, continue
1331 getting fragments until we _do_ receive the last fragment.
1333 Request/Response PDU's look like the following...
1335 |<------------------PDU len----------------------------------------------->|
1336 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1338 +------------+-----------------+-------------+---------------+-------------+
1339 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1340 +------------+-----------------+-------------+---------------+-------------+
1342 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1343 signing & sealing being negotiated.
1345 ****************************************************************************/
1347 struct rpc_api_pipe_state
{
1348 struct event_context
*ev
;
1349 struct rpc_pipe_client
*cli
;
1350 uint8_t expected_pkt_type
;
1352 prs_struct incoming_frag
;
1353 struct rpc_hdr_info rhdr
;
1355 prs_struct incoming_pdu
; /* Incoming reply */
1356 uint32_t incoming_pdu_offset
;
1359 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state
*state
)
1361 prs_mem_free(&state
->incoming_frag
);
1362 prs_mem_free(&state
->incoming_pdu
);
1366 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
);
1367 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
);
1369 static struct tevent_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
1370 struct event_context
*ev
,
1371 struct rpc_pipe_client
*cli
,
1372 prs_struct
*data
, /* Outgoing PDU */
1373 uint8_t expected_pkt_type
)
1375 struct tevent_req
*req
, *subreq
;
1376 struct rpc_api_pipe_state
*state
;
1377 uint16_t max_recv_frag
;
1380 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_api_pipe_state
);
1386 state
->expected_pkt_type
= expected_pkt_type
;
1387 state
->incoming_pdu_offset
= 0;
1389 prs_init_empty(&state
->incoming_frag
, state
, UNMARSHALL
);
1391 prs_init_empty(&state
->incoming_pdu
, state
, UNMARSHALL
);
1392 /* Make incoming_pdu dynamic with no memory. */
1393 prs_give_memory(&state
->incoming_pdu
, NULL
, 0, true);
1395 talloc_set_destructor(state
, rpc_api_pipe_state_destructor
);
1398 * Ensure we're not sending too much.
1400 if (prs_offset(data
) > cli
->max_xmit_frag
) {
1401 status
= NT_STATUS_INVALID_PARAMETER
;
1405 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli
)));
1407 max_recv_frag
= cli
->max_recv_frag
;
1410 max_recv_frag
= RPC_HEADER_LEN
+ 10 + (sys_random() % 32);
1413 subreq
= cli_api_pipe_send(state
, ev
, cli
->transport
,
1414 (uint8_t *)prs_data_p(data
),
1415 prs_offset(data
), max_recv_frag
);
1416 if (subreq
== NULL
) {
1419 tevent_req_set_callback(subreq
, rpc_api_pipe_trans_done
, req
);
1423 tevent_req_nterror(req
, status
);
1424 return tevent_req_post(req
, ev
);
1430 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
)
1432 struct tevent_req
*req
= tevent_req_callback_data(
1433 subreq
, struct tevent_req
);
1434 struct rpc_api_pipe_state
*state
= tevent_req_data(
1435 req
, struct rpc_api_pipe_state
);
1437 uint8_t *rdata
= NULL
;
1438 uint32_t rdata_len
= 0;
1441 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
1442 TALLOC_FREE(subreq
);
1443 if (!NT_STATUS_IS_OK(status
)) {
1444 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
1445 tevent_req_nterror(req
, status
);
1449 if (rdata
== NULL
) {
1450 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1451 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1452 tevent_req_done(req
);
1457 * Give the memory received from cli_trans as dynamic to the current
1458 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1461 rdata_copy
= (char *)memdup(rdata
, rdata_len
);
1463 if (tevent_req_nomem(rdata_copy
, req
)) {
1466 prs_give_memory(&state
->incoming_frag
, rdata_copy
, rdata_len
, true);
1468 /* Ensure we have enough data for a pdu. */
1469 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1470 &state
->rhdr
, &state
->incoming_frag
);
1471 if (tevent_req_nomem(subreq
, req
)) {
1474 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1477 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
)
1479 struct tevent_req
*req
= tevent_req_callback_data(
1480 subreq
, struct tevent_req
);
1481 struct rpc_api_pipe_state
*state
= tevent_req_data(
1482 req
, struct rpc_api_pipe_state
);
1485 uint32_t rdata_len
= 0;
1487 status
= get_complete_frag_recv(subreq
);
1488 TALLOC_FREE(subreq
);
1489 if (!NT_STATUS_IS_OK(status
)) {
1490 DEBUG(5, ("get_complete_frag failed: %s\n",
1491 nt_errstr(status
)));
1492 tevent_req_nterror(req
, status
);
1496 status
= cli_pipe_validate_current_pdu(
1497 state
->cli
, &state
->rhdr
, &state
->incoming_frag
,
1498 state
->expected_pkt_type
, &rdata
, &rdata_len
,
1499 &state
->incoming_pdu
);
1501 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1502 (unsigned)prs_data_size(&state
->incoming_frag
),
1503 (unsigned)state
->incoming_pdu_offset
,
1504 nt_errstr(status
)));
1506 if (!NT_STATUS_IS_OK(status
)) {
1507 tevent_req_nterror(req
, status
);
1511 if ((state
->rhdr
.flags
& DCERPC_PFC_FLAG_FIRST
)
1512 && (state
->rhdr
.pack_type
[0] == 0)) {
1514 * Set the data type correctly for big-endian data on the
1517 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1519 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1520 prs_set_endian_data(&state
->incoming_pdu
, RPC_BIG_ENDIAN
);
1523 * Check endianness on subsequent packets.
1525 if (state
->incoming_frag
.bigendian_data
1526 != state
->incoming_pdu
.bigendian_data
) {
1527 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1529 state
->incoming_pdu
.bigendian_data
?"big":"little",
1530 state
->incoming_frag
.bigendian_data
?"big":"little"));
1531 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1535 /* Now copy the data portion out of the pdu into rbuf. */
1536 if (!prs_force_grow(&state
->incoming_pdu
, rdata_len
)) {
1537 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1541 memcpy(prs_data_p(&state
->incoming_pdu
) + state
->incoming_pdu_offset
,
1542 rdata
, (size_t)rdata_len
);
1543 state
->incoming_pdu_offset
+= rdata_len
;
1545 status
= cli_pipe_reset_current_pdu(state
->cli
, &state
->rhdr
,
1546 &state
->incoming_frag
);
1547 if (!NT_STATUS_IS_OK(status
)) {
1548 tevent_req_nterror(req
, status
);
1552 if (state
->rhdr
.flags
& DCERPC_PFC_FLAG_LAST
) {
1553 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1554 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1555 (unsigned)prs_data_size(&state
->incoming_pdu
)));
1556 tevent_req_done(req
);
1560 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1561 &state
->rhdr
, &state
->incoming_frag
);
1562 if (tevent_req_nomem(subreq
, req
)) {
1565 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1568 static NTSTATUS
rpc_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1569 prs_struct
*reply_pdu
)
1571 struct rpc_api_pipe_state
*state
= tevent_req_data(
1572 req
, struct rpc_api_pipe_state
);
1575 if (tevent_req_is_nterror(req
, &status
)) {
1579 *reply_pdu
= state
->incoming_pdu
;
1580 reply_pdu
->mem_ctx
= mem_ctx
;
1583 * Prevent state->incoming_pdu from being freed in
1584 * rpc_api_pipe_state_destructor()
1586 prs_init_empty(&state
->incoming_pdu
, state
, UNMARSHALL
);
1588 return NT_STATUS_OK
;
1591 /*******************************************************************
1592 Creates krb5 auth bind.
1593 ********************************************************************/
1595 static NTSTATUS
create_krb5_auth_bind_req( struct rpc_pipe_client
*cli
,
1596 enum dcerpc_AuthLevel auth_level
,
1597 RPC_HDR_AUTH
*pauth_out
,
1598 prs_struct
*auth_data
)
1602 struct kerberos_auth_struct
*a
= cli
->auth
->a_u
.kerberos_auth
;
1603 DATA_BLOB tkt
= data_blob_null
;
1604 DATA_BLOB tkt_wrapped
= data_blob_null
;
1606 /* We may change the pad length before marshalling. */
1607 init_rpc_hdr_auth(pauth_out
, DCERPC_AUTH_TYPE_KRB5
, (int)auth_level
, 0, 1);
1609 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1610 a
->service_principal
));
1612 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1614 ret
= cli_krb5_get_ticket(a
->service_principal
, 0, &tkt
,
1615 &a
->session_key
, (uint32
)AP_OPTS_MUTUAL_REQUIRED
, NULL
, NULL
, NULL
);
1618 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1620 a
->service_principal
,
1621 error_message(ret
) ));
1623 data_blob_free(&tkt
);
1624 prs_mem_free(auth_data
);
1625 return NT_STATUS_INVALID_PARAMETER
;
1628 /* wrap that up in a nice GSS-API wrapping */
1629 tkt_wrapped
= spnego_gen_krb5_wrap(tkt
, TOK_ID_KRB_AP_REQ
);
1631 data_blob_free(&tkt
);
1633 /* Auth len in the rpc header doesn't include auth_header. */
1634 if (!prs_copy_data_in(auth_data
, (char *)tkt_wrapped
.data
, tkt_wrapped
.length
)) {
1635 data_blob_free(&tkt_wrapped
);
1636 prs_mem_free(auth_data
);
1637 return NT_STATUS_NO_MEMORY
;
1640 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1641 dump_data(5, tkt_wrapped
.data
, tkt_wrapped
.length
);
1643 data_blob_free(&tkt_wrapped
);
1644 return NT_STATUS_OK
;
1646 return NT_STATUS_INVALID_PARAMETER
;
1650 /*******************************************************************
1651 Creates SPNEGO NTLMSSP auth bind.
1652 ********************************************************************/
1654 static NTSTATUS
create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1655 enum dcerpc_AuthLevel auth_level
,
1656 RPC_HDR_AUTH
*pauth_out
,
1657 prs_struct
*auth_data
)
1660 DATA_BLOB null_blob
= data_blob_null
;
1661 DATA_BLOB request
= data_blob_null
;
1662 DATA_BLOB spnego_msg
= data_blob_null
;
1664 /* We may change the pad length before marshalling. */
1665 init_rpc_hdr_auth(pauth_out
, DCERPC_AUTH_TYPE_SPNEGO
, (int)auth_level
, 0, 1);
1667 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1668 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1672 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1673 data_blob_free(&request
);
1674 prs_mem_free(auth_data
);
1678 /* Wrap this in SPNEGO. */
1679 spnego_msg
= gen_negTokenInit(OID_NTLMSSP
, request
);
1681 data_blob_free(&request
);
1683 /* Auth len in the rpc header doesn't include auth_header. */
1684 if (!prs_copy_data_in(auth_data
, (char *)spnego_msg
.data
, spnego_msg
.length
)) {
1685 data_blob_free(&spnego_msg
);
1686 prs_mem_free(auth_data
);
1687 return NT_STATUS_NO_MEMORY
;
1690 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1691 dump_data(5, spnego_msg
.data
, spnego_msg
.length
);
1693 data_blob_free(&spnego_msg
);
1694 return NT_STATUS_OK
;
1697 /*******************************************************************
1698 Creates NTLMSSP auth bind.
1699 ********************************************************************/
1701 static NTSTATUS
create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1702 enum dcerpc_AuthLevel auth_level
,
1703 RPC_HDR_AUTH
*pauth_out
,
1704 prs_struct
*auth_data
)
1707 DATA_BLOB null_blob
= data_blob_null
;
1708 DATA_BLOB request
= data_blob_null
;
1710 /* We may change the pad length before marshalling. */
1711 init_rpc_hdr_auth(pauth_out
, DCERPC_AUTH_TYPE_NTLMSSP
, (int)auth_level
, 0, 1);
1713 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1714 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1718 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1719 data_blob_free(&request
);
1720 prs_mem_free(auth_data
);
1724 /* Auth len in the rpc header doesn't include auth_header. */
1725 if (!prs_copy_data_in(auth_data
, (char *)request
.data
, request
.length
)) {
1726 data_blob_free(&request
);
1727 prs_mem_free(auth_data
);
1728 return NT_STATUS_NO_MEMORY
;
1731 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1732 dump_data(5, request
.data
, request
.length
);
1734 data_blob_free(&request
);
1735 return NT_STATUS_OK
;
1738 /*******************************************************************
1739 Creates schannel auth bind.
1740 ********************************************************************/
1742 static NTSTATUS
create_schannel_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1743 enum dcerpc_AuthLevel auth_level
,
1744 RPC_HDR_AUTH
*pauth_out
,
1745 prs_struct
*auth_data
)
1747 struct NL_AUTH_MESSAGE r
;
1748 enum ndr_err_code ndr_err
;
1751 /* We may change the pad length before marshalling. */
1752 init_rpc_hdr_auth(pauth_out
, DCERPC_AUTH_TYPE_SCHANNEL
, (int)auth_level
, 0, 1);
1754 /* Use lp_workgroup() if domain not specified */
1756 if (!cli
->auth
->domain
|| !cli
->auth
->domain
[0]) {
1757 cli
->auth
->domain
= talloc_strdup(cli
, lp_workgroup());
1758 if (cli
->auth
->domain
== NULL
) {
1759 return NT_STATUS_NO_MEMORY
;
1764 * Now marshall the data into the auth parse_struct.
1767 r
.MessageType
= NL_NEGOTIATE_REQUEST
;
1768 r
.Flags
= NL_FLAG_OEM_NETBIOS_DOMAIN_NAME
|
1769 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME
;
1770 r
.oem_netbios_domain
.a
= cli
->auth
->domain
;
1771 r
.oem_netbios_computer
.a
= global_myname();
1773 ndr_err
= ndr_push_struct_blob(&blob
, talloc_tos(), NULL
, &r
,
1774 (ndr_push_flags_fn_t
)ndr_push_NL_AUTH_MESSAGE
);
1775 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1776 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1777 prs_mem_free(auth_data
);
1778 return ndr_map_error2ntstatus(ndr_err
);
1781 if (DEBUGLEVEL
>= 10) {
1782 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE
, &r
);
1785 if (!prs_copy_data_in(auth_data
, (const char *)blob
.data
, blob
.length
))
1787 prs_mem_free(auth_data
);
1788 return NT_STATUS_NO_MEMORY
;
1791 return NT_STATUS_OK
;
1794 /*******************************************************************
1795 Creates the internals of a DCE/RPC bind request or alter context PDU.
1796 ********************************************************************/
1798 static NTSTATUS
create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type
,
1799 prs_struct
*rpc_out
,
1801 const struct ndr_syntax_id
*abstract
,
1802 const struct ndr_syntax_id
*transfer
,
1803 RPC_HDR_AUTH
*phdr_auth
,
1804 prs_struct
*pauth_info
)
1808 RPC_CONTEXT rpc_ctx
;
1809 uint16 auth_len
= prs_offset(pauth_info
);
1810 uint8 ss_padding_len
= 0;
1811 uint16 frag_len
= 0;
1813 /* create the RPC context. */
1814 init_rpc_context(&rpc_ctx
, 0 /* context id */, abstract
, transfer
);
1816 /* create the bind request RPC_HDR_RB */
1817 init_rpc_hdr_rb(&hdr_rb
, RPC_MAX_PDU_FRAG_LEN
, RPC_MAX_PDU_FRAG_LEN
, 0x0, &rpc_ctx
);
1819 /* Start building the frag length. */
1820 frag_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1822 /* Do we need to pad ? */
1824 uint16 data_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1825 if (data_len
% CLIENT_NDR_PADDING_SIZE
) {
1826 ss_padding_len
= CLIENT_NDR_PADDING_SIZE
- (data_len
% CLIENT_NDR_PADDING_SIZE
);
1827 phdr_auth
->auth_pad_len
= ss_padding_len
;
1829 frag_len
+= RPC_HDR_AUTH_LEN
+ auth_len
+ ss_padding_len
;
1832 /* Create the request RPC_HDR */
1833 init_rpc_hdr(&hdr
, pkt_type
, DCERPC_PFC_FLAG_FIRST
|DCERPC_PFC_FLAG_LAST
, rpc_call_id
, frag_len
, auth_len
);
1835 /* Marshall the RPC header */
1836 if(!smb_io_rpc_hdr("hdr" , &hdr
, rpc_out
, 0)) {
1837 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1838 return NT_STATUS_NO_MEMORY
;
1841 /* Marshall the bind request data */
1842 if(!smb_io_rpc_hdr_rb("", &hdr_rb
, rpc_out
, 0)) {
1843 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1844 return NT_STATUS_NO_MEMORY
;
1848 * Grow the outgoing buffer to store any auth info.
1852 if (ss_padding_len
) {
1853 char pad
[CLIENT_NDR_PADDING_SIZE
];
1854 memset(pad
, '\0', CLIENT_NDR_PADDING_SIZE
);
1855 if (!prs_copy_data_in(rpc_out
, pad
, ss_padding_len
)) {
1856 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1857 return NT_STATUS_NO_MEMORY
;
1861 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth
, rpc_out
, 0)) {
1862 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1863 return NT_STATUS_NO_MEMORY
;
1867 if(!prs_append_prs_data( rpc_out
, pauth_info
)) {
1868 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1869 return NT_STATUS_NO_MEMORY
;
1873 return NT_STATUS_OK
;
1876 /*******************************************************************
1877 Creates a DCE/RPC bind request.
1878 ********************************************************************/
1880 static NTSTATUS
create_rpc_bind_req(struct rpc_pipe_client
*cli
,
1881 prs_struct
*rpc_out
,
1883 const struct ndr_syntax_id
*abstract
,
1884 const struct ndr_syntax_id
*transfer
,
1885 enum pipe_auth_type auth_type
,
1886 enum dcerpc_AuthLevel auth_level
)
1888 RPC_HDR_AUTH hdr_auth
;
1889 prs_struct auth_info
;
1890 NTSTATUS ret
= NT_STATUS_OK
;
1892 ZERO_STRUCT(hdr_auth
);
1893 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
1894 return NT_STATUS_NO_MEMORY
;
1896 switch (auth_type
) {
1897 case PIPE_AUTH_TYPE_SCHANNEL
:
1898 ret
= create_schannel_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1899 if (!NT_STATUS_IS_OK(ret
)) {
1900 prs_mem_free(&auth_info
);
1905 case PIPE_AUTH_TYPE_NTLMSSP
:
1906 ret
= create_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1907 if (!NT_STATUS_IS_OK(ret
)) {
1908 prs_mem_free(&auth_info
);
1913 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1914 ret
= create_spnego_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1915 if (!NT_STATUS_IS_OK(ret
)) {
1916 prs_mem_free(&auth_info
);
1921 case PIPE_AUTH_TYPE_KRB5
:
1922 ret
= create_krb5_auth_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1923 if (!NT_STATUS_IS_OK(ret
)) {
1924 prs_mem_free(&auth_info
);
1929 case PIPE_AUTH_TYPE_NONE
:
1933 /* "Can't" happen. */
1934 return NT_STATUS_INVALID_INFO_CLASS
;
1937 ret
= create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND
,
1945 prs_mem_free(&auth_info
);
1949 /*******************************************************************
1950 Create and add the NTLMSSP sign/seal auth header and data.
1951 ********************************************************************/
1953 static NTSTATUS
add_ntlmssp_auth_footer(struct rpc_pipe_client
*cli
,
1955 uint32 ss_padding_len
,
1956 prs_struct
*outgoing_pdu
)
1958 RPC_HDR_AUTH auth_info
;
1960 DATA_BLOB auth_blob
= data_blob_null
;
1961 uint16 data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1963 if (!cli
->auth
->a_u
.ntlmssp_state
) {
1964 return NT_STATUS_INVALID_PARAMETER
;
1967 /* Init and marshall the auth header. */
1968 init_rpc_hdr_auth(&auth_info
,
1969 map_pipe_auth_type_to_rpc_auth_type(
1970 cli
->auth
->auth_type
),
1971 cli
->auth
->auth_level
,
1973 1 /* context id. */);
1975 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1976 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1977 data_blob_free(&auth_blob
);
1978 return NT_STATUS_NO_MEMORY
;
1981 switch (cli
->auth
->auth_level
) {
1982 case DCERPC_AUTH_LEVEL_PRIVACY
:
1983 /* Data portion is encrypted. */
1984 status
= ntlmssp_seal_packet(cli
->auth
->a_u
.ntlmssp_state
,
1985 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1987 (unsigned char *)prs_data_p(outgoing_pdu
),
1988 (size_t)prs_offset(outgoing_pdu
),
1990 if (!NT_STATUS_IS_OK(status
)) {
1991 data_blob_free(&auth_blob
);
1996 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1997 /* Data is signed. */
1998 status
= ntlmssp_sign_packet(cli
->auth
->a_u
.ntlmssp_state
,
1999 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
2001 (unsigned char *)prs_data_p(outgoing_pdu
),
2002 (size_t)prs_offset(outgoing_pdu
),
2004 if (!NT_STATUS_IS_OK(status
)) {
2005 data_blob_free(&auth_blob
);
2012 smb_panic("bad auth level");
2014 return NT_STATUS_INVALID_PARAMETER
;
2017 /* Finally marshall the blob. */
2019 if (!prs_copy_data_in(outgoing_pdu
, (const char *)auth_blob
.data
, NTLMSSP_SIG_SIZE
)) {
2020 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2021 (unsigned int)NTLMSSP_SIG_SIZE
));
2022 data_blob_free(&auth_blob
);
2023 return NT_STATUS_NO_MEMORY
;
2026 data_blob_free(&auth_blob
);
2027 return NT_STATUS_OK
;
2030 /*******************************************************************
2031 Create and add the schannel sign/seal auth header and data.
2032 ********************************************************************/
2034 static NTSTATUS
add_schannel_auth_footer(struct rpc_pipe_client
*cli
,
2036 uint32 ss_padding_len
,
2037 prs_struct
*outgoing_pdu
)
2039 RPC_HDR_AUTH auth_info
;
2040 struct schannel_state
*sas
= cli
->auth
->a_u
.schannel_auth
;
2041 char *data_p
= prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
2042 size_t data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
2047 return NT_STATUS_INVALID_PARAMETER
;
2050 /* Init and marshall the auth header. */
2051 init_rpc_hdr_auth(&auth_info
,
2052 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
->auth_type
),
2053 cli
->auth
->auth_level
,
2055 1 /* context id. */);
2057 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
2058 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2059 return NT_STATUS_NO_MEMORY
;
2062 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2065 switch (cli
->auth
->auth_level
) {
2066 case DCERPC_AUTH_LEVEL_PRIVACY
:
2067 status
= netsec_outgoing_packet(sas
,
2074 case DCERPC_AUTH_LEVEL_INTEGRITY
:
2075 status
= netsec_outgoing_packet(sas
,
2083 status
= NT_STATUS_INTERNAL_ERROR
;
2087 if (!NT_STATUS_IS_OK(status
)) {
2088 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2089 nt_errstr(status
)));
2093 if (DEBUGLEVEL
>= 10) {
2094 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob
);
2097 /* Finally marshall the blob. */
2098 if (!prs_copy_data_in(outgoing_pdu
, (const char *)blob
.data
, blob
.length
)) {
2099 return NT_STATUS_NO_MEMORY
;
2102 return NT_STATUS_OK
;
2105 /*******************************************************************
2106 Calculate how much data we're going to send in this packet, also
2107 work out any sign/seal padding length.
2108 ********************************************************************/
2110 static uint32
calculate_data_len_tosend(struct rpc_pipe_client
*cli
,
2114 uint32
*p_ss_padding
)
2116 uint32 data_space
, data_len
;
2119 if ((data_left
> 0) && (sys_random() % 2)) {
2120 data_left
= MAX(data_left
/2, 1);
2124 switch (cli
->auth
->auth_level
) {
2125 case DCERPC_AUTH_LEVEL_NONE
:
2126 case DCERPC_AUTH_LEVEL_CONNECT
:
2127 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
;
2128 data_len
= MIN(data_space
, data_left
);
2131 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ data_len
;
2134 case DCERPC_AUTH_LEVEL_INTEGRITY
:
2135 case DCERPC_AUTH_LEVEL_PRIVACY
:
2136 /* Treat the same for all authenticated rpc requests. */
2137 switch(cli
->auth
->auth_type
) {
2138 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2139 case PIPE_AUTH_TYPE_NTLMSSP
:
2140 *p_auth_len
= NTLMSSP_SIG_SIZE
;
2142 case PIPE_AUTH_TYPE_SCHANNEL
:
2143 *p_auth_len
= RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
;
2146 smb_panic("bad auth type");
2150 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
-
2151 RPC_HDR_AUTH_LEN
- *p_auth_len
;
2153 data_len
= MIN(data_space
, data_left
);
2155 if (data_len
% CLIENT_NDR_PADDING_SIZE
) {
2156 *p_ss_padding
= CLIENT_NDR_PADDING_SIZE
- (data_len
% CLIENT_NDR_PADDING_SIZE
);
2158 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ /* Normal headers. */
2159 data_len
+ *p_ss_padding
+ /* data plus padding. */
2160 RPC_HDR_AUTH_LEN
+ *p_auth_len
; /* Auth header and auth data. */
2164 smb_panic("bad auth level");
2170 /*******************************************************************
2172 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2173 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2174 and deals with signing/sealing details.
2175 ********************************************************************/
2177 struct rpc_api_pipe_req_state
{
2178 struct event_context
*ev
;
2179 struct rpc_pipe_client
*cli
;
2182 prs_struct
*req_data
;
2183 uint32_t req_data_sent
;
2184 prs_struct outgoing_frag
;
2185 prs_struct reply_pdu
;
2188 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state
*s
)
2190 prs_mem_free(&s
->outgoing_frag
);
2191 prs_mem_free(&s
->reply_pdu
);
2195 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
2196 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
2197 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
2198 bool *is_last_frag
);
2200 struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
2201 struct event_context
*ev
,
2202 struct rpc_pipe_client
*cli
,
2204 prs_struct
*req_data
)
2206 struct tevent_req
*req
, *subreq
;
2207 struct rpc_api_pipe_req_state
*state
;
2211 req
= tevent_req_create(mem_ctx
, &state
,
2212 struct rpc_api_pipe_req_state
);
2218 state
->op_num
= op_num
;
2219 state
->req_data
= req_data
;
2220 state
->req_data_sent
= 0;
2221 state
->call_id
= get_rpc_call_id();
2223 if (cli
->max_xmit_frag
2224 < RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ RPC_MAX_SIGN_SIZE
) {
2225 /* Server is screwed up ! */
2226 status
= NT_STATUS_INVALID_PARAMETER
;
2230 prs_init_empty(&state
->reply_pdu
, state
, UNMARSHALL
);
2232 if (!prs_init(&state
->outgoing_frag
, cli
->max_xmit_frag
,
2237 talloc_set_destructor(state
, rpc_api_pipe_req_state_destructor
);
2239 status
= prepare_next_frag(state
, &is_last_frag
);
2240 if (!NT_STATUS_IS_OK(status
)) {
2245 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
2246 &state
->outgoing_frag
,
2247 DCERPC_PKT_RESPONSE
);
2248 if (subreq
== NULL
) {
2251 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
2253 subreq
= rpc_write_send(
2254 state
, ev
, cli
->transport
,
2255 (uint8_t *)prs_data_p(&state
->outgoing_frag
),
2256 prs_offset(&state
->outgoing_frag
));
2257 if (subreq
== NULL
) {
2260 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
2266 tevent_req_nterror(req
, status
);
2267 return tevent_req_post(req
, ev
);
2273 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
2277 RPC_HDR_REQ hdr_req
;
2278 uint32_t data_sent_thistime
;
2282 uint32_t ss_padding
;
2284 char pad
[8] = { 0, };
2287 data_left
= prs_offset(state
->req_data
) - state
->req_data_sent
;
2289 data_sent_thistime
= calculate_data_len_tosend(
2290 state
->cli
, data_left
, &frag_len
, &auth_len
, &ss_padding
);
2292 if (state
->req_data_sent
== 0) {
2293 flags
= DCERPC_PFC_FLAG_FIRST
;
2296 if (data_sent_thistime
== data_left
) {
2297 flags
|= DCERPC_PFC_FLAG_LAST
;
2300 if (!prs_set_offset(&state
->outgoing_frag
, 0)) {
2301 return NT_STATUS_NO_MEMORY
;
2304 /* Create and marshall the header and request header. */
2305 init_rpc_hdr(&hdr
, DCERPC_PKT_REQUEST
, flags
, state
->call_id
, frag_len
,
2308 if (!smb_io_rpc_hdr("hdr ", &hdr
, &state
->outgoing_frag
, 0)) {
2309 return NT_STATUS_NO_MEMORY
;
2312 /* Create the rpc request RPC_HDR_REQ */
2313 init_rpc_hdr_req(&hdr_req
, prs_offset(state
->req_data
),
2316 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req
,
2317 &state
->outgoing_frag
, 0)) {
2318 return NT_STATUS_NO_MEMORY
;
2321 /* Copy in the data, plus any ss padding. */
2322 if (!prs_append_some_prs_data(&state
->outgoing_frag
,
2323 state
->req_data
, state
->req_data_sent
,
2324 data_sent_thistime
)) {
2325 return NT_STATUS_NO_MEMORY
;
2328 /* Copy the sign/seal padding data. */
2329 if (!prs_copy_data_in(&state
->outgoing_frag
, pad
, ss_padding
)) {
2330 return NT_STATUS_NO_MEMORY
;
2333 /* Generate any auth sign/seal and add the auth footer. */
2334 switch (state
->cli
->auth
->auth_type
) {
2335 case PIPE_AUTH_TYPE_NONE
:
2336 status
= NT_STATUS_OK
;
2338 case PIPE_AUTH_TYPE_NTLMSSP
:
2339 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2340 status
= add_ntlmssp_auth_footer(state
->cli
, &hdr
, ss_padding
,
2341 &state
->outgoing_frag
);
2343 case PIPE_AUTH_TYPE_SCHANNEL
:
2344 status
= add_schannel_auth_footer(state
->cli
, &hdr
, ss_padding
,
2345 &state
->outgoing_frag
);
2348 status
= NT_STATUS_INVALID_PARAMETER
;
2352 state
->req_data_sent
+= data_sent_thistime
;
2353 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
2358 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
2360 struct tevent_req
*req
= tevent_req_callback_data(
2361 subreq
, struct tevent_req
);
2362 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2363 req
, struct rpc_api_pipe_req_state
);
2367 status
= rpc_write_recv(subreq
);
2368 TALLOC_FREE(subreq
);
2369 if (!NT_STATUS_IS_OK(status
)) {
2370 tevent_req_nterror(req
, status
);
2374 status
= prepare_next_frag(state
, &is_last_frag
);
2375 if (!NT_STATUS_IS_OK(status
)) {
2376 tevent_req_nterror(req
, status
);
2381 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2382 &state
->outgoing_frag
,
2383 DCERPC_PKT_RESPONSE
);
2384 if (tevent_req_nomem(subreq
, req
)) {
2387 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
2389 subreq
= rpc_write_send(
2391 state
->cli
->transport
,
2392 (uint8_t *)prs_data_p(&state
->outgoing_frag
),
2393 prs_offset(&state
->outgoing_frag
));
2394 if (tevent_req_nomem(subreq
, req
)) {
2397 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
2402 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
2404 struct tevent_req
*req
= tevent_req_callback_data(
2405 subreq
, struct tevent_req
);
2406 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2407 req
, struct rpc_api_pipe_req_state
);
2410 status
= rpc_api_pipe_recv(subreq
, state
, &state
->reply_pdu
);
2411 TALLOC_FREE(subreq
);
2412 if (!NT_STATUS_IS_OK(status
)) {
2413 tevent_req_nterror(req
, status
);
2416 tevent_req_done(req
);
2419 NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2420 prs_struct
*reply_pdu
)
2422 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2423 req
, struct rpc_api_pipe_req_state
);
2426 if (tevent_req_is_nterror(req
, &status
)) {
2428 * We always have to initialize to reply pdu, even if there is
2429 * none. The rpccli_* caller routines expect this.
2431 prs_init_empty(reply_pdu
, mem_ctx
, UNMARSHALL
);
2435 *reply_pdu
= state
->reply_pdu
;
2436 reply_pdu
->mem_ctx
= mem_ctx
;
2439 * Prevent state->req_pdu from being freed in
2440 * rpc_api_pipe_req_state_destructor()
2442 prs_init_empty(&state
->reply_pdu
, state
, UNMARSHALL
);
2444 return NT_STATUS_OK
;
2448 /****************************************************************************
2449 Set the handle state.
2450 ****************************************************************************/
2452 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client
*cli
,
2453 const char *pipe_name
, uint16 device_state
)
2455 bool state_set
= False
;
2457 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
2458 char *rparam
= NULL
;
2460 uint32 rparam_len
, rdata_len
;
2462 if (pipe_name
== NULL
)
2465 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2466 cli
->fnum
, pipe_name
, device_state
));
2468 /* create parameters: device state */
2469 SSVAL(param
, 0, device_state
);
2471 /* create setup parameters. */
2473 setup
[1] = cli
->fnum
; /* pipe file handle. got this from an SMBOpenX. */
2475 /* send the data on \PIPE\ */
2476 if (cli_api_pipe(cli
->cli
, "\\PIPE\\",
2477 setup
, 2, 0, /* setup, length, max */
2478 param
, 2, 0, /* param, length, max */
2479 NULL
, 0, 1024, /* data, length, max */
2480 &rparam
, &rparam_len
, /* return param, length */
2481 &rdata
, &rdata_len
)) /* return data, length */
2483 DEBUG(5, ("Set Handle state: return OK\n"));
2494 /****************************************************************************
2495 Check the rpc bind acknowledge response.
2496 ****************************************************************************/
2498 static bool check_bind_response(RPC_HDR_BA
*hdr_ba
,
2499 const struct ndr_syntax_id
*transfer
)
2501 if ( hdr_ba
->addr
.len
== 0) {
2502 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2505 /* check the transfer syntax */
2506 if ((hdr_ba
->transfer
.if_version
!= transfer
->if_version
) ||
2507 (memcmp(&hdr_ba
->transfer
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
2508 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2512 if (hdr_ba
->res
.num_results
!= 0x1 || hdr_ba
->res
.result
!= 0) {
2513 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2514 hdr_ba
->res
.num_results
, hdr_ba
->res
.reason
));
2517 DEBUG(5,("check_bind_response: accepted!\n"));
2521 /*******************************************************************
2522 Creates a DCE/RPC bind authentication response.
2523 This is the packet that is sent back to the server once we
2524 have received a BIND-ACK, to finish the third leg of
2525 the authentication handshake.
2526 ********************************************************************/
2528 static NTSTATUS
create_rpc_bind_auth3(struct rpc_pipe_client
*cli
,
2530 enum pipe_auth_type auth_type
,
2531 enum dcerpc_AuthLevel auth_level
,
2532 DATA_BLOB
*pauth_blob
,
2533 prs_struct
*rpc_out
)
2536 RPC_HDR_AUTH hdr_auth
;
2539 /* Create the request RPC_HDR */
2540 init_rpc_hdr(&hdr
, DCERPC_PKT_AUTH3
, DCERPC_PFC_FLAG_FIRST
|DCERPC_PFC_FLAG_LAST
, rpc_call_id
,
2541 RPC_HEADER_LEN
+ 4 /* pad */ + RPC_HDR_AUTH_LEN
+ pauth_blob
->length
,
2542 pauth_blob
->length
);
2545 if(!smb_io_rpc_hdr("hdr", &hdr
, rpc_out
, 0)) {
2546 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2547 return NT_STATUS_NO_MEMORY
;
2551 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2552 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2555 /* 4 bytes padding. */
2556 if (!prs_uint32("pad", rpc_out
, 0, &pad
)) {
2557 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2558 return NT_STATUS_NO_MEMORY
;
2561 /* Create the request RPC_HDR_AUTHA */
2562 init_rpc_hdr_auth(&hdr_auth
,
2563 map_pipe_auth_type_to_rpc_auth_type(auth_type
),
2566 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rpc_out
, 0)) {
2567 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2568 return NT_STATUS_NO_MEMORY
;
2572 * Append the auth data to the outgoing buffer.
2575 if(!prs_copy_data_in(rpc_out
, (char *)pauth_blob
->data
, pauth_blob
->length
)) {
2576 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2577 return NT_STATUS_NO_MEMORY
;
2580 return NT_STATUS_OK
;
2583 /*******************************************************************
2584 Creates a DCE/RPC bind alter context authentication request which
2585 may contain a spnego auth blobl
2586 ********************************************************************/
2588 static NTSTATUS
create_rpc_alter_context(uint32 rpc_call_id
,
2589 const struct ndr_syntax_id
*abstract
,
2590 const struct ndr_syntax_id
*transfer
,
2591 enum dcerpc_AuthLevel auth_level
,
2592 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
2593 prs_struct
*rpc_out
)
2595 RPC_HDR_AUTH hdr_auth
;
2596 prs_struct auth_info
;
2597 NTSTATUS ret
= NT_STATUS_OK
;
2599 ZERO_STRUCT(hdr_auth
);
2600 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
2601 return NT_STATUS_NO_MEMORY
;
2603 /* We may change the pad length before marshalling. */
2604 init_rpc_hdr_auth(&hdr_auth
, DCERPC_AUTH_TYPE_SPNEGO
, (int)auth_level
, 0, 1);
2606 if (pauth_blob
->length
) {
2607 if (!prs_copy_data_in(&auth_info
, (const char *)pauth_blob
->data
, pauth_blob
->length
)) {
2608 prs_mem_free(&auth_info
);
2609 return NT_STATUS_NO_MEMORY
;
2613 ret
= create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER
,
2620 prs_mem_free(&auth_info
);
2624 /****************************************************************************
2626 ****************************************************************************/
2628 struct rpc_pipe_bind_state
{
2629 struct event_context
*ev
;
2630 struct rpc_pipe_client
*cli
;
2632 uint32_t rpc_call_id
;
2635 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state
*state
)
2637 prs_mem_free(&state
->rpc_out
);
2641 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
2642 static NTSTATUS
rpc_finish_auth3_bind_send(struct tevent_req
*req
,
2643 struct rpc_pipe_bind_state
*state
,
2644 struct rpc_hdr_info
*phdr
,
2645 prs_struct
*reply_pdu
);
2646 static void rpc_bind_auth3_write_done(struct tevent_req
*subreq
);
2647 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req
*req
,
2648 struct rpc_pipe_bind_state
*state
,
2649 struct rpc_hdr_info
*phdr
,
2650 prs_struct
*reply_pdu
);
2651 static void rpc_bind_ntlmssp_api_done(struct tevent_req
*subreq
);
2653 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
2654 struct event_context
*ev
,
2655 struct rpc_pipe_client
*cli
,
2656 struct cli_pipe_auth_data
*auth
)
2658 struct tevent_req
*req
, *subreq
;
2659 struct rpc_pipe_bind_state
*state
;
2662 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
2667 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2668 rpccli_pipe_txt(talloc_tos(), cli
),
2669 (unsigned int)auth
->auth_type
,
2670 (unsigned int)auth
->auth_level
));
2674 state
->rpc_call_id
= get_rpc_call_id();
2676 prs_init_empty(&state
->rpc_out
, state
, MARSHALL
);
2677 talloc_set_destructor(state
, rpc_pipe_bind_state_destructor
);
2679 cli
->auth
= talloc_move(cli
, &auth
);
2681 /* Marshall the outgoing data. */
2682 status
= create_rpc_bind_req(cli
, &state
->rpc_out
,
2684 &cli
->abstract_syntax
,
2685 &cli
->transfer_syntax
,
2686 cli
->auth
->auth_type
,
2687 cli
->auth
->auth_level
);
2689 if (!NT_STATUS_IS_OK(status
)) {
2693 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
2694 DCERPC_PKT_BIND_ACK
);
2695 if (subreq
== NULL
) {
2698 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2702 tevent_req_nterror(req
, status
);
2703 return tevent_req_post(req
, ev
);
2709 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
2711 struct tevent_req
*req
= tevent_req_callback_data(
2712 subreq
, struct tevent_req
);
2713 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2714 req
, struct rpc_pipe_bind_state
);
2715 prs_struct reply_pdu
;
2716 struct rpc_hdr_info hdr
;
2717 struct rpc_hdr_ba_info hdr_ba
;
2720 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &reply_pdu
);
2721 TALLOC_FREE(subreq
);
2722 if (!NT_STATUS_IS_OK(status
)) {
2723 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2724 rpccli_pipe_txt(talloc_tos(), state
->cli
),
2725 nt_errstr(status
)));
2726 tevent_req_nterror(req
, status
);
2730 /* Unmarshall the RPC header */
2731 if (!smb_io_rpc_hdr("hdr", &hdr
, &reply_pdu
, 0)) {
2732 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2733 prs_mem_free(&reply_pdu
);
2734 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2738 if (!smb_io_rpc_hdr_ba("", &hdr_ba
, &reply_pdu
, 0)) {
2739 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2741 prs_mem_free(&reply_pdu
);
2742 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2746 if (!check_bind_response(&hdr_ba
, &state
->cli
->transfer_syntax
)) {
2747 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2748 prs_mem_free(&reply_pdu
);
2749 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2753 state
->cli
->max_xmit_frag
= hdr_ba
.bba
.max_tsize
;
2754 state
->cli
->max_recv_frag
= hdr_ba
.bba
.max_rsize
;
2757 * For authenticated binds we may need to do 3 or 4 leg binds.
2760 switch(state
->cli
->auth
->auth_type
) {
2762 case PIPE_AUTH_TYPE_NONE
:
2763 case PIPE_AUTH_TYPE_SCHANNEL
:
2764 /* Bind complete. */
2765 prs_mem_free(&reply_pdu
);
2766 tevent_req_done(req
);
2769 case PIPE_AUTH_TYPE_NTLMSSP
:
2770 /* Need to send AUTH3 packet - no reply. */
2771 status
= rpc_finish_auth3_bind_send(req
, state
, &hdr
,
2773 prs_mem_free(&reply_pdu
);
2774 if (!NT_STATUS_IS_OK(status
)) {
2775 tevent_req_nterror(req
, status
);
2779 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2780 /* Need to send alter context request and reply. */
2781 status
= rpc_finish_spnego_ntlmssp_bind_send(req
, state
, &hdr
,
2783 prs_mem_free(&reply_pdu
);
2784 if (!NT_STATUS_IS_OK(status
)) {
2785 tevent_req_nterror(req
, status
);
2789 case PIPE_AUTH_TYPE_KRB5
:
2793 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2794 (unsigned int)state
->cli
->auth
->auth_type
));
2795 prs_mem_free(&reply_pdu
);
2796 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2800 static NTSTATUS
rpc_finish_auth3_bind_send(struct tevent_req
*req
,
2801 struct rpc_pipe_bind_state
*state
,
2802 struct rpc_hdr_info
*phdr
,
2803 prs_struct
*reply_pdu
)
2805 DATA_BLOB server_response
= data_blob_null
;
2806 DATA_BLOB client_reply
= data_blob_null
;
2807 struct rpc_hdr_auth_info hdr_auth
;
2808 struct tevent_req
*subreq
;
2811 if ((phdr
->auth_len
== 0)
2812 || (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
2813 return NT_STATUS_INVALID_PARAMETER
;
2816 if (!prs_set_offset(
2818 phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
2819 return NT_STATUS_INVALID_PARAMETER
;
2822 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, reply_pdu
, 0)) {
2823 return NT_STATUS_INVALID_PARAMETER
;
2826 /* TODO - check auth_type/auth_level match. */
2828 server_response
= data_blob_talloc(talloc_tos(), NULL
, phdr
->auth_len
);
2829 prs_copy_data_out((char *)server_response
.data
, reply_pdu
,
2832 status
= ntlmssp_update(state
->cli
->auth
->a_u
.ntlmssp_state
,
2833 server_response
, &client_reply
);
2835 if (!NT_STATUS_IS_OK(status
)) {
2836 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2837 "blob failed: %s.\n", nt_errstr(status
)));
2841 prs_init_empty(&state
->rpc_out
, talloc_tos(), MARSHALL
);
2843 status
= create_rpc_bind_auth3(state
->cli
, state
->rpc_call_id
,
2844 state
->cli
->auth
->auth_type
,
2845 state
->cli
->auth
->auth_level
,
2846 &client_reply
, &state
->rpc_out
);
2847 data_blob_free(&client_reply
);
2849 if (!NT_STATUS_IS_OK(status
)) {
2853 subreq
= rpc_write_send(state
, state
->ev
, state
->cli
->transport
,
2854 (uint8_t *)prs_data_p(&state
->rpc_out
),
2855 prs_offset(&state
->rpc_out
));
2856 if (subreq
== NULL
) {
2857 return NT_STATUS_NO_MEMORY
;
2859 tevent_req_set_callback(subreq
, rpc_bind_auth3_write_done
, req
);
2860 return NT_STATUS_OK
;
2863 static void rpc_bind_auth3_write_done(struct tevent_req
*subreq
)
2865 struct tevent_req
*req
= tevent_req_callback_data(
2866 subreq
, struct tevent_req
);
2869 status
= rpc_write_recv(subreq
);
2870 TALLOC_FREE(subreq
);
2871 if (!NT_STATUS_IS_OK(status
)) {
2872 tevent_req_nterror(req
, status
);
2875 tevent_req_done(req
);
2878 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req
*req
,
2879 struct rpc_pipe_bind_state
*state
,
2880 struct rpc_hdr_info
*phdr
,
2881 prs_struct
*reply_pdu
)
2883 DATA_BLOB server_spnego_response
= data_blob_null
;
2884 DATA_BLOB server_ntlm_response
= data_blob_null
;
2885 DATA_BLOB client_reply
= data_blob_null
;
2886 DATA_BLOB tmp_blob
= data_blob_null
;
2887 RPC_HDR_AUTH hdr_auth
;
2888 struct tevent_req
*subreq
;
2891 if ((phdr
->auth_len
== 0)
2892 || (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
2893 return NT_STATUS_INVALID_PARAMETER
;
2896 /* Process the returned NTLMSSP blob first. */
2897 if (!prs_set_offset(
2899 phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
2900 return NT_STATUS_INVALID_PARAMETER
;
2903 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, reply_pdu
, 0)) {
2904 return NT_STATUS_INVALID_PARAMETER
;
2907 server_spnego_response
= data_blob(NULL
, phdr
->auth_len
);
2908 prs_copy_data_out((char *)server_spnego_response
.data
,
2909 reply_pdu
, phdr
->auth_len
);
2912 * The server might give us back two challenges - tmp_blob is for the
2915 if (!spnego_parse_challenge(server_spnego_response
,
2916 &server_ntlm_response
, &tmp_blob
)) {
2917 data_blob_free(&server_spnego_response
);
2918 data_blob_free(&server_ntlm_response
);
2919 data_blob_free(&tmp_blob
);
2920 return NT_STATUS_INVALID_PARAMETER
;
2923 /* We're finished with the server spnego response and the tmp_blob. */
2924 data_blob_free(&server_spnego_response
);
2925 data_blob_free(&tmp_blob
);
2927 status
= ntlmssp_update(state
->cli
->auth
->a_u
.ntlmssp_state
,
2928 server_ntlm_response
, &client_reply
);
2930 /* Finished with the server_ntlm response */
2931 data_blob_free(&server_ntlm_response
);
2933 if (!NT_STATUS_IS_OK(status
)) {
2934 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2935 "using server blob failed.\n"));
2936 data_blob_free(&client_reply
);
2940 /* SPNEGO wrap the client reply. */
2941 tmp_blob
= spnego_gen_auth(client_reply
);
2942 data_blob_free(&client_reply
);
2943 client_reply
= tmp_blob
;
2944 tmp_blob
= data_blob_null
;
2946 /* Now prepare the alter context pdu. */
2947 prs_init_empty(&state
->rpc_out
, state
, MARSHALL
);
2949 status
= create_rpc_alter_context(state
->rpc_call_id
,
2950 &state
->cli
->abstract_syntax
,
2951 &state
->cli
->transfer_syntax
,
2952 state
->cli
->auth
->auth_level
,
2955 data_blob_free(&client_reply
);
2957 if (!NT_STATUS_IS_OK(status
)) {
2961 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2962 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
);
2963 if (subreq
== NULL
) {
2964 return NT_STATUS_NO_MEMORY
;
2966 tevent_req_set_callback(subreq
, rpc_bind_ntlmssp_api_done
, req
);
2967 return NT_STATUS_OK
;
2970 static void rpc_bind_ntlmssp_api_done(struct tevent_req
*subreq
)
2972 struct tevent_req
*req
= tevent_req_callback_data(
2973 subreq
, struct tevent_req
);
2974 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2975 req
, struct rpc_pipe_bind_state
);
2976 DATA_BLOB server_spnego_response
= data_blob_null
;
2977 DATA_BLOB tmp_blob
= data_blob_null
;
2978 prs_struct reply_pdu
;
2979 struct rpc_hdr_info hdr
;
2980 struct rpc_hdr_auth_info hdr_auth
;
2983 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &reply_pdu
);
2984 TALLOC_FREE(subreq
);
2985 if (!NT_STATUS_IS_OK(status
)) {
2986 tevent_req_nterror(req
, status
);
2990 /* Get the auth blob from the reply. */
2991 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr
, &reply_pdu
, 0)) {
2992 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2993 "unmarshall RPC_HDR.\n"));
2994 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2998 if (!prs_set_offset(
3000 hdr
.frag_len
- hdr
.auth_len
- RPC_HDR_AUTH_LEN
)) {
3001 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3005 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, &reply_pdu
, 0)) {
3006 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3010 server_spnego_response
= data_blob(NULL
, hdr
.auth_len
);
3011 prs_copy_data_out((char *)server_spnego_response
.data
, &reply_pdu
,
3014 /* Check we got a valid auth response. */
3015 if (!spnego_parse_auth_response(server_spnego_response
, NT_STATUS_OK
,
3016 OID_NTLMSSP
, &tmp_blob
)) {
3017 data_blob_free(&server_spnego_response
);
3018 data_blob_free(&tmp_blob
);
3019 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3023 data_blob_free(&server_spnego_response
);
3024 data_blob_free(&tmp_blob
);
3026 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3027 "%s.\n", rpccli_pipe_txt(talloc_tos(), state
->cli
)));
3028 tevent_req_done(req
);
3031 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
3033 return tevent_req_simple_recv_ntstatus(req
);
3036 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
3037 struct cli_pipe_auth_data
*auth
)
3039 TALLOC_CTX
*frame
= talloc_stackframe();
3040 struct event_context
*ev
;
3041 struct tevent_req
*req
;
3042 NTSTATUS status
= NT_STATUS_OK
;
3044 ev
= event_context_init(frame
);
3046 status
= NT_STATUS_NO_MEMORY
;
3050 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
3052 status
= NT_STATUS_NO_MEMORY
;
3056 if (!tevent_req_poll(req
, ev
)) {
3057 status
= map_nt_error_from_unix(errno
);
3061 status
= rpc_pipe_bind_recv(req
);
3067 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
3068 unsigned int timeout
)
3070 struct cli_state
*cli
;
3072 if (rpc_cli
->transport
->transport
== NCACN_NP
) {
3073 cli
= rpc_pipe_np_smb_conn(rpc_cli
);
3077 return cli_set_timeout(cli
, timeout
);
3080 if (rpc_cli
->transport
->transport
== NCACN_IP_TCP
||
3081 rpc_cli
->transport
->transport
== NCALRPC
) {
3082 return rpccli_set_sock_timeout(rpc_cli
, timeout
);
3085 if (rpc_cli
->transport
->transport
== NCACN_INTERNAL
) {
3086 cli
= rpc_pipe_smbd_smb_conn(rpc_cli
);
3090 return cli_set_timeout(cli
, timeout
);
3096 bool rpccli_get_pwd_hash(struct rpc_pipe_client
*rpc_cli
, uint8_t nt_hash
[16])
3098 struct cli_state
*cli
;
3100 if ((rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_NTLMSSP
)
3101 || (rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
)) {
3102 memcpy(nt_hash
, rpc_cli
->auth
->a_u
.ntlmssp_state
->nt_hash
, 16);
3106 cli
= rpc_pipe_np_smb_conn(rpc_cli
);
3110 E_md4hash(cli
->password
? cli
->password
: "", nt_hash
);
3114 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
3115 struct cli_pipe_auth_data
**presult
)
3117 struct cli_pipe_auth_data
*result
;
3119 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3120 if (result
== NULL
) {
3121 return NT_STATUS_NO_MEMORY
;
3124 result
->auth_type
= PIPE_AUTH_TYPE_NONE
;
3125 result
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
3127 result
->user_name
= talloc_strdup(result
, "");
3128 result
->domain
= talloc_strdup(result
, "");
3129 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3130 TALLOC_FREE(result
);
3131 return NT_STATUS_NO_MEMORY
;
3135 return NT_STATUS_OK
;
3138 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data
*auth
)
3140 ntlmssp_end(&auth
->a_u
.ntlmssp_state
);
3144 static NTSTATUS
rpccli_ntlmssp_bind_data(TALLOC_CTX
*mem_ctx
,
3145 enum pipe_auth_type auth_type
,
3146 enum dcerpc_AuthLevel auth_level
,
3148 const char *username
,
3149 const char *password
,
3150 struct cli_pipe_auth_data
**presult
)
3152 struct cli_pipe_auth_data
*result
;
3155 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3156 if (result
== NULL
) {
3157 return NT_STATUS_NO_MEMORY
;
3160 result
->auth_type
= auth_type
;
3161 result
->auth_level
= auth_level
;
3163 result
->user_name
= talloc_strdup(result
, username
);
3164 result
->domain
= talloc_strdup(result
, domain
);
3165 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3166 status
= NT_STATUS_NO_MEMORY
;
3170 status
= ntlmssp_client_start(&result
->a_u
.ntlmssp_state
);
3171 if (!NT_STATUS_IS_OK(status
)) {
3175 talloc_set_destructor(result
, cli_auth_ntlmssp_data_destructor
);
3177 status
= ntlmssp_set_username(result
->a_u
.ntlmssp_state
, username
);
3178 if (!NT_STATUS_IS_OK(status
)) {
3182 status
= ntlmssp_set_domain(result
->a_u
.ntlmssp_state
, domain
);
3183 if (!NT_STATUS_IS_OK(status
)) {
3187 status
= ntlmssp_set_password(result
->a_u
.ntlmssp_state
, password
);
3188 if (!NT_STATUS_IS_OK(status
)) {
3193 * Turn off sign+seal to allow selected auth level to turn it back on.
3195 result
->a_u
.ntlmssp_state
->neg_flags
&=
3196 ~(NTLMSSP_NEGOTIATE_SIGN
| NTLMSSP_NEGOTIATE_SEAL
);
3198 if (auth_level
== DCERPC_AUTH_LEVEL_INTEGRITY
) {
3199 result
->a_u
.ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
3200 } else if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
3201 result
->a_u
.ntlmssp_state
->neg_flags
3202 |= NTLMSSP_NEGOTIATE_SEAL
| NTLMSSP_NEGOTIATE_SIGN
;
3206 return NT_STATUS_OK
;
3209 TALLOC_FREE(result
);
3213 NTSTATUS
rpccli_schannel_bind_data(TALLOC_CTX
*mem_ctx
, const char *domain
,
3214 enum dcerpc_AuthLevel auth_level
,
3215 struct netlogon_creds_CredentialState
*creds
,
3216 struct cli_pipe_auth_data
**presult
)
3218 struct cli_pipe_auth_data
*result
;
3220 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3221 if (result
== NULL
) {
3222 return NT_STATUS_NO_MEMORY
;
3225 result
->auth_type
= PIPE_AUTH_TYPE_SCHANNEL
;
3226 result
->auth_level
= auth_level
;
3228 result
->user_name
= talloc_strdup(result
, "");
3229 result
->domain
= talloc_strdup(result
, domain
);
3230 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3234 result
->a_u
.schannel_auth
= talloc(result
, struct schannel_state
);
3235 if (result
->a_u
.schannel_auth
== NULL
) {
3239 result
->a_u
.schannel_auth
->state
= SCHANNEL_STATE_START
;
3240 result
->a_u
.schannel_auth
->seq_num
= 0;
3241 result
->a_u
.schannel_auth
->initiator
= true;
3242 result
->a_u
.schannel_auth
->creds
= creds
;
3245 return NT_STATUS_OK
;
3248 TALLOC_FREE(result
);
3249 return NT_STATUS_NO_MEMORY
;
3253 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct
*auth
)
3255 data_blob_free(&auth
->session_key
);
3260 static NTSTATUS
rpccli_kerberos_bind_data(TALLOC_CTX
*mem_ctx
,
3261 enum dcerpc_AuthLevel auth_level
,
3262 const char *service_princ
,
3263 const char *username
,
3264 const char *password
,
3265 struct cli_pipe_auth_data
**presult
)
3268 struct cli_pipe_auth_data
*result
;
3270 if ((username
!= NULL
) && (password
!= NULL
)) {
3271 int ret
= kerberos_kinit_password(username
, password
, 0, NULL
);
3273 return NT_STATUS_ACCESS_DENIED
;
3277 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3278 if (result
== NULL
) {
3279 return NT_STATUS_NO_MEMORY
;
3282 result
->auth_type
= PIPE_AUTH_TYPE_KRB5
;
3283 result
->auth_level
= auth_level
;
3286 * Username / domain need fixing!
3288 result
->user_name
= talloc_strdup(result
, "");
3289 result
->domain
= talloc_strdup(result
, "");
3290 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3294 result
->a_u
.kerberos_auth
= TALLOC_ZERO_P(
3295 result
, struct kerberos_auth_struct
);
3296 if (result
->a_u
.kerberos_auth
== NULL
) {
3299 talloc_set_destructor(result
->a_u
.kerberos_auth
,
3300 cli_auth_kerberos_data_destructor
);
3302 result
->a_u
.kerberos_auth
->service_principal
= talloc_strdup(
3303 result
, service_princ
);
3304 if (result
->a_u
.kerberos_auth
->service_principal
== NULL
) {
3309 return NT_STATUS_OK
;
3312 TALLOC_FREE(result
);
3313 return NT_STATUS_NO_MEMORY
;
3315 return NT_STATUS_NOT_SUPPORTED
;
3320 * Create an rpc pipe client struct, connecting to a tcp port.
3322 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
3324 const struct ndr_syntax_id
*abstract_syntax
,
3325 struct rpc_pipe_client
**presult
)
3327 struct rpc_pipe_client
*result
;
3328 struct sockaddr_storage addr
;
3332 result
= TALLOC_ZERO_P(mem_ctx
, struct rpc_pipe_client
);
3333 if (result
== NULL
) {
3334 return NT_STATUS_NO_MEMORY
;
3337 result
->abstract_syntax
= *abstract_syntax
;
3338 result
->transfer_syntax
= ndr_transfer_syntax
;
3339 result
->dispatch
= cli_do_rpc_ndr
;
3340 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3341 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3343 result
->desthost
= talloc_strdup(result
, host
);
3344 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3345 result
, "\\\\%s", result
->desthost
);
3346 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3347 status
= NT_STATUS_NO_MEMORY
;
3351 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3352 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3354 if (!resolve_name(host
, &addr
, 0, false)) {
3355 status
= NT_STATUS_NOT_FOUND
;
3359 status
= open_socket_out(&addr
, port
, 60, &fd
);
3360 if (!NT_STATUS_IS_OK(status
)) {
3363 set_socket_options(fd
, lp_socket_options());
3365 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
3366 if (!NT_STATUS_IS_OK(status
)) {
3371 result
->transport
->transport
= NCACN_IP_TCP
;
3374 return NT_STATUS_OK
;
3377 TALLOC_FREE(result
);
3382 * Determine the tcp port on which a dcerpc interface is listening
3383 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3386 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
3387 const struct ndr_syntax_id
*abstract_syntax
,
3391 struct rpc_pipe_client
*epm_pipe
= NULL
;
3392 struct cli_pipe_auth_data
*auth
= NULL
;
3393 struct dcerpc_binding
*map_binding
= NULL
;
3394 struct dcerpc_binding
*res_binding
= NULL
;
3395 struct epm_twr_t
*map_tower
= NULL
;
3396 struct epm_twr_t
*res_towers
= NULL
;
3397 struct policy_handle
*entry_handle
= NULL
;
3398 uint32_t num_towers
= 0;
3399 uint32_t max_towers
= 1;
3400 struct epm_twr_p_t towers
;
3401 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
3403 if (pport
== NULL
) {
3404 status
= NT_STATUS_INVALID_PARAMETER
;
3408 /* open the connection to the endpoint mapper */
3409 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, 135,
3410 &ndr_table_epmapper
.syntax_id
,
3413 if (!NT_STATUS_IS_OK(status
)) {
3417 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
3418 if (!NT_STATUS_IS_OK(status
)) {
3422 status
= rpc_pipe_bind(epm_pipe
, auth
);
3423 if (!NT_STATUS_IS_OK(status
)) {
3427 /* create tower for asking the epmapper */
3429 map_binding
= TALLOC_ZERO_P(tmp_ctx
, struct dcerpc_binding
);
3430 if (map_binding
== NULL
) {
3431 status
= NT_STATUS_NO_MEMORY
;
3435 map_binding
->transport
= NCACN_IP_TCP
;
3436 map_binding
->object
= *abstract_syntax
;
3437 map_binding
->host
= host
; /* needed? */
3438 map_binding
->endpoint
= "0"; /* correct? needed? */
3440 map_tower
= TALLOC_ZERO_P(tmp_ctx
, struct epm_twr_t
);
3441 if (map_tower
== NULL
) {
3442 status
= NT_STATUS_NO_MEMORY
;
3446 status
= dcerpc_binding_build_tower(tmp_ctx
, map_binding
,
3447 &(map_tower
->tower
));
3448 if (!NT_STATUS_IS_OK(status
)) {
3452 /* allocate further parameters for the epm_Map call */
3454 res_towers
= TALLOC_ARRAY(tmp_ctx
, struct epm_twr_t
, max_towers
);
3455 if (res_towers
== NULL
) {
3456 status
= NT_STATUS_NO_MEMORY
;
3459 towers
.twr
= res_towers
;
3461 entry_handle
= TALLOC_ZERO_P(tmp_ctx
, struct policy_handle
);
3462 if (entry_handle
== NULL
) {
3463 status
= NT_STATUS_NO_MEMORY
;
3467 /* ask the endpoint mapper for the port */
3469 status
= rpccli_epm_Map(epm_pipe
,
3471 CONST_DISCARD(struct GUID
*,
3472 &(abstract_syntax
->uuid
)),
3479 if (!NT_STATUS_IS_OK(status
)) {
3483 if (num_towers
!= 1) {
3484 status
= NT_STATUS_UNSUCCESSFUL
;
3488 /* extract the port from the answer */
3490 status
= dcerpc_binding_from_tower(tmp_ctx
,
3491 &(towers
.twr
->tower
),
3493 if (!NT_STATUS_IS_OK(status
)) {
3497 /* are further checks here necessary? */
3498 if (res_binding
->transport
!= NCACN_IP_TCP
) {
3499 status
= NT_STATUS_UNSUCCESSFUL
;
3503 *pport
= (uint16_t)atoi(res_binding
->endpoint
);
3506 TALLOC_FREE(tmp_ctx
);
3511 * Create a rpc pipe client struct, connecting to a host via tcp.
3512 * The port is determined by asking the endpoint mapper on the given
3515 NTSTATUS
rpc_pipe_open_tcp(TALLOC_CTX
*mem_ctx
, const char *host
,
3516 const struct ndr_syntax_id
*abstract_syntax
,
3517 struct rpc_pipe_client
**presult
)
3522 status
= rpc_pipe_get_tcp_port(host
, abstract_syntax
, &port
);
3523 if (!NT_STATUS_IS_OK(status
)) {
3527 return rpc_pipe_open_tcp_port(mem_ctx
, host
, port
,
3528 abstract_syntax
, presult
);
3531 /********************************************************************
3532 Create a rpc pipe client struct, connecting to a unix domain socket
3533 ********************************************************************/
3534 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
, const char *socket_path
,
3535 const struct ndr_syntax_id
*abstract_syntax
,
3536 struct rpc_pipe_client
**presult
)
3538 struct rpc_pipe_client
*result
;
3539 struct sockaddr_un addr
;
3543 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
3544 if (result
== NULL
) {
3545 return NT_STATUS_NO_MEMORY
;
3548 result
->abstract_syntax
= *abstract_syntax
;
3549 result
->transfer_syntax
= ndr_transfer_syntax
;
3550 result
->dispatch
= cli_do_rpc_ndr
;
3551 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3552 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3554 result
->desthost
= get_myname(result
);
3555 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3556 result
, "\\\\%s", result
->desthost
);
3557 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3558 status
= NT_STATUS_NO_MEMORY
;
3562 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3563 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3565 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3567 status
= map_nt_error_from_unix(errno
);
3572 addr
.sun_family
= AF_UNIX
;
3573 strncpy(addr
.sun_path
, socket_path
, sizeof(addr
.sun_path
));
3575 if (sys_connect(fd
, (struct sockaddr
*)(void *)&addr
) == -1) {
3576 DEBUG(0, ("connect(%s) failed: %s\n", socket_path
,
3579 return map_nt_error_from_unix(errno
);
3582 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
3583 if (!NT_STATUS_IS_OK(status
)) {
3588 result
->transport
->transport
= NCALRPC
;
3591 return NT_STATUS_OK
;
3594 TALLOC_FREE(result
);
3598 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client
*p
)
3600 struct cli_state
*cli
;
3602 cli
= rpc_pipe_np_smb_conn(p
);
3604 DLIST_REMOVE(cli
->pipe_list
, p
);
3609 /****************************************************************************
3610 Open a named pipe over SMB to a remote server.
3612 * CAVEAT CALLER OF THIS FUNCTION:
3613 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3614 * so be sure that this function is called AFTER any structure (vs pointer)
3615 * assignment of the cli. In particular, libsmbclient does structure
3616 * assignments of cli, which invalidates the data in the returned
3617 * rpc_pipe_client if this function is called before the structure assignment
3620 ****************************************************************************/
3622 static NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
3623 const struct ndr_syntax_id
*abstract_syntax
,
3624 struct rpc_pipe_client
**presult
)
3626 struct rpc_pipe_client
*result
;
3629 /* sanity check to protect against crashes */
3632 return NT_STATUS_INVALID_HANDLE
;
3635 result
= TALLOC_ZERO_P(NULL
, struct rpc_pipe_client
);
3636 if (result
== NULL
) {
3637 return NT_STATUS_NO_MEMORY
;
3640 result
->abstract_syntax
= *abstract_syntax
;
3641 result
->transfer_syntax
= ndr_transfer_syntax
;
3642 result
->dispatch
= cli_do_rpc_ndr
;
3643 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3644 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3645 result
->desthost
= talloc_strdup(result
, cli
->desthost
);
3646 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3647 result
, "\\\\%s", result
->desthost
);
3649 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3650 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3652 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3653 TALLOC_FREE(result
);
3654 return NT_STATUS_NO_MEMORY
;
3657 status
= rpc_transport_np_init(result
, cli
, abstract_syntax
,
3658 &result
->transport
);
3659 if (!NT_STATUS_IS_OK(status
)) {
3660 TALLOC_FREE(result
);
3664 result
->transport
->transport
= NCACN_NP
;
3666 DLIST_ADD(cli
->pipe_list
, result
);
3667 talloc_set_destructor(result
, rpc_pipe_client_np_destructor
);
3670 return NT_STATUS_OK
;
3673 NTSTATUS
rpc_pipe_open_local(TALLOC_CTX
*mem_ctx
,
3674 struct rpc_cli_smbd_conn
*conn
,
3675 const struct ndr_syntax_id
*syntax
,
3676 struct rpc_pipe_client
**presult
)
3678 struct rpc_pipe_client
*result
;
3679 struct cli_pipe_auth_data
*auth
;
3682 result
= talloc(mem_ctx
, struct rpc_pipe_client
);
3683 if (result
== NULL
) {
3684 return NT_STATUS_NO_MEMORY
;
3686 result
->abstract_syntax
= *syntax
;
3687 result
->transfer_syntax
= ndr_transfer_syntax
;
3688 result
->dispatch
= cli_do_rpc_ndr
;
3689 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3690 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3691 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3692 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3694 result
->desthost
= talloc_strdup(result
, global_myname());
3695 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3696 result
, "\\\\%s", global_myname());
3697 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3698 TALLOC_FREE(result
);
3699 return NT_STATUS_NO_MEMORY
;
3702 status
= rpc_transport_smbd_init(result
, conn
, syntax
,
3703 &result
->transport
);
3704 if (!NT_STATUS_IS_OK(status
)) {
3705 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3706 nt_errstr(status
)));
3707 TALLOC_FREE(result
);
3711 status
= rpccli_anon_bind_data(result
, &auth
);
3712 if (!NT_STATUS_IS_OK(status
)) {
3713 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3714 nt_errstr(status
)));
3715 TALLOC_FREE(result
);
3719 status
= rpc_pipe_bind(result
, auth
);
3720 if (!NT_STATUS_IS_OK(status
)) {
3721 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status
)));
3722 TALLOC_FREE(result
);
3726 result
->transport
->transport
= NCACN_INTERNAL
;
3729 return NT_STATUS_OK
;
3732 /****************************************************************************
3733 Open a pipe to a remote server.
3734 ****************************************************************************/
3736 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3737 enum dcerpc_transport_t transport
,
3738 const struct ndr_syntax_id
*interface
,
3739 struct rpc_pipe_client
**presult
)
3741 switch (transport
) {
3743 return rpc_pipe_open_tcp(NULL
, cli
->desthost
, interface
,
3746 return rpc_pipe_open_np(cli
, interface
, presult
);
3748 return NT_STATUS_NOT_IMPLEMENTED
;
3752 /****************************************************************************
3753 Open a named pipe to an SMB server and bind anonymously.
3754 ****************************************************************************/
3756 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
3757 enum dcerpc_transport_t transport
,
3758 const struct ndr_syntax_id
*interface
,
3759 struct rpc_pipe_client
**presult
)
3761 struct rpc_pipe_client
*result
;
3762 struct cli_pipe_auth_data
*auth
;
3765 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3766 if (!NT_STATUS_IS_OK(status
)) {
3770 status
= rpccli_anon_bind_data(result
, &auth
);
3771 if (!NT_STATUS_IS_OK(status
)) {
3772 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3773 nt_errstr(status
)));
3774 TALLOC_FREE(result
);
3779 * This is a bit of an abstraction violation due to the fact that an
3780 * anonymous bind on an authenticated SMB inherits the user/domain
3781 * from the enclosing SMB creds
3784 TALLOC_FREE(auth
->user_name
);
3785 TALLOC_FREE(auth
->domain
);
3787 auth
->user_name
= talloc_strdup(auth
, cli
->user_name
);
3788 auth
->domain
= talloc_strdup(auth
, cli
->domain
);
3789 auth
->user_session_key
= data_blob_talloc(auth
,
3790 cli
->user_session_key
.data
,
3791 cli
->user_session_key
.length
);
3793 if ((auth
->user_name
== NULL
) || (auth
->domain
== NULL
)) {
3794 TALLOC_FREE(result
);
3795 return NT_STATUS_NO_MEMORY
;
3798 status
= rpc_pipe_bind(result
, auth
);
3799 if (!NT_STATUS_IS_OK(status
)) {
3801 if (ndr_syntax_id_equal(interface
,
3802 &ndr_table_dssetup
.syntax_id
)) {
3803 /* non AD domains just don't have this pipe, avoid
3804 * level 0 statement in that case - gd */
3807 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3808 "%s failed with error %s\n",
3809 get_pipe_name_from_syntax(talloc_tos(), interface
),
3810 nt_errstr(status
) ));
3811 TALLOC_FREE(result
);
3815 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3816 "%s and bound anonymously.\n",
3817 get_pipe_name_from_syntax(talloc_tos(), interface
),
3821 return NT_STATUS_OK
;
3824 /****************************************************************************
3825 ****************************************************************************/
3827 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
3828 const struct ndr_syntax_id
*interface
,
3829 struct rpc_pipe_client
**presult
)
3831 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
3832 interface
, presult
);
3835 /****************************************************************************
3836 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3837 ****************************************************************************/
3839 static NTSTATUS
cli_rpc_pipe_open_ntlmssp_internal(struct cli_state
*cli
,
3840 const struct ndr_syntax_id
*interface
,
3841 enum dcerpc_transport_t transport
,
3842 enum pipe_auth_type auth_type
,
3843 enum dcerpc_AuthLevel auth_level
,
3845 const char *username
,
3846 const char *password
,
3847 struct rpc_pipe_client
**presult
)
3849 struct rpc_pipe_client
*result
;
3850 struct cli_pipe_auth_data
*auth
;
3853 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3854 if (!NT_STATUS_IS_OK(status
)) {
3858 status
= rpccli_ntlmssp_bind_data(
3859 result
, auth_type
, auth_level
, domain
, username
,
3861 if (!NT_STATUS_IS_OK(status
)) {
3862 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3863 nt_errstr(status
)));
3867 status
= rpc_pipe_bind(result
, auth
);
3868 if (!NT_STATUS_IS_OK(status
)) {
3869 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3870 nt_errstr(status
) ));
3874 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3875 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3876 get_pipe_name_from_syntax(talloc_tos(), interface
),
3877 cli
->desthost
, domain
, username
));
3880 return NT_STATUS_OK
;
3884 TALLOC_FREE(result
);
3888 /****************************************************************************
3890 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3891 ****************************************************************************/
3893 NTSTATUS
cli_rpc_pipe_open_ntlmssp(struct cli_state
*cli
,
3894 const struct ndr_syntax_id
*interface
,
3895 enum dcerpc_transport_t transport
,
3896 enum dcerpc_AuthLevel auth_level
,
3898 const char *username
,
3899 const char *password
,
3900 struct rpc_pipe_client
**presult
)
3902 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3905 PIPE_AUTH_TYPE_NTLMSSP
,
3913 /****************************************************************************
3915 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3916 ****************************************************************************/
3918 NTSTATUS
cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state
*cli
,
3919 const struct ndr_syntax_id
*interface
,
3920 enum dcerpc_transport_t transport
,
3921 enum dcerpc_AuthLevel auth_level
,
3923 const char *username
,
3924 const char *password
,
3925 struct rpc_pipe_client
**presult
)
3927 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3930 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
,
3938 /****************************************************************************
3939 Get a the schannel session key out of an already opened netlogon pipe.
3940 ****************************************************************************/
3941 static NTSTATUS
get_schannel_session_key_common(struct rpc_pipe_client
*netlogon_pipe
,
3942 struct cli_state
*cli
,
3946 enum netr_SchannelType sec_chan_type
= 0;
3947 unsigned char machine_pwd
[16];
3948 const char *machine_account
;
3951 /* Get the machine account credentials from secrets.tdb. */
3952 if (!get_trust_pw_hash(domain
, machine_pwd
, &machine_account
,
3955 DEBUG(0, ("get_schannel_session_key: could not fetch "
3956 "trust account password for domain '%s'\n",
3958 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3961 status
= rpccli_netlogon_setup_creds(netlogon_pipe
,
3962 cli
->desthost
, /* server name */
3963 domain
, /* domain */
3964 global_myname(), /* client name */
3965 machine_account
, /* machine account name */
3970 if (!NT_STATUS_IS_OK(status
)) {
3971 DEBUG(3, ("get_schannel_session_key_common: "
3972 "rpccli_netlogon_setup_creds failed with result %s "
3973 "to server %s, domain %s, machine account %s.\n",
3974 nt_errstr(status
), cli
->desthost
, domain
,
3979 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
3980 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3982 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3985 return NT_STATUS_OK
;;
3988 /****************************************************************************
3989 Open a netlogon pipe and get the schannel session key.
3990 Now exposed to external callers.
3991 ****************************************************************************/
3994 NTSTATUS
get_schannel_session_key(struct cli_state
*cli
,
3997 struct rpc_pipe_client
**presult
)
3999 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
4002 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
.syntax_id
,
4004 if (!NT_STATUS_IS_OK(status
)) {
4008 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
4010 if (!NT_STATUS_IS_OK(status
)) {
4011 TALLOC_FREE(netlogon_pipe
);
4015 *presult
= netlogon_pipe
;
4016 return NT_STATUS_OK
;
4019 /****************************************************************************
4021 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4022 using session_key. sign and seal.
4024 The *pdc will be stolen onto this new pipe
4025 ****************************************************************************/
4027 NTSTATUS
cli_rpc_pipe_open_schannel_with_key(struct cli_state
*cli
,
4028 const struct ndr_syntax_id
*interface
,
4029 enum dcerpc_transport_t transport
,
4030 enum dcerpc_AuthLevel auth_level
,
4032 struct netlogon_creds_CredentialState
**pdc
,
4033 struct rpc_pipe_client
**presult
)
4035 struct rpc_pipe_client
*result
;
4036 struct cli_pipe_auth_data
*auth
;
4039 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
4040 if (!NT_STATUS_IS_OK(status
)) {
4044 status
= rpccli_schannel_bind_data(result
, domain
, auth_level
,
4046 if (!NT_STATUS_IS_OK(status
)) {
4047 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4048 nt_errstr(status
)));
4049 TALLOC_FREE(result
);
4053 status
= rpc_pipe_bind(result
, auth
);
4054 if (!NT_STATUS_IS_OK(status
)) {
4055 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4056 "cli_rpc_pipe_bind failed with error %s\n",
4057 nt_errstr(status
) ));
4058 TALLOC_FREE(result
);
4063 * The credentials on a new netlogon pipe are the ones we are passed
4064 * in - reference them in
4066 result
->dc
= talloc_move(result
, pdc
);
4068 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4069 "for domain %s and bound using schannel.\n",
4070 get_pipe_name_from_syntax(talloc_tos(), interface
),
4071 cli
->desthost
, domain
));
4074 return NT_STATUS_OK
;
4077 /****************************************************************************
4078 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4079 Fetch the session key ourselves using a temporary netlogon pipe. This
4080 version uses an ntlmssp auth bound netlogon pipe to get the key.
4081 ****************************************************************************/
4083 static NTSTATUS
get_schannel_session_key_auth_ntlmssp(struct cli_state
*cli
,
4085 const char *username
,
4086 const char *password
,
4088 struct rpc_pipe_client
**presult
)
4090 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
4093 status
= cli_rpc_pipe_open_spnego_ntlmssp(
4094 cli
, &ndr_table_netlogon
.syntax_id
, NCACN_NP
,
4095 DCERPC_AUTH_LEVEL_PRIVACY
,
4096 domain
, username
, password
, &netlogon_pipe
);
4097 if (!NT_STATUS_IS_OK(status
)) {
4101 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
4103 if (!NT_STATUS_IS_OK(status
)) {
4104 TALLOC_FREE(netlogon_pipe
);
4108 *presult
= netlogon_pipe
;
4109 return NT_STATUS_OK
;
4112 /****************************************************************************
4113 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4114 Fetch the session key ourselves using a temporary netlogon pipe. This version
4115 uses an ntlmssp bind to get the session key.
4116 ****************************************************************************/
4118 NTSTATUS
cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
*cli
,
4119 const struct ndr_syntax_id
*interface
,
4120 enum dcerpc_transport_t transport
,
4121 enum dcerpc_AuthLevel auth_level
,
4123 const char *username
,
4124 const char *password
,
4125 struct rpc_pipe_client
**presult
)
4127 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
4128 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
4129 struct rpc_pipe_client
*result
= NULL
;
4132 status
= get_schannel_session_key_auth_ntlmssp(
4133 cli
, domain
, username
, password
, &neg_flags
, &netlogon_pipe
);
4134 if (!NT_STATUS_IS_OK(status
)) {
4135 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4136 "key from server %s for domain %s.\n",
4137 cli
->desthost
, domain
));
4141 status
= cli_rpc_pipe_open_schannel_with_key(
4142 cli
, interface
, transport
, auth_level
, domain
, &netlogon_pipe
->dc
,
4145 /* Now we've bound using the session key we can close the netlog pipe. */
4146 TALLOC_FREE(netlogon_pipe
);
4148 if (NT_STATUS_IS_OK(status
)) {
4154 /****************************************************************************
4155 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4156 Fetch the session key ourselves using a temporary netlogon pipe.
4157 ****************************************************************************/
4159 NTSTATUS
cli_rpc_pipe_open_schannel(struct cli_state
*cli
,
4160 const struct ndr_syntax_id
*interface
,
4161 enum dcerpc_transport_t transport
,
4162 enum dcerpc_AuthLevel auth_level
,
4164 struct rpc_pipe_client
**presult
)
4166 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
4167 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
4168 struct rpc_pipe_client
*result
= NULL
;
4171 status
= get_schannel_session_key(cli
, domain
, &neg_flags
,
4173 if (!NT_STATUS_IS_OK(status
)) {
4174 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4175 "key from server %s for domain %s.\n",
4176 cli
->desthost
, domain
));
4180 status
= cli_rpc_pipe_open_schannel_with_key(
4181 cli
, interface
, transport
, auth_level
, domain
, &netlogon_pipe
->dc
,
4184 /* Now we've bound using the session key we can close the netlog pipe. */
4185 TALLOC_FREE(netlogon_pipe
);
4187 if (NT_STATUS_IS_OK(status
)) {
4194 /****************************************************************************
4195 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4196 The idea is this can be called with service_princ, username and password all
4197 NULL so long as the caller has a TGT.
4198 ****************************************************************************/
4200 NTSTATUS
cli_rpc_pipe_open_krb5(struct cli_state
*cli
,
4201 const struct ndr_syntax_id
*interface
,
4202 enum dcerpc_AuthLevel auth_level
,
4203 const char *service_princ
,
4204 const char *username
,
4205 const char *password
,
4206 struct rpc_pipe_client
**presult
)
4209 struct rpc_pipe_client
*result
;
4210 struct cli_pipe_auth_data
*auth
;
4213 status
= cli_rpc_pipe_open(cli
, NCACN_NP
, interface
, &result
);
4214 if (!NT_STATUS_IS_OK(status
)) {
4218 status
= rpccli_kerberos_bind_data(result
, auth_level
, service_princ
,
4219 username
, password
, &auth
);
4220 if (!NT_STATUS_IS_OK(status
)) {
4221 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4222 nt_errstr(status
)));
4223 TALLOC_FREE(result
);
4227 status
= rpc_pipe_bind(result
, auth
);
4228 if (!NT_STATUS_IS_OK(status
)) {
4229 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4230 "with error %s\n", nt_errstr(status
)));
4231 TALLOC_FREE(result
);
4236 return NT_STATUS_OK
;
4238 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4239 return NT_STATUS_NOT_IMPLEMENTED
;
4243 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
4244 struct rpc_pipe_client
*cli
,
4245 DATA_BLOB
*session_key
)
4247 if (!session_key
|| !cli
) {
4248 return NT_STATUS_INVALID_PARAMETER
;
4252 return NT_STATUS_INVALID_PARAMETER
;
4255 switch (cli
->auth
->auth_type
) {
4256 case PIPE_AUTH_TYPE_SCHANNEL
:
4257 *session_key
= data_blob_talloc(mem_ctx
,
4258 cli
->auth
->a_u
.schannel_auth
->creds
->session_key
, 16);
4260 case PIPE_AUTH_TYPE_NTLMSSP
:
4261 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
4262 *session_key
= data_blob_talloc(mem_ctx
,
4263 cli
->auth
->a_u
.ntlmssp_state
->session_key
.data
,
4264 cli
->auth
->a_u
.ntlmssp_state
->session_key
.length
);
4266 case PIPE_AUTH_TYPE_KRB5
:
4267 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
4268 *session_key
= data_blob_talloc(mem_ctx
,
4269 cli
->auth
->a_u
.kerberos_auth
->session_key
.data
,
4270 cli
->auth
->a_u
.kerberos_auth
->session_key
.length
);
4272 case PIPE_AUTH_TYPE_NONE
:
4273 *session_key
= data_blob_talloc(mem_ctx
,
4274 cli
->auth
->user_session_key
.data
,
4275 cli
->auth
->user_session_key
.length
);
4278 return NT_STATUS_NO_USER_SESSION_KEY
;
4281 return NT_STATUS_OK
;