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 "../libcli/auth/libcli_auth.h"
22 #include "librpc/gen_ndr/cli_epmapper.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
24 #include "../libcli/auth/schannel.h"
25 #include "../libcli/auth/schannel_proto.h"
26 #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 bool ndr_syntax_from_string(const char *s
, uint32_t version
,
199 struct ndr_syntax_id
*syntax
)
202 status
= GUID_from_string(s
, &syntax
->uuid
);
203 if (!NT_STATUS_IS_OK(status
)) {
204 DEBUG(10, ("GUID_from_string returned %s\n",
208 syntax
->if_version
= version
;
212 /********************************************************************
213 Map internal value to wire value.
214 ********************************************************************/
216 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type
)
220 case PIPE_AUTH_TYPE_NONE
:
221 return DCERPC_AUTH_TYPE_NONE
;
223 case PIPE_AUTH_TYPE_NTLMSSP
:
224 return DCERPC_AUTH_TYPE_NTLMSSP
;
226 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
227 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
228 return DCERPC_AUTH_TYPE_SPNEGO
;
230 case PIPE_AUTH_TYPE_SCHANNEL
:
231 return DCERPC_AUTH_TYPE_SCHANNEL
;
233 case PIPE_AUTH_TYPE_KRB5
:
234 return DCERPC_AUTH_TYPE_KRB5
;
237 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
239 (unsigned int)auth_type
));
245 /********************************************************************
246 Pipe description for a DEBUG
247 ********************************************************************/
248 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
249 struct rpc_pipe_client
*cli
)
251 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
252 if (result
== NULL
) {
258 /********************************************************************
260 ********************************************************************/
262 static uint32
get_rpc_call_id(void)
264 static uint32 call_id
= 0;
269 * Realloc pdu to have a least "size" bytes
272 static bool rpc_grow_buffer(prs_struct
*pdu
, size_t size
)
276 if (prs_data_size(pdu
) >= size
) {
280 extra_size
= size
- prs_data_size(pdu
);
282 if (!prs_force_grow(pdu
, extra_size
)) {
283 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
284 "%d bytes.\n", (int)extra_size
));
288 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
289 (int)extra_size
, prs_data_size(pdu
)));
294 /*******************************************************************
295 Use SMBreadX to get rest of one fragment's worth of rpc data.
296 Reads the whole size or give an error message
297 ********************************************************************/
299 struct rpc_read_state
{
300 struct event_context
*ev
;
301 struct rpc_cli_transport
*transport
;
307 static void rpc_read_done(struct tevent_req
*subreq
);
309 static struct tevent_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
310 struct event_context
*ev
,
311 struct rpc_cli_transport
*transport
,
312 uint8_t *data
, size_t size
)
314 struct tevent_req
*req
, *subreq
;
315 struct rpc_read_state
*state
;
317 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_read_state
);
322 state
->transport
= transport
;
327 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size
));
329 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
331 if (subreq
== NULL
) {
334 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
342 static void rpc_read_done(struct tevent_req
*subreq
)
344 struct tevent_req
*req
= tevent_req_callback_data(
345 subreq
, struct tevent_req
);
346 struct rpc_read_state
*state
= tevent_req_data(
347 req
, struct rpc_read_state
);
351 status
= state
->transport
->read_recv(subreq
, &received
);
353 if (!NT_STATUS_IS_OK(status
)) {
354 tevent_req_nterror(req
, status
);
358 state
->num_read
+= received
;
359 if (state
->num_read
== state
->size
) {
360 tevent_req_done(req
);
364 subreq
= state
->transport
->read_send(state
, state
->ev
,
365 state
->data
+ state
->num_read
,
366 state
->size
- state
->num_read
,
367 state
->transport
->priv
);
368 if (tevent_req_nomem(subreq
, req
)) {
371 tevent_req_set_callback(subreq
, rpc_read_done
, req
);
374 static NTSTATUS
rpc_read_recv(struct tevent_req
*req
)
376 return tevent_req_simple_recv_ntstatus(req
);
379 struct rpc_write_state
{
380 struct event_context
*ev
;
381 struct rpc_cli_transport
*transport
;
387 static void rpc_write_done(struct tevent_req
*subreq
);
389 static struct tevent_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
390 struct event_context
*ev
,
391 struct rpc_cli_transport
*transport
,
392 const uint8_t *data
, size_t size
)
394 struct tevent_req
*req
, *subreq
;
395 struct rpc_write_state
*state
;
397 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_write_state
);
402 state
->transport
= transport
;
405 state
->num_written
= 0;
407 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size
));
409 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
410 if (subreq
== NULL
) {
413 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
420 static void rpc_write_done(struct tevent_req
*subreq
)
422 struct tevent_req
*req
= tevent_req_callback_data(
423 subreq
, struct tevent_req
);
424 struct rpc_write_state
*state
= tevent_req_data(
425 req
, struct rpc_write_state
);
429 status
= state
->transport
->write_recv(subreq
, &written
);
431 if (!NT_STATUS_IS_OK(status
)) {
432 tevent_req_nterror(req
, status
);
436 state
->num_written
+= written
;
438 if (state
->num_written
== state
->size
) {
439 tevent_req_done(req
);
443 subreq
= state
->transport
->write_send(state
, state
->ev
,
444 state
->data
+ state
->num_written
,
445 state
->size
- state
->num_written
,
446 state
->transport
->priv
);
447 if (tevent_req_nomem(subreq
, req
)) {
450 tevent_req_set_callback(subreq
, rpc_write_done
, req
);
453 static NTSTATUS
rpc_write_recv(struct tevent_req
*req
)
455 return tevent_req_simple_recv_ntstatus(req
);
459 static NTSTATUS
parse_rpc_header(struct rpc_pipe_client
*cli
,
460 struct rpc_hdr_info
*prhdr
,
464 * This next call sets the endian bit correctly in current_pdu. We
465 * will propagate this to rbuf later.
468 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr
, pdu
, 0)) {
469 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
470 return NT_STATUS_BUFFER_TOO_SMALL
;
473 if (prhdr
->frag_len
> cli
->max_recv_frag
) {
474 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
475 " we only allow %d\n", (int)prhdr
->frag_len
,
476 (int)cli
->max_recv_frag
));
477 return NT_STATUS_BUFFER_TOO_SMALL
;
483 /****************************************************************************
484 Try and get a PDU's worth of data from current_pdu. If not, then read more
486 ****************************************************************************/
488 struct get_complete_frag_state
{
489 struct event_context
*ev
;
490 struct rpc_pipe_client
*cli
;
491 struct rpc_hdr_info
*prhdr
;
495 static void get_complete_frag_got_header(struct tevent_req
*subreq
);
496 static void get_complete_frag_got_rest(struct tevent_req
*subreq
);
498 static struct tevent_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
499 struct event_context
*ev
,
500 struct rpc_pipe_client
*cli
,
501 struct rpc_hdr_info
*prhdr
,
504 struct tevent_req
*req
, *subreq
;
505 struct get_complete_frag_state
*state
;
509 req
= tevent_req_create(mem_ctx
, &state
,
510 struct get_complete_frag_state
);
516 state
->prhdr
= prhdr
;
519 pdu_len
= prs_data_size(pdu
);
520 if (pdu_len
< RPC_HEADER_LEN
) {
521 if (!rpc_grow_buffer(pdu
, RPC_HEADER_LEN
)) {
522 status
= NT_STATUS_NO_MEMORY
;
525 subreq
= rpc_read_send(
527 state
->cli
->transport
,
528 (uint8_t *)(prs_data_p(state
->pdu
) + pdu_len
),
529 RPC_HEADER_LEN
- pdu_len
);
530 if (subreq
== NULL
) {
531 status
= NT_STATUS_NO_MEMORY
;
534 tevent_req_set_callback(subreq
, get_complete_frag_got_header
,
539 status
= parse_rpc_header(cli
, prhdr
, pdu
);
540 if (!NT_STATUS_IS_OK(status
)) {
545 * Ensure we have frag_len bytes of data.
547 if (pdu_len
< prhdr
->frag_len
) {
548 if (!rpc_grow_buffer(pdu
, prhdr
->frag_len
)) {
549 status
= NT_STATUS_NO_MEMORY
;
552 subreq
= rpc_read_send(state
, state
->ev
,
553 state
->cli
->transport
,
554 (uint8_t *)(prs_data_p(pdu
) + pdu_len
),
555 prhdr
->frag_len
- pdu_len
);
556 if (subreq
== NULL
) {
557 status
= NT_STATUS_NO_MEMORY
;
560 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
,
565 status
= NT_STATUS_OK
;
567 if (NT_STATUS_IS_OK(status
)) {
568 tevent_req_done(req
);
570 tevent_req_nterror(req
, status
);
572 return tevent_req_post(req
, ev
);
575 static void get_complete_frag_got_header(struct tevent_req
*subreq
)
577 struct tevent_req
*req
= tevent_req_callback_data(
578 subreq
, struct tevent_req
);
579 struct get_complete_frag_state
*state
= tevent_req_data(
580 req
, struct get_complete_frag_state
);
583 status
= rpc_read_recv(subreq
);
585 if (!NT_STATUS_IS_OK(status
)) {
586 tevent_req_nterror(req
, status
);
590 status
= parse_rpc_header(state
->cli
, state
->prhdr
, state
->pdu
);
591 if (!NT_STATUS_IS_OK(status
)) {
592 tevent_req_nterror(req
, status
);
596 if (!rpc_grow_buffer(state
->pdu
, state
->prhdr
->frag_len
)) {
597 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
602 * We're here in this piece of code because we've read exactly
603 * RPC_HEADER_LEN bytes into state->pdu.
606 subreq
= rpc_read_send(
607 state
, state
->ev
, state
->cli
->transport
,
608 (uint8_t *)(prs_data_p(state
->pdu
) + RPC_HEADER_LEN
),
609 state
->prhdr
->frag_len
- RPC_HEADER_LEN
);
610 if (tevent_req_nomem(subreq
, req
)) {
613 tevent_req_set_callback(subreq
, get_complete_frag_got_rest
, req
);
616 static void get_complete_frag_got_rest(struct tevent_req
*subreq
)
618 struct tevent_req
*req
= tevent_req_callback_data(
619 subreq
, struct tevent_req
);
622 status
= rpc_read_recv(subreq
);
624 if (!NT_STATUS_IS_OK(status
)) {
625 tevent_req_nterror(req
, status
);
628 tevent_req_done(req
);
631 static NTSTATUS
get_complete_frag_recv(struct tevent_req
*req
)
633 return tevent_req_simple_recv_ntstatus(req
);
636 /****************************************************************************
637 NTLMSSP specific sign/seal.
638 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
639 In fact I should probably abstract these into identical pieces of code... JRA.
640 ****************************************************************************/
642 static NTSTATUS
cli_pipe_verify_ntlmssp(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
643 prs_struct
*current_pdu
,
644 uint8
*p_ss_padding_len
)
646 RPC_HDR_AUTH auth_info
;
647 uint32 save_offset
= prs_offset(current_pdu
);
648 uint32 auth_len
= prhdr
->auth_len
;
649 NTLMSSP_STATE
*ntlmssp_state
= cli
->auth
->a_u
.ntlmssp_state
;
650 unsigned char *data
= NULL
;
652 unsigned char *full_packet_data
= NULL
;
653 size_t full_packet_data_len
;
657 if (cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_NONE
658 || cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_CONNECT
) {
662 if (!ntlmssp_state
) {
663 return NT_STATUS_INVALID_PARAMETER
;
666 /* Ensure there's enough data for an authenticated response. */
667 if ((auth_len
> RPC_MAX_SIGN_SIZE
) ||
668 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
669 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
670 (unsigned int)auth_len
));
671 return NT_STATUS_BUFFER_TOO_SMALL
;
675 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
676 * after the RPC header.
677 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
678 * functions as NTLMv2 checks the rpc headers also.
681 data
= (unsigned char *)(prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
);
682 data_len
= (size_t)(prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
);
684 full_packet_data
= (unsigned char *)prs_data_p(current_pdu
);
685 full_packet_data_len
= prhdr
->frag_len
- auth_len
;
687 /* Pull the auth header and the following data into a blob. */
688 if(!prs_set_offset(current_pdu
, RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
)) {
689 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
690 (unsigned int)RPC_HEADER_LEN
+ (unsigned int)RPC_HDR_RESP_LEN
+ (unsigned int)data_len
));
691 return NT_STATUS_BUFFER_TOO_SMALL
;
694 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
695 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
696 return NT_STATUS_BUFFER_TOO_SMALL
;
699 auth_blob
.data
= (unsigned char *)prs_data_p(current_pdu
) + prs_offset(current_pdu
);
700 auth_blob
.length
= auth_len
;
702 switch (cli
->auth
->auth_level
) {
703 case DCERPC_AUTH_LEVEL_PRIVACY
:
704 /* Data is encrypted. */
705 status
= ntlmssp_unseal_packet(ntlmssp_state
,
708 full_packet_data_len
,
710 if (!NT_STATUS_IS_OK(status
)) {
711 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
712 "packet from %s. Error was %s.\n",
713 rpccli_pipe_txt(talloc_tos(), cli
),
714 nt_errstr(status
) ));
718 case DCERPC_AUTH_LEVEL_INTEGRITY
:
719 /* Data is signed. */
720 status
= ntlmssp_check_packet(ntlmssp_state
,
723 full_packet_data_len
,
725 if (!NT_STATUS_IS_OK(status
)) {
726 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
727 "packet from %s. Error was %s.\n",
728 rpccli_pipe_txt(talloc_tos(), cli
),
729 nt_errstr(status
) ));
734 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
735 "auth level %d\n", cli
->auth
->auth_level
));
736 return NT_STATUS_INVALID_INFO_CLASS
;
740 * Return the current pointer to the data offset.
743 if(!prs_set_offset(current_pdu
, save_offset
)) {
744 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
745 (unsigned int)save_offset
));
746 return NT_STATUS_BUFFER_TOO_SMALL
;
750 * Remember the padding length. We must remove it from the real data
751 * stream once the sign/seal is done.
754 *p_ss_padding_len
= auth_info
.auth_pad_len
;
759 /****************************************************************************
760 schannel specific sign/seal.
761 ****************************************************************************/
763 static NTSTATUS
cli_pipe_verify_schannel(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
764 prs_struct
*current_pdu
,
765 uint8
*p_ss_padding_len
)
767 RPC_HDR_AUTH auth_info
;
768 uint32 auth_len
= prhdr
->auth_len
;
769 uint32 save_offset
= prs_offset(current_pdu
);
770 struct schannel_state
*schannel_auth
=
771 cli
->auth
->a_u
.schannel_auth
;
777 if (cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_NONE
778 || cli
->auth
->auth_level
== DCERPC_AUTH_LEVEL_CONNECT
) {
782 if (auth_len
< RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
) {
783 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len
));
784 return NT_STATUS_INVALID_PARAMETER
;
787 if (!schannel_auth
) {
788 return NT_STATUS_INVALID_PARAMETER
;
791 /* Ensure there's enough data for an authenticated response. */
792 if ((auth_len
> RPC_MAX_SIGN_SIZE
) ||
793 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
794 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
795 (unsigned int)auth_len
));
796 return NT_STATUS_INVALID_PARAMETER
;
799 data_len
= prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
;
801 if(!prs_set_offset(current_pdu
, RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
)) {
802 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
803 (unsigned int)RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
));
804 return NT_STATUS_BUFFER_TOO_SMALL
;
807 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
808 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
809 return NT_STATUS_BUFFER_TOO_SMALL
;
812 if (auth_info
.auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
) {
813 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
814 auth_info
.auth_type
));
815 return NT_STATUS_BUFFER_TOO_SMALL
;
818 blob
= data_blob_const(prs_data_p(current_pdu
) + prs_offset(current_pdu
), auth_len
);
820 if (DEBUGLEVEL
>= 10) {
821 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob
);
824 data
= (uint8_t *)prs_data_p(current_pdu
)+RPC_HEADER_LEN
+RPC_HDR_RESP_LEN
;
826 switch (cli
->auth
->auth_level
) {
827 case DCERPC_AUTH_LEVEL_PRIVACY
:
828 status
= netsec_incoming_packet(schannel_auth
,
835 case DCERPC_AUTH_LEVEL_INTEGRITY
:
836 status
= netsec_incoming_packet(schannel_auth
,
844 status
= NT_STATUS_INTERNAL_ERROR
;
848 if (!NT_STATUS_IS_OK(status
)) {
849 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
850 "Connection to %s (%s).\n",
851 rpccli_pipe_txt(talloc_tos(), cli
),
853 return NT_STATUS_INVALID_PARAMETER
;
857 * Return the current pointer to the data offset.
860 if(!prs_set_offset(current_pdu
, save_offset
)) {
861 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
862 (unsigned int)save_offset
));
863 return NT_STATUS_BUFFER_TOO_SMALL
;
867 * Remember the padding length. We must remove it from the real data
868 * stream once the sign/seal is done.
871 *p_ss_padding_len
= auth_info
.auth_pad_len
;
876 /****************************************************************************
877 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
878 ****************************************************************************/
880 static NTSTATUS
cli_pipe_validate_rpc_response(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
881 prs_struct
*current_pdu
,
882 uint8
*p_ss_padding_len
)
884 NTSTATUS ret
= NT_STATUS_OK
;
886 /* Paranioa checks for auth_len. */
887 if (prhdr
->auth_len
) {
888 if (prhdr
->auth_len
> prhdr
->frag_len
) {
889 return NT_STATUS_INVALID_PARAMETER
;
892 if (prhdr
->auth_len
+ (unsigned int)RPC_HDR_AUTH_LEN
< prhdr
->auth_len
||
893 prhdr
->auth_len
+ (unsigned int)RPC_HDR_AUTH_LEN
< (unsigned int)RPC_HDR_AUTH_LEN
) {
894 /* Integer wrap attempt. */
895 return NT_STATUS_INVALID_PARAMETER
;
900 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
903 switch(cli
->auth
->auth_type
) {
904 case PIPE_AUTH_TYPE_NONE
:
905 if (prhdr
->auth_len
) {
906 DEBUG(3, ("cli_pipe_validate_rpc_response: "
907 "Connection to %s - got non-zero "
909 rpccli_pipe_txt(talloc_tos(), cli
),
910 (unsigned int)prhdr
->auth_len
));
911 return NT_STATUS_INVALID_PARAMETER
;
915 case PIPE_AUTH_TYPE_NTLMSSP
:
916 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
917 ret
= cli_pipe_verify_ntlmssp(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
918 if (!NT_STATUS_IS_OK(ret
)) {
923 case PIPE_AUTH_TYPE_SCHANNEL
:
924 ret
= cli_pipe_verify_schannel(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
925 if (!NT_STATUS_IS_OK(ret
)) {
930 case PIPE_AUTH_TYPE_KRB5
:
931 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
933 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
934 "to %s - unknown internal auth type %u.\n",
935 rpccli_pipe_txt(talloc_tos(), cli
),
936 cli
->auth
->auth_type
));
937 return NT_STATUS_INVALID_INFO_CLASS
;
943 /****************************************************************************
944 Do basic authentication checks on an incoming pdu.
945 ****************************************************************************/
947 static NTSTATUS
cli_pipe_validate_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
948 prs_struct
*current_pdu
,
949 uint8 expected_pkt_type
,
952 prs_struct
*return_data
)
955 NTSTATUS ret
= NT_STATUS_OK
;
956 uint32 current_pdu_len
= prs_data_size(current_pdu
);
958 if (current_pdu_len
!= prhdr
->frag_len
) {
959 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
960 (unsigned int)current_pdu_len
, (unsigned int)prhdr
->frag_len
));
961 return NT_STATUS_INVALID_PARAMETER
;
965 * Point the return values at the real data including the RPC
966 * header. Just in case the caller wants it.
968 *ppdata
= prs_data_p(current_pdu
);
969 *pdata_len
= current_pdu_len
;
971 /* Ensure we have the correct type. */
972 switch (prhdr
->pkt_type
) {
973 case DCERPC_PKT_ALTER_RESP
:
974 case DCERPC_PKT_BIND_ACK
:
976 /* Alter context and bind ack share the same packet definitions. */
980 case DCERPC_PKT_RESPONSE
:
982 RPC_HDR_RESP rhdr_resp
;
983 uint8 ss_padding_len
= 0;
985 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
986 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
987 return NT_STATUS_BUFFER_TOO_SMALL
;
990 /* Here's where we deal with incoming sign/seal. */
991 ret
= cli_pipe_validate_rpc_response(cli
, prhdr
,
992 current_pdu
, &ss_padding_len
);
993 if (!NT_STATUS_IS_OK(ret
)) {
997 /* Point the return values at the NDR data. Remember to remove any ss padding. */
998 *ppdata
= prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
1000 if (current_pdu_len
< RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ ss_padding_len
) {
1001 return NT_STATUS_BUFFER_TOO_SMALL
;
1004 *pdata_len
= current_pdu_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- ss_padding_len
;
1006 /* Remember to remove the auth footer. */
1007 if (prhdr
->auth_len
) {
1008 /* We've already done integer wrap tests on auth_len in
1009 cli_pipe_validate_rpc_response(). */
1010 if (*pdata_len
< RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
) {
1011 return NT_STATUS_BUFFER_TOO_SMALL
;
1013 *pdata_len
-= (RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
);
1016 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1017 current_pdu_len
, *pdata_len
, ss_padding_len
));
1020 * If this is the first reply, and the allocation hint is reasonably, try and
1021 * set up the return_data parse_struct to the correct size.
1024 if ((prs_data_size(return_data
) == 0) && rhdr_resp
.alloc_hint
&& (rhdr_resp
.alloc_hint
< 15*1024*1024)) {
1025 if (!prs_set_buffer_size(return_data
, rhdr_resp
.alloc_hint
)) {
1026 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1027 "too large to allocate\n",
1028 (unsigned int)rhdr_resp
.alloc_hint
));
1029 return NT_STATUS_NO_MEMORY
;
1036 case DCERPC_PKT_BIND_NAK
:
1037 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1038 "received from %s!\n",
1039 rpccli_pipe_txt(talloc_tos(), cli
)));
1040 /* Use this for now... */
1041 return NT_STATUS_NETWORK_ACCESS_DENIED
;
1043 case DCERPC_PKT_FAULT
:
1045 RPC_HDR_RESP rhdr_resp
;
1046 RPC_HDR_FAULT fault_resp
;
1048 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
1049 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1050 return NT_STATUS_BUFFER_TOO_SMALL
;
1053 if(!smb_io_rpc_hdr_fault("fault", &fault_resp
, current_pdu
, 0)) {
1054 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
1055 return NT_STATUS_BUFFER_TOO_SMALL
;
1058 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1059 "code %s received from %s!\n",
1060 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp
.status
)),
1061 rpccli_pipe_txt(talloc_tos(), cli
)));
1062 if (NT_STATUS_IS_OK(fault_resp
.status
)) {
1063 return NT_STATUS_UNSUCCESSFUL
;
1065 return fault_resp
.status
;
1070 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1072 (unsigned int)prhdr
->pkt_type
,
1073 rpccli_pipe_txt(talloc_tos(), cli
)));
1074 return NT_STATUS_INVALID_INFO_CLASS
;
1077 if (prhdr
->pkt_type
!= expected_pkt_type
) {
1078 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1079 "got an unexpected RPC packet type - %u, not %u\n",
1080 rpccli_pipe_txt(talloc_tos(), cli
),
1082 expected_pkt_type
));
1083 return NT_STATUS_INVALID_INFO_CLASS
;
1086 /* Do this just before return - we don't want to modify any rpc header
1087 data before now as we may have needed to do cryptographic actions on
1090 if ((prhdr
->pkt_type
== DCERPC_PKT_BIND_ACK
) && !(prhdr
->flags
& DCERPC_PFC_FLAG_LAST
)) {
1091 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1092 "setting fragment first/last ON.\n"));
1093 prhdr
->flags
|= DCERPC_PFC_FLAG_FIRST
|DCERPC_PFC_FLAG_LAST
;
1096 return NT_STATUS_OK
;
1099 /****************************************************************************
1100 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1101 Normally the frag_len and buffer size will match, but on the first trans
1102 reply there is a theoretical chance that buffer size > frag_len, so we must
1104 ****************************************************************************/
1106 static NTSTATUS
cli_pipe_reset_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
, prs_struct
*current_pdu
)
1108 uint32 current_pdu_len
= prs_data_size(current_pdu
);
1110 if (current_pdu_len
< prhdr
->frag_len
) {
1111 return NT_STATUS_BUFFER_TOO_SMALL
;
1115 if (current_pdu_len
== (uint32
)prhdr
->frag_len
) {
1116 prs_mem_free(current_pdu
);
1117 prs_init_empty(current_pdu
, prs_get_mem_context(current_pdu
), UNMARSHALL
);
1118 /* Make current_pdu dynamic with no memory. */
1119 prs_give_memory(current_pdu
, 0, 0, True
);
1120 return NT_STATUS_OK
;
1124 * Oh no ! More data in buffer than we processed in current pdu.
1125 * Cheat. Move the data down and shrink the buffer.
1128 memcpy(prs_data_p(current_pdu
), prs_data_p(current_pdu
) + prhdr
->frag_len
,
1129 current_pdu_len
- prhdr
->frag_len
);
1131 /* Remember to set the read offset back to zero. */
1132 prs_set_offset(current_pdu
, 0);
1134 /* Shrink the buffer. */
1135 if (!prs_set_buffer_size(current_pdu
, current_pdu_len
- prhdr
->frag_len
)) {
1136 return NT_STATUS_BUFFER_TOO_SMALL
;
1139 return NT_STATUS_OK
;
1142 /****************************************************************************
1143 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1144 ****************************************************************************/
1146 struct cli_api_pipe_state
{
1147 struct event_context
*ev
;
1148 struct rpc_cli_transport
*transport
;
1153 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
);
1154 static void cli_api_pipe_write_done(struct tevent_req
*subreq
);
1155 static void cli_api_pipe_read_done(struct tevent_req
*subreq
);
1157 static struct tevent_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
1158 struct event_context
*ev
,
1159 struct rpc_cli_transport
*transport
,
1160 uint8_t *data
, size_t data_len
,
1161 uint32_t max_rdata_len
)
1163 struct tevent_req
*req
, *subreq
;
1164 struct cli_api_pipe_state
*state
;
1167 req
= tevent_req_create(mem_ctx
, &state
, struct cli_api_pipe_state
);
1172 state
->transport
= transport
;
1174 if (max_rdata_len
< RPC_HEADER_LEN
) {
1176 * For a RPC reply we always need at least RPC_HEADER_LEN
1177 * bytes. We check this here because we will receive
1178 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1180 status
= NT_STATUS_INVALID_PARAMETER
;
1184 if (transport
->trans_send
!= NULL
) {
1185 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
1186 max_rdata_len
, transport
->priv
);
1187 if (subreq
== NULL
) {
1190 tevent_req_set_callback(subreq
, cli_api_pipe_trans_done
, req
);
1195 * If the transport does not provide a "trans" routine, i.e. for
1196 * example the ncacn_ip_tcp transport, do the write/read step here.
1199 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
1200 if (subreq
== NULL
) {
1203 tevent_req_set_callback(subreq
, cli_api_pipe_write_done
, req
);
1206 status
= NT_STATUS_INVALID_PARAMETER
;
1209 tevent_req_nterror(req
, status
);
1210 return tevent_req_post(req
, ev
);
1216 static void cli_api_pipe_trans_done(struct tevent_req
*subreq
)
1218 struct tevent_req
*req
= tevent_req_callback_data(
1219 subreq
, struct tevent_req
);
1220 struct cli_api_pipe_state
*state
= tevent_req_data(
1221 req
, struct cli_api_pipe_state
);
1224 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
1226 TALLOC_FREE(subreq
);
1227 if (!NT_STATUS_IS_OK(status
)) {
1228 tevent_req_nterror(req
, status
);
1231 tevent_req_done(req
);
1234 static void cli_api_pipe_write_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
= rpc_write_recv(subreq
);
1243 TALLOC_FREE(subreq
);
1244 if (!NT_STATUS_IS_OK(status
)) {
1245 tevent_req_nterror(req
, status
);
1249 state
->rdata
= TALLOC_ARRAY(state
, uint8_t, RPC_HEADER_LEN
);
1250 if (tevent_req_nomem(state
->rdata
, req
)) {
1255 * We don't need to use rpc_read_send here, the upper layer will cope
1256 * with a short read, transport->trans_send could also return less
1257 * than state->max_rdata_len.
1259 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
1261 state
->transport
->priv
);
1262 if (tevent_req_nomem(subreq
, req
)) {
1265 tevent_req_set_callback(subreq
, cli_api_pipe_read_done
, req
);
1268 static void cli_api_pipe_read_done(struct tevent_req
*subreq
)
1270 struct tevent_req
*req
= tevent_req_callback_data(
1271 subreq
, struct tevent_req
);
1272 struct cli_api_pipe_state
*state
= tevent_req_data(
1273 req
, struct cli_api_pipe_state
);
1277 status
= state
->transport
->read_recv(subreq
, &received
);
1278 TALLOC_FREE(subreq
);
1279 if (!NT_STATUS_IS_OK(status
)) {
1280 tevent_req_nterror(req
, status
);
1283 state
->rdata_len
= received
;
1284 tevent_req_done(req
);
1287 static NTSTATUS
cli_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1288 uint8_t **prdata
, uint32_t *prdata_len
)
1290 struct cli_api_pipe_state
*state
= tevent_req_data(
1291 req
, struct cli_api_pipe_state
);
1294 if (tevent_req_is_nterror(req
, &status
)) {
1298 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
1299 *prdata_len
= state
->rdata_len
;
1300 return NT_STATUS_OK
;
1303 /****************************************************************************
1304 Send data on an rpc pipe via trans. The prs_struct data must be the last
1305 pdu fragment of an NDR data stream.
1307 Receive response data from an rpc pipe, which may be large...
1309 Read the first fragment: unfortunately have to use SMBtrans for the first
1310 bit, then SMBreadX for subsequent bits.
1312 If first fragment received also wasn't the last fragment, continue
1313 getting fragments until we _do_ receive the last fragment.
1315 Request/Response PDU's look like the following...
1317 |<------------------PDU len----------------------------------------------->|
1318 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1320 +------------+-----------------+-------------+---------------+-------------+
1321 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1322 +------------+-----------------+-------------+---------------+-------------+
1324 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1325 signing & sealing being negotiated.
1327 ****************************************************************************/
1329 struct rpc_api_pipe_state
{
1330 struct event_context
*ev
;
1331 struct rpc_pipe_client
*cli
;
1332 uint8_t expected_pkt_type
;
1334 prs_struct incoming_frag
;
1335 struct rpc_hdr_info rhdr
;
1337 prs_struct incoming_pdu
; /* Incoming reply */
1338 uint32_t incoming_pdu_offset
;
1341 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state
*state
)
1343 prs_mem_free(&state
->incoming_frag
);
1344 prs_mem_free(&state
->incoming_pdu
);
1348 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
);
1349 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
);
1351 static struct tevent_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
1352 struct event_context
*ev
,
1353 struct rpc_pipe_client
*cli
,
1354 prs_struct
*data
, /* Outgoing PDU */
1355 uint8_t expected_pkt_type
)
1357 struct tevent_req
*req
, *subreq
;
1358 struct rpc_api_pipe_state
*state
;
1359 uint16_t max_recv_frag
;
1362 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_api_pipe_state
);
1368 state
->expected_pkt_type
= expected_pkt_type
;
1369 state
->incoming_pdu_offset
= 0;
1371 prs_init_empty(&state
->incoming_frag
, state
, UNMARSHALL
);
1373 prs_init_empty(&state
->incoming_pdu
, state
, UNMARSHALL
);
1374 /* Make incoming_pdu dynamic with no memory. */
1375 prs_give_memory(&state
->incoming_pdu
, NULL
, 0, true);
1377 talloc_set_destructor(state
, rpc_api_pipe_state_destructor
);
1380 * Ensure we're not sending too much.
1382 if (prs_offset(data
) > cli
->max_xmit_frag
) {
1383 status
= NT_STATUS_INVALID_PARAMETER
;
1387 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli
)));
1389 max_recv_frag
= cli
->max_recv_frag
;
1392 max_recv_frag
= RPC_HEADER_LEN
+ 10 + (sys_random() % 32);
1395 subreq
= cli_api_pipe_send(state
, ev
, cli
->transport
,
1396 (uint8_t *)prs_data_p(data
),
1397 prs_offset(data
), max_recv_frag
);
1398 if (subreq
== NULL
) {
1401 tevent_req_set_callback(subreq
, rpc_api_pipe_trans_done
, req
);
1405 tevent_req_nterror(req
, status
);
1406 return tevent_req_post(req
, ev
);
1412 static void rpc_api_pipe_trans_done(struct tevent_req
*subreq
)
1414 struct tevent_req
*req
= tevent_req_callback_data(
1415 subreq
, struct tevent_req
);
1416 struct rpc_api_pipe_state
*state
= tevent_req_data(
1417 req
, struct rpc_api_pipe_state
);
1419 uint8_t *rdata
= NULL
;
1420 uint32_t rdata_len
= 0;
1423 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
1424 TALLOC_FREE(subreq
);
1425 if (!NT_STATUS_IS_OK(status
)) {
1426 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
1427 tevent_req_nterror(req
, status
);
1431 if (rdata
== NULL
) {
1432 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1433 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1434 tevent_req_done(req
);
1439 * Give the memory received from cli_trans as dynamic to the current
1440 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1443 rdata_copy
= (char *)memdup(rdata
, rdata_len
);
1445 if (tevent_req_nomem(rdata_copy
, req
)) {
1448 prs_give_memory(&state
->incoming_frag
, rdata_copy
, rdata_len
, true);
1450 /* Ensure we have enough data for a pdu. */
1451 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1452 &state
->rhdr
, &state
->incoming_frag
);
1453 if (tevent_req_nomem(subreq
, req
)) {
1456 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1459 static void rpc_api_pipe_got_pdu(struct tevent_req
*subreq
)
1461 struct tevent_req
*req
= tevent_req_callback_data(
1462 subreq
, struct tevent_req
);
1463 struct rpc_api_pipe_state
*state
= tevent_req_data(
1464 req
, struct rpc_api_pipe_state
);
1467 uint32_t rdata_len
= 0;
1469 status
= get_complete_frag_recv(subreq
);
1470 TALLOC_FREE(subreq
);
1471 if (!NT_STATUS_IS_OK(status
)) {
1472 DEBUG(5, ("get_complete_frag failed: %s\n",
1473 nt_errstr(status
)));
1474 tevent_req_nterror(req
, status
);
1478 status
= cli_pipe_validate_current_pdu(
1479 state
->cli
, &state
->rhdr
, &state
->incoming_frag
,
1480 state
->expected_pkt_type
, &rdata
, &rdata_len
,
1481 &state
->incoming_pdu
);
1483 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1484 (unsigned)prs_data_size(&state
->incoming_frag
),
1485 (unsigned)state
->incoming_pdu_offset
,
1486 nt_errstr(status
)));
1488 if (!NT_STATUS_IS_OK(status
)) {
1489 tevent_req_nterror(req
, status
);
1493 if ((state
->rhdr
.flags
& DCERPC_PFC_FLAG_FIRST
)
1494 && (state
->rhdr
.pack_type
[0] == 0)) {
1496 * Set the data type correctly for big-endian data on the
1499 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1501 rpccli_pipe_txt(talloc_tos(), state
->cli
)));
1502 prs_set_endian_data(&state
->incoming_pdu
, RPC_BIG_ENDIAN
);
1505 * Check endianness on subsequent packets.
1507 if (state
->incoming_frag
.bigendian_data
1508 != state
->incoming_pdu
.bigendian_data
) {
1509 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1511 state
->incoming_pdu
.bigendian_data
?"big":"little",
1512 state
->incoming_frag
.bigendian_data
?"big":"little"));
1513 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1517 /* Now copy the data portion out of the pdu into rbuf. */
1518 if (!prs_force_grow(&state
->incoming_pdu
, rdata_len
)) {
1519 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1523 memcpy(prs_data_p(&state
->incoming_pdu
) + state
->incoming_pdu_offset
,
1524 rdata
, (size_t)rdata_len
);
1525 state
->incoming_pdu_offset
+= rdata_len
;
1527 status
= cli_pipe_reset_current_pdu(state
->cli
, &state
->rhdr
,
1528 &state
->incoming_frag
);
1529 if (!NT_STATUS_IS_OK(status
)) {
1530 tevent_req_nterror(req
, status
);
1534 if (state
->rhdr
.flags
& DCERPC_PFC_FLAG_LAST
) {
1535 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1536 rpccli_pipe_txt(talloc_tos(), state
->cli
),
1537 (unsigned)prs_data_size(&state
->incoming_pdu
)));
1538 tevent_req_done(req
);
1542 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1543 &state
->rhdr
, &state
->incoming_frag
);
1544 if (tevent_req_nomem(subreq
, req
)) {
1547 tevent_req_set_callback(subreq
, rpc_api_pipe_got_pdu
, req
);
1550 static NTSTATUS
rpc_api_pipe_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1551 prs_struct
*reply_pdu
)
1553 struct rpc_api_pipe_state
*state
= tevent_req_data(
1554 req
, struct rpc_api_pipe_state
);
1557 if (tevent_req_is_nterror(req
, &status
)) {
1561 *reply_pdu
= state
->incoming_pdu
;
1562 reply_pdu
->mem_ctx
= mem_ctx
;
1565 * Prevent state->incoming_pdu from being freed in
1566 * rpc_api_pipe_state_destructor()
1568 prs_init_empty(&state
->incoming_pdu
, state
, UNMARSHALL
);
1570 return NT_STATUS_OK
;
1573 /*******************************************************************
1574 Creates krb5 auth bind.
1575 ********************************************************************/
1577 static NTSTATUS
create_krb5_auth_bind_req( struct rpc_pipe_client
*cli
,
1578 enum dcerpc_AuthLevel auth_level
,
1579 RPC_HDR_AUTH
*pauth_out
,
1580 prs_struct
*auth_data
)
1584 struct kerberos_auth_struct
*a
= cli
->auth
->a_u
.kerberos_auth
;
1585 DATA_BLOB tkt
= data_blob_null
;
1586 DATA_BLOB tkt_wrapped
= data_blob_null
;
1588 /* We may change the pad length before marshalling. */
1589 init_rpc_hdr_auth(pauth_out
, DCERPC_AUTH_TYPE_KRB5
, (int)auth_level
, 0, 1);
1591 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1592 a
->service_principal
));
1594 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1596 ret
= cli_krb5_get_ticket(a
->service_principal
, 0, &tkt
,
1597 &a
->session_key
, (uint32
)AP_OPTS_MUTUAL_REQUIRED
, NULL
, NULL
, NULL
);
1600 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1602 a
->service_principal
,
1603 error_message(ret
) ));
1605 data_blob_free(&tkt
);
1606 prs_mem_free(auth_data
);
1607 return NT_STATUS_INVALID_PARAMETER
;
1610 /* wrap that up in a nice GSS-API wrapping */
1611 tkt_wrapped
= spnego_gen_krb5_wrap(tkt
, TOK_ID_KRB_AP_REQ
);
1613 data_blob_free(&tkt
);
1615 /* Auth len in the rpc header doesn't include auth_header. */
1616 if (!prs_copy_data_in(auth_data
, (char *)tkt_wrapped
.data
, tkt_wrapped
.length
)) {
1617 data_blob_free(&tkt_wrapped
);
1618 prs_mem_free(auth_data
);
1619 return NT_STATUS_NO_MEMORY
;
1622 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1623 dump_data(5, tkt_wrapped
.data
, tkt_wrapped
.length
);
1625 data_blob_free(&tkt_wrapped
);
1626 return NT_STATUS_OK
;
1628 return NT_STATUS_INVALID_PARAMETER
;
1632 /*******************************************************************
1633 Creates SPNEGO NTLMSSP auth bind.
1634 ********************************************************************/
1636 static NTSTATUS
create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1637 enum dcerpc_AuthLevel auth_level
,
1638 RPC_HDR_AUTH
*pauth_out
,
1639 prs_struct
*auth_data
)
1642 DATA_BLOB null_blob
= data_blob_null
;
1643 DATA_BLOB request
= data_blob_null
;
1644 DATA_BLOB spnego_msg
= data_blob_null
;
1646 /* We may change the pad length before marshalling. */
1647 init_rpc_hdr_auth(pauth_out
, DCERPC_AUTH_TYPE_SPNEGO
, (int)auth_level
, 0, 1);
1649 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1650 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1654 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1655 data_blob_free(&request
);
1656 prs_mem_free(auth_data
);
1660 /* Wrap this in SPNEGO. */
1661 spnego_msg
= gen_negTokenInit(OID_NTLMSSP
, request
);
1663 data_blob_free(&request
);
1665 /* Auth len in the rpc header doesn't include auth_header. */
1666 if (!prs_copy_data_in(auth_data
, (char *)spnego_msg
.data
, spnego_msg
.length
)) {
1667 data_blob_free(&spnego_msg
);
1668 prs_mem_free(auth_data
);
1669 return NT_STATUS_NO_MEMORY
;
1672 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1673 dump_data(5, spnego_msg
.data
, spnego_msg
.length
);
1675 data_blob_free(&spnego_msg
);
1676 return NT_STATUS_OK
;
1679 /*******************************************************************
1680 Creates NTLMSSP auth bind.
1681 ********************************************************************/
1683 static NTSTATUS
create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1684 enum dcerpc_AuthLevel auth_level
,
1685 RPC_HDR_AUTH
*pauth_out
,
1686 prs_struct
*auth_data
)
1689 DATA_BLOB null_blob
= data_blob_null
;
1690 DATA_BLOB request
= data_blob_null
;
1692 /* We may change the pad length before marshalling. */
1693 init_rpc_hdr_auth(pauth_out
, DCERPC_AUTH_TYPE_NTLMSSP
, (int)auth_level
, 0, 1);
1695 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1696 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1700 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1701 data_blob_free(&request
);
1702 prs_mem_free(auth_data
);
1706 /* Auth len in the rpc header doesn't include auth_header. */
1707 if (!prs_copy_data_in(auth_data
, (char *)request
.data
, request
.length
)) {
1708 data_blob_free(&request
);
1709 prs_mem_free(auth_data
);
1710 return NT_STATUS_NO_MEMORY
;
1713 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1714 dump_data(5, request
.data
, request
.length
);
1716 data_blob_free(&request
);
1717 return NT_STATUS_OK
;
1720 /*******************************************************************
1721 Creates schannel auth bind.
1722 ********************************************************************/
1724 static NTSTATUS
create_schannel_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1725 enum dcerpc_AuthLevel auth_level
,
1726 RPC_HDR_AUTH
*pauth_out
,
1727 prs_struct
*auth_data
)
1729 struct NL_AUTH_MESSAGE r
;
1730 enum ndr_err_code ndr_err
;
1733 /* We may change the pad length before marshalling. */
1734 init_rpc_hdr_auth(pauth_out
, DCERPC_AUTH_TYPE_SCHANNEL
, (int)auth_level
, 0, 1);
1736 /* Use lp_workgroup() if domain not specified */
1738 if (!cli
->auth
->domain
|| !cli
->auth
->domain
[0]) {
1739 cli
->auth
->domain
= talloc_strdup(cli
, lp_workgroup());
1740 if (cli
->auth
->domain
== NULL
) {
1741 return NT_STATUS_NO_MEMORY
;
1746 * Now marshall the data into the auth parse_struct.
1749 r
.MessageType
= NL_NEGOTIATE_REQUEST
;
1750 r
.Flags
= NL_FLAG_OEM_NETBIOS_DOMAIN_NAME
|
1751 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME
;
1752 r
.oem_netbios_domain
.a
= cli
->auth
->domain
;
1753 r
.oem_netbios_computer
.a
= global_myname();
1755 ndr_err
= ndr_push_struct_blob(&blob
, talloc_tos(), NULL
, &r
,
1756 (ndr_push_flags_fn_t
)ndr_push_NL_AUTH_MESSAGE
);
1757 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1758 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1759 prs_mem_free(auth_data
);
1760 return ndr_map_error2ntstatus(ndr_err
);
1763 if (DEBUGLEVEL
>= 10) {
1764 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE
, &r
);
1767 if (!prs_copy_data_in(auth_data
, (const char *)blob
.data
, blob
.length
))
1769 prs_mem_free(auth_data
);
1770 return NT_STATUS_NO_MEMORY
;
1773 return NT_STATUS_OK
;
1776 /*******************************************************************
1777 Creates the internals of a DCE/RPC bind request or alter context PDU.
1778 ********************************************************************/
1780 static NTSTATUS
create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type
,
1781 prs_struct
*rpc_out
,
1783 const struct ndr_syntax_id
*abstract
,
1784 const struct ndr_syntax_id
*transfer
,
1785 RPC_HDR_AUTH
*phdr_auth
,
1786 prs_struct
*pauth_info
)
1790 RPC_CONTEXT rpc_ctx
;
1791 uint16 auth_len
= prs_offset(pauth_info
);
1792 uint8 ss_padding_len
= 0;
1793 uint16 frag_len
= 0;
1795 /* create the RPC context. */
1796 init_rpc_context(&rpc_ctx
, 0 /* context id */, abstract
, transfer
);
1798 /* create the bind request RPC_HDR_RB */
1799 init_rpc_hdr_rb(&hdr_rb
, RPC_MAX_PDU_FRAG_LEN
, RPC_MAX_PDU_FRAG_LEN
, 0x0, &rpc_ctx
);
1801 /* Start building the frag length. */
1802 frag_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1804 /* Do we need to pad ? */
1806 uint16 data_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1808 ss_padding_len
= 8 - (data_len
% 8);
1809 phdr_auth
->auth_pad_len
= ss_padding_len
;
1811 frag_len
+= RPC_HDR_AUTH_LEN
+ auth_len
+ ss_padding_len
;
1814 /* Create the request RPC_HDR */
1815 init_rpc_hdr(&hdr
, pkt_type
, DCERPC_PFC_FLAG_FIRST
|DCERPC_PFC_FLAG_LAST
, rpc_call_id
, frag_len
, auth_len
);
1817 /* Marshall the RPC header */
1818 if(!smb_io_rpc_hdr("hdr" , &hdr
, rpc_out
, 0)) {
1819 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1820 return NT_STATUS_NO_MEMORY
;
1823 /* Marshall the bind request data */
1824 if(!smb_io_rpc_hdr_rb("", &hdr_rb
, rpc_out
, 0)) {
1825 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1826 return NT_STATUS_NO_MEMORY
;
1830 * Grow the outgoing buffer to store any auth info.
1834 if (ss_padding_len
) {
1836 memset(pad
, '\0', 8);
1837 if (!prs_copy_data_in(rpc_out
, pad
, ss_padding_len
)) {
1838 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1839 return NT_STATUS_NO_MEMORY
;
1843 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth
, rpc_out
, 0)) {
1844 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1845 return NT_STATUS_NO_MEMORY
;
1849 if(!prs_append_prs_data( rpc_out
, pauth_info
)) {
1850 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1851 return NT_STATUS_NO_MEMORY
;
1855 return NT_STATUS_OK
;
1858 /*******************************************************************
1859 Creates a DCE/RPC bind request.
1860 ********************************************************************/
1862 static NTSTATUS
create_rpc_bind_req(struct rpc_pipe_client
*cli
,
1863 prs_struct
*rpc_out
,
1865 const struct ndr_syntax_id
*abstract
,
1866 const struct ndr_syntax_id
*transfer
,
1867 enum pipe_auth_type auth_type
,
1868 enum dcerpc_AuthLevel auth_level
)
1870 RPC_HDR_AUTH hdr_auth
;
1871 prs_struct auth_info
;
1872 NTSTATUS ret
= NT_STATUS_OK
;
1874 ZERO_STRUCT(hdr_auth
);
1875 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
1876 return NT_STATUS_NO_MEMORY
;
1878 switch (auth_type
) {
1879 case PIPE_AUTH_TYPE_SCHANNEL
:
1880 ret
= create_schannel_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1881 if (!NT_STATUS_IS_OK(ret
)) {
1882 prs_mem_free(&auth_info
);
1887 case PIPE_AUTH_TYPE_NTLMSSP
:
1888 ret
= create_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1889 if (!NT_STATUS_IS_OK(ret
)) {
1890 prs_mem_free(&auth_info
);
1895 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1896 ret
= create_spnego_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1897 if (!NT_STATUS_IS_OK(ret
)) {
1898 prs_mem_free(&auth_info
);
1903 case PIPE_AUTH_TYPE_KRB5
:
1904 ret
= create_krb5_auth_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1905 if (!NT_STATUS_IS_OK(ret
)) {
1906 prs_mem_free(&auth_info
);
1911 case PIPE_AUTH_TYPE_NONE
:
1915 /* "Can't" happen. */
1916 return NT_STATUS_INVALID_INFO_CLASS
;
1919 ret
= create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND
,
1927 prs_mem_free(&auth_info
);
1931 /*******************************************************************
1932 Create and add the NTLMSSP sign/seal auth header and data.
1933 ********************************************************************/
1935 static NTSTATUS
add_ntlmssp_auth_footer(struct rpc_pipe_client
*cli
,
1937 uint32 ss_padding_len
,
1938 prs_struct
*outgoing_pdu
)
1940 RPC_HDR_AUTH auth_info
;
1942 DATA_BLOB auth_blob
= data_blob_null
;
1943 uint16 data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1945 if (!cli
->auth
->a_u
.ntlmssp_state
) {
1946 return NT_STATUS_INVALID_PARAMETER
;
1949 /* Init and marshall the auth header. */
1950 init_rpc_hdr_auth(&auth_info
,
1951 map_pipe_auth_type_to_rpc_auth_type(
1952 cli
->auth
->auth_type
),
1953 cli
->auth
->auth_level
,
1955 1 /* context id. */);
1957 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1958 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1959 data_blob_free(&auth_blob
);
1960 return NT_STATUS_NO_MEMORY
;
1963 switch (cli
->auth
->auth_level
) {
1964 case DCERPC_AUTH_LEVEL_PRIVACY
:
1965 /* Data portion is encrypted. */
1966 status
= ntlmssp_seal_packet(cli
->auth
->a_u
.ntlmssp_state
,
1967 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1969 (unsigned char *)prs_data_p(outgoing_pdu
),
1970 (size_t)prs_offset(outgoing_pdu
),
1972 if (!NT_STATUS_IS_OK(status
)) {
1973 data_blob_free(&auth_blob
);
1978 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1979 /* Data is signed. */
1980 status
= ntlmssp_sign_packet(cli
->auth
->a_u
.ntlmssp_state
,
1981 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1983 (unsigned char *)prs_data_p(outgoing_pdu
),
1984 (size_t)prs_offset(outgoing_pdu
),
1986 if (!NT_STATUS_IS_OK(status
)) {
1987 data_blob_free(&auth_blob
);
1994 smb_panic("bad auth level");
1996 return NT_STATUS_INVALID_PARAMETER
;
1999 /* Finally marshall the blob. */
2001 if (!prs_copy_data_in(outgoing_pdu
, (const char *)auth_blob
.data
, NTLMSSP_SIG_SIZE
)) {
2002 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2003 (unsigned int)NTLMSSP_SIG_SIZE
));
2004 data_blob_free(&auth_blob
);
2005 return NT_STATUS_NO_MEMORY
;
2008 data_blob_free(&auth_blob
);
2009 return NT_STATUS_OK
;
2012 /*******************************************************************
2013 Create and add the schannel sign/seal auth header and data.
2014 ********************************************************************/
2016 static NTSTATUS
add_schannel_auth_footer(struct rpc_pipe_client
*cli
,
2018 uint32 ss_padding_len
,
2019 prs_struct
*outgoing_pdu
)
2021 RPC_HDR_AUTH auth_info
;
2022 struct schannel_state
*sas
= cli
->auth
->a_u
.schannel_auth
;
2023 char *data_p
= prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
2024 size_t data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
2029 return NT_STATUS_INVALID_PARAMETER
;
2032 /* Init and marshall the auth header. */
2033 init_rpc_hdr_auth(&auth_info
,
2034 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
->auth_type
),
2035 cli
->auth
->auth_level
,
2037 1 /* context id. */);
2039 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
2040 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2041 return NT_STATUS_NO_MEMORY
;
2044 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2047 switch (cli
->auth
->auth_level
) {
2048 case DCERPC_AUTH_LEVEL_PRIVACY
:
2049 status
= netsec_outgoing_packet(sas
,
2056 case DCERPC_AUTH_LEVEL_INTEGRITY
:
2057 status
= netsec_outgoing_packet(sas
,
2065 status
= NT_STATUS_INTERNAL_ERROR
;
2069 if (!NT_STATUS_IS_OK(status
)) {
2070 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2071 nt_errstr(status
)));
2075 if (DEBUGLEVEL
>= 10) {
2076 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob
);
2079 /* Finally marshall the blob. */
2080 if (!prs_copy_data_in(outgoing_pdu
, (const char *)blob
.data
, blob
.length
)) {
2081 return NT_STATUS_NO_MEMORY
;
2084 return NT_STATUS_OK
;
2087 /*******************************************************************
2088 Calculate how much data we're going to send in this packet, also
2089 work out any sign/seal padding length.
2090 ********************************************************************/
2092 static uint32
calculate_data_len_tosend(struct rpc_pipe_client
*cli
,
2096 uint32
*p_ss_padding
)
2098 uint32 data_space
, data_len
;
2101 if ((data_left
> 0) && (sys_random() % 2)) {
2102 data_left
= MAX(data_left
/2, 1);
2106 switch (cli
->auth
->auth_level
) {
2107 case DCERPC_AUTH_LEVEL_NONE
:
2108 case DCERPC_AUTH_LEVEL_CONNECT
:
2109 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
;
2110 data_len
= MIN(data_space
, data_left
);
2113 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ data_len
;
2116 case DCERPC_AUTH_LEVEL_INTEGRITY
:
2117 case DCERPC_AUTH_LEVEL_PRIVACY
:
2118 /* Treat the same for all authenticated rpc requests. */
2119 switch(cli
->auth
->auth_type
) {
2120 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2121 case PIPE_AUTH_TYPE_NTLMSSP
:
2122 *p_auth_len
= NTLMSSP_SIG_SIZE
;
2124 case PIPE_AUTH_TYPE_SCHANNEL
:
2125 *p_auth_len
= RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
;
2128 smb_panic("bad auth type");
2132 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
-
2133 RPC_HDR_AUTH_LEN
- *p_auth_len
;
2135 data_len
= MIN(data_space
, data_left
);
2138 *p_ss_padding
= 8 - (data_len
% 8);
2140 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ /* Normal headers. */
2141 data_len
+ *p_ss_padding
+ /* data plus padding. */
2142 RPC_HDR_AUTH_LEN
+ *p_auth_len
; /* Auth header and auth data. */
2146 smb_panic("bad auth level");
2152 /*******************************************************************
2154 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2155 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2156 and deals with signing/sealing details.
2157 ********************************************************************/
2159 struct rpc_api_pipe_req_state
{
2160 struct event_context
*ev
;
2161 struct rpc_pipe_client
*cli
;
2164 prs_struct
*req_data
;
2165 uint32_t req_data_sent
;
2166 prs_struct outgoing_frag
;
2167 prs_struct reply_pdu
;
2170 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state
*s
)
2172 prs_mem_free(&s
->outgoing_frag
);
2173 prs_mem_free(&s
->reply_pdu
);
2177 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
);
2178 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
);
2179 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
2180 bool *is_last_frag
);
2182 struct tevent_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
2183 struct event_context
*ev
,
2184 struct rpc_pipe_client
*cli
,
2186 prs_struct
*req_data
)
2188 struct tevent_req
*req
, *subreq
;
2189 struct rpc_api_pipe_req_state
*state
;
2193 req
= tevent_req_create(mem_ctx
, &state
,
2194 struct rpc_api_pipe_req_state
);
2200 state
->op_num
= op_num
;
2201 state
->req_data
= req_data
;
2202 state
->req_data_sent
= 0;
2203 state
->call_id
= get_rpc_call_id();
2205 if (cli
->max_xmit_frag
2206 < RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ RPC_MAX_SIGN_SIZE
) {
2207 /* Server is screwed up ! */
2208 status
= NT_STATUS_INVALID_PARAMETER
;
2212 prs_init_empty(&state
->reply_pdu
, state
, UNMARSHALL
);
2214 if (!prs_init(&state
->outgoing_frag
, cli
->max_xmit_frag
,
2219 talloc_set_destructor(state
, rpc_api_pipe_req_state_destructor
);
2221 status
= prepare_next_frag(state
, &is_last_frag
);
2222 if (!NT_STATUS_IS_OK(status
)) {
2227 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
2228 &state
->outgoing_frag
,
2229 DCERPC_PKT_RESPONSE
);
2230 if (subreq
== NULL
) {
2233 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
2235 subreq
= rpc_write_send(
2236 state
, ev
, cli
->transport
,
2237 (uint8_t *)prs_data_p(&state
->outgoing_frag
),
2238 prs_offset(&state
->outgoing_frag
));
2239 if (subreq
== NULL
) {
2242 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
2248 tevent_req_nterror(req
, status
);
2249 return tevent_req_post(req
, ev
);
2255 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
2259 RPC_HDR_REQ hdr_req
;
2260 uint32_t data_sent_thistime
;
2264 uint32_t ss_padding
;
2266 char pad
[8] = { 0, };
2269 data_left
= prs_offset(state
->req_data
) - state
->req_data_sent
;
2271 data_sent_thistime
= calculate_data_len_tosend(
2272 state
->cli
, data_left
, &frag_len
, &auth_len
, &ss_padding
);
2274 if (state
->req_data_sent
== 0) {
2275 flags
= DCERPC_PFC_FLAG_FIRST
;
2278 if (data_sent_thistime
== data_left
) {
2279 flags
|= DCERPC_PFC_FLAG_LAST
;
2282 if (!prs_set_offset(&state
->outgoing_frag
, 0)) {
2283 return NT_STATUS_NO_MEMORY
;
2286 /* Create and marshall the header and request header. */
2287 init_rpc_hdr(&hdr
, DCERPC_PKT_REQUEST
, flags
, state
->call_id
, frag_len
,
2290 if (!smb_io_rpc_hdr("hdr ", &hdr
, &state
->outgoing_frag
, 0)) {
2291 return NT_STATUS_NO_MEMORY
;
2294 /* Create the rpc request RPC_HDR_REQ */
2295 init_rpc_hdr_req(&hdr_req
, prs_offset(state
->req_data
),
2298 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req
,
2299 &state
->outgoing_frag
, 0)) {
2300 return NT_STATUS_NO_MEMORY
;
2303 /* Copy in the data, plus any ss padding. */
2304 if (!prs_append_some_prs_data(&state
->outgoing_frag
,
2305 state
->req_data
, state
->req_data_sent
,
2306 data_sent_thistime
)) {
2307 return NT_STATUS_NO_MEMORY
;
2310 /* Copy the sign/seal padding data. */
2311 if (!prs_copy_data_in(&state
->outgoing_frag
, pad
, ss_padding
)) {
2312 return NT_STATUS_NO_MEMORY
;
2315 /* Generate any auth sign/seal and add the auth footer. */
2316 switch (state
->cli
->auth
->auth_type
) {
2317 case PIPE_AUTH_TYPE_NONE
:
2318 status
= NT_STATUS_OK
;
2320 case PIPE_AUTH_TYPE_NTLMSSP
:
2321 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2322 status
= add_ntlmssp_auth_footer(state
->cli
, &hdr
, ss_padding
,
2323 &state
->outgoing_frag
);
2325 case PIPE_AUTH_TYPE_SCHANNEL
:
2326 status
= add_schannel_auth_footer(state
->cli
, &hdr
, ss_padding
,
2327 &state
->outgoing_frag
);
2330 status
= NT_STATUS_INVALID_PARAMETER
;
2334 state
->req_data_sent
+= data_sent_thistime
;
2335 *is_last_frag
= ((flags
& DCERPC_PFC_FLAG_LAST
) != 0);
2340 static void rpc_api_pipe_req_write_done(struct tevent_req
*subreq
)
2342 struct tevent_req
*req
= tevent_req_callback_data(
2343 subreq
, struct tevent_req
);
2344 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2345 req
, struct rpc_api_pipe_req_state
);
2349 status
= rpc_write_recv(subreq
);
2350 TALLOC_FREE(subreq
);
2351 if (!NT_STATUS_IS_OK(status
)) {
2352 tevent_req_nterror(req
, status
);
2356 status
= prepare_next_frag(state
, &is_last_frag
);
2357 if (!NT_STATUS_IS_OK(status
)) {
2358 tevent_req_nterror(req
, status
);
2363 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2364 &state
->outgoing_frag
,
2365 DCERPC_PKT_RESPONSE
);
2366 if (tevent_req_nomem(subreq
, req
)) {
2369 tevent_req_set_callback(subreq
, rpc_api_pipe_req_done
, req
);
2371 subreq
= rpc_write_send(
2373 state
->cli
->transport
,
2374 (uint8_t *)prs_data_p(&state
->outgoing_frag
),
2375 prs_offset(&state
->outgoing_frag
));
2376 if (tevent_req_nomem(subreq
, req
)) {
2379 tevent_req_set_callback(subreq
, rpc_api_pipe_req_write_done
,
2384 static void rpc_api_pipe_req_done(struct tevent_req
*subreq
)
2386 struct tevent_req
*req
= tevent_req_callback_data(
2387 subreq
, struct tevent_req
);
2388 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2389 req
, struct rpc_api_pipe_req_state
);
2392 status
= rpc_api_pipe_recv(subreq
, state
, &state
->reply_pdu
);
2393 TALLOC_FREE(subreq
);
2394 if (!NT_STATUS_IS_OK(status
)) {
2395 tevent_req_nterror(req
, status
);
2398 tevent_req_done(req
);
2401 NTSTATUS
rpc_api_pipe_req_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2402 prs_struct
*reply_pdu
)
2404 struct rpc_api_pipe_req_state
*state
= tevent_req_data(
2405 req
, struct rpc_api_pipe_req_state
);
2408 if (tevent_req_is_nterror(req
, &status
)) {
2410 * We always have to initialize to reply pdu, even if there is
2411 * none. The rpccli_* caller routines expect this.
2413 prs_init_empty(reply_pdu
, mem_ctx
, UNMARSHALL
);
2417 *reply_pdu
= state
->reply_pdu
;
2418 reply_pdu
->mem_ctx
= mem_ctx
;
2421 * Prevent state->req_pdu from being freed in
2422 * rpc_api_pipe_req_state_destructor()
2424 prs_init_empty(&state
->reply_pdu
, state
, UNMARSHALL
);
2426 return NT_STATUS_OK
;
2430 /****************************************************************************
2431 Set the handle state.
2432 ****************************************************************************/
2434 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client
*cli
,
2435 const char *pipe_name
, uint16 device_state
)
2437 bool state_set
= False
;
2439 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
2440 char *rparam
= NULL
;
2442 uint32 rparam_len
, rdata_len
;
2444 if (pipe_name
== NULL
)
2447 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2448 cli
->fnum
, pipe_name
, device_state
));
2450 /* create parameters: device state */
2451 SSVAL(param
, 0, device_state
);
2453 /* create setup parameters. */
2455 setup
[1] = cli
->fnum
; /* pipe file handle. got this from an SMBOpenX. */
2457 /* send the data on \PIPE\ */
2458 if (cli_api_pipe(cli
->cli
, "\\PIPE\\",
2459 setup
, 2, 0, /* setup, length, max */
2460 param
, 2, 0, /* param, length, max */
2461 NULL
, 0, 1024, /* data, length, max */
2462 &rparam
, &rparam_len
, /* return param, length */
2463 &rdata
, &rdata_len
)) /* return data, length */
2465 DEBUG(5, ("Set Handle state: return OK\n"));
2476 /****************************************************************************
2477 Check the rpc bind acknowledge response.
2478 ****************************************************************************/
2480 static bool check_bind_response(RPC_HDR_BA
*hdr_ba
,
2481 const struct ndr_syntax_id
*transfer
)
2483 if ( hdr_ba
->addr
.len
== 0) {
2484 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2487 /* check the transfer syntax */
2488 if ((hdr_ba
->transfer
.if_version
!= transfer
->if_version
) ||
2489 (memcmp(&hdr_ba
->transfer
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
2490 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2494 if (hdr_ba
->res
.num_results
!= 0x1 || hdr_ba
->res
.result
!= 0) {
2495 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2496 hdr_ba
->res
.num_results
, hdr_ba
->res
.reason
));
2499 DEBUG(5,("check_bind_response: accepted!\n"));
2503 /*******************************************************************
2504 Creates a DCE/RPC bind authentication response.
2505 This is the packet that is sent back to the server once we
2506 have received a BIND-ACK, to finish the third leg of
2507 the authentication handshake.
2508 ********************************************************************/
2510 static NTSTATUS
create_rpc_bind_auth3(struct rpc_pipe_client
*cli
,
2512 enum pipe_auth_type auth_type
,
2513 enum dcerpc_AuthLevel auth_level
,
2514 DATA_BLOB
*pauth_blob
,
2515 prs_struct
*rpc_out
)
2518 RPC_HDR_AUTH hdr_auth
;
2521 /* Create the request RPC_HDR */
2522 init_rpc_hdr(&hdr
, DCERPC_PKT_AUTH3
, DCERPC_PFC_FLAG_FIRST
|DCERPC_PFC_FLAG_LAST
, rpc_call_id
,
2523 RPC_HEADER_LEN
+ 4 /* pad */ + RPC_HDR_AUTH_LEN
+ pauth_blob
->length
,
2524 pauth_blob
->length
);
2527 if(!smb_io_rpc_hdr("hdr", &hdr
, rpc_out
, 0)) {
2528 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2529 return NT_STATUS_NO_MEMORY
;
2533 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2534 about padding - shouldn't this pad to length 8 ? JRA.
2537 /* 4 bytes padding. */
2538 if (!prs_uint32("pad", rpc_out
, 0, &pad
)) {
2539 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2540 return NT_STATUS_NO_MEMORY
;
2543 /* Create the request RPC_HDR_AUTHA */
2544 init_rpc_hdr_auth(&hdr_auth
,
2545 map_pipe_auth_type_to_rpc_auth_type(auth_type
),
2548 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rpc_out
, 0)) {
2549 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2550 return NT_STATUS_NO_MEMORY
;
2554 * Append the auth data to the outgoing buffer.
2557 if(!prs_copy_data_in(rpc_out
, (char *)pauth_blob
->data
, pauth_blob
->length
)) {
2558 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2559 return NT_STATUS_NO_MEMORY
;
2562 return NT_STATUS_OK
;
2565 /*******************************************************************
2566 Creates a DCE/RPC bind alter context authentication request which
2567 may contain a spnego auth blobl
2568 ********************************************************************/
2570 static NTSTATUS
create_rpc_alter_context(uint32 rpc_call_id
,
2571 const struct ndr_syntax_id
*abstract
,
2572 const struct ndr_syntax_id
*transfer
,
2573 enum dcerpc_AuthLevel auth_level
,
2574 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
2575 prs_struct
*rpc_out
)
2577 RPC_HDR_AUTH hdr_auth
;
2578 prs_struct auth_info
;
2579 NTSTATUS ret
= NT_STATUS_OK
;
2581 ZERO_STRUCT(hdr_auth
);
2582 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
2583 return NT_STATUS_NO_MEMORY
;
2585 /* We may change the pad length before marshalling. */
2586 init_rpc_hdr_auth(&hdr_auth
, DCERPC_AUTH_TYPE_SPNEGO
, (int)auth_level
, 0, 1);
2588 if (pauth_blob
->length
) {
2589 if (!prs_copy_data_in(&auth_info
, (const char *)pauth_blob
->data
, pauth_blob
->length
)) {
2590 prs_mem_free(&auth_info
);
2591 return NT_STATUS_NO_MEMORY
;
2595 ret
= create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER
,
2602 prs_mem_free(&auth_info
);
2606 /****************************************************************************
2608 ****************************************************************************/
2610 struct rpc_pipe_bind_state
{
2611 struct event_context
*ev
;
2612 struct rpc_pipe_client
*cli
;
2614 uint32_t rpc_call_id
;
2617 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state
*state
)
2619 prs_mem_free(&state
->rpc_out
);
2623 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
);
2624 static NTSTATUS
rpc_finish_auth3_bind_send(struct tevent_req
*req
,
2625 struct rpc_pipe_bind_state
*state
,
2626 struct rpc_hdr_info
*phdr
,
2627 prs_struct
*reply_pdu
);
2628 static void rpc_bind_auth3_write_done(struct tevent_req
*subreq
);
2629 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req
*req
,
2630 struct rpc_pipe_bind_state
*state
,
2631 struct rpc_hdr_info
*phdr
,
2632 prs_struct
*reply_pdu
);
2633 static void rpc_bind_ntlmssp_api_done(struct tevent_req
*subreq
);
2635 struct tevent_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
2636 struct event_context
*ev
,
2637 struct rpc_pipe_client
*cli
,
2638 struct cli_pipe_auth_data
*auth
)
2640 struct tevent_req
*req
, *subreq
;
2641 struct rpc_pipe_bind_state
*state
;
2644 req
= tevent_req_create(mem_ctx
, &state
, struct rpc_pipe_bind_state
);
2649 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2650 rpccli_pipe_txt(talloc_tos(), cli
),
2651 (unsigned int)auth
->auth_type
,
2652 (unsigned int)auth
->auth_level
));
2656 state
->rpc_call_id
= get_rpc_call_id();
2658 prs_init_empty(&state
->rpc_out
, state
, MARSHALL
);
2659 talloc_set_destructor(state
, rpc_pipe_bind_state_destructor
);
2661 cli
->auth
= talloc_move(cli
, &auth
);
2663 /* Marshall the outgoing data. */
2664 status
= create_rpc_bind_req(cli
, &state
->rpc_out
,
2666 &cli
->abstract_syntax
,
2667 &cli
->transfer_syntax
,
2668 cli
->auth
->auth_type
,
2669 cli
->auth
->auth_level
);
2671 if (!NT_STATUS_IS_OK(status
)) {
2675 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
2676 DCERPC_PKT_BIND_ACK
);
2677 if (subreq
== NULL
) {
2680 tevent_req_set_callback(subreq
, rpc_pipe_bind_step_one_done
, req
);
2684 tevent_req_nterror(req
, status
);
2685 return tevent_req_post(req
, ev
);
2691 static void rpc_pipe_bind_step_one_done(struct tevent_req
*subreq
)
2693 struct tevent_req
*req
= tevent_req_callback_data(
2694 subreq
, struct tevent_req
);
2695 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2696 req
, struct rpc_pipe_bind_state
);
2697 prs_struct reply_pdu
;
2698 struct rpc_hdr_info hdr
;
2699 struct rpc_hdr_ba_info hdr_ba
;
2702 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &reply_pdu
);
2703 TALLOC_FREE(subreq
);
2704 if (!NT_STATUS_IS_OK(status
)) {
2705 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2706 rpccli_pipe_txt(talloc_tos(), state
->cli
),
2707 nt_errstr(status
)));
2708 tevent_req_nterror(req
, status
);
2712 /* Unmarshall the RPC header */
2713 if (!smb_io_rpc_hdr("hdr", &hdr
, &reply_pdu
, 0)) {
2714 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2715 prs_mem_free(&reply_pdu
);
2716 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2720 if (!smb_io_rpc_hdr_ba("", &hdr_ba
, &reply_pdu
, 0)) {
2721 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2723 prs_mem_free(&reply_pdu
);
2724 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2728 if (!check_bind_response(&hdr_ba
, &state
->cli
->transfer_syntax
)) {
2729 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2730 prs_mem_free(&reply_pdu
);
2731 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2735 state
->cli
->max_xmit_frag
= hdr_ba
.bba
.max_tsize
;
2736 state
->cli
->max_recv_frag
= hdr_ba
.bba
.max_rsize
;
2739 * For authenticated binds we may need to do 3 or 4 leg binds.
2742 switch(state
->cli
->auth
->auth_type
) {
2744 case PIPE_AUTH_TYPE_NONE
:
2745 case PIPE_AUTH_TYPE_SCHANNEL
:
2746 /* Bind complete. */
2747 prs_mem_free(&reply_pdu
);
2748 tevent_req_done(req
);
2751 case PIPE_AUTH_TYPE_NTLMSSP
:
2752 /* Need to send AUTH3 packet - no reply. */
2753 status
= rpc_finish_auth3_bind_send(req
, state
, &hdr
,
2755 prs_mem_free(&reply_pdu
);
2756 if (!NT_STATUS_IS_OK(status
)) {
2757 tevent_req_nterror(req
, status
);
2761 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2762 /* Need to send alter context request and reply. */
2763 status
= rpc_finish_spnego_ntlmssp_bind_send(req
, state
, &hdr
,
2765 prs_mem_free(&reply_pdu
);
2766 if (!NT_STATUS_IS_OK(status
)) {
2767 tevent_req_nterror(req
, status
);
2771 case PIPE_AUTH_TYPE_KRB5
:
2775 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2776 (unsigned int)state
->cli
->auth
->auth_type
));
2777 prs_mem_free(&reply_pdu
);
2778 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2782 static NTSTATUS
rpc_finish_auth3_bind_send(struct tevent_req
*req
,
2783 struct rpc_pipe_bind_state
*state
,
2784 struct rpc_hdr_info
*phdr
,
2785 prs_struct
*reply_pdu
)
2787 DATA_BLOB server_response
= data_blob_null
;
2788 DATA_BLOB client_reply
= data_blob_null
;
2789 struct rpc_hdr_auth_info hdr_auth
;
2790 struct tevent_req
*subreq
;
2793 if ((phdr
->auth_len
== 0)
2794 || (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
2795 return NT_STATUS_INVALID_PARAMETER
;
2798 if (!prs_set_offset(
2800 phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
2801 return NT_STATUS_INVALID_PARAMETER
;
2804 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, reply_pdu
, 0)) {
2805 return NT_STATUS_INVALID_PARAMETER
;
2808 /* TODO - check auth_type/auth_level match. */
2810 server_response
= data_blob_talloc(talloc_tos(), NULL
, phdr
->auth_len
);
2811 prs_copy_data_out((char *)server_response
.data
, reply_pdu
,
2814 status
= ntlmssp_update(state
->cli
->auth
->a_u
.ntlmssp_state
,
2815 server_response
, &client_reply
);
2817 if (!NT_STATUS_IS_OK(status
)) {
2818 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2819 "blob failed: %s.\n", nt_errstr(status
)));
2823 prs_init_empty(&state
->rpc_out
, talloc_tos(), MARSHALL
);
2825 status
= create_rpc_bind_auth3(state
->cli
, state
->rpc_call_id
,
2826 state
->cli
->auth
->auth_type
,
2827 state
->cli
->auth
->auth_level
,
2828 &client_reply
, &state
->rpc_out
);
2829 data_blob_free(&client_reply
);
2831 if (!NT_STATUS_IS_OK(status
)) {
2835 subreq
= rpc_write_send(state
, state
->ev
, state
->cli
->transport
,
2836 (uint8_t *)prs_data_p(&state
->rpc_out
),
2837 prs_offset(&state
->rpc_out
));
2838 if (subreq
== NULL
) {
2839 return NT_STATUS_NO_MEMORY
;
2841 tevent_req_set_callback(subreq
, rpc_bind_auth3_write_done
, req
);
2842 return NT_STATUS_OK
;
2845 static void rpc_bind_auth3_write_done(struct tevent_req
*subreq
)
2847 struct tevent_req
*req
= tevent_req_callback_data(
2848 subreq
, struct tevent_req
);
2851 status
= rpc_write_recv(subreq
);
2852 TALLOC_FREE(subreq
);
2853 if (!NT_STATUS_IS_OK(status
)) {
2854 tevent_req_nterror(req
, status
);
2857 tevent_req_done(req
);
2860 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req
*req
,
2861 struct rpc_pipe_bind_state
*state
,
2862 struct rpc_hdr_info
*phdr
,
2863 prs_struct
*reply_pdu
)
2865 DATA_BLOB server_spnego_response
= data_blob_null
;
2866 DATA_BLOB server_ntlm_response
= data_blob_null
;
2867 DATA_BLOB client_reply
= data_blob_null
;
2868 DATA_BLOB tmp_blob
= data_blob_null
;
2869 RPC_HDR_AUTH hdr_auth
;
2870 struct tevent_req
*subreq
;
2873 if ((phdr
->auth_len
== 0)
2874 || (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
2875 return NT_STATUS_INVALID_PARAMETER
;
2878 /* Process the returned NTLMSSP blob first. */
2879 if (!prs_set_offset(
2881 phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
2882 return NT_STATUS_INVALID_PARAMETER
;
2885 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, reply_pdu
, 0)) {
2886 return NT_STATUS_INVALID_PARAMETER
;
2889 server_spnego_response
= data_blob(NULL
, phdr
->auth_len
);
2890 prs_copy_data_out((char *)server_spnego_response
.data
,
2891 reply_pdu
, phdr
->auth_len
);
2894 * The server might give us back two challenges - tmp_blob is for the
2897 if (!spnego_parse_challenge(server_spnego_response
,
2898 &server_ntlm_response
, &tmp_blob
)) {
2899 data_blob_free(&server_spnego_response
);
2900 data_blob_free(&server_ntlm_response
);
2901 data_blob_free(&tmp_blob
);
2902 return NT_STATUS_INVALID_PARAMETER
;
2905 /* We're finished with the server spnego response and the tmp_blob. */
2906 data_blob_free(&server_spnego_response
);
2907 data_blob_free(&tmp_blob
);
2909 status
= ntlmssp_update(state
->cli
->auth
->a_u
.ntlmssp_state
,
2910 server_ntlm_response
, &client_reply
);
2912 /* Finished with the server_ntlm response */
2913 data_blob_free(&server_ntlm_response
);
2915 if (!NT_STATUS_IS_OK(status
)) {
2916 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2917 "using server blob failed.\n"));
2918 data_blob_free(&client_reply
);
2922 /* SPNEGO wrap the client reply. */
2923 tmp_blob
= spnego_gen_auth(client_reply
);
2924 data_blob_free(&client_reply
);
2925 client_reply
= tmp_blob
;
2926 tmp_blob
= data_blob_null
;
2928 /* Now prepare the alter context pdu. */
2929 prs_init_empty(&state
->rpc_out
, state
, MARSHALL
);
2931 status
= create_rpc_alter_context(state
->rpc_call_id
,
2932 &state
->cli
->abstract_syntax
,
2933 &state
->cli
->transfer_syntax
,
2934 state
->cli
->auth
->auth_level
,
2937 data_blob_free(&client_reply
);
2939 if (!NT_STATUS_IS_OK(status
)) {
2943 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2944 &state
->rpc_out
, DCERPC_PKT_ALTER_RESP
);
2945 if (subreq
== NULL
) {
2946 return NT_STATUS_NO_MEMORY
;
2948 tevent_req_set_callback(subreq
, rpc_bind_ntlmssp_api_done
, req
);
2949 return NT_STATUS_OK
;
2952 static void rpc_bind_ntlmssp_api_done(struct tevent_req
*subreq
)
2954 struct tevent_req
*req
= tevent_req_callback_data(
2955 subreq
, struct tevent_req
);
2956 struct rpc_pipe_bind_state
*state
= tevent_req_data(
2957 req
, struct rpc_pipe_bind_state
);
2958 DATA_BLOB server_spnego_response
= data_blob_null
;
2959 DATA_BLOB tmp_blob
= data_blob_null
;
2960 prs_struct reply_pdu
;
2961 struct rpc_hdr_info hdr
;
2962 struct rpc_hdr_auth_info hdr_auth
;
2965 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &reply_pdu
);
2966 TALLOC_FREE(subreq
);
2967 if (!NT_STATUS_IS_OK(status
)) {
2968 tevent_req_nterror(req
, status
);
2972 /* Get the auth blob from the reply. */
2973 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr
, &reply_pdu
, 0)) {
2974 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2975 "unmarshall RPC_HDR.\n"));
2976 tevent_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2980 if (!prs_set_offset(
2982 hdr
.frag_len
- hdr
.auth_len
- RPC_HDR_AUTH_LEN
)) {
2983 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2987 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, &reply_pdu
, 0)) {
2988 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2992 server_spnego_response
= data_blob(NULL
, hdr
.auth_len
);
2993 prs_copy_data_out((char *)server_spnego_response
.data
, &reply_pdu
,
2996 /* Check we got a valid auth response. */
2997 if (!spnego_parse_auth_response(server_spnego_response
, NT_STATUS_OK
,
2998 OID_NTLMSSP
, &tmp_blob
)) {
2999 data_blob_free(&server_spnego_response
);
3000 data_blob_free(&tmp_blob
);
3001 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3005 data_blob_free(&server_spnego_response
);
3006 data_blob_free(&tmp_blob
);
3008 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3009 "%s.\n", rpccli_pipe_txt(talloc_tos(), state
->cli
)));
3010 tevent_req_done(req
);
3013 NTSTATUS
rpc_pipe_bind_recv(struct tevent_req
*req
)
3015 return tevent_req_simple_recv_ntstatus(req
);
3018 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
3019 struct cli_pipe_auth_data
*auth
)
3021 TALLOC_CTX
*frame
= talloc_stackframe();
3022 struct event_context
*ev
;
3023 struct tevent_req
*req
;
3024 NTSTATUS status
= NT_STATUS_OK
;
3026 ev
= event_context_init(frame
);
3028 status
= NT_STATUS_NO_MEMORY
;
3032 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
3034 status
= NT_STATUS_NO_MEMORY
;
3038 if (!tevent_req_poll(req
, ev
)) {
3039 status
= map_nt_error_from_unix(errno
);
3043 status
= rpc_pipe_bind_recv(req
);
3049 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
3050 unsigned int timeout
)
3052 struct cli_state
*cli
= rpc_pipe_np_smb_conn(rpc_cli
);
3057 return cli_set_timeout(cli
, timeout
);
3060 bool rpccli_get_pwd_hash(struct rpc_pipe_client
*rpc_cli
, uint8_t nt_hash
[16])
3062 struct cli_state
*cli
;
3064 if ((rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_NTLMSSP
)
3065 || (rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
)) {
3066 memcpy(nt_hash
, rpc_cli
->auth
->a_u
.ntlmssp_state
->nt_hash
, 16);
3070 cli
= rpc_pipe_np_smb_conn(rpc_cli
);
3074 E_md4hash(cli
->password
? cli
->password
: "", nt_hash
);
3078 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
3079 struct cli_pipe_auth_data
**presult
)
3081 struct cli_pipe_auth_data
*result
;
3083 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3084 if (result
== NULL
) {
3085 return NT_STATUS_NO_MEMORY
;
3088 result
->auth_type
= PIPE_AUTH_TYPE_NONE
;
3089 result
->auth_level
= DCERPC_AUTH_LEVEL_NONE
;
3091 result
->user_name
= talloc_strdup(result
, "");
3092 result
->domain
= talloc_strdup(result
, "");
3093 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3094 TALLOC_FREE(result
);
3095 return NT_STATUS_NO_MEMORY
;
3099 return NT_STATUS_OK
;
3102 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data
*auth
)
3104 ntlmssp_end(&auth
->a_u
.ntlmssp_state
);
3108 NTSTATUS
rpccli_ntlmssp_bind_data(TALLOC_CTX
*mem_ctx
,
3109 enum pipe_auth_type auth_type
,
3110 enum dcerpc_AuthLevel auth_level
,
3112 const char *username
,
3113 const char *password
,
3114 struct cli_pipe_auth_data
**presult
)
3116 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
= auth_type
;
3125 result
->auth_level
= auth_level
;
3127 result
->user_name
= talloc_strdup(result
, username
);
3128 result
->domain
= talloc_strdup(result
, domain
);
3129 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3130 status
= NT_STATUS_NO_MEMORY
;
3134 status
= ntlmssp_client_start(&result
->a_u
.ntlmssp_state
);
3135 if (!NT_STATUS_IS_OK(status
)) {
3139 talloc_set_destructor(result
, cli_auth_ntlmssp_data_destructor
);
3141 status
= ntlmssp_set_username(result
->a_u
.ntlmssp_state
, username
);
3142 if (!NT_STATUS_IS_OK(status
)) {
3146 status
= ntlmssp_set_domain(result
->a_u
.ntlmssp_state
, domain
);
3147 if (!NT_STATUS_IS_OK(status
)) {
3151 status
= ntlmssp_set_password(result
->a_u
.ntlmssp_state
, password
);
3152 if (!NT_STATUS_IS_OK(status
)) {
3157 * Turn off sign+seal to allow selected auth level to turn it back on.
3159 result
->a_u
.ntlmssp_state
->neg_flags
&=
3160 ~(NTLMSSP_NEGOTIATE_SIGN
| NTLMSSP_NEGOTIATE_SEAL
);
3162 if (auth_level
== DCERPC_AUTH_LEVEL_INTEGRITY
) {
3163 result
->a_u
.ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
3164 } else if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
3165 result
->a_u
.ntlmssp_state
->neg_flags
3166 |= NTLMSSP_NEGOTIATE_SEAL
| NTLMSSP_NEGOTIATE_SIGN
;
3170 return NT_STATUS_OK
;
3173 TALLOC_FREE(result
);
3177 NTSTATUS
rpccli_schannel_bind_data(TALLOC_CTX
*mem_ctx
, const char *domain
,
3178 enum dcerpc_AuthLevel auth_level
,
3179 struct netlogon_creds_CredentialState
*creds
,
3180 struct cli_pipe_auth_data
**presult
)
3182 struct cli_pipe_auth_data
*result
;
3184 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3185 if (result
== NULL
) {
3186 return NT_STATUS_NO_MEMORY
;
3189 result
->auth_type
= PIPE_AUTH_TYPE_SCHANNEL
;
3190 result
->auth_level
= auth_level
;
3192 result
->user_name
= talloc_strdup(result
, "");
3193 result
->domain
= talloc_strdup(result
, domain
);
3194 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3198 result
->a_u
.schannel_auth
= talloc(result
, struct schannel_state
);
3199 if (result
->a_u
.schannel_auth
== NULL
) {
3203 result
->a_u
.schannel_auth
->state
= SCHANNEL_STATE_START
;
3204 result
->a_u
.schannel_auth
->seq_num
= 0;
3205 result
->a_u
.schannel_auth
->initiator
= true;
3206 result
->a_u
.schannel_auth
->creds
= creds
;
3209 return NT_STATUS_OK
;
3212 TALLOC_FREE(result
);
3213 return NT_STATUS_NO_MEMORY
;
3217 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct
*auth
)
3219 data_blob_free(&auth
->session_key
);
3224 NTSTATUS
rpccli_kerberos_bind_data(TALLOC_CTX
*mem_ctx
,
3225 enum dcerpc_AuthLevel auth_level
,
3226 const char *service_princ
,
3227 const char *username
,
3228 const char *password
,
3229 struct cli_pipe_auth_data
**presult
)
3232 struct cli_pipe_auth_data
*result
;
3234 if ((username
!= NULL
) && (password
!= NULL
)) {
3235 int ret
= kerberos_kinit_password(username
, password
, 0, NULL
);
3237 return NT_STATUS_ACCESS_DENIED
;
3241 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3242 if (result
== NULL
) {
3243 return NT_STATUS_NO_MEMORY
;
3246 result
->auth_type
= PIPE_AUTH_TYPE_KRB5
;
3247 result
->auth_level
= auth_level
;
3250 * Username / domain need fixing!
3252 result
->user_name
= talloc_strdup(result
, "");
3253 result
->domain
= talloc_strdup(result
, "");
3254 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3258 result
->a_u
.kerberos_auth
= TALLOC_ZERO_P(
3259 result
, struct kerberos_auth_struct
);
3260 if (result
->a_u
.kerberos_auth
== NULL
) {
3263 talloc_set_destructor(result
->a_u
.kerberos_auth
,
3264 cli_auth_kerberos_data_destructor
);
3266 result
->a_u
.kerberos_auth
->service_principal
= talloc_strdup(
3267 result
, service_princ
);
3268 if (result
->a_u
.kerberos_auth
->service_principal
== NULL
) {
3273 return NT_STATUS_OK
;
3276 TALLOC_FREE(result
);
3277 return NT_STATUS_NO_MEMORY
;
3279 return NT_STATUS_NOT_SUPPORTED
;
3284 * Create an rpc pipe client struct, connecting to a tcp port.
3286 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
3288 const struct ndr_syntax_id
*abstract_syntax
,
3289 struct rpc_pipe_client
**presult
)
3291 struct rpc_pipe_client
*result
;
3292 struct sockaddr_storage addr
;
3296 result
= TALLOC_ZERO_P(mem_ctx
, struct rpc_pipe_client
);
3297 if (result
== NULL
) {
3298 return NT_STATUS_NO_MEMORY
;
3301 result
->abstract_syntax
= *abstract_syntax
;
3302 result
->transfer_syntax
= ndr_transfer_syntax
;
3303 result
->dispatch
= cli_do_rpc_ndr
;
3304 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3305 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3307 result
->desthost
= talloc_strdup(result
, host
);
3308 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3309 result
, "\\\\%s", result
->desthost
);
3310 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3311 status
= NT_STATUS_NO_MEMORY
;
3315 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3316 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3318 if (!resolve_name(host
, &addr
, 0, false)) {
3319 status
= NT_STATUS_NOT_FOUND
;
3323 status
= open_socket_out(&addr
, port
, 60, &fd
);
3324 if (!NT_STATUS_IS_OK(status
)) {
3327 set_socket_options(fd
, lp_socket_options());
3329 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
3330 if (!NT_STATUS_IS_OK(status
)) {
3335 result
->transport
->transport
= NCACN_IP_TCP
;
3338 return NT_STATUS_OK
;
3341 TALLOC_FREE(result
);
3346 * Determine the tcp port on which a dcerpc interface is listening
3347 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3350 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
3351 const struct ndr_syntax_id
*abstract_syntax
,
3355 struct rpc_pipe_client
*epm_pipe
= NULL
;
3356 struct cli_pipe_auth_data
*auth
= NULL
;
3357 struct dcerpc_binding
*map_binding
= NULL
;
3358 struct dcerpc_binding
*res_binding
= NULL
;
3359 struct epm_twr_t
*map_tower
= NULL
;
3360 struct epm_twr_t
*res_towers
= NULL
;
3361 struct policy_handle
*entry_handle
= NULL
;
3362 uint32_t num_towers
= 0;
3363 uint32_t max_towers
= 1;
3364 struct epm_twr_p_t towers
;
3365 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
3367 if (pport
== NULL
) {
3368 status
= NT_STATUS_INVALID_PARAMETER
;
3372 /* open the connection to the endpoint mapper */
3373 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, 135,
3374 &ndr_table_epmapper
.syntax_id
,
3377 if (!NT_STATUS_IS_OK(status
)) {
3381 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
3382 if (!NT_STATUS_IS_OK(status
)) {
3386 status
= rpc_pipe_bind(epm_pipe
, auth
);
3387 if (!NT_STATUS_IS_OK(status
)) {
3391 /* create tower for asking the epmapper */
3393 map_binding
= TALLOC_ZERO_P(tmp_ctx
, struct dcerpc_binding
);
3394 if (map_binding
== NULL
) {
3395 status
= NT_STATUS_NO_MEMORY
;
3399 map_binding
->transport
= NCACN_IP_TCP
;
3400 map_binding
->object
= *abstract_syntax
;
3401 map_binding
->host
= host
; /* needed? */
3402 map_binding
->endpoint
= "0"; /* correct? needed? */
3404 map_tower
= TALLOC_ZERO_P(tmp_ctx
, struct epm_twr_t
);
3405 if (map_tower
== NULL
) {
3406 status
= NT_STATUS_NO_MEMORY
;
3410 status
= dcerpc_binding_build_tower(tmp_ctx
, map_binding
,
3411 &(map_tower
->tower
));
3412 if (!NT_STATUS_IS_OK(status
)) {
3416 /* allocate further parameters for the epm_Map call */
3418 res_towers
= TALLOC_ARRAY(tmp_ctx
, struct epm_twr_t
, max_towers
);
3419 if (res_towers
== NULL
) {
3420 status
= NT_STATUS_NO_MEMORY
;
3423 towers
.twr
= res_towers
;
3425 entry_handle
= TALLOC_ZERO_P(tmp_ctx
, struct policy_handle
);
3426 if (entry_handle
== NULL
) {
3427 status
= NT_STATUS_NO_MEMORY
;
3431 /* ask the endpoint mapper for the port */
3433 status
= rpccli_epm_Map(epm_pipe
,
3435 CONST_DISCARD(struct GUID
*,
3436 &(abstract_syntax
->uuid
)),
3443 if (!NT_STATUS_IS_OK(status
)) {
3447 if (num_towers
!= 1) {
3448 status
= NT_STATUS_UNSUCCESSFUL
;
3452 /* extract the port from the answer */
3454 status
= dcerpc_binding_from_tower(tmp_ctx
,
3455 &(towers
.twr
->tower
),
3457 if (!NT_STATUS_IS_OK(status
)) {
3461 /* are further checks here necessary? */
3462 if (res_binding
->transport
!= NCACN_IP_TCP
) {
3463 status
= NT_STATUS_UNSUCCESSFUL
;
3467 *pport
= (uint16_t)atoi(res_binding
->endpoint
);
3470 TALLOC_FREE(tmp_ctx
);
3475 * Create a rpc pipe client struct, connecting to a host via tcp.
3476 * The port is determined by asking the endpoint mapper on the given
3479 NTSTATUS
rpc_pipe_open_tcp(TALLOC_CTX
*mem_ctx
, const char *host
,
3480 const struct ndr_syntax_id
*abstract_syntax
,
3481 struct rpc_pipe_client
**presult
)
3488 status
= rpc_pipe_get_tcp_port(host
, abstract_syntax
, &port
);
3489 if (!NT_STATUS_IS_OK(status
)) {
3493 status
= rpc_pipe_open_tcp_port(mem_ctx
, host
, port
,
3494 abstract_syntax
, presult
);
3500 /********************************************************************
3501 Create a rpc pipe client struct, connecting to a unix domain socket
3502 ********************************************************************/
3503 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
, const char *socket_path
,
3504 const struct ndr_syntax_id
*abstract_syntax
,
3505 struct rpc_pipe_client
**presult
)
3507 struct rpc_pipe_client
*result
;
3508 struct sockaddr_un addr
;
3512 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
3513 if (result
== NULL
) {
3514 return NT_STATUS_NO_MEMORY
;
3517 result
->abstract_syntax
= *abstract_syntax
;
3518 result
->transfer_syntax
= ndr_transfer_syntax
;
3519 result
->dispatch
= cli_do_rpc_ndr
;
3520 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3521 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3523 result
->desthost
= get_myname(result
);
3524 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3525 result
, "\\\\%s", result
->desthost
);
3526 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3527 status
= NT_STATUS_NO_MEMORY
;
3531 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3532 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3534 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3536 status
= map_nt_error_from_unix(errno
);
3541 addr
.sun_family
= AF_UNIX
;
3542 strncpy(addr
.sun_path
, socket_path
, sizeof(addr
.sun_path
));
3544 if (sys_connect(fd
, (struct sockaddr
*)(void *)&addr
) == -1) {
3545 DEBUG(0, ("connect(%s) failed: %s\n", socket_path
,
3548 return map_nt_error_from_unix(errno
);
3551 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
3552 if (!NT_STATUS_IS_OK(status
)) {
3557 result
->transport
->transport
= NCALRPC
;
3560 return NT_STATUS_OK
;
3563 TALLOC_FREE(result
);
3567 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client
*p
)
3569 struct cli_state
*cli
;
3571 cli
= rpc_pipe_np_smb_conn(p
);
3573 DLIST_REMOVE(cli
->pipe_list
, p
);
3578 /****************************************************************************
3579 Open a named pipe over SMB to a remote server.
3581 * CAVEAT CALLER OF THIS FUNCTION:
3582 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3583 * so be sure that this function is called AFTER any structure (vs pointer)
3584 * assignment of the cli. In particular, libsmbclient does structure
3585 * assignments of cli, which invalidates the data in the returned
3586 * rpc_pipe_client if this function is called before the structure assignment
3589 ****************************************************************************/
3591 static NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
3592 const struct ndr_syntax_id
*abstract_syntax
,
3593 struct rpc_pipe_client
**presult
)
3595 struct rpc_pipe_client
*result
;
3598 /* sanity check to protect against crashes */
3601 return NT_STATUS_INVALID_HANDLE
;
3604 result
= TALLOC_ZERO_P(NULL
, struct rpc_pipe_client
);
3605 if (result
== NULL
) {
3606 return NT_STATUS_NO_MEMORY
;
3609 result
->abstract_syntax
= *abstract_syntax
;
3610 result
->transfer_syntax
= ndr_transfer_syntax
;
3611 result
->dispatch
= cli_do_rpc_ndr
;
3612 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3613 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3614 result
->desthost
= talloc_strdup(result
, cli
->desthost
);
3615 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3616 result
, "\\\\%s", result
->desthost
);
3618 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3619 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3621 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3622 TALLOC_FREE(result
);
3623 return NT_STATUS_NO_MEMORY
;
3626 status
= rpc_transport_np_init(result
, cli
, abstract_syntax
,
3627 &result
->transport
);
3628 if (!NT_STATUS_IS_OK(status
)) {
3629 TALLOC_FREE(result
);
3633 result
->transport
->transport
= NCACN_NP
;
3635 DLIST_ADD(cli
->pipe_list
, result
);
3636 talloc_set_destructor(result
, rpc_pipe_client_np_destructor
);
3639 return NT_STATUS_OK
;
3642 NTSTATUS
rpc_pipe_open_local(TALLOC_CTX
*mem_ctx
,
3643 struct rpc_cli_smbd_conn
*conn
,
3644 const struct ndr_syntax_id
*syntax
,
3645 struct rpc_pipe_client
**presult
)
3647 struct rpc_pipe_client
*result
;
3648 struct cli_pipe_auth_data
*auth
;
3651 result
= talloc(mem_ctx
, struct rpc_pipe_client
);
3652 if (result
== NULL
) {
3653 return NT_STATUS_NO_MEMORY
;
3655 result
->abstract_syntax
= *syntax
;
3656 result
->transfer_syntax
= ndr_transfer_syntax
;
3657 result
->dispatch
= cli_do_rpc_ndr
;
3658 result
->dispatch_send
= cli_do_rpc_ndr_send
;
3659 result
->dispatch_recv
= cli_do_rpc_ndr_recv
;
3660 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3661 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3663 result
->desthost
= talloc_strdup(result
, global_myname());
3664 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3665 result
, "\\\\%s", global_myname());
3666 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3667 TALLOC_FREE(result
);
3668 return NT_STATUS_NO_MEMORY
;
3671 status
= rpc_transport_smbd_init(result
, conn
, syntax
,
3672 &result
->transport
);
3673 if (!NT_STATUS_IS_OK(status
)) {
3674 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3675 nt_errstr(status
)));
3676 TALLOC_FREE(result
);
3680 status
= rpccli_anon_bind_data(result
, &auth
);
3681 if (!NT_STATUS_IS_OK(status
)) {
3682 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3683 nt_errstr(status
)));
3684 TALLOC_FREE(result
);
3688 status
= rpc_pipe_bind(result
, auth
);
3689 if (!NT_STATUS_IS_OK(status
)) {
3690 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status
)));
3691 TALLOC_FREE(result
);
3695 result
->transport
->transport
= NCACN_INTERNAL
;
3698 return NT_STATUS_OK
;
3701 /****************************************************************************
3702 Open a pipe to a remote server.
3703 ****************************************************************************/
3705 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3706 enum dcerpc_transport_t transport
,
3707 const struct ndr_syntax_id
*interface
,
3708 struct rpc_pipe_client
**presult
)
3710 switch (transport
) {
3712 return rpc_pipe_open_tcp(NULL
, cli
->desthost
, interface
,
3715 return rpc_pipe_open_np(cli
, interface
, presult
);
3717 return NT_STATUS_NOT_IMPLEMENTED
;
3721 /****************************************************************************
3722 Open a named pipe to an SMB server and bind anonymously.
3723 ****************************************************************************/
3725 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
3726 enum dcerpc_transport_t transport
,
3727 const struct ndr_syntax_id
*interface
,
3728 struct rpc_pipe_client
**presult
)
3730 struct rpc_pipe_client
*result
;
3731 struct cli_pipe_auth_data
*auth
;
3734 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3735 if (!NT_STATUS_IS_OK(status
)) {
3739 status
= rpccli_anon_bind_data(result
, &auth
);
3740 if (!NT_STATUS_IS_OK(status
)) {
3741 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3742 nt_errstr(status
)));
3743 TALLOC_FREE(result
);
3748 * This is a bit of an abstraction violation due to the fact that an
3749 * anonymous bind on an authenticated SMB inherits the user/domain
3750 * from the enclosing SMB creds
3753 TALLOC_FREE(auth
->user_name
);
3754 TALLOC_FREE(auth
->domain
);
3756 auth
->user_name
= talloc_strdup(auth
, cli
->user_name
);
3757 auth
->domain
= talloc_strdup(auth
, cli
->domain
);
3758 auth
->user_session_key
= data_blob_talloc(auth
,
3759 cli
->user_session_key
.data
,
3760 cli
->user_session_key
.length
);
3762 if ((auth
->user_name
== NULL
) || (auth
->domain
== NULL
)) {
3763 TALLOC_FREE(result
);
3764 return NT_STATUS_NO_MEMORY
;
3767 status
= rpc_pipe_bind(result
, auth
);
3768 if (!NT_STATUS_IS_OK(status
)) {
3770 if (ndr_syntax_id_equal(interface
,
3771 &ndr_table_dssetup
.syntax_id
)) {
3772 /* non AD domains just don't have this pipe, avoid
3773 * level 0 statement in that case - gd */
3776 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3777 "%s failed with error %s\n",
3778 get_pipe_name_from_syntax(talloc_tos(), interface
),
3779 nt_errstr(status
) ));
3780 TALLOC_FREE(result
);
3784 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3785 "%s and bound anonymously.\n",
3786 get_pipe_name_from_syntax(talloc_tos(), interface
),
3790 return NT_STATUS_OK
;
3793 /****************************************************************************
3794 ****************************************************************************/
3796 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
3797 const struct ndr_syntax_id
*interface
,
3798 struct rpc_pipe_client
**presult
)
3800 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
3801 interface
, presult
);
3804 /****************************************************************************
3805 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3806 ****************************************************************************/
3808 static NTSTATUS
cli_rpc_pipe_open_ntlmssp_internal(struct cli_state
*cli
,
3809 const struct ndr_syntax_id
*interface
,
3810 enum dcerpc_transport_t transport
,
3811 enum pipe_auth_type auth_type
,
3812 enum dcerpc_AuthLevel auth_level
,
3814 const char *username
,
3815 const char *password
,
3816 struct rpc_pipe_client
**presult
)
3818 struct rpc_pipe_client
*result
;
3819 struct cli_pipe_auth_data
*auth
;
3822 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3823 if (!NT_STATUS_IS_OK(status
)) {
3827 status
= rpccli_ntlmssp_bind_data(
3828 result
, auth_type
, auth_level
, domain
, username
,
3830 if (!NT_STATUS_IS_OK(status
)) {
3831 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3832 nt_errstr(status
)));
3836 status
= rpc_pipe_bind(result
, auth
);
3837 if (!NT_STATUS_IS_OK(status
)) {
3838 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3839 nt_errstr(status
) ));
3843 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3844 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3845 get_pipe_name_from_syntax(talloc_tos(), interface
),
3846 cli
->desthost
, domain
, username
));
3849 return NT_STATUS_OK
;
3853 TALLOC_FREE(result
);
3857 /****************************************************************************
3859 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3860 ****************************************************************************/
3862 NTSTATUS
cli_rpc_pipe_open_ntlmssp(struct cli_state
*cli
,
3863 const struct ndr_syntax_id
*interface
,
3864 enum dcerpc_transport_t transport
,
3865 enum dcerpc_AuthLevel auth_level
,
3867 const char *username
,
3868 const char *password
,
3869 struct rpc_pipe_client
**presult
)
3871 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3874 PIPE_AUTH_TYPE_NTLMSSP
,
3882 /****************************************************************************
3884 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3885 ****************************************************************************/
3887 NTSTATUS
cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state
*cli
,
3888 const struct ndr_syntax_id
*interface
,
3889 enum dcerpc_transport_t transport
,
3890 enum dcerpc_AuthLevel auth_level
,
3892 const char *username
,
3893 const char *password
,
3894 struct rpc_pipe_client
**presult
)
3896 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3899 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
,
3907 /****************************************************************************
3908 Get a the schannel session key out of an already opened netlogon pipe.
3909 ****************************************************************************/
3910 static NTSTATUS
get_schannel_session_key_common(struct rpc_pipe_client
*netlogon_pipe
,
3911 struct cli_state
*cli
,
3915 enum netr_SchannelType sec_chan_type
= 0;
3916 unsigned char machine_pwd
[16];
3917 const char *machine_account
;
3920 /* Get the machine account credentials from secrets.tdb. */
3921 if (!get_trust_pw_hash(domain
, machine_pwd
, &machine_account
,
3924 DEBUG(0, ("get_schannel_session_key: could not fetch "
3925 "trust account password for domain '%s'\n",
3927 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3930 status
= rpccli_netlogon_setup_creds(netlogon_pipe
,
3931 cli
->desthost
, /* server name */
3932 domain
, /* domain */
3933 global_myname(), /* client name */
3934 machine_account
, /* machine account name */
3939 if (!NT_STATUS_IS_OK(status
)) {
3940 DEBUG(3, ("get_schannel_session_key_common: "
3941 "rpccli_netlogon_setup_creds failed with result %s "
3942 "to server %s, domain %s, machine account %s.\n",
3943 nt_errstr(status
), cli
->desthost
, domain
,
3948 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
3949 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3951 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3954 return NT_STATUS_OK
;;
3957 /****************************************************************************
3958 Open a netlogon pipe and get the schannel session key.
3959 Now exposed to external callers.
3960 ****************************************************************************/
3963 NTSTATUS
get_schannel_session_key(struct cli_state
*cli
,
3966 struct rpc_pipe_client
**presult
)
3968 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3971 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
.syntax_id
,
3973 if (!NT_STATUS_IS_OK(status
)) {
3977 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
3979 if (!NT_STATUS_IS_OK(status
)) {
3980 TALLOC_FREE(netlogon_pipe
);
3984 *presult
= netlogon_pipe
;
3985 return NT_STATUS_OK
;
3988 /****************************************************************************
3990 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3991 using session_key. sign and seal.
3993 The *pdc will be stolen onto this new pipe
3994 ****************************************************************************/
3996 NTSTATUS
cli_rpc_pipe_open_schannel_with_key(struct cli_state
*cli
,
3997 const struct ndr_syntax_id
*interface
,
3998 enum dcerpc_transport_t transport
,
3999 enum dcerpc_AuthLevel auth_level
,
4001 struct netlogon_creds_CredentialState
**pdc
,
4002 struct rpc_pipe_client
**presult
)
4004 struct rpc_pipe_client
*result
;
4005 struct cli_pipe_auth_data
*auth
;
4008 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
4009 if (!NT_STATUS_IS_OK(status
)) {
4013 status
= rpccli_schannel_bind_data(result
, domain
, auth_level
,
4015 if (!NT_STATUS_IS_OK(status
)) {
4016 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4017 nt_errstr(status
)));
4018 TALLOC_FREE(result
);
4022 status
= rpc_pipe_bind(result
, auth
);
4023 if (!NT_STATUS_IS_OK(status
)) {
4024 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4025 "cli_rpc_pipe_bind failed with error %s\n",
4026 nt_errstr(status
) ));
4027 TALLOC_FREE(result
);
4032 * The credentials on a new netlogon pipe are the ones we are passed
4033 * in - reference them in
4035 result
->dc
= talloc_move(result
, pdc
);
4037 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4038 "for domain %s and bound using schannel.\n",
4039 get_pipe_name_from_syntax(talloc_tos(), interface
),
4040 cli
->desthost
, domain
));
4043 return NT_STATUS_OK
;
4046 /****************************************************************************
4047 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4048 Fetch the session key ourselves using a temporary netlogon pipe. This
4049 version uses an ntlmssp auth bound netlogon pipe to get the key.
4050 ****************************************************************************/
4052 static NTSTATUS
get_schannel_session_key_auth_ntlmssp(struct cli_state
*cli
,
4054 const char *username
,
4055 const char *password
,
4057 struct rpc_pipe_client
**presult
)
4059 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
4062 status
= cli_rpc_pipe_open_spnego_ntlmssp(
4063 cli
, &ndr_table_netlogon
.syntax_id
, NCACN_NP
,
4064 DCERPC_AUTH_LEVEL_PRIVACY
,
4065 domain
, username
, password
, &netlogon_pipe
);
4066 if (!NT_STATUS_IS_OK(status
)) {
4070 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
4072 if (!NT_STATUS_IS_OK(status
)) {
4073 TALLOC_FREE(netlogon_pipe
);
4077 *presult
= netlogon_pipe
;
4078 return NT_STATUS_OK
;
4081 /****************************************************************************
4082 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4083 Fetch the session key ourselves using a temporary netlogon pipe. This version
4084 uses an ntlmssp bind to get the session key.
4085 ****************************************************************************/
4087 NTSTATUS
cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
*cli
,
4088 const struct ndr_syntax_id
*interface
,
4089 enum dcerpc_transport_t transport
,
4090 enum dcerpc_AuthLevel auth_level
,
4092 const char *username
,
4093 const char *password
,
4094 struct rpc_pipe_client
**presult
)
4096 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
4097 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
4098 struct rpc_pipe_client
*result
= NULL
;
4101 status
= get_schannel_session_key_auth_ntlmssp(
4102 cli
, domain
, username
, password
, &neg_flags
, &netlogon_pipe
);
4103 if (!NT_STATUS_IS_OK(status
)) {
4104 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4105 "key from server %s for domain %s.\n",
4106 cli
->desthost
, domain
));
4110 status
= cli_rpc_pipe_open_schannel_with_key(
4111 cli
, interface
, transport
, auth_level
, domain
, &netlogon_pipe
->dc
,
4114 /* Now we've bound using the session key we can close the netlog pipe. */
4115 TALLOC_FREE(netlogon_pipe
);
4117 if (NT_STATUS_IS_OK(status
)) {
4123 /****************************************************************************
4124 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4125 Fetch the session key ourselves using a temporary netlogon pipe.
4126 ****************************************************************************/
4128 NTSTATUS
cli_rpc_pipe_open_schannel(struct cli_state
*cli
,
4129 const struct ndr_syntax_id
*interface
,
4130 enum dcerpc_transport_t transport
,
4131 enum dcerpc_AuthLevel auth_level
,
4133 struct rpc_pipe_client
**presult
)
4135 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
4136 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
4137 struct rpc_pipe_client
*result
= NULL
;
4140 status
= get_schannel_session_key(cli
, domain
, &neg_flags
,
4142 if (!NT_STATUS_IS_OK(status
)) {
4143 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4144 "key from server %s for domain %s.\n",
4145 cli
->desthost
, domain
));
4149 status
= cli_rpc_pipe_open_schannel_with_key(
4150 cli
, interface
, transport
, auth_level
, domain
, &netlogon_pipe
->dc
,
4153 /* Now we've bound using the session key we can close the netlog pipe. */
4154 TALLOC_FREE(netlogon_pipe
);
4156 if (NT_STATUS_IS_OK(status
)) {
4160 return NT_STATUS_OK
;
4163 /****************************************************************************
4164 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4165 The idea is this can be called with service_princ, username and password all
4166 NULL so long as the caller has a TGT.
4167 ****************************************************************************/
4169 NTSTATUS
cli_rpc_pipe_open_krb5(struct cli_state
*cli
,
4170 const struct ndr_syntax_id
*interface
,
4171 enum dcerpc_AuthLevel auth_level
,
4172 const char *service_princ
,
4173 const char *username
,
4174 const char *password
,
4175 struct rpc_pipe_client
**presult
)
4178 struct rpc_pipe_client
*result
;
4179 struct cli_pipe_auth_data
*auth
;
4182 status
= cli_rpc_pipe_open(cli
, NCACN_NP
, interface
, &result
);
4183 if (!NT_STATUS_IS_OK(status
)) {
4187 status
= rpccli_kerberos_bind_data(result
, auth_level
, service_princ
,
4188 username
, password
, &auth
);
4189 if (!NT_STATUS_IS_OK(status
)) {
4190 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4191 nt_errstr(status
)));
4192 TALLOC_FREE(result
);
4196 status
= rpc_pipe_bind(result
, auth
);
4197 if (!NT_STATUS_IS_OK(status
)) {
4198 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4199 "with error %s\n", nt_errstr(status
)));
4200 TALLOC_FREE(result
);
4205 return NT_STATUS_OK
;
4207 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4208 return NT_STATUS_NOT_IMPLEMENTED
;
4212 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
4213 struct rpc_pipe_client
*cli
,
4214 DATA_BLOB
*session_key
)
4216 if (!session_key
|| !cli
) {
4217 return NT_STATUS_INVALID_PARAMETER
;
4221 return NT_STATUS_INVALID_PARAMETER
;
4224 switch (cli
->auth
->auth_type
) {
4225 case PIPE_AUTH_TYPE_SCHANNEL
:
4226 *session_key
= data_blob_talloc(mem_ctx
,
4227 cli
->auth
->a_u
.schannel_auth
->creds
->session_key
, 16);
4229 case PIPE_AUTH_TYPE_NTLMSSP
:
4230 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
4231 *session_key
= data_blob_talloc(mem_ctx
,
4232 cli
->auth
->a_u
.ntlmssp_state
->session_key
.data
,
4233 cli
->auth
->a_u
.ntlmssp_state
->session_key
.length
);
4235 case PIPE_AUTH_TYPE_KRB5
:
4236 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
4237 *session_key
= data_blob_talloc(mem_ctx
,
4238 cli
->auth
->a_u
.kerberos_auth
->session_key
.data
,
4239 cli
->auth
->a_u
.kerberos_auth
->session_key
.length
);
4241 case PIPE_AUTH_TYPE_NONE
:
4242 *session_key
= data_blob_talloc(mem_ctx
,
4243 cli
->auth
->user_session_key
.data
,
4244 cli
->auth
->user_session_key
.length
);
4247 return NT_STATUS_NO_USER_SESSION_KEY
;
4250 return NT_STATUS_OK
;