2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
25 #define DBGC_CLASS DBGC_RPC_CLI
27 /*******************************************************************
28 interface/version dce/rpc pipe identification
29 ********************************************************************/
31 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
32 #define PIPE_SAMR "\\PIPE\\samr"
33 #define PIPE_WINREG "\\PIPE\\winreg"
34 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
35 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
36 #define PIPE_NTLSA "\\PIPE\\ntlsa"
37 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
38 #define PIPE_LSASS "\\PIPE\\lsass"
39 #define PIPE_LSARPC "\\PIPE\\lsarpc"
40 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
41 #define PIPE_NETDFS "\\PIPE\\netdfs"
42 #define PIPE_ECHO "\\PIPE\\rpcecho"
43 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
44 #define PIPE_EPM "\\PIPE\\epmapper"
45 #define PIPE_SVCCTL "\\PIPE\\svcctl"
46 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
47 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
48 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
51 * IMPORTANT!! If you update this structure, make sure to
52 * update the index #defines in smb.h.
55 static const struct pipe_id_info
{
56 /* the names appear not to matter: the syntaxes _do_ matter */
58 const char *client_pipe
;
59 const RPC_IFACE
*abstr_syntax
; /* this one is the abstract syntax id */
62 { PIPE_LSARPC
, &ndr_table_lsarpc
.syntax_id
},
63 { PIPE_LSARPC
, &ndr_table_dssetup
.syntax_id
},
64 { PIPE_SAMR
, &ndr_table_samr
.syntax_id
},
65 { PIPE_NETLOGON
, &ndr_table_netlogon
.syntax_id
},
66 { PIPE_SRVSVC
, &ndr_table_srvsvc
.syntax_id
},
67 { PIPE_WKSSVC
, &ndr_table_wkssvc
.syntax_id
},
68 { PIPE_WINREG
, &ndr_table_winreg
.syntax_id
},
69 { PIPE_SPOOLSS
, &ndr_table_spoolss
.syntax_id
},
70 { PIPE_NETDFS
, &ndr_table_netdfs
.syntax_id
},
71 { PIPE_ECHO
, &ndr_table_rpcecho
.syntax_id
},
72 { PIPE_SHUTDOWN
, &ndr_table_initshutdown
.syntax_id
},
73 { PIPE_SVCCTL
, &ndr_table_svcctl
.syntax_id
},
74 { PIPE_EVENTLOG
, &ndr_table_eventlog
.syntax_id
},
75 { PIPE_NTSVCS
, &ndr_table_ntsvcs
.syntax_id
},
76 { PIPE_EPMAPPER
, &ndr_table_epmapper
.syntax_id
},
77 { PIPE_DRSUAPI
, &ndr_table_drsuapi
.syntax_id
},
81 /****************************************************************************
82 Return the pipe name from the interface.
83 ****************************************************************************/
85 const char *get_pipe_name_from_iface(const struct ndr_syntax_id
*interface
)
90 for (i
= 0; pipe_names
[i
].client_pipe
; i
++) {
91 if (ndr_syntax_id_equal(pipe_names
[i
].abstr_syntax
,
93 return &pipe_names
[i
].client_pipe
[5];
98 * Here we should ask \\epmapper, but for now our code is only
99 * interested in the known pipes mentioned in pipe_names[]
102 guid_str
= GUID_string(talloc_tos(), &interface
->uuid
);
103 if (guid_str
== NULL
) {
106 result
= talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str
,
107 (int)interface
->if_version
);
108 TALLOC_FREE(guid_str
);
110 if (result
== NULL
) {
116 /********************************************************************
117 Map internal value to wire value.
118 ********************************************************************/
120 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type
)
124 case PIPE_AUTH_TYPE_NONE
:
125 return RPC_ANONYMOUS_AUTH_TYPE
;
127 case PIPE_AUTH_TYPE_NTLMSSP
:
128 return RPC_NTLMSSP_AUTH_TYPE
;
130 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
131 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
132 return RPC_SPNEGO_AUTH_TYPE
;
134 case PIPE_AUTH_TYPE_SCHANNEL
:
135 return RPC_SCHANNEL_AUTH_TYPE
;
137 case PIPE_AUTH_TYPE_KRB5
:
138 return RPC_KRB5_AUTH_TYPE
;
141 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
143 (unsigned int)auth_type
));
149 /********************************************************************
150 Pipe description for a DEBUG
151 ********************************************************************/
152 static const char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
,
153 struct rpc_pipe_client
*cli
)
155 char *result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
156 if (result
== NULL
) {
162 /********************************************************************
164 ********************************************************************/
166 static uint32
get_rpc_call_id(void)
168 static uint32 call_id
= 0;
173 * Realloc pdu to have a least "size" bytes
176 static bool rpc_grow_buffer(prs_struct
*pdu
, size_t size
)
180 if (prs_data_size(pdu
) >= size
) {
184 extra_size
= size
- prs_data_size(pdu
);
186 if (!prs_force_grow(pdu
, extra_size
)) {
187 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
188 "%d bytes.\n", (int)extra_size
));
192 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
193 (int)extra_size
, prs_data_size(pdu
)));
198 /*******************************************************************
199 Use SMBreadX to get rest of one fragment's worth of rpc data.
200 Reads the whole size or give an error message
201 ********************************************************************/
203 struct rpc_read_state
{
204 struct event_context
*ev
;
205 struct rpc_cli_transport
*transport
;
211 static void rpc_read_done(struct async_req
*subreq
);
213 static struct async_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
214 struct event_context
*ev
,
215 struct rpc_cli_transport
*transport
,
216 uint8_t *data
, size_t size
)
218 struct async_req
*result
, *subreq
;
219 struct rpc_read_state
*state
;
221 if (!async_req_setup(mem_ctx
, &result
, &state
,
222 struct rpc_read_state
)) {
226 state
->transport
= transport
;
231 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size
));
233 subreq
= transport
->read_send(state
, ev
, (uint8_t *)data
, size
,
235 if (subreq
== NULL
) {
238 subreq
->async
.fn
= rpc_read_done
;
239 subreq
->async
.priv
= result
;
247 static void rpc_read_done(struct async_req
*subreq
)
249 struct async_req
*req
= talloc_get_type_abort(
250 subreq
->async
.priv
, struct async_req
);
251 struct rpc_read_state
*state
= talloc_get_type_abort(
252 req
->private_data
, struct rpc_read_state
);
256 status
= state
->transport
->read_recv(subreq
, &received
);
258 if (!NT_STATUS_IS_OK(status
)) {
259 async_req_nterror(req
, status
);
263 state
->num_read
+= received
;
264 if (state
->num_read
== state
->size
) {
269 subreq
= state
->transport
->read_send(state
, state
->ev
,
270 state
->data
+ state
->num_read
,
271 state
->size
- state
->num_read
,
272 state
->transport
->priv
);
273 if (async_req_nomem(subreq
, req
)) {
276 subreq
->async
.fn
= rpc_read_done
;
277 subreq
->async
.priv
= req
;
280 static NTSTATUS
rpc_read_recv(struct async_req
*req
)
282 return async_req_simple_recv_ntstatus(req
);
285 struct rpc_write_state
{
286 struct event_context
*ev
;
287 struct rpc_cli_transport
*transport
;
293 static void rpc_write_done(struct async_req
*subreq
);
295 static struct async_req
*rpc_write_send(TALLOC_CTX
*mem_ctx
,
296 struct event_context
*ev
,
297 struct rpc_cli_transport
*transport
,
298 const uint8_t *data
, size_t size
)
300 struct async_req
*result
, *subreq
;
301 struct rpc_write_state
*state
;
303 if (!async_req_setup(mem_ctx
, &result
, &state
,
304 struct rpc_write_state
)) {
308 state
->transport
= transport
;
311 state
->num_written
= 0;
313 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size
));
315 subreq
= transport
->write_send(state
, ev
, data
, size
, transport
->priv
);
316 if (subreq
== NULL
) {
319 subreq
->async
.fn
= rpc_write_done
;
320 subreq
->async
.priv
= result
;
327 static void rpc_write_done(struct async_req
*subreq
)
329 struct async_req
*req
= talloc_get_type_abort(
330 subreq
->async
.priv
, struct async_req
);
331 struct rpc_write_state
*state
= talloc_get_type_abort(
332 req
->private_data
, struct rpc_write_state
);
336 status
= state
->transport
->write_recv(subreq
, &written
);
338 if (!NT_STATUS_IS_OK(status
)) {
339 async_req_nterror(req
, status
);
343 state
->num_written
+= written
;
345 if (state
->num_written
== state
->size
) {
350 subreq
= state
->transport
->write_send(state
, state
->ev
,
351 state
->data
+ state
->num_written
,
352 state
->size
- state
->num_written
,
353 state
->transport
->priv
);
354 if (async_req_nomem(subreq
, req
)) {
357 subreq
->async
.fn
= rpc_write_done
;
358 subreq
->async
.priv
= req
;
361 static NTSTATUS
rpc_write_recv(struct async_req
*req
)
363 return async_req_simple_recv_ntstatus(req
);
367 static NTSTATUS
parse_rpc_header(struct rpc_pipe_client
*cli
,
368 struct rpc_hdr_info
*prhdr
,
372 * This next call sets the endian bit correctly in current_pdu. We
373 * will propagate this to rbuf later.
376 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr
, pdu
, 0)) {
377 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
378 return NT_STATUS_BUFFER_TOO_SMALL
;
381 if (prhdr
->frag_len
> cli
->max_recv_frag
) {
382 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
383 " we only allow %d\n", (int)prhdr
->frag_len
,
384 (int)cli
->max_recv_frag
));
385 return NT_STATUS_BUFFER_TOO_SMALL
;
391 /****************************************************************************
392 Try and get a PDU's worth of data from current_pdu. If not, then read more
394 ****************************************************************************/
396 struct get_complete_frag_state
{
397 struct event_context
*ev
;
398 struct rpc_pipe_client
*cli
;
399 struct rpc_hdr_info
*prhdr
;
403 static void get_complete_frag_got_header(struct async_req
*subreq
);
404 static void get_complete_frag_got_rest(struct async_req
*subreq
);
406 static struct async_req
*get_complete_frag_send(TALLOC_CTX
*mem_ctx
,
407 struct event_context
*ev
,
408 struct rpc_pipe_client
*cli
,
409 struct rpc_hdr_info
*prhdr
,
412 struct async_req
*result
, *subreq
;
413 struct get_complete_frag_state
*state
;
417 if (!async_req_setup(mem_ctx
, &result
, &state
,
418 struct get_complete_frag_state
)) {
423 state
->prhdr
= prhdr
;
426 pdu_len
= prs_data_size(pdu
);
427 if (pdu_len
< RPC_HEADER_LEN
) {
428 if (!rpc_grow_buffer(pdu
, RPC_HEADER_LEN
)) {
429 status
= NT_STATUS_NO_MEMORY
;
432 subreq
= rpc_read_send(
434 state
->cli
->transport
,
435 (uint8_t *)(prs_data_p(state
->pdu
) + pdu_len
),
436 RPC_HEADER_LEN
- pdu_len
);
437 if (subreq
== NULL
) {
438 status
= NT_STATUS_NO_MEMORY
;
441 subreq
->async
.fn
= get_complete_frag_got_header
;
442 subreq
->async
.priv
= result
;
446 status
= parse_rpc_header(cli
, prhdr
, pdu
);
447 if (!NT_STATUS_IS_OK(status
)) {
452 * Ensure we have frag_len bytes of data.
454 if (pdu_len
< prhdr
->frag_len
) {
455 if (!rpc_grow_buffer(pdu
, prhdr
->frag_len
)) {
456 status
= NT_STATUS_NO_MEMORY
;
459 subreq
= rpc_read_send(state
, state
->ev
,
460 state
->cli
->transport
,
461 (uint8_t *)(prs_data_p(pdu
) + pdu_len
),
462 prhdr
->frag_len
- pdu_len
);
463 if (subreq
== NULL
) {
464 status
= NT_STATUS_NO_MEMORY
;
467 subreq
->async
.fn
= get_complete_frag_got_rest
;
468 subreq
->async
.priv
= result
;
472 status
= NT_STATUS_OK
;
474 if (async_post_ntstatus(result
, ev
, status
)) {
481 static void get_complete_frag_got_header(struct async_req
*subreq
)
483 struct async_req
*req
= talloc_get_type_abort(
484 subreq
->async
.priv
, struct async_req
);
485 struct get_complete_frag_state
*state
= talloc_get_type_abort(
486 req
->private_data
, struct get_complete_frag_state
);
489 status
= rpc_read_recv(subreq
);
491 if (!NT_STATUS_IS_OK(status
)) {
492 async_req_nterror(req
, status
);
496 status
= parse_rpc_header(state
->cli
, state
->prhdr
, state
->pdu
);
497 if (!NT_STATUS_IS_OK(status
)) {
498 async_req_nterror(req
, status
);
502 if (!rpc_grow_buffer(state
->pdu
, state
->prhdr
->frag_len
)) {
503 async_req_nterror(req
, NT_STATUS_NO_MEMORY
);
508 * We're here in this piece of code because we've read exactly
509 * RPC_HEADER_LEN bytes into state->pdu.
512 subreq
= rpc_read_send(
513 state
, state
->ev
, state
->cli
->transport
,
514 (uint8_t *)(prs_data_p(state
->pdu
) + RPC_HEADER_LEN
),
515 state
->prhdr
->frag_len
- RPC_HEADER_LEN
);
516 if (async_req_nomem(subreq
, req
)) {
519 subreq
->async
.fn
= get_complete_frag_got_rest
;
520 subreq
->async
.priv
= req
;
523 static void get_complete_frag_got_rest(struct async_req
*subreq
)
525 struct async_req
*req
= talloc_get_type_abort(
526 subreq
->async
.priv
, struct async_req
);
529 status
= rpc_read_recv(subreq
);
531 if (!NT_STATUS_IS_OK(status
)) {
532 async_req_nterror(req
, status
);
538 static NTSTATUS
get_complete_frag_recv(struct async_req
*req
)
540 return async_req_simple_recv_ntstatus(req
);
543 /****************************************************************************
544 NTLMSSP specific sign/seal.
545 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
546 In fact I should probably abstract these into identical pieces of code... JRA.
547 ****************************************************************************/
549 static NTSTATUS
cli_pipe_verify_ntlmssp(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
550 prs_struct
*current_pdu
,
551 uint8
*p_ss_padding_len
)
553 RPC_HDR_AUTH auth_info
;
554 uint32 save_offset
= prs_offset(current_pdu
);
555 uint32 auth_len
= prhdr
->auth_len
;
556 NTLMSSP_STATE
*ntlmssp_state
= cli
->auth
->a_u
.ntlmssp_state
;
557 unsigned char *data
= NULL
;
559 unsigned char *full_packet_data
= NULL
;
560 size_t full_packet_data_len
;
564 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_NONE
565 || cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_CONNECT
) {
569 if (!ntlmssp_state
) {
570 return NT_STATUS_INVALID_PARAMETER
;
573 /* Ensure there's enough data for an authenticated response. */
574 if ((auth_len
> RPC_MAX_SIGN_SIZE
) ||
575 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
576 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
577 (unsigned int)auth_len
));
578 return NT_STATUS_BUFFER_TOO_SMALL
;
582 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
583 * after the RPC header.
584 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
585 * functions as NTLMv2 checks the rpc headers also.
588 data
= (unsigned char *)(prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
);
589 data_len
= (size_t)(prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
);
591 full_packet_data
= (unsigned char *)prs_data_p(current_pdu
);
592 full_packet_data_len
= prhdr
->frag_len
- auth_len
;
594 /* Pull the auth header and the following data into a blob. */
595 if(!prs_set_offset(current_pdu
, RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
)) {
596 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
597 (unsigned int)RPC_HEADER_LEN
+ (unsigned int)RPC_HDR_RESP_LEN
+ (unsigned int)data_len
));
598 return NT_STATUS_BUFFER_TOO_SMALL
;
601 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
602 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
603 return NT_STATUS_BUFFER_TOO_SMALL
;
606 auth_blob
.data
= (unsigned char *)prs_data_p(current_pdu
) + prs_offset(current_pdu
);
607 auth_blob
.length
= auth_len
;
609 switch (cli
->auth
->auth_level
) {
610 case PIPE_AUTH_LEVEL_PRIVACY
:
611 /* Data is encrypted. */
612 status
= ntlmssp_unseal_packet(ntlmssp_state
,
615 full_packet_data_len
,
617 if (!NT_STATUS_IS_OK(status
)) {
618 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
619 "packet from %s. Error was %s.\n",
620 rpccli_pipe_txt(debug_ctx(), cli
),
621 nt_errstr(status
) ));
625 case PIPE_AUTH_LEVEL_INTEGRITY
:
626 /* Data is signed. */
627 status
= ntlmssp_check_packet(ntlmssp_state
,
630 full_packet_data_len
,
632 if (!NT_STATUS_IS_OK(status
)) {
633 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
634 "packet from %s. Error was %s.\n",
635 rpccli_pipe_txt(debug_ctx(), cli
),
636 nt_errstr(status
) ));
641 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
642 "auth level %d\n", cli
->auth
->auth_level
));
643 return NT_STATUS_INVALID_INFO_CLASS
;
647 * Return the current pointer to the data offset.
650 if(!prs_set_offset(current_pdu
, save_offset
)) {
651 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
652 (unsigned int)save_offset
));
653 return NT_STATUS_BUFFER_TOO_SMALL
;
657 * Remember the padding length. We must remove it from the real data
658 * stream once the sign/seal is done.
661 *p_ss_padding_len
= auth_info
.auth_pad_len
;
666 /****************************************************************************
667 schannel specific sign/seal.
668 ****************************************************************************/
670 static NTSTATUS
cli_pipe_verify_schannel(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
671 prs_struct
*current_pdu
,
672 uint8
*p_ss_padding_len
)
674 RPC_HDR_AUTH auth_info
;
675 RPC_AUTH_SCHANNEL_CHK schannel_chk
;
676 uint32 auth_len
= prhdr
->auth_len
;
677 uint32 save_offset
= prs_offset(current_pdu
);
678 struct schannel_auth_struct
*schannel_auth
=
679 cli
->auth
->a_u
.schannel_auth
;
682 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_NONE
683 || cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_CONNECT
) {
687 if (auth_len
< RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
) {
688 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len
));
689 return NT_STATUS_INVALID_PARAMETER
;
692 if (!schannel_auth
) {
693 return NT_STATUS_INVALID_PARAMETER
;
696 /* Ensure there's enough data for an authenticated response. */
697 if ((auth_len
> RPC_MAX_SIGN_SIZE
) ||
698 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
699 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
700 (unsigned int)auth_len
));
701 return NT_STATUS_INVALID_PARAMETER
;
704 data_len
= prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
;
706 if(!prs_set_offset(current_pdu
, RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
)) {
707 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
708 (unsigned int)RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
));
709 return NT_STATUS_BUFFER_TOO_SMALL
;
712 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
713 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
714 return NT_STATUS_BUFFER_TOO_SMALL
;
717 if (auth_info
.auth_type
!= RPC_SCHANNEL_AUTH_TYPE
) {
718 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
719 auth_info
.auth_type
));
720 return NT_STATUS_BUFFER_TOO_SMALL
;
723 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
,
724 &schannel_chk
, current_pdu
, 0)) {
725 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
726 return NT_STATUS_BUFFER_TOO_SMALL
;
729 if (!schannel_decode(schannel_auth
,
730 cli
->auth
->auth_level
,
733 prs_data_p(current_pdu
)+RPC_HEADER_LEN
+RPC_HDR_RESP_LEN
,
735 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
736 "Connection to %s.\n",
737 rpccli_pipe_txt(debug_ctx(), cli
)));
738 return NT_STATUS_INVALID_PARAMETER
;
741 /* The sequence number gets incremented on both send and receive. */
742 schannel_auth
->seq_num
++;
745 * Return the current pointer to the data offset.
748 if(!prs_set_offset(current_pdu
, save_offset
)) {
749 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
750 (unsigned int)save_offset
));
751 return NT_STATUS_BUFFER_TOO_SMALL
;
755 * Remember the padding length. We must remove it from the real data
756 * stream once the sign/seal is done.
759 *p_ss_padding_len
= auth_info
.auth_pad_len
;
764 /****************************************************************************
765 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
766 ****************************************************************************/
768 static NTSTATUS
cli_pipe_validate_rpc_response(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
769 prs_struct
*current_pdu
,
770 uint8
*p_ss_padding_len
)
772 NTSTATUS ret
= NT_STATUS_OK
;
774 /* Paranioa checks for auth_len. */
775 if (prhdr
->auth_len
) {
776 if (prhdr
->auth_len
> prhdr
->frag_len
) {
777 return NT_STATUS_INVALID_PARAMETER
;
780 if (prhdr
->auth_len
+ (unsigned int)RPC_HDR_AUTH_LEN
< prhdr
->auth_len
||
781 prhdr
->auth_len
+ (unsigned int)RPC_HDR_AUTH_LEN
< (unsigned int)RPC_HDR_AUTH_LEN
) {
782 /* Integer wrap attempt. */
783 return NT_STATUS_INVALID_PARAMETER
;
788 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
791 switch(cli
->auth
->auth_type
) {
792 case PIPE_AUTH_TYPE_NONE
:
793 if (prhdr
->auth_len
) {
794 DEBUG(3, ("cli_pipe_validate_rpc_response: "
795 "Connection to %s - got non-zero "
797 rpccli_pipe_txt(debug_ctx(), cli
),
798 (unsigned int)prhdr
->auth_len
));
799 return NT_STATUS_INVALID_PARAMETER
;
803 case PIPE_AUTH_TYPE_NTLMSSP
:
804 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
805 ret
= cli_pipe_verify_ntlmssp(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
806 if (!NT_STATUS_IS_OK(ret
)) {
811 case PIPE_AUTH_TYPE_SCHANNEL
:
812 ret
= cli_pipe_verify_schannel(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
813 if (!NT_STATUS_IS_OK(ret
)) {
818 case PIPE_AUTH_TYPE_KRB5
:
819 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
821 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
822 "to %s - unknown internal auth type %u.\n",
823 rpccli_pipe_txt(debug_ctx(), cli
),
824 cli
->auth
->auth_type
));
825 return NT_STATUS_INVALID_INFO_CLASS
;
831 /****************************************************************************
832 Do basic authentication checks on an incoming pdu.
833 ****************************************************************************/
835 static NTSTATUS
cli_pipe_validate_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
836 prs_struct
*current_pdu
,
837 uint8 expected_pkt_type
,
840 prs_struct
*return_data
)
843 NTSTATUS ret
= NT_STATUS_OK
;
844 uint32 current_pdu_len
= prs_data_size(current_pdu
);
846 if (current_pdu_len
!= prhdr
->frag_len
) {
847 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
848 (unsigned int)current_pdu_len
, (unsigned int)prhdr
->frag_len
));
849 return NT_STATUS_INVALID_PARAMETER
;
853 * Point the return values at the real data including the RPC
854 * header. Just in case the caller wants it.
856 *ppdata
= prs_data_p(current_pdu
);
857 *pdata_len
= current_pdu_len
;
859 /* Ensure we have the correct type. */
860 switch (prhdr
->pkt_type
) {
861 case RPC_ALTCONTRESP
:
864 /* Alter context and bind ack share the same packet definitions. */
870 RPC_HDR_RESP rhdr_resp
;
871 uint8 ss_padding_len
= 0;
873 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
874 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
875 return NT_STATUS_BUFFER_TOO_SMALL
;
878 /* Here's where we deal with incoming sign/seal. */
879 ret
= cli_pipe_validate_rpc_response(cli
, prhdr
,
880 current_pdu
, &ss_padding_len
);
881 if (!NT_STATUS_IS_OK(ret
)) {
885 /* Point the return values at the NDR data. Remember to remove any ss padding. */
886 *ppdata
= prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
888 if (current_pdu_len
< RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ ss_padding_len
) {
889 return NT_STATUS_BUFFER_TOO_SMALL
;
892 *pdata_len
= current_pdu_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- ss_padding_len
;
894 /* Remember to remove the auth footer. */
895 if (prhdr
->auth_len
) {
896 /* We've already done integer wrap tests on auth_len in
897 cli_pipe_validate_rpc_response(). */
898 if (*pdata_len
< RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
) {
899 return NT_STATUS_BUFFER_TOO_SMALL
;
901 *pdata_len
-= (RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
);
904 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
905 current_pdu_len
, *pdata_len
, ss_padding_len
));
908 * If this is the first reply, and the allocation hint is reasonably, try and
909 * set up the return_data parse_struct to the correct size.
912 if ((prs_data_size(return_data
) == 0) && rhdr_resp
.alloc_hint
&& (rhdr_resp
.alloc_hint
< 15*1024*1024)) {
913 if (!prs_set_buffer_size(return_data
, rhdr_resp
.alloc_hint
)) {
914 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
915 "too large to allocate\n",
916 (unsigned int)rhdr_resp
.alloc_hint
));
917 return NT_STATUS_NO_MEMORY
;
925 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
926 "received from %s!\n",
927 rpccli_pipe_txt(debug_ctx(), cli
)));
928 /* Use this for now... */
929 return NT_STATUS_NETWORK_ACCESS_DENIED
;
933 RPC_HDR_RESP rhdr_resp
;
934 RPC_HDR_FAULT fault_resp
;
936 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
937 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
938 return NT_STATUS_BUFFER_TOO_SMALL
;
941 if(!smb_io_rpc_hdr_fault("fault", &fault_resp
, current_pdu
, 0)) {
942 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
943 return NT_STATUS_BUFFER_TOO_SMALL
;
946 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
947 "code %s received from %s!\n",
948 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp
.status
)),
949 rpccli_pipe_txt(debug_ctx(), cli
)));
950 if (NT_STATUS_IS_OK(fault_resp
.status
)) {
951 return NT_STATUS_UNSUCCESSFUL
;
953 return fault_resp
.status
;
958 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
960 (unsigned int)prhdr
->pkt_type
,
961 rpccli_pipe_txt(debug_ctx(), cli
)));
962 return NT_STATUS_INVALID_INFO_CLASS
;
965 if (prhdr
->pkt_type
!= expected_pkt_type
) {
966 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
967 "got an unexpected RPC packet type - %u, not %u\n",
968 rpccli_pipe_txt(debug_ctx(), cli
),
971 return NT_STATUS_INVALID_INFO_CLASS
;
974 /* Do this just before return - we don't want to modify any rpc header
975 data before now as we may have needed to do cryptographic actions on
978 if ((prhdr
->pkt_type
== RPC_BINDACK
) && !(prhdr
->flags
& RPC_FLG_LAST
)) {
979 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
980 "setting fragment first/last ON.\n"));
981 prhdr
->flags
|= RPC_FLG_FIRST
|RPC_FLG_LAST
;
987 /****************************************************************************
988 Ensure we eat the just processed pdu from the current_pdu prs_struct.
989 Normally the frag_len and buffer size will match, but on the first trans
990 reply there is a theoretical chance that buffer size > frag_len, so we must
992 ****************************************************************************/
994 static NTSTATUS
cli_pipe_reset_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
, prs_struct
*current_pdu
)
996 uint32 current_pdu_len
= prs_data_size(current_pdu
);
998 if (current_pdu_len
< prhdr
->frag_len
) {
999 return NT_STATUS_BUFFER_TOO_SMALL
;
1003 if (current_pdu_len
== (uint32
)prhdr
->frag_len
) {
1004 prs_mem_free(current_pdu
);
1005 prs_init_empty(current_pdu
, prs_get_mem_context(current_pdu
), UNMARSHALL
);
1006 /* Make current_pdu dynamic with no memory. */
1007 prs_give_memory(current_pdu
, 0, 0, True
);
1008 return NT_STATUS_OK
;
1012 * Oh no ! More data in buffer than we processed in current pdu.
1013 * Cheat. Move the data down and shrink the buffer.
1016 memcpy(prs_data_p(current_pdu
), prs_data_p(current_pdu
) + prhdr
->frag_len
,
1017 current_pdu_len
- prhdr
->frag_len
);
1019 /* Remember to set the read offset back to zero. */
1020 prs_set_offset(current_pdu
, 0);
1022 /* Shrink the buffer. */
1023 if (!prs_set_buffer_size(current_pdu
, current_pdu_len
- prhdr
->frag_len
)) {
1024 return NT_STATUS_BUFFER_TOO_SMALL
;
1027 return NT_STATUS_OK
;
1030 /****************************************************************************
1031 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1032 ****************************************************************************/
1034 struct cli_api_pipe_state
{
1035 struct event_context
*ev
;
1036 struct rpc_cli_transport
*transport
;
1041 static void cli_api_pipe_trans_done(struct async_req
*subreq
);
1042 static void cli_api_pipe_write_done(struct async_req
*subreq
);
1043 static void cli_api_pipe_read_done(struct async_req
*subreq
);
1045 static struct async_req
*cli_api_pipe_send(TALLOC_CTX
*mem_ctx
,
1046 struct event_context
*ev
,
1047 struct rpc_cli_transport
*transport
,
1048 uint8_t *data
, size_t data_len
,
1049 uint32_t max_rdata_len
)
1051 struct async_req
*result
, *subreq
;
1052 struct cli_api_pipe_state
*state
;
1055 if (!async_req_setup(mem_ctx
, &result
, &state
,
1056 struct cli_api_pipe_state
)) {
1060 state
->transport
= transport
;
1062 if (max_rdata_len
< RPC_HEADER_LEN
) {
1064 * For a RPC reply we always need at least RPC_HEADER_LEN
1065 * bytes. We check this here because we will receive
1066 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1068 status
= NT_STATUS_INVALID_PARAMETER
;
1072 if (transport
->trans_send
!= NULL
) {
1073 subreq
= transport
->trans_send(state
, ev
, data
, data_len
,
1074 max_rdata_len
, transport
->priv
);
1075 if (subreq
== NULL
) {
1076 status
= NT_STATUS_NO_MEMORY
;
1079 subreq
->async
.fn
= cli_api_pipe_trans_done
;
1080 subreq
->async
.priv
= result
;
1085 * If the transport does not provide a "trans" routine, i.e. for
1086 * example the ncacn_ip_tcp transport, do the write/read step here.
1089 subreq
= rpc_write_send(state
, ev
, transport
, data
, data_len
);
1090 if (subreq
== NULL
) {
1093 subreq
->async
.fn
= cli_api_pipe_write_done
;
1094 subreq
->async
.priv
= result
;
1097 status
= NT_STATUS_INVALID_PARAMETER
;
1100 if (async_post_ntstatus(result
, ev
, status
)) {
1104 TALLOC_FREE(result
);
1108 static void cli_api_pipe_trans_done(struct async_req
*subreq
)
1110 struct async_req
*req
= talloc_get_type_abort(
1111 subreq
->async
.priv
, struct async_req
);
1112 struct cli_api_pipe_state
*state
= talloc_get_type_abort(
1113 req
->private_data
, struct cli_api_pipe_state
);
1116 status
= state
->transport
->trans_recv(subreq
, state
, &state
->rdata
,
1118 TALLOC_FREE(subreq
);
1119 if (!NT_STATUS_IS_OK(status
)) {
1120 async_req_nterror(req
, status
);
1123 async_req_done(req
);
1126 static void cli_api_pipe_write_done(struct async_req
*subreq
)
1128 struct async_req
*req
= talloc_get_type_abort(
1129 subreq
->async
.priv
, struct async_req
);
1130 struct cli_api_pipe_state
*state
= talloc_get_type_abort(
1131 req
->private_data
, struct cli_api_pipe_state
);
1134 status
= rpc_write_recv(subreq
);
1135 TALLOC_FREE(subreq
);
1136 if (!NT_STATUS_IS_OK(status
)) {
1137 async_req_nterror(req
, status
);
1141 state
->rdata
= TALLOC_ARRAY(state
, uint8_t, RPC_HEADER_LEN
);
1142 if (async_req_nomem(state
->rdata
, req
)) {
1147 * We don't need to use rpc_read_send here, the upper layer will cope
1148 * with a short read, transport->trans_send could also return less
1149 * than state->max_rdata_len.
1151 subreq
= state
->transport
->read_send(state
, state
->ev
, state
->rdata
,
1153 state
->transport
->priv
);
1154 if (async_req_nomem(subreq
, req
)) {
1157 subreq
->async
.fn
= cli_api_pipe_read_done
;
1158 subreq
->async
.priv
= req
;
1161 static void cli_api_pipe_read_done(struct async_req
*subreq
)
1163 struct async_req
*req
= talloc_get_type_abort(
1164 subreq
->async
.priv
, struct async_req
);
1165 struct cli_api_pipe_state
*state
= talloc_get_type_abort(
1166 req
->private_data
, struct cli_api_pipe_state
);
1170 status
= state
->transport
->read_recv(subreq
, &received
);
1171 TALLOC_FREE(subreq
);
1172 if (!NT_STATUS_IS_OK(status
)) {
1173 async_req_nterror(req
, status
);
1176 state
->rdata_len
= received
;
1177 async_req_done(req
);
1180 static NTSTATUS
cli_api_pipe_recv(struct async_req
*req
, TALLOC_CTX
*mem_ctx
,
1181 uint8_t **prdata
, uint32_t *prdata_len
)
1183 struct cli_api_pipe_state
*state
= talloc_get_type_abort(
1184 req
->private_data
, struct cli_api_pipe_state
);
1187 if (async_req_is_nterror(req
, &status
)) {
1191 *prdata
= talloc_move(mem_ctx
, &state
->rdata
);
1192 *prdata_len
= state
->rdata_len
;
1193 return NT_STATUS_OK
;
1196 /****************************************************************************
1197 Send data on an rpc pipe via trans. The prs_struct data must be the last
1198 pdu fragment of an NDR data stream.
1200 Receive response data from an rpc pipe, which may be large...
1202 Read the first fragment: unfortunately have to use SMBtrans for the first
1203 bit, then SMBreadX for subsequent bits.
1205 If first fragment received also wasn't the last fragment, continue
1206 getting fragments until we _do_ receive the last fragment.
1208 Request/Response PDU's look like the following...
1210 |<------------------PDU len----------------------------------------------->|
1211 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1213 +------------+-----------------+-------------+---------------+-------------+
1214 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1215 +------------+-----------------+-------------+---------------+-------------+
1217 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1218 signing & sealing being negotiated.
1220 ****************************************************************************/
1222 struct rpc_api_pipe_state
{
1223 struct event_context
*ev
;
1224 struct rpc_pipe_client
*cli
;
1225 uint8_t expected_pkt_type
;
1227 prs_struct incoming_frag
;
1228 struct rpc_hdr_info rhdr
;
1230 prs_struct incoming_pdu
; /* Incoming reply */
1231 uint32_t incoming_pdu_offset
;
1234 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state
*state
)
1236 prs_mem_free(&state
->incoming_frag
);
1237 prs_mem_free(&state
->incoming_pdu
);
1241 static void rpc_api_pipe_trans_done(struct async_req
*subreq
);
1242 static void rpc_api_pipe_got_pdu(struct async_req
*subreq
);
1244 static struct async_req
*rpc_api_pipe_send(TALLOC_CTX
*mem_ctx
,
1245 struct event_context
*ev
,
1246 struct rpc_pipe_client
*cli
,
1247 prs_struct
*data
, /* Outgoing PDU */
1248 uint8_t expected_pkt_type
)
1250 struct async_req
*result
, *subreq
;
1251 struct rpc_api_pipe_state
*state
;
1252 uint16_t max_recv_frag
;
1255 if (!async_req_setup(mem_ctx
, &result
, &state
,
1256 struct rpc_api_pipe_state
)) {
1261 state
->expected_pkt_type
= expected_pkt_type
;
1262 state
->incoming_pdu_offset
= 0;
1264 prs_init_empty(&state
->incoming_frag
, state
, UNMARSHALL
);
1266 prs_init_empty(&state
->incoming_pdu
, state
, UNMARSHALL
);
1267 /* Make incoming_pdu dynamic with no memory. */
1268 prs_give_memory(&state
->incoming_pdu
, NULL
, 0, true);
1270 talloc_set_destructor(state
, rpc_api_pipe_state_destructor
);
1273 * Ensure we're not sending too much.
1275 if (prs_offset(data
) > cli
->max_xmit_frag
) {
1276 status
= NT_STATUS_INVALID_PARAMETER
;
1280 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli
)));
1282 max_recv_frag
= cli
->max_recv_frag
;
1285 max_recv_frag
= RPC_HEADER_LEN
+ 10 + (sys_random() % 32);
1288 subreq
= cli_api_pipe_send(state
, ev
, cli
->transport
,
1289 (uint8_t *)prs_data_p(data
),
1290 prs_offset(data
), max_recv_frag
);
1291 if (subreq
== NULL
) {
1292 status
= NT_STATUS_NO_MEMORY
;
1295 subreq
->async
.fn
= rpc_api_pipe_trans_done
;
1296 subreq
->async
.priv
= result
;
1300 if (async_post_ntstatus(result
, ev
, status
)) {
1303 TALLOC_FREE(result
);
1307 static void rpc_api_pipe_trans_done(struct async_req
*subreq
)
1309 struct async_req
*req
= talloc_get_type_abort(
1310 subreq
->async
.priv
, struct async_req
);
1311 struct rpc_api_pipe_state
*state
= talloc_get_type_abort(
1312 req
->private_data
, struct rpc_api_pipe_state
);
1314 uint8_t *rdata
= NULL
;
1315 uint32_t rdata_len
= 0;
1318 status
= cli_api_pipe_recv(subreq
, state
, &rdata
, &rdata_len
);
1319 TALLOC_FREE(subreq
);
1320 if (!NT_STATUS_IS_OK(status
)) {
1321 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status
)));
1322 async_req_nterror(req
, status
);
1326 if (rdata
== NULL
) {
1327 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1328 rpccli_pipe_txt(debug_ctx(), state
->cli
)));
1329 async_req_done(req
);
1334 * Give the memory received from cli_trans as dynamic to the current
1335 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1338 rdata_copy
= (char *)memdup(rdata
, rdata_len
);
1340 if (async_req_nomem(rdata_copy
, req
)) {
1343 prs_give_memory(&state
->incoming_frag
, rdata_copy
, rdata_len
, true);
1345 /* Ensure we have enough data for a pdu. */
1346 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1347 &state
->rhdr
, &state
->incoming_frag
);
1348 if (async_req_nomem(subreq
, req
)) {
1351 subreq
->async
.fn
= rpc_api_pipe_got_pdu
;
1352 subreq
->async
.priv
= req
;
1355 static void rpc_api_pipe_got_pdu(struct async_req
*subreq
)
1357 struct async_req
*req
= talloc_get_type_abort(
1358 subreq
->async
.priv
, struct async_req
);
1359 struct rpc_api_pipe_state
*state
= talloc_get_type_abort(
1360 req
->private_data
, struct rpc_api_pipe_state
);
1363 uint32_t rdata_len
= 0;
1365 status
= get_complete_frag_recv(subreq
);
1366 TALLOC_FREE(subreq
);
1367 if (!NT_STATUS_IS_OK(status
)) {
1368 DEBUG(5, ("get_complete_frag failed: %s\n",
1369 nt_errstr(status
)));
1370 async_req_nterror(req
, status
);
1374 status
= cli_pipe_validate_current_pdu(
1375 state
->cli
, &state
->rhdr
, &state
->incoming_frag
,
1376 state
->expected_pkt_type
, &rdata
, &rdata_len
,
1377 &state
->incoming_pdu
);
1379 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1380 (unsigned)prs_data_size(&state
->incoming_frag
),
1381 (unsigned)state
->incoming_pdu_offset
,
1382 nt_errstr(status
)));
1384 if (!NT_STATUS_IS_OK(status
)) {
1385 async_req_nterror(req
, status
);
1389 if ((state
->rhdr
.flags
& RPC_FLG_FIRST
)
1390 && (state
->rhdr
.pack_type
[0] == 0)) {
1392 * Set the data type correctly for big-endian data on the
1395 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1397 rpccli_pipe_txt(debug_ctx(), state
->cli
)));
1398 prs_set_endian_data(&state
->incoming_pdu
, RPC_BIG_ENDIAN
);
1401 * Check endianness on subsequent packets.
1403 if (state
->incoming_frag
.bigendian_data
1404 != state
->incoming_pdu
.bigendian_data
) {
1405 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1407 state
->incoming_pdu
.bigendian_data
?"big":"little",
1408 state
->incoming_frag
.bigendian_data
?"big":"little"));
1409 async_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1413 /* Now copy the data portion out of the pdu into rbuf. */
1414 if (!prs_force_grow(&state
->incoming_pdu
, rdata_len
)) {
1415 async_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1419 memcpy(prs_data_p(&state
->incoming_pdu
) + state
->incoming_pdu_offset
,
1420 rdata
, (size_t)rdata_len
);
1421 state
->incoming_pdu_offset
+= rdata_len
;
1423 status
= cli_pipe_reset_current_pdu(state
->cli
, &state
->rhdr
,
1424 &state
->incoming_frag
);
1425 if (!NT_STATUS_IS_OK(status
)) {
1426 async_req_nterror(req
, status
);
1430 if (state
->rhdr
.flags
& RPC_FLG_LAST
) {
1431 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1432 rpccli_pipe_txt(debug_ctx(), state
->cli
),
1433 (unsigned)prs_data_size(&state
->incoming_pdu
)));
1434 async_req_done(req
);
1438 subreq
= get_complete_frag_send(state
, state
->ev
, state
->cli
,
1439 &state
->rhdr
, &state
->incoming_frag
);
1440 if (async_req_nomem(subreq
, req
)) {
1443 subreq
->async
.fn
= rpc_api_pipe_got_pdu
;
1444 subreq
->async
.priv
= req
;
1447 static NTSTATUS
rpc_api_pipe_recv(struct async_req
*req
, TALLOC_CTX
*mem_ctx
,
1448 prs_struct
*reply_pdu
)
1450 struct rpc_api_pipe_state
*state
= talloc_get_type_abort(
1451 req
->private_data
, struct rpc_api_pipe_state
);
1454 if (async_req_is_nterror(req
, &status
)) {
1458 *reply_pdu
= state
->incoming_pdu
;
1459 reply_pdu
->mem_ctx
= mem_ctx
;
1462 * Prevent state->incoming_pdu from being freed in
1463 * rpc_api_pipe_state_destructor()
1465 prs_init_empty(&state
->incoming_pdu
, state
, UNMARSHALL
);
1467 return NT_STATUS_OK
;
1470 /*******************************************************************
1471 Creates krb5 auth bind.
1472 ********************************************************************/
1474 static NTSTATUS
create_krb5_auth_bind_req( struct rpc_pipe_client
*cli
,
1475 enum pipe_auth_level auth_level
,
1476 RPC_HDR_AUTH
*pauth_out
,
1477 prs_struct
*auth_data
)
1481 struct kerberos_auth_struct
*a
= cli
->auth
->a_u
.kerberos_auth
;
1482 DATA_BLOB tkt
= data_blob_null
;
1483 DATA_BLOB tkt_wrapped
= data_blob_null
;
1485 /* We may change the pad length before marshalling. */
1486 init_rpc_hdr_auth(pauth_out
, RPC_KRB5_AUTH_TYPE
, (int)auth_level
, 0, 1);
1488 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1489 a
->service_principal
));
1491 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1493 ret
= cli_krb5_get_ticket(a
->service_principal
, 0, &tkt
,
1494 &a
->session_key
, (uint32
)AP_OPTS_MUTUAL_REQUIRED
, NULL
, NULL
);
1497 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1499 a
->service_principal
,
1500 error_message(ret
) ));
1502 data_blob_free(&tkt
);
1503 prs_mem_free(auth_data
);
1504 return NT_STATUS_INVALID_PARAMETER
;
1507 /* wrap that up in a nice GSS-API wrapping */
1508 tkt_wrapped
= spnego_gen_krb5_wrap(tkt
, TOK_ID_KRB_AP_REQ
);
1510 data_blob_free(&tkt
);
1512 /* Auth len in the rpc header doesn't include auth_header. */
1513 if (!prs_copy_data_in(auth_data
, (char *)tkt_wrapped
.data
, tkt_wrapped
.length
)) {
1514 data_blob_free(&tkt_wrapped
);
1515 prs_mem_free(auth_data
);
1516 return NT_STATUS_NO_MEMORY
;
1519 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1520 dump_data(5, tkt_wrapped
.data
, tkt_wrapped
.length
);
1522 data_blob_free(&tkt_wrapped
);
1523 return NT_STATUS_OK
;
1525 return NT_STATUS_INVALID_PARAMETER
;
1529 /*******************************************************************
1530 Creates SPNEGO NTLMSSP auth bind.
1531 ********************************************************************/
1533 static NTSTATUS
create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1534 enum pipe_auth_level auth_level
,
1535 RPC_HDR_AUTH
*pauth_out
,
1536 prs_struct
*auth_data
)
1539 DATA_BLOB null_blob
= data_blob_null
;
1540 DATA_BLOB request
= data_blob_null
;
1541 DATA_BLOB spnego_msg
= data_blob_null
;
1543 /* We may change the pad length before marshalling. */
1544 init_rpc_hdr_auth(pauth_out
, RPC_SPNEGO_AUTH_TYPE
, (int)auth_level
, 0, 1);
1546 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1547 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1551 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1552 data_blob_free(&request
);
1553 prs_mem_free(auth_data
);
1557 /* Wrap this in SPNEGO. */
1558 spnego_msg
= gen_negTokenInit(OID_NTLMSSP
, request
);
1560 data_blob_free(&request
);
1562 /* Auth len in the rpc header doesn't include auth_header. */
1563 if (!prs_copy_data_in(auth_data
, (char *)spnego_msg
.data
, spnego_msg
.length
)) {
1564 data_blob_free(&spnego_msg
);
1565 prs_mem_free(auth_data
);
1566 return NT_STATUS_NO_MEMORY
;
1569 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1570 dump_data(5, spnego_msg
.data
, spnego_msg
.length
);
1572 data_blob_free(&spnego_msg
);
1573 return NT_STATUS_OK
;
1576 /*******************************************************************
1577 Creates NTLMSSP auth bind.
1578 ********************************************************************/
1580 static NTSTATUS
create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1581 enum pipe_auth_level auth_level
,
1582 RPC_HDR_AUTH
*pauth_out
,
1583 prs_struct
*auth_data
)
1586 DATA_BLOB null_blob
= data_blob_null
;
1587 DATA_BLOB request
= data_blob_null
;
1589 /* We may change the pad length before marshalling. */
1590 init_rpc_hdr_auth(pauth_out
, RPC_NTLMSSP_AUTH_TYPE
, (int)auth_level
, 0, 1);
1592 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1593 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1597 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1598 data_blob_free(&request
);
1599 prs_mem_free(auth_data
);
1603 /* Auth len in the rpc header doesn't include auth_header. */
1604 if (!prs_copy_data_in(auth_data
, (char *)request
.data
, request
.length
)) {
1605 data_blob_free(&request
);
1606 prs_mem_free(auth_data
);
1607 return NT_STATUS_NO_MEMORY
;
1610 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1611 dump_data(5, request
.data
, request
.length
);
1613 data_blob_free(&request
);
1614 return NT_STATUS_OK
;
1617 /*******************************************************************
1618 Creates schannel auth bind.
1619 ********************************************************************/
1621 static NTSTATUS
create_schannel_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1622 enum pipe_auth_level auth_level
,
1623 RPC_HDR_AUTH
*pauth_out
,
1624 prs_struct
*auth_data
)
1626 RPC_AUTH_SCHANNEL_NEG schannel_neg
;
1628 /* We may change the pad length before marshalling. */
1629 init_rpc_hdr_auth(pauth_out
, RPC_SCHANNEL_AUTH_TYPE
, (int)auth_level
, 0, 1);
1631 /* Use lp_workgroup() if domain not specified */
1633 if (!cli
->auth
->domain
|| !cli
->auth
->domain
[0]) {
1634 cli
->auth
->domain
= talloc_strdup(cli
, lp_workgroup());
1635 if (cli
->auth
->domain
== NULL
) {
1636 return NT_STATUS_NO_MEMORY
;
1640 init_rpc_auth_schannel_neg(&schannel_neg
, cli
->auth
->domain
,
1644 * Now marshall the data into the auth parse_struct.
1647 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1648 &schannel_neg
, auth_data
, 0)) {
1649 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1650 prs_mem_free(auth_data
);
1651 return NT_STATUS_NO_MEMORY
;
1654 return NT_STATUS_OK
;
1657 /*******************************************************************
1658 Creates the internals of a DCE/RPC bind request or alter context PDU.
1659 ********************************************************************/
1661 static NTSTATUS
create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type
,
1662 prs_struct
*rpc_out
,
1664 const RPC_IFACE
*abstract
,
1665 const RPC_IFACE
*transfer
,
1666 RPC_HDR_AUTH
*phdr_auth
,
1667 prs_struct
*pauth_info
)
1671 RPC_CONTEXT rpc_ctx
;
1672 uint16 auth_len
= prs_offset(pauth_info
);
1673 uint8 ss_padding_len
= 0;
1674 uint16 frag_len
= 0;
1676 /* create the RPC context. */
1677 init_rpc_context(&rpc_ctx
, 0 /* context id */, abstract
, transfer
);
1679 /* create the bind request RPC_HDR_RB */
1680 init_rpc_hdr_rb(&hdr_rb
, RPC_MAX_PDU_FRAG_LEN
, RPC_MAX_PDU_FRAG_LEN
, 0x0, &rpc_ctx
);
1682 /* Start building the frag length. */
1683 frag_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1685 /* Do we need to pad ? */
1687 uint16 data_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1689 ss_padding_len
= 8 - (data_len
% 8);
1690 phdr_auth
->auth_pad_len
= ss_padding_len
;
1692 frag_len
+= RPC_HDR_AUTH_LEN
+ auth_len
+ ss_padding_len
;
1695 /* Create the request RPC_HDR */
1696 init_rpc_hdr(&hdr
, pkt_type
, RPC_FLG_FIRST
|RPC_FLG_LAST
, rpc_call_id
, frag_len
, auth_len
);
1698 /* Marshall the RPC header */
1699 if(!smb_io_rpc_hdr("hdr" , &hdr
, rpc_out
, 0)) {
1700 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1701 return NT_STATUS_NO_MEMORY
;
1704 /* Marshall the bind request data */
1705 if(!smb_io_rpc_hdr_rb("", &hdr_rb
, rpc_out
, 0)) {
1706 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1707 return NT_STATUS_NO_MEMORY
;
1711 * Grow the outgoing buffer to store any auth info.
1715 if (ss_padding_len
) {
1717 memset(pad
, '\0', 8);
1718 if (!prs_copy_data_in(rpc_out
, pad
, ss_padding_len
)) {
1719 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1720 return NT_STATUS_NO_MEMORY
;
1724 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth
, rpc_out
, 0)) {
1725 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1726 return NT_STATUS_NO_MEMORY
;
1730 if(!prs_append_prs_data( rpc_out
, pauth_info
)) {
1731 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1732 return NT_STATUS_NO_MEMORY
;
1736 return NT_STATUS_OK
;
1739 /*******************************************************************
1740 Creates a DCE/RPC bind request.
1741 ********************************************************************/
1743 static NTSTATUS
create_rpc_bind_req(struct rpc_pipe_client
*cli
,
1744 prs_struct
*rpc_out
,
1746 const RPC_IFACE
*abstract
,
1747 const RPC_IFACE
*transfer
,
1748 enum pipe_auth_type auth_type
,
1749 enum pipe_auth_level auth_level
)
1751 RPC_HDR_AUTH hdr_auth
;
1752 prs_struct auth_info
;
1753 NTSTATUS ret
= NT_STATUS_OK
;
1755 ZERO_STRUCT(hdr_auth
);
1756 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
1757 return NT_STATUS_NO_MEMORY
;
1759 switch (auth_type
) {
1760 case PIPE_AUTH_TYPE_SCHANNEL
:
1761 ret
= create_schannel_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1762 if (!NT_STATUS_IS_OK(ret
)) {
1763 prs_mem_free(&auth_info
);
1768 case PIPE_AUTH_TYPE_NTLMSSP
:
1769 ret
= create_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1770 if (!NT_STATUS_IS_OK(ret
)) {
1771 prs_mem_free(&auth_info
);
1776 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1777 ret
= create_spnego_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1778 if (!NT_STATUS_IS_OK(ret
)) {
1779 prs_mem_free(&auth_info
);
1784 case PIPE_AUTH_TYPE_KRB5
:
1785 ret
= create_krb5_auth_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1786 if (!NT_STATUS_IS_OK(ret
)) {
1787 prs_mem_free(&auth_info
);
1792 case PIPE_AUTH_TYPE_NONE
:
1796 /* "Can't" happen. */
1797 return NT_STATUS_INVALID_INFO_CLASS
;
1800 ret
= create_bind_or_alt_ctx_internal(RPC_BIND
,
1808 prs_mem_free(&auth_info
);
1812 /*******************************************************************
1813 Create and add the NTLMSSP sign/seal auth header and data.
1814 ********************************************************************/
1816 static NTSTATUS
add_ntlmssp_auth_footer(struct rpc_pipe_client
*cli
,
1818 uint32 ss_padding_len
,
1819 prs_struct
*outgoing_pdu
)
1821 RPC_HDR_AUTH auth_info
;
1823 DATA_BLOB auth_blob
= data_blob_null
;
1824 uint16 data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1826 if (!cli
->auth
->a_u
.ntlmssp_state
) {
1827 return NT_STATUS_INVALID_PARAMETER
;
1830 /* Init and marshall the auth header. */
1831 init_rpc_hdr_auth(&auth_info
,
1832 map_pipe_auth_type_to_rpc_auth_type(
1833 cli
->auth
->auth_type
),
1834 cli
->auth
->auth_level
,
1836 1 /* context id. */);
1838 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1839 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1840 data_blob_free(&auth_blob
);
1841 return NT_STATUS_NO_MEMORY
;
1844 switch (cli
->auth
->auth_level
) {
1845 case PIPE_AUTH_LEVEL_PRIVACY
:
1846 /* Data portion is encrypted. */
1847 status
= ntlmssp_seal_packet(cli
->auth
->a_u
.ntlmssp_state
,
1848 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1850 (unsigned char *)prs_data_p(outgoing_pdu
),
1851 (size_t)prs_offset(outgoing_pdu
),
1853 if (!NT_STATUS_IS_OK(status
)) {
1854 data_blob_free(&auth_blob
);
1859 case PIPE_AUTH_LEVEL_INTEGRITY
:
1860 /* Data is signed. */
1861 status
= ntlmssp_sign_packet(cli
->auth
->a_u
.ntlmssp_state
,
1862 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1864 (unsigned char *)prs_data_p(outgoing_pdu
),
1865 (size_t)prs_offset(outgoing_pdu
),
1867 if (!NT_STATUS_IS_OK(status
)) {
1868 data_blob_free(&auth_blob
);
1875 smb_panic("bad auth level");
1877 return NT_STATUS_INVALID_PARAMETER
;
1880 /* Finally marshall the blob. */
1882 if (!prs_copy_data_in(outgoing_pdu
, (const char *)auth_blob
.data
, NTLMSSP_SIG_SIZE
)) {
1883 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1884 (unsigned int)NTLMSSP_SIG_SIZE
));
1885 data_blob_free(&auth_blob
);
1886 return NT_STATUS_NO_MEMORY
;
1889 data_blob_free(&auth_blob
);
1890 return NT_STATUS_OK
;
1893 /*******************************************************************
1894 Create and add the schannel sign/seal auth header and data.
1895 ********************************************************************/
1897 static NTSTATUS
add_schannel_auth_footer(struct rpc_pipe_client
*cli
,
1899 uint32 ss_padding_len
,
1900 prs_struct
*outgoing_pdu
)
1902 RPC_HDR_AUTH auth_info
;
1903 RPC_AUTH_SCHANNEL_CHK verf
;
1904 struct schannel_auth_struct
*sas
= cli
->auth
->a_u
.schannel_auth
;
1905 char *data_p
= prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
1906 size_t data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1909 return NT_STATUS_INVALID_PARAMETER
;
1912 /* Init and marshall the auth header. */
1913 init_rpc_hdr_auth(&auth_info
,
1914 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
->auth_type
),
1915 cli
->auth
->auth_level
,
1917 1 /* context id. */);
1919 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1920 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1921 return NT_STATUS_NO_MEMORY
;
1924 switch (cli
->auth
->auth_level
) {
1925 case PIPE_AUTH_LEVEL_PRIVACY
:
1926 case PIPE_AUTH_LEVEL_INTEGRITY
:
1927 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1930 schannel_encode(sas
,
1931 cli
->auth
->auth_level
,
1932 SENDER_IS_INITIATOR
,
1942 smb_panic("bad auth level");
1944 return NT_STATUS_INVALID_PARAMETER
;
1947 /* Finally marshall the blob. */
1948 smb_io_rpc_auth_schannel_chk("",
1949 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
,
1954 return NT_STATUS_OK
;
1957 /*******************************************************************
1958 Calculate how much data we're going to send in this packet, also
1959 work out any sign/seal padding length.
1960 ********************************************************************/
1962 static uint32
calculate_data_len_tosend(struct rpc_pipe_client
*cli
,
1966 uint32
*p_ss_padding
)
1968 uint32 data_space
, data_len
;
1971 if ((data_left
> 0) && (sys_random() % 2)) {
1972 data_left
= MAX(data_left
/2, 1);
1976 switch (cli
->auth
->auth_level
) {
1977 case PIPE_AUTH_LEVEL_NONE
:
1978 case PIPE_AUTH_LEVEL_CONNECT
:
1979 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
;
1980 data_len
= MIN(data_space
, data_left
);
1983 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ data_len
;
1986 case PIPE_AUTH_LEVEL_INTEGRITY
:
1987 case PIPE_AUTH_LEVEL_PRIVACY
:
1988 /* Treat the same for all authenticated rpc requests. */
1989 switch(cli
->auth
->auth_type
) {
1990 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1991 case PIPE_AUTH_TYPE_NTLMSSP
:
1992 *p_auth_len
= NTLMSSP_SIG_SIZE
;
1994 case PIPE_AUTH_TYPE_SCHANNEL
:
1995 *p_auth_len
= RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
;
1998 smb_panic("bad auth type");
2002 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
-
2003 RPC_HDR_AUTH_LEN
- *p_auth_len
;
2005 data_len
= MIN(data_space
, data_left
);
2008 *p_ss_padding
= 8 - (data_len
% 8);
2010 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ /* Normal headers. */
2011 data_len
+ *p_ss_padding
+ /* data plus padding. */
2012 RPC_HDR_AUTH_LEN
+ *p_auth_len
; /* Auth header and auth data. */
2016 smb_panic("bad auth level");
2022 /*******************************************************************
2024 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2025 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2026 and deals with signing/sealing details.
2027 ********************************************************************/
2029 struct rpc_api_pipe_req_state
{
2030 struct event_context
*ev
;
2031 struct rpc_pipe_client
*cli
;
2034 prs_struct
*req_data
;
2035 uint32_t req_data_sent
;
2036 prs_struct outgoing_frag
;
2037 prs_struct reply_pdu
;
2040 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state
*s
)
2042 prs_mem_free(&s
->outgoing_frag
);
2043 prs_mem_free(&s
->reply_pdu
);
2047 static void rpc_api_pipe_req_write_done(struct async_req
*subreq
);
2048 static void rpc_api_pipe_req_done(struct async_req
*subreq
);
2049 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
2050 bool *is_last_frag
);
2052 struct async_req
*rpc_api_pipe_req_send(TALLOC_CTX
*mem_ctx
,
2053 struct event_context
*ev
,
2054 struct rpc_pipe_client
*cli
,
2056 prs_struct
*req_data
)
2058 struct async_req
*result
, *subreq
;
2059 struct rpc_api_pipe_req_state
*state
;
2063 if (!async_req_setup(mem_ctx
, &result
, &state
,
2064 struct rpc_api_pipe_req_state
)) {
2069 state
->op_num
= op_num
;
2070 state
->req_data
= req_data
;
2071 state
->req_data_sent
= 0;
2072 state
->call_id
= get_rpc_call_id();
2074 if (cli
->max_xmit_frag
2075 < RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ RPC_MAX_SIGN_SIZE
) {
2076 /* Server is screwed up ! */
2077 status
= NT_STATUS_INVALID_PARAMETER
;
2081 prs_init_empty(&state
->reply_pdu
, state
, UNMARSHALL
);
2083 if (!prs_init(&state
->outgoing_frag
, cli
->max_xmit_frag
,
2085 status
= NT_STATUS_NO_MEMORY
;
2089 talloc_set_destructor(state
, rpc_api_pipe_req_state_destructor
);
2091 status
= prepare_next_frag(state
, &is_last_frag
);
2092 if (!NT_STATUS_IS_OK(status
)) {
2097 subreq
= rpc_api_pipe_send(state
, ev
, state
->cli
,
2098 &state
->outgoing_frag
,
2100 if (subreq
== NULL
) {
2101 status
= NT_STATUS_NO_MEMORY
;
2104 subreq
->async
.fn
= rpc_api_pipe_req_done
;
2105 subreq
->async
.priv
= result
;
2107 subreq
= rpc_write_send(
2108 state
, ev
, cli
->transport
,
2109 (uint8_t *)prs_data_p(&state
->outgoing_frag
),
2110 prs_offset(&state
->outgoing_frag
));
2111 if (subreq
== NULL
) {
2112 status
= NT_STATUS_NO_MEMORY
;
2115 subreq
->async
.fn
= rpc_api_pipe_req_write_done
;
2116 subreq
->async
.priv
= result
;
2121 if (async_post_ntstatus(result
, ev
, status
)) {
2124 TALLOC_FREE(result
);
2128 static NTSTATUS
prepare_next_frag(struct rpc_api_pipe_req_state
*state
,
2132 RPC_HDR_REQ hdr_req
;
2133 uint32_t data_sent_thistime
;
2137 uint32_t ss_padding
;
2139 char pad
[8] = { 0, };
2142 data_left
= prs_offset(state
->req_data
) - state
->req_data_sent
;
2144 data_sent_thistime
= calculate_data_len_tosend(
2145 state
->cli
, data_left
, &frag_len
, &auth_len
, &ss_padding
);
2147 if (state
->req_data_sent
== 0) {
2148 flags
= RPC_FLG_FIRST
;
2151 if (data_sent_thistime
== data_left
) {
2152 flags
|= RPC_FLG_LAST
;
2155 if (!prs_set_offset(&state
->outgoing_frag
, 0)) {
2156 return NT_STATUS_NO_MEMORY
;
2159 /* Create and marshall the header and request header. */
2160 init_rpc_hdr(&hdr
, RPC_REQUEST
, flags
, state
->call_id
, frag_len
,
2163 if (!smb_io_rpc_hdr("hdr ", &hdr
, &state
->outgoing_frag
, 0)) {
2164 return NT_STATUS_NO_MEMORY
;
2167 /* Create the rpc request RPC_HDR_REQ */
2168 init_rpc_hdr_req(&hdr_req
, prs_offset(state
->req_data
),
2171 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req
,
2172 &state
->outgoing_frag
, 0)) {
2173 return NT_STATUS_NO_MEMORY
;
2176 /* Copy in the data, plus any ss padding. */
2177 if (!prs_append_some_prs_data(&state
->outgoing_frag
,
2178 state
->req_data
, state
->req_data_sent
,
2179 data_sent_thistime
)) {
2180 return NT_STATUS_NO_MEMORY
;
2183 /* Copy the sign/seal padding data. */
2184 if (!prs_copy_data_in(&state
->outgoing_frag
, pad
, ss_padding
)) {
2185 return NT_STATUS_NO_MEMORY
;
2188 /* Generate any auth sign/seal and add the auth footer. */
2189 switch (state
->cli
->auth
->auth_type
) {
2190 case PIPE_AUTH_TYPE_NONE
:
2191 status
= NT_STATUS_OK
;
2193 case PIPE_AUTH_TYPE_NTLMSSP
:
2194 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2195 status
= add_ntlmssp_auth_footer(state
->cli
, &hdr
, ss_padding
,
2196 &state
->outgoing_frag
);
2198 case PIPE_AUTH_TYPE_SCHANNEL
:
2199 status
= add_schannel_auth_footer(state
->cli
, &hdr
, ss_padding
,
2200 &state
->outgoing_frag
);
2203 status
= NT_STATUS_INVALID_PARAMETER
;
2207 state
->req_data_sent
+= data_sent_thistime
;
2208 *is_last_frag
= ((flags
& RPC_FLG_LAST
) != 0);
2213 static void rpc_api_pipe_req_write_done(struct async_req
*subreq
)
2215 struct async_req
*req
= talloc_get_type_abort(
2216 subreq
->async
.priv
, struct async_req
);
2217 struct rpc_api_pipe_req_state
*state
= talloc_get_type_abort(
2218 req
->private_data
, struct rpc_api_pipe_req_state
);
2222 status
= rpc_write_recv(subreq
);
2223 TALLOC_FREE(subreq
);
2224 if (!NT_STATUS_IS_OK(status
)) {
2225 async_req_nterror(req
, status
);
2229 status
= prepare_next_frag(state
, &is_last_frag
);
2230 if (!NT_STATUS_IS_OK(status
)) {
2231 async_req_nterror(req
, status
);
2236 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2237 &state
->outgoing_frag
,
2239 if (async_req_nomem(subreq
, req
)) {
2242 subreq
->async
.fn
= rpc_api_pipe_req_done
;
2243 subreq
->async
.priv
= req
;
2245 subreq
= rpc_write_send(
2247 state
->cli
->transport
,
2248 (uint8_t *)prs_data_p(&state
->outgoing_frag
),
2249 prs_offset(&state
->outgoing_frag
));
2250 if (async_req_nomem(subreq
, req
)) {
2253 subreq
->async
.fn
= rpc_api_pipe_req_write_done
;
2254 subreq
->async
.priv
= req
;
2258 static void rpc_api_pipe_req_done(struct async_req
*subreq
)
2260 struct async_req
*req
= talloc_get_type_abort(
2261 subreq
->async
.priv
, struct async_req
);
2262 struct rpc_api_pipe_req_state
*state
= talloc_get_type_abort(
2263 req
->private_data
, struct rpc_api_pipe_req_state
);
2266 status
= rpc_api_pipe_recv(subreq
, state
, &state
->reply_pdu
);
2267 TALLOC_FREE(subreq
);
2268 if (!NT_STATUS_IS_OK(status
)) {
2269 async_req_nterror(req
, status
);
2272 async_req_done(req
);
2275 NTSTATUS
rpc_api_pipe_req_recv(struct async_req
*req
, TALLOC_CTX
*mem_ctx
,
2276 prs_struct
*reply_pdu
)
2278 struct rpc_api_pipe_req_state
*state
= talloc_get_type_abort(
2279 req
->private_data
, struct rpc_api_pipe_req_state
);
2282 if (async_req_is_nterror(req
, &status
)) {
2284 * We always have to initialize to reply pdu, even if there is
2285 * none. The rpccli_* caller routines expect this.
2287 prs_init_empty(reply_pdu
, mem_ctx
, UNMARSHALL
);
2291 *reply_pdu
= state
->reply_pdu
;
2292 reply_pdu
->mem_ctx
= mem_ctx
;
2295 * Prevent state->req_pdu from being freed in
2296 * rpc_api_pipe_req_state_destructor()
2298 prs_init_empty(&state
->reply_pdu
, state
, UNMARSHALL
);
2300 return NT_STATUS_OK
;
2303 NTSTATUS
rpc_api_pipe_req(TALLOC_CTX
*mem_ctx
, struct rpc_pipe_client
*cli
,
2305 prs_struct
*in_data
,
2306 prs_struct
*out_data
)
2308 TALLOC_CTX
*frame
= talloc_stackframe();
2309 struct event_context
*ev
;
2310 struct async_req
*req
;
2311 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2313 ev
= event_context_init(frame
);
2318 req
= rpc_api_pipe_req_send(frame
, ev
, cli
, op_num
, in_data
);
2323 while (req
->state
< ASYNC_REQ_DONE
) {
2324 event_loop_once(ev
);
2327 status
= rpc_api_pipe_req_recv(req
, mem_ctx
, out_data
);
2334 /****************************************************************************
2335 Set the handle state.
2336 ****************************************************************************/
2338 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client
*cli
,
2339 const char *pipe_name
, uint16 device_state
)
2341 bool state_set
= False
;
2343 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
2344 char *rparam
= NULL
;
2346 uint32 rparam_len
, rdata_len
;
2348 if (pipe_name
== NULL
)
2351 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2352 cli
->fnum
, pipe_name
, device_state
));
2354 /* create parameters: device state */
2355 SSVAL(param
, 0, device_state
);
2357 /* create setup parameters. */
2359 setup
[1] = cli
->fnum
; /* pipe file handle. got this from an SMBOpenX. */
2361 /* send the data on \PIPE\ */
2362 if (cli_api_pipe(cli
->cli
, "\\PIPE\\",
2363 setup
, 2, 0, /* setup, length, max */
2364 param
, 2, 0, /* param, length, max */
2365 NULL
, 0, 1024, /* data, length, max */
2366 &rparam
, &rparam_len
, /* return param, length */
2367 &rdata
, &rdata_len
)) /* return data, length */
2369 DEBUG(5, ("Set Handle state: return OK\n"));
2380 /****************************************************************************
2381 Check the rpc bind acknowledge response.
2382 ****************************************************************************/
2384 static bool check_bind_response(RPC_HDR_BA
*hdr_ba
, const RPC_IFACE
*transfer
)
2386 if ( hdr_ba
->addr
.len
== 0) {
2387 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2390 /* check the transfer syntax */
2391 if ((hdr_ba
->transfer
.if_version
!= transfer
->if_version
) ||
2392 (memcmp(&hdr_ba
->transfer
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
2393 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2397 if (hdr_ba
->res
.num_results
!= 0x1 || hdr_ba
->res
.result
!= 0) {
2398 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2399 hdr_ba
->res
.num_results
, hdr_ba
->res
.reason
));
2402 DEBUG(5,("check_bind_response: accepted!\n"));
2406 /*******************************************************************
2407 Creates a DCE/RPC bind authentication response.
2408 This is the packet that is sent back to the server once we
2409 have received a BIND-ACK, to finish the third leg of
2410 the authentication handshake.
2411 ********************************************************************/
2413 static NTSTATUS
create_rpc_bind_auth3(struct rpc_pipe_client
*cli
,
2415 enum pipe_auth_type auth_type
,
2416 enum pipe_auth_level auth_level
,
2417 DATA_BLOB
*pauth_blob
,
2418 prs_struct
*rpc_out
)
2421 RPC_HDR_AUTH hdr_auth
;
2424 /* Create the request RPC_HDR */
2425 init_rpc_hdr(&hdr
, RPC_AUTH3
, RPC_FLG_FIRST
|RPC_FLG_LAST
, rpc_call_id
,
2426 RPC_HEADER_LEN
+ 4 /* pad */ + RPC_HDR_AUTH_LEN
+ pauth_blob
->length
,
2427 pauth_blob
->length
);
2430 if(!smb_io_rpc_hdr("hdr", &hdr
, rpc_out
, 0)) {
2431 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2432 return NT_STATUS_NO_MEMORY
;
2436 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2437 about padding - shouldn't this pad to length 8 ? JRA.
2440 /* 4 bytes padding. */
2441 if (!prs_uint32("pad", rpc_out
, 0, &pad
)) {
2442 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2443 return NT_STATUS_NO_MEMORY
;
2446 /* Create the request RPC_HDR_AUTHA */
2447 init_rpc_hdr_auth(&hdr_auth
,
2448 map_pipe_auth_type_to_rpc_auth_type(auth_type
),
2451 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rpc_out
, 0)) {
2452 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2453 return NT_STATUS_NO_MEMORY
;
2457 * Append the auth data to the outgoing buffer.
2460 if(!prs_copy_data_in(rpc_out
, (char *)pauth_blob
->data
, pauth_blob
->length
)) {
2461 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2462 return NT_STATUS_NO_MEMORY
;
2465 return NT_STATUS_OK
;
2468 /*******************************************************************
2469 Creates a DCE/RPC bind alter context authentication request which
2470 may contain a spnego auth blobl
2471 ********************************************************************/
2473 static NTSTATUS
create_rpc_alter_context(uint32 rpc_call_id
,
2474 const RPC_IFACE
*abstract
,
2475 const RPC_IFACE
*transfer
,
2476 enum pipe_auth_level auth_level
,
2477 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
2478 prs_struct
*rpc_out
)
2480 RPC_HDR_AUTH hdr_auth
;
2481 prs_struct auth_info
;
2482 NTSTATUS ret
= NT_STATUS_OK
;
2484 ZERO_STRUCT(hdr_auth
);
2485 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
2486 return NT_STATUS_NO_MEMORY
;
2488 /* We may change the pad length before marshalling. */
2489 init_rpc_hdr_auth(&hdr_auth
, RPC_SPNEGO_AUTH_TYPE
, (int)auth_level
, 0, 1);
2491 if (pauth_blob
->length
) {
2492 if (!prs_copy_data_in(&auth_info
, (const char *)pauth_blob
->data
, pauth_blob
->length
)) {
2493 prs_mem_free(&auth_info
);
2494 return NT_STATUS_NO_MEMORY
;
2498 ret
= create_bind_or_alt_ctx_internal(RPC_ALTCONT
,
2505 prs_mem_free(&auth_info
);
2509 /****************************************************************************
2511 ****************************************************************************/
2513 struct rpc_pipe_bind_state
{
2514 struct event_context
*ev
;
2515 struct rpc_pipe_client
*cli
;
2517 uint32_t rpc_call_id
;
2520 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state
*state
)
2522 prs_mem_free(&state
->rpc_out
);
2526 static void rpc_pipe_bind_step_one_done(struct async_req
*subreq
);
2527 static NTSTATUS
rpc_finish_auth3_bind_send(struct async_req
*req
,
2528 struct rpc_pipe_bind_state
*state
,
2529 struct rpc_hdr_info
*phdr
,
2530 prs_struct
*reply_pdu
);
2531 static void rpc_bind_auth3_write_done(struct async_req
*subreq
);
2532 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct async_req
*req
,
2533 struct rpc_pipe_bind_state
*state
,
2534 struct rpc_hdr_info
*phdr
,
2535 prs_struct
*reply_pdu
);
2536 static void rpc_bind_ntlmssp_api_done(struct async_req
*subreq
);
2538 struct async_req
*rpc_pipe_bind_send(TALLOC_CTX
*mem_ctx
,
2539 struct event_context
*ev
,
2540 struct rpc_pipe_client
*cli
,
2541 struct cli_pipe_auth_data
*auth
)
2543 struct async_req
*result
, *subreq
;
2544 struct rpc_pipe_bind_state
*state
;
2547 if (!async_req_setup(mem_ctx
, &result
, &state
,
2548 struct rpc_pipe_bind_state
)) {
2552 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2553 rpccli_pipe_txt(debug_ctx(), cli
),
2554 (unsigned int)auth
->auth_type
,
2555 (unsigned int)auth
->auth_level
));
2559 state
->rpc_call_id
= get_rpc_call_id();
2561 prs_init_empty(&state
->rpc_out
, state
, MARSHALL
);
2562 talloc_set_destructor(state
, rpc_pipe_bind_state_destructor
);
2564 cli
->auth
= talloc_move(cli
, &auth
);
2566 /* Marshall the outgoing data. */
2567 status
= create_rpc_bind_req(cli
, &state
->rpc_out
,
2569 &cli
->abstract_syntax
,
2570 &cli
->transfer_syntax
,
2571 cli
->auth
->auth_type
,
2572 cli
->auth
->auth_level
);
2574 if (!NT_STATUS_IS_OK(status
)) {
2578 subreq
= rpc_api_pipe_send(state
, ev
, cli
, &state
->rpc_out
,
2580 if (subreq
== NULL
) {
2581 status
= NT_STATUS_NO_MEMORY
;
2584 subreq
->async
.fn
= rpc_pipe_bind_step_one_done
;
2585 subreq
->async
.priv
= result
;
2589 if (async_post_ntstatus(result
, ev
, status
)) {
2592 TALLOC_FREE(result
);
2596 static void rpc_pipe_bind_step_one_done(struct async_req
*subreq
)
2598 struct async_req
*req
= talloc_get_type_abort(
2599 subreq
->async
.priv
, struct async_req
);
2600 struct rpc_pipe_bind_state
*state
= talloc_get_type_abort(
2601 req
->private_data
, struct rpc_pipe_bind_state
);
2602 prs_struct reply_pdu
;
2603 struct rpc_hdr_info hdr
;
2604 struct rpc_hdr_ba_info hdr_ba
;
2607 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &reply_pdu
);
2608 TALLOC_FREE(subreq
);
2609 if (!NT_STATUS_IS_OK(status
)) {
2610 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2611 rpccli_pipe_txt(debug_ctx(), state
->cli
),
2612 nt_errstr(status
)));
2613 async_req_nterror(req
, status
);
2617 /* Unmarshall the RPC header */
2618 if (!smb_io_rpc_hdr("hdr", &hdr
, &reply_pdu
, 0)) {
2619 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2620 prs_mem_free(&reply_pdu
);
2621 async_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2625 if (!smb_io_rpc_hdr_ba("", &hdr_ba
, &reply_pdu
, 0)) {
2626 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2628 prs_mem_free(&reply_pdu
);
2629 async_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2633 if (!check_bind_response(&hdr_ba
, &state
->cli
->transfer_syntax
)) {
2634 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2635 prs_mem_free(&reply_pdu
);
2636 async_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2640 state
->cli
->max_xmit_frag
= hdr_ba
.bba
.max_tsize
;
2641 state
->cli
->max_recv_frag
= hdr_ba
.bba
.max_rsize
;
2644 * For authenticated binds we may need to do 3 or 4 leg binds.
2647 switch(state
->cli
->auth
->auth_type
) {
2649 case PIPE_AUTH_TYPE_NONE
:
2650 case PIPE_AUTH_TYPE_SCHANNEL
:
2651 /* Bind complete. */
2652 prs_mem_free(&reply_pdu
);
2653 async_req_done(req
);
2656 case PIPE_AUTH_TYPE_NTLMSSP
:
2657 /* Need to send AUTH3 packet - no reply. */
2658 status
= rpc_finish_auth3_bind_send(req
, state
, &hdr
,
2660 prs_mem_free(&reply_pdu
);
2661 if (!NT_STATUS_IS_OK(status
)) {
2662 async_req_nterror(req
, status
);
2666 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2667 /* Need to send alter context request and reply. */
2668 status
= rpc_finish_spnego_ntlmssp_bind_send(req
, state
, &hdr
,
2670 prs_mem_free(&reply_pdu
);
2671 if (!NT_STATUS_IS_OK(status
)) {
2672 async_req_nterror(req
, status
);
2676 case PIPE_AUTH_TYPE_KRB5
:
2680 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2681 (unsigned int)state
->cli
->auth
->auth_type
));
2682 prs_mem_free(&reply_pdu
);
2683 async_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2687 static NTSTATUS
rpc_finish_auth3_bind_send(struct async_req
*req
,
2688 struct rpc_pipe_bind_state
*state
,
2689 struct rpc_hdr_info
*phdr
,
2690 prs_struct
*reply_pdu
)
2692 DATA_BLOB server_response
= data_blob_null
;
2693 DATA_BLOB client_reply
= data_blob_null
;
2694 struct rpc_hdr_auth_info hdr_auth
;
2695 struct async_req
*subreq
;
2698 if ((phdr
->auth_len
== 0)
2699 || (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
2700 return NT_STATUS_INVALID_PARAMETER
;
2703 if (!prs_set_offset(
2705 phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
2706 return NT_STATUS_INVALID_PARAMETER
;
2709 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, reply_pdu
, 0)) {
2710 return NT_STATUS_INVALID_PARAMETER
;
2713 /* TODO - check auth_type/auth_level match. */
2715 server_response
= data_blob_talloc(talloc_tos(), NULL
, phdr
->auth_len
);
2716 prs_copy_data_out((char *)server_response
.data
, reply_pdu
,
2719 status
= ntlmssp_update(state
->cli
->auth
->a_u
.ntlmssp_state
,
2720 server_response
, &client_reply
);
2722 if (!NT_STATUS_IS_OK(status
)) {
2723 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2724 "blob failed: %s.\n", nt_errstr(status
)));
2728 prs_init_empty(&state
->rpc_out
, talloc_tos(), MARSHALL
);
2730 status
= create_rpc_bind_auth3(state
->cli
, state
->rpc_call_id
,
2731 state
->cli
->auth
->auth_type
,
2732 state
->cli
->auth
->auth_level
,
2733 &client_reply
, &state
->rpc_out
);
2734 data_blob_free(&client_reply
);
2736 if (!NT_STATUS_IS_OK(status
)) {
2740 subreq
= rpc_write_send(state
, state
->ev
, state
->cli
->transport
,
2741 (uint8_t *)prs_data_p(&state
->rpc_out
),
2742 prs_offset(&state
->rpc_out
));
2743 if (subreq
== NULL
) {
2744 return NT_STATUS_NO_MEMORY
;
2746 subreq
->async
.fn
= rpc_bind_auth3_write_done
;
2747 subreq
->async
.priv
= req
;
2748 return NT_STATUS_OK
;
2751 static void rpc_bind_auth3_write_done(struct async_req
*subreq
)
2753 struct async_req
*req
= talloc_get_type_abort(
2754 subreq
->async
.priv
, struct async_req
);
2757 status
= rpc_write_recv(subreq
);
2758 TALLOC_FREE(subreq
);
2759 if (!NT_STATUS_IS_OK(status
)) {
2760 async_req_nterror(req
, status
);
2763 async_req_done(req
);
2766 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind_send(struct async_req
*req
,
2767 struct rpc_pipe_bind_state
*state
,
2768 struct rpc_hdr_info
*phdr
,
2769 prs_struct
*reply_pdu
)
2771 DATA_BLOB server_spnego_response
= data_blob_null
;
2772 DATA_BLOB server_ntlm_response
= data_blob_null
;
2773 DATA_BLOB client_reply
= data_blob_null
;
2774 DATA_BLOB tmp_blob
= data_blob_null
;
2775 RPC_HDR_AUTH hdr_auth
;
2776 struct async_req
*subreq
;
2779 if ((phdr
->auth_len
== 0)
2780 || (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
2781 return NT_STATUS_INVALID_PARAMETER
;
2784 /* Process the returned NTLMSSP blob first. */
2785 if (!prs_set_offset(
2787 phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
2788 return NT_STATUS_INVALID_PARAMETER
;
2791 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, reply_pdu
, 0)) {
2792 return NT_STATUS_INVALID_PARAMETER
;
2795 server_spnego_response
= data_blob(NULL
, phdr
->auth_len
);
2796 prs_copy_data_out((char *)server_spnego_response
.data
,
2797 reply_pdu
, phdr
->auth_len
);
2800 * The server might give us back two challenges - tmp_blob is for the
2803 if (!spnego_parse_challenge(server_spnego_response
,
2804 &server_ntlm_response
, &tmp_blob
)) {
2805 data_blob_free(&server_spnego_response
);
2806 data_blob_free(&server_ntlm_response
);
2807 data_blob_free(&tmp_blob
);
2808 return NT_STATUS_INVALID_PARAMETER
;
2811 /* We're finished with the server spnego response and the tmp_blob. */
2812 data_blob_free(&server_spnego_response
);
2813 data_blob_free(&tmp_blob
);
2815 status
= ntlmssp_update(state
->cli
->auth
->a_u
.ntlmssp_state
,
2816 server_ntlm_response
, &client_reply
);
2818 /* Finished with the server_ntlm response */
2819 data_blob_free(&server_ntlm_response
);
2821 if (!NT_STATUS_IS_OK(status
)) {
2822 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2823 "using server blob failed.\n"));
2824 data_blob_free(&client_reply
);
2828 /* SPNEGO wrap the client reply. */
2829 tmp_blob
= spnego_gen_auth(client_reply
);
2830 data_blob_free(&client_reply
);
2831 client_reply
= tmp_blob
;
2832 tmp_blob
= data_blob_null
;
2834 /* Now prepare the alter context pdu. */
2835 prs_init_empty(&state
->rpc_out
, state
, MARSHALL
);
2837 status
= create_rpc_alter_context(state
->rpc_call_id
,
2838 &state
->cli
->abstract_syntax
,
2839 &state
->cli
->transfer_syntax
,
2840 state
->cli
->auth
->auth_level
,
2843 data_blob_free(&client_reply
);
2845 if (!NT_STATUS_IS_OK(status
)) {
2849 subreq
= rpc_api_pipe_send(state
, state
->ev
, state
->cli
,
2850 &state
->rpc_out
, RPC_ALTCONTRESP
);
2851 if (subreq
== NULL
) {
2852 return NT_STATUS_NO_MEMORY
;
2854 subreq
->async
.fn
= rpc_bind_ntlmssp_api_done
;
2855 subreq
->async
.priv
= req
;
2856 return NT_STATUS_OK
;
2859 static void rpc_bind_ntlmssp_api_done(struct async_req
*subreq
)
2861 struct async_req
*req
= talloc_get_type_abort(
2862 subreq
->async
.priv
, struct async_req
);
2863 struct rpc_pipe_bind_state
*state
= talloc_get_type_abort(
2864 req
->private_data
, struct rpc_pipe_bind_state
);
2865 DATA_BLOB server_spnego_response
= data_blob_null
;
2866 DATA_BLOB tmp_blob
= data_blob_null
;
2867 prs_struct reply_pdu
;
2868 struct rpc_hdr_info hdr
;
2869 struct rpc_hdr_auth_info hdr_auth
;
2872 status
= rpc_api_pipe_recv(subreq
, talloc_tos(), &reply_pdu
);
2873 TALLOC_FREE(subreq
);
2874 if (!NT_STATUS_IS_OK(status
)) {
2875 async_req_nterror(req
, status
);
2879 /* Get the auth blob from the reply. */
2880 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr
, &reply_pdu
, 0)) {
2881 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2882 "unmarshall RPC_HDR.\n"));
2883 async_req_nterror(req
, NT_STATUS_BUFFER_TOO_SMALL
);
2887 if (!prs_set_offset(
2889 hdr
.frag_len
- hdr
.auth_len
- RPC_HDR_AUTH_LEN
)) {
2890 async_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2894 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, &reply_pdu
, 0)) {
2895 async_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2899 server_spnego_response
= data_blob(NULL
, hdr
.auth_len
);
2900 prs_copy_data_out((char *)server_spnego_response
.data
, &reply_pdu
,
2903 /* Check we got a valid auth response. */
2904 if (!spnego_parse_auth_response(server_spnego_response
, NT_STATUS_OK
,
2905 OID_NTLMSSP
, &tmp_blob
)) {
2906 data_blob_free(&server_spnego_response
);
2907 data_blob_free(&tmp_blob
);
2908 async_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2912 data_blob_free(&server_spnego_response
);
2913 data_blob_free(&tmp_blob
);
2915 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2916 "%s.\n", rpccli_pipe_txt(debug_ctx(), state
->cli
)));
2917 async_req_done(req
);
2920 NTSTATUS
rpc_pipe_bind_recv(struct async_req
*req
)
2922 return async_req_simple_recv_ntstatus(req
);
2925 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2926 struct cli_pipe_auth_data
*auth
)
2928 TALLOC_CTX
*frame
= talloc_stackframe();
2929 struct event_context
*ev
;
2930 struct async_req
*req
;
2931 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2933 ev
= event_context_init(frame
);
2938 req
= rpc_pipe_bind_send(frame
, ev
, cli
, auth
);
2943 while (req
->state
< ASYNC_REQ_DONE
) {
2944 event_loop_once(ev
);
2947 status
= rpc_pipe_bind_recv(req
);
2953 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2955 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*rpc_cli
,
2956 unsigned int timeout
)
2960 if (rpc_cli
->transport
== NULL
) {
2961 return RPCCLI_DEFAULT_TIMEOUT
;
2964 if (rpc_cli
->transport
->set_timeout
== NULL
) {
2965 return RPCCLI_DEFAULT_TIMEOUT
;
2968 old
= rpc_cli
->transport
->set_timeout(rpc_cli
->transport
->priv
, timeout
);
2970 return RPCCLI_DEFAULT_TIMEOUT
;
2976 bool rpccli_is_connected(struct rpc_pipe_client
*rpc_cli
)
2978 if (rpc_cli
== NULL
) {
2982 if (rpc_cli
->transport
== NULL
) {
2986 return rpc_cli
->transport
->is_connected(rpc_cli
->transport
->priv
);
2989 bool rpccli_get_pwd_hash(struct rpc_pipe_client
*rpc_cli
, uint8_t nt_hash
[16])
2991 struct cli_state
*cli
;
2993 if ((rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_NTLMSSP
)
2994 || (rpc_cli
->auth
->auth_type
== PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
)) {
2995 memcpy(nt_hash
, rpc_cli
->auth
->a_u
.ntlmssp_state
->nt_hash
, 16);
2999 cli
= rpc_pipe_np_smb_conn(rpc_cli
);
3003 E_md4hash(cli
->password
? cli
->password
: "", nt_hash
);
3007 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
3008 struct cli_pipe_auth_data
**presult
)
3010 struct cli_pipe_auth_data
*result
;
3012 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3013 if (result
== NULL
) {
3014 return NT_STATUS_NO_MEMORY
;
3017 result
->auth_type
= PIPE_AUTH_TYPE_NONE
;
3018 result
->auth_level
= PIPE_AUTH_LEVEL_NONE
;
3020 result
->user_name
= talloc_strdup(result
, "");
3021 result
->domain
= talloc_strdup(result
, "");
3022 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3023 TALLOC_FREE(result
);
3024 return NT_STATUS_NO_MEMORY
;
3028 return NT_STATUS_OK
;
3031 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data
*auth
)
3033 ntlmssp_end(&auth
->a_u
.ntlmssp_state
);
3037 NTSTATUS
rpccli_ntlmssp_bind_data(TALLOC_CTX
*mem_ctx
,
3038 enum pipe_auth_type auth_type
,
3039 enum pipe_auth_level auth_level
,
3041 const char *username
,
3042 const char *password
,
3043 struct cli_pipe_auth_data
**presult
)
3045 struct cli_pipe_auth_data
*result
;
3048 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3049 if (result
== NULL
) {
3050 return NT_STATUS_NO_MEMORY
;
3053 result
->auth_type
= auth_type
;
3054 result
->auth_level
= auth_level
;
3056 result
->user_name
= talloc_strdup(result
, username
);
3057 result
->domain
= talloc_strdup(result
, domain
);
3058 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3059 status
= NT_STATUS_NO_MEMORY
;
3063 status
= ntlmssp_client_start(&result
->a_u
.ntlmssp_state
);
3064 if (!NT_STATUS_IS_OK(status
)) {
3068 talloc_set_destructor(result
, cli_auth_ntlmssp_data_destructor
);
3070 status
= ntlmssp_set_username(result
->a_u
.ntlmssp_state
, username
);
3071 if (!NT_STATUS_IS_OK(status
)) {
3075 status
= ntlmssp_set_domain(result
->a_u
.ntlmssp_state
, domain
);
3076 if (!NT_STATUS_IS_OK(status
)) {
3080 status
= ntlmssp_set_password(result
->a_u
.ntlmssp_state
, password
);
3081 if (!NT_STATUS_IS_OK(status
)) {
3086 * Turn off sign+seal to allow selected auth level to turn it back on.
3088 result
->a_u
.ntlmssp_state
->neg_flags
&=
3089 ~(NTLMSSP_NEGOTIATE_SIGN
| NTLMSSP_NEGOTIATE_SEAL
);
3091 if (auth_level
== PIPE_AUTH_LEVEL_INTEGRITY
) {
3092 result
->a_u
.ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
3093 } else if (auth_level
== PIPE_AUTH_LEVEL_PRIVACY
) {
3094 result
->a_u
.ntlmssp_state
->neg_flags
3095 |= NTLMSSP_NEGOTIATE_SEAL
| NTLMSSP_NEGOTIATE_SIGN
;
3099 return NT_STATUS_OK
;
3102 TALLOC_FREE(result
);
3106 NTSTATUS
rpccli_schannel_bind_data(TALLOC_CTX
*mem_ctx
, const char *domain
,
3107 enum pipe_auth_level auth_level
,
3108 const uint8_t sess_key
[16],
3109 struct cli_pipe_auth_data
**presult
)
3111 struct cli_pipe_auth_data
*result
;
3113 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3114 if (result
== NULL
) {
3115 return NT_STATUS_NO_MEMORY
;
3118 result
->auth_type
= PIPE_AUTH_TYPE_SCHANNEL
;
3119 result
->auth_level
= auth_level
;
3121 result
->user_name
= talloc_strdup(result
, "");
3122 result
->domain
= talloc_strdup(result
, domain
);
3123 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3127 result
->a_u
.schannel_auth
= talloc(result
,
3128 struct schannel_auth_struct
);
3129 if (result
->a_u
.schannel_auth
== NULL
) {
3133 memcpy(result
->a_u
.schannel_auth
->sess_key
, sess_key
,
3134 sizeof(result
->a_u
.schannel_auth
->sess_key
));
3135 result
->a_u
.schannel_auth
->seq_num
= 0;
3138 return NT_STATUS_OK
;
3141 TALLOC_FREE(result
);
3142 return NT_STATUS_NO_MEMORY
;
3146 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct
*auth
)
3148 data_blob_free(&auth
->session_key
);
3153 NTSTATUS
rpccli_kerberos_bind_data(TALLOC_CTX
*mem_ctx
,
3154 enum pipe_auth_level auth_level
,
3155 const char *service_princ
,
3156 const char *username
,
3157 const char *password
,
3158 struct cli_pipe_auth_data
**presult
)
3161 struct cli_pipe_auth_data
*result
;
3163 if ((username
!= NULL
) && (password
!= NULL
)) {
3164 int ret
= kerberos_kinit_password(username
, password
, 0, NULL
);
3166 return NT_STATUS_ACCESS_DENIED
;
3170 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
3171 if (result
== NULL
) {
3172 return NT_STATUS_NO_MEMORY
;
3175 result
->auth_type
= PIPE_AUTH_TYPE_KRB5
;
3176 result
->auth_level
= auth_level
;
3179 * Username / domain need fixing!
3181 result
->user_name
= talloc_strdup(result
, "");
3182 result
->domain
= talloc_strdup(result
, "");
3183 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
3187 result
->a_u
.kerberos_auth
= TALLOC_ZERO_P(
3188 result
, struct kerberos_auth_struct
);
3189 if (result
->a_u
.kerberos_auth
== NULL
) {
3192 talloc_set_destructor(result
->a_u
.kerberos_auth
,
3193 cli_auth_kerberos_data_destructor
);
3195 result
->a_u
.kerberos_auth
->service_principal
= talloc_strdup(
3196 result
, service_princ
);
3197 if (result
->a_u
.kerberos_auth
->service_principal
== NULL
) {
3202 return NT_STATUS_OK
;
3205 TALLOC_FREE(result
);
3206 return NT_STATUS_NO_MEMORY
;
3208 return NT_STATUS_NOT_SUPPORTED
;
3213 * Create an rpc pipe client struct, connecting to a tcp port.
3215 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
3217 const struct ndr_syntax_id
*abstract_syntax
,
3218 struct rpc_pipe_client
**presult
)
3220 struct rpc_pipe_client
*result
;
3221 struct sockaddr_storage addr
;
3225 result
= TALLOC_ZERO_P(mem_ctx
, struct rpc_pipe_client
);
3226 if (result
== NULL
) {
3227 return NT_STATUS_NO_MEMORY
;
3230 result
->abstract_syntax
= *abstract_syntax
;
3231 result
->transfer_syntax
= ndr_transfer_syntax
;
3232 result
->dispatch
= cli_do_rpc_ndr
;
3234 result
->desthost
= talloc_strdup(result
, host
);
3235 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3236 result
, "\\\\%s", result
->desthost
);
3237 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3238 status
= NT_STATUS_NO_MEMORY
;
3242 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3243 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3245 if (!resolve_name(host
, &addr
, 0)) {
3246 status
= NT_STATUS_NOT_FOUND
;
3250 status
= open_socket_out(&addr
, port
, 60, &fd
);
3251 if (!NT_STATUS_IS_OK(status
)) {
3254 set_socket_options(fd
, lp_socket_options());
3256 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
3257 if (!NT_STATUS_IS_OK(status
)) {
3262 result
->transport
->transport
= NCACN_IP_TCP
;
3265 return NT_STATUS_OK
;
3268 TALLOC_FREE(result
);
3273 * Determine the tcp port on which a dcerpc interface is listening
3274 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3277 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
3278 const struct ndr_syntax_id
*abstract_syntax
,
3282 struct rpc_pipe_client
*epm_pipe
= NULL
;
3283 struct cli_pipe_auth_data
*auth
= NULL
;
3284 struct dcerpc_binding
*map_binding
= NULL
;
3285 struct dcerpc_binding
*res_binding
= NULL
;
3286 struct epm_twr_t
*map_tower
= NULL
;
3287 struct epm_twr_t
*res_towers
= NULL
;
3288 struct policy_handle
*entry_handle
= NULL
;
3289 uint32_t num_towers
= 0;
3290 uint32_t max_towers
= 1;
3291 struct epm_twr_p_t towers
;
3292 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
3294 if (pport
== NULL
) {
3295 status
= NT_STATUS_INVALID_PARAMETER
;
3299 /* open the connection to the endpoint mapper */
3300 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, 135,
3301 &ndr_table_epmapper
.syntax_id
,
3304 if (!NT_STATUS_IS_OK(status
)) {
3308 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
3309 if (!NT_STATUS_IS_OK(status
)) {
3313 status
= rpc_pipe_bind(epm_pipe
, auth
);
3314 if (!NT_STATUS_IS_OK(status
)) {
3318 /* create tower for asking the epmapper */
3320 map_binding
= TALLOC_ZERO_P(tmp_ctx
, struct dcerpc_binding
);
3321 if (map_binding
== NULL
) {
3322 status
= NT_STATUS_NO_MEMORY
;
3326 map_binding
->transport
= NCACN_IP_TCP
;
3327 map_binding
->object
= *abstract_syntax
;
3328 map_binding
->host
= host
; /* needed? */
3329 map_binding
->endpoint
= "0"; /* correct? needed? */
3331 map_tower
= TALLOC_ZERO_P(tmp_ctx
, struct epm_twr_t
);
3332 if (map_tower
== NULL
) {
3333 status
= NT_STATUS_NO_MEMORY
;
3337 status
= dcerpc_binding_build_tower(tmp_ctx
, map_binding
,
3338 &(map_tower
->tower
));
3339 if (!NT_STATUS_IS_OK(status
)) {
3343 /* allocate further parameters for the epm_Map call */
3345 res_towers
= TALLOC_ARRAY(tmp_ctx
, struct epm_twr_t
, max_towers
);
3346 if (res_towers
== NULL
) {
3347 status
= NT_STATUS_NO_MEMORY
;
3350 towers
.twr
= res_towers
;
3352 entry_handle
= TALLOC_ZERO_P(tmp_ctx
, struct policy_handle
);
3353 if (entry_handle
== NULL
) {
3354 status
= NT_STATUS_NO_MEMORY
;
3358 /* ask the endpoint mapper for the port */
3360 status
= rpccli_epm_Map(epm_pipe
,
3362 CONST_DISCARD(struct GUID
*,
3363 &(abstract_syntax
->uuid
)),
3370 if (!NT_STATUS_IS_OK(status
)) {
3374 if (num_towers
!= 1) {
3375 status
= NT_STATUS_UNSUCCESSFUL
;
3379 /* extract the port from the answer */
3381 status
= dcerpc_binding_from_tower(tmp_ctx
,
3382 &(towers
.twr
->tower
),
3384 if (!NT_STATUS_IS_OK(status
)) {
3388 /* are further checks here necessary? */
3389 if (res_binding
->transport
!= NCACN_IP_TCP
) {
3390 status
= NT_STATUS_UNSUCCESSFUL
;
3394 *pport
= (uint16_t)atoi(res_binding
->endpoint
);
3397 TALLOC_FREE(tmp_ctx
);
3402 * Create a rpc pipe client struct, connecting to a host via tcp.
3403 * The port is determined by asking the endpoint mapper on the given
3406 NTSTATUS
rpc_pipe_open_tcp(TALLOC_CTX
*mem_ctx
, const char *host
,
3407 const struct ndr_syntax_id
*abstract_syntax
,
3408 struct rpc_pipe_client
**presult
)
3415 status
= rpc_pipe_get_tcp_port(host
, abstract_syntax
, &port
);
3416 if (!NT_STATUS_IS_OK(status
)) {
3420 status
= rpc_pipe_open_tcp_port(mem_ctx
, host
, port
,
3421 abstract_syntax
, presult
);
3427 /********************************************************************
3428 Create a rpc pipe client struct, connecting to a unix domain socket
3429 ********************************************************************/
3430 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
, const char *socket_path
,
3431 const struct ndr_syntax_id
*abstract_syntax
,
3432 struct rpc_pipe_client
**presult
)
3434 struct rpc_pipe_client
*result
;
3435 struct sockaddr_un addr
;
3439 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
3440 if (result
== NULL
) {
3441 return NT_STATUS_NO_MEMORY
;
3444 result
->abstract_syntax
= *abstract_syntax
;
3445 result
->transfer_syntax
= ndr_transfer_syntax
;
3446 result
->dispatch
= cli_do_rpc_ndr
;
3448 result
->desthost
= get_myname(result
);
3449 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3450 result
, "\\\\%s", result
->desthost
);
3451 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3452 status
= NT_STATUS_NO_MEMORY
;
3456 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3457 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3459 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3461 status
= map_nt_error_from_unix(errno
);
3466 addr
.sun_family
= AF_UNIX
;
3467 strncpy(addr
.sun_path
, socket_path
, sizeof(addr
.sun_path
));
3469 if (sys_connect(fd
, (struct sockaddr
*)&addr
) == -1) {
3470 DEBUG(0, ("connect(%s) failed: %s\n", socket_path
,
3473 return map_nt_error_from_unix(errno
);
3476 status
= rpc_transport_sock_init(result
, fd
, &result
->transport
);
3477 if (!NT_STATUS_IS_OK(status
)) {
3482 result
->transport
->transport
= NCALRPC
;
3485 return NT_STATUS_OK
;
3488 TALLOC_FREE(result
);
3492 struct rpc_pipe_client_np_ref
{
3493 struct cli_state
*cli
;
3494 struct rpc_pipe_client
*pipe
;
3497 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref
*np_ref
)
3499 DLIST_REMOVE(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3503 /****************************************************************************
3504 Open a named pipe over SMB to a remote server.
3506 * CAVEAT CALLER OF THIS FUNCTION:
3507 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3508 * so be sure that this function is called AFTER any structure (vs pointer)
3509 * assignment of the cli. In particular, libsmbclient does structure
3510 * assignments of cli, which invalidates the data in the returned
3511 * rpc_pipe_client if this function is called before the structure assignment
3514 ****************************************************************************/
3516 static NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
3517 const struct ndr_syntax_id
*abstract_syntax
,
3518 struct rpc_pipe_client
**presult
)
3520 struct rpc_pipe_client
*result
;
3522 struct rpc_pipe_client_np_ref
*np_ref
;
3524 /* sanity check to protect against crashes */
3527 return NT_STATUS_INVALID_HANDLE
;
3530 result
= TALLOC_ZERO_P(NULL
, struct rpc_pipe_client
);
3531 if (result
== NULL
) {
3532 return NT_STATUS_NO_MEMORY
;
3535 result
->abstract_syntax
= *abstract_syntax
;
3536 result
->transfer_syntax
= ndr_transfer_syntax
;
3537 result
->dispatch
= cli_do_rpc_ndr
;
3538 result
->desthost
= talloc_strdup(result
, cli
->desthost
);
3539 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3540 result
, "\\\\%s", result
->desthost
);
3542 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3543 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3545 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3546 TALLOC_FREE(result
);
3547 return NT_STATUS_NO_MEMORY
;
3550 status
= rpc_transport_np_init(result
, cli
, abstract_syntax
,
3551 &result
->transport
);
3552 if (!NT_STATUS_IS_OK(status
)) {
3553 TALLOC_FREE(result
);
3557 result
->transport
->transport
= NCACN_NP
;
3559 np_ref
= talloc(result
->transport
, struct rpc_pipe_client_np_ref
);
3560 if (np_ref
== NULL
) {
3561 TALLOC_FREE(result
);
3562 return NT_STATUS_NO_MEMORY
;
3565 np_ref
->pipe
= result
;
3567 DLIST_ADD(np_ref
->cli
->pipe_list
, np_ref
->pipe
);
3568 talloc_set_destructor(np_ref
, rpc_pipe_client_np_ref_destructor
);
3571 return NT_STATUS_OK
;
3574 NTSTATUS
rpc_pipe_open_local(TALLOC_CTX
*mem_ctx
,
3575 struct rpc_cli_smbd_conn
*conn
,
3576 const struct ndr_syntax_id
*syntax
,
3577 struct rpc_pipe_client
**presult
)
3579 struct rpc_pipe_client
*result
;
3580 struct cli_pipe_auth_data
*auth
;
3583 result
= talloc(mem_ctx
, struct rpc_pipe_client
);
3584 if (result
== NULL
) {
3585 return NT_STATUS_NO_MEMORY
;
3587 result
->abstract_syntax
= *syntax
;
3588 result
->transfer_syntax
= ndr_transfer_syntax
;
3589 result
->dispatch
= cli_do_rpc_ndr
;
3590 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3591 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3593 result
->desthost
= talloc_strdup(result
, global_myname());
3594 result
->srv_name_slash
= talloc_asprintf_strupper_m(
3595 result
, "\\\\%s", global_myname());
3596 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3597 TALLOC_FREE(result
);
3598 return NT_STATUS_NO_MEMORY
;
3601 status
= rpc_transport_smbd_init(result
, conn
, syntax
,
3602 &result
->transport
);
3603 if (!NT_STATUS_IS_OK(status
)) {
3604 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3605 nt_errstr(status
)));
3606 TALLOC_FREE(result
);
3610 status
= rpccli_anon_bind_data(result
, &auth
);
3611 if (!NT_STATUS_IS_OK(status
)) {
3612 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3613 nt_errstr(status
)));
3614 TALLOC_FREE(result
);
3618 status
= rpc_pipe_bind(result
, auth
);
3619 if (!NT_STATUS_IS_OK(status
)) {
3620 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status
)));
3621 TALLOC_FREE(result
);
3625 result
->transport
->transport
= NCACN_INTERNAL
;
3628 return NT_STATUS_OK
;
3631 /****************************************************************************
3632 Open a pipe to a remote server.
3633 ****************************************************************************/
3635 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3636 enum dcerpc_transport_t transport
,
3637 const struct ndr_syntax_id
*interface
,
3638 struct rpc_pipe_client
**presult
)
3640 switch (transport
) {
3642 return rpc_pipe_open_tcp(NULL
, cli
->desthost
, interface
,
3645 return rpc_pipe_open_np(cli
, interface
, presult
);
3647 return NT_STATUS_NOT_IMPLEMENTED
;
3651 /****************************************************************************
3652 Open a named pipe to an SMB server and bind anonymously.
3653 ****************************************************************************/
3655 NTSTATUS
cli_rpc_pipe_open_noauth_transport(struct cli_state
*cli
,
3656 enum dcerpc_transport_t transport
,
3657 const struct ndr_syntax_id
*interface
,
3658 struct rpc_pipe_client
**presult
)
3660 struct rpc_pipe_client
*result
;
3661 struct cli_pipe_auth_data
*auth
;
3664 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3665 if (!NT_STATUS_IS_OK(status
)) {
3669 status
= rpccli_anon_bind_data(result
, &auth
);
3670 if (!NT_STATUS_IS_OK(status
)) {
3671 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3672 nt_errstr(status
)));
3673 TALLOC_FREE(result
);
3678 * This is a bit of an abstraction violation due to the fact that an
3679 * anonymous bind on an authenticated SMB inherits the user/domain
3680 * from the enclosing SMB creds
3683 TALLOC_FREE(auth
->user_name
);
3684 TALLOC_FREE(auth
->domain
);
3686 auth
->user_name
= talloc_strdup(auth
, cli
->user_name
);
3687 auth
->domain
= talloc_strdup(auth
, cli
->domain
);
3688 auth
->user_session_key
= data_blob_talloc(auth
,
3689 cli
->user_session_key
.data
,
3690 cli
->user_session_key
.length
);
3692 if ((auth
->user_name
== NULL
) || (auth
->domain
== NULL
)) {
3693 TALLOC_FREE(result
);
3694 return NT_STATUS_NO_MEMORY
;
3697 status
= rpc_pipe_bind(result
, auth
);
3698 if (!NT_STATUS_IS_OK(status
)) {
3700 if (ndr_syntax_id_equal(interface
,
3701 &ndr_table_dssetup
.syntax_id
)) {
3702 /* non AD domains just don't have this pipe, avoid
3703 * level 0 statement in that case - gd */
3706 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3707 "%s failed with error %s\n",
3708 get_pipe_name_from_iface(interface
),
3709 nt_errstr(status
) ));
3710 TALLOC_FREE(result
);
3714 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3715 "%s and bound anonymously.\n",
3716 get_pipe_name_from_iface(interface
), cli
->desthost
));
3719 return NT_STATUS_OK
;
3722 /****************************************************************************
3723 ****************************************************************************/
3725 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
3726 const struct ndr_syntax_id
*interface
,
3727 struct rpc_pipe_client
**presult
)
3729 return cli_rpc_pipe_open_noauth_transport(cli
, NCACN_NP
,
3730 interface
, presult
);
3733 /****************************************************************************
3734 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3735 ****************************************************************************/
3737 static NTSTATUS
cli_rpc_pipe_open_ntlmssp_internal(struct cli_state
*cli
,
3738 const struct ndr_syntax_id
*interface
,
3739 enum dcerpc_transport_t transport
,
3740 enum pipe_auth_type auth_type
,
3741 enum pipe_auth_level auth_level
,
3743 const char *username
,
3744 const char *password
,
3745 struct rpc_pipe_client
**presult
)
3747 struct rpc_pipe_client
*result
;
3748 struct cli_pipe_auth_data
*auth
;
3751 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3752 if (!NT_STATUS_IS_OK(status
)) {
3756 status
= rpccli_ntlmssp_bind_data(
3757 result
, auth_type
, auth_level
, domain
, username
,
3759 if (!NT_STATUS_IS_OK(status
)) {
3760 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3761 nt_errstr(status
)));
3765 status
= rpc_pipe_bind(result
, auth
);
3766 if (!NT_STATUS_IS_OK(status
)) {
3767 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3768 nt_errstr(status
) ));
3772 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3773 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3774 get_pipe_name_from_iface(interface
), cli
->desthost
, domain
,
3778 return NT_STATUS_OK
;
3782 TALLOC_FREE(result
);
3786 /****************************************************************************
3788 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3789 ****************************************************************************/
3791 NTSTATUS
cli_rpc_pipe_open_ntlmssp(struct cli_state
*cli
,
3792 const struct ndr_syntax_id
*interface
,
3793 enum dcerpc_transport_t transport
,
3794 enum pipe_auth_level auth_level
,
3796 const char *username
,
3797 const char *password
,
3798 struct rpc_pipe_client
**presult
)
3800 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3803 PIPE_AUTH_TYPE_NTLMSSP
,
3811 /****************************************************************************
3813 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3814 ****************************************************************************/
3816 NTSTATUS
cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state
*cli
,
3817 const struct ndr_syntax_id
*interface
,
3818 enum dcerpc_transport_t transport
,
3819 enum pipe_auth_level auth_level
,
3821 const char *username
,
3822 const char *password
,
3823 struct rpc_pipe_client
**presult
)
3825 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3828 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
,
3836 /****************************************************************************
3837 Get a the schannel session key out of an already opened netlogon pipe.
3838 ****************************************************************************/
3839 static NTSTATUS
get_schannel_session_key_common(struct rpc_pipe_client
*netlogon_pipe
,
3840 struct cli_state
*cli
,
3844 uint32 sec_chan_type
= 0;
3845 unsigned char machine_pwd
[16];
3846 const char *machine_account
;
3849 /* Get the machine account credentials from secrets.tdb. */
3850 if (!get_trust_pw_hash(domain
, machine_pwd
, &machine_account
,
3853 DEBUG(0, ("get_schannel_session_key: could not fetch "
3854 "trust account password for domain '%s'\n",
3856 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3859 status
= rpccli_netlogon_setup_creds(netlogon_pipe
,
3860 cli
->desthost
, /* server name */
3861 domain
, /* domain */
3862 global_myname(), /* client name */
3863 machine_account
, /* machine account name */
3868 if (!NT_STATUS_IS_OK(status
)) {
3869 DEBUG(3, ("get_schannel_session_key_common: "
3870 "rpccli_netlogon_setup_creds failed with result %s "
3871 "to server %s, domain %s, machine account %s.\n",
3872 nt_errstr(status
), cli
->desthost
, domain
,
3877 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
3878 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3880 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3883 return NT_STATUS_OK
;;
3886 /****************************************************************************
3887 Open a netlogon pipe and get the schannel session key.
3888 Now exposed to external callers.
3889 ****************************************************************************/
3892 NTSTATUS
get_schannel_session_key(struct cli_state
*cli
,
3895 struct rpc_pipe_client
**presult
)
3897 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3900 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
.syntax_id
,
3902 if (!NT_STATUS_IS_OK(status
)) {
3906 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
3908 if (!NT_STATUS_IS_OK(status
)) {
3909 TALLOC_FREE(netlogon_pipe
);
3913 *presult
= netlogon_pipe
;
3914 return NT_STATUS_OK
;
3917 /****************************************************************************
3919 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3920 using session_key. sign and seal.
3921 ****************************************************************************/
3923 NTSTATUS
cli_rpc_pipe_open_schannel_with_key(struct cli_state
*cli
,
3924 const struct ndr_syntax_id
*interface
,
3925 enum dcerpc_transport_t transport
,
3926 enum pipe_auth_level auth_level
,
3928 const struct dcinfo
*pdc
,
3929 struct rpc_pipe_client
**presult
)
3931 struct rpc_pipe_client
*result
;
3932 struct cli_pipe_auth_data
*auth
;
3935 status
= cli_rpc_pipe_open(cli
, transport
, interface
, &result
);
3936 if (!NT_STATUS_IS_OK(status
)) {
3940 status
= rpccli_schannel_bind_data(result
, domain
, auth_level
,
3941 pdc
->sess_key
, &auth
);
3942 if (!NT_STATUS_IS_OK(status
)) {
3943 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3944 nt_errstr(status
)));
3945 TALLOC_FREE(result
);
3949 status
= rpc_pipe_bind(result
, auth
);
3950 if (!NT_STATUS_IS_OK(status
)) {
3951 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3952 "cli_rpc_pipe_bind failed with error %s\n",
3953 nt_errstr(status
) ));
3954 TALLOC_FREE(result
);
3959 * The credentials on a new netlogon pipe are the ones we are passed
3960 * in - copy them over.
3962 result
->dc
= (struct dcinfo
*)talloc_memdup(result
, pdc
, sizeof(*pdc
));
3963 if (result
->dc
== NULL
) {
3964 DEBUG(0, ("talloc failed\n"));
3965 TALLOC_FREE(result
);
3966 return NT_STATUS_NO_MEMORY
;
3969 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3970 "for domain %s and bound using schannel.\n",
3971 get_pipe_name_from_iface(interface
),
3972 cli
->desthost
, domain
));
3975 return NT_STATUS_OK
;
3978 /****************************************************************************
3979 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3980 Fetch the session key ourselves using a temporary netlogon pipe. This
3981 version uses an ntlmssp auth bound netlogon pipe to get the key.
3982 ****************************************************************************/
3984 static NTSTATUS
get_schannel_session_key_auth_ntlmssp(struct cli_state
*cli
,
3986 const char *username
,
3987 const char *password
,
3989 struct rpc_pipe_client
**presult
)
3991 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3994 status
= cli_rpc_pipe_open_spnego_ntlmssp(
3995 cli
, &ndr_table_netlogon
.syntax_id
, NCACN_NP
,
3996 PIPE_AUTH_LEVEL_PRIVACY
,
3997 domain
, username
, password
, &netlogon_pipe
);
3998 if (!NT_STATUS_IS_OK(status
)) {
4002 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
4004 if (!NT_STATUS_IS_OK(status
)) {
4005 TALLOC_FREE(netlogon_pipe
);
4009 *presult
= netlogon_pipe
;
4010 return NT_STATUS_OK
;
4013 /****************************************************************************
4014 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4015 Fetch the session key ourselves using a temporary netlogon pipe. This version
4016 uses an ntlmssp bind to get the session key.
4017 ****************************************************************************/
4019 NTSTATUS
cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
*cli
,
4020 const struct ndr_syntax_id
*interface
,
4021 enum dcerpc_transport_t transport
,
4022 enum pipe_auth_level auth_level
,
4024 const char *username
,
4025 const char *password
,
4026 struct rpc_pipe_client
**presult
)
4028 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
4029 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
4030 struct rpc_pipe_client
*result
= NULL
;
4033 status
= get_schannel_session_key_auth_ntlmssp(
4034 cli
, domain
, username
, password
, &neg_flags
, &netlogon_pipe
);
4035 if (!NT_STATUS_IS_OK(status
)) {
4036 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4037 "key from server %s for domain %s.\n",
4038 cli
->desthost
, domain
));
4042 status
= cli_rpc_pipe_open_schannel_with_key(
4043 cli
, interface
, transport
, auth_level
, domain
, netlogon_pipe
->dc
,
4046 /* Now we've bound using the session key we can close the netlog pipe. */
4047 TALLOC_FREE(netlogon_pipe
);
4049 if (NT_STATUS_IS_OK(status
)) {
4055 /****************************************************************************
4056 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4057 Fetch the session key ourselves using a temporary netlogon pipe.
4058 ****************************************************************************/
4060 NTSTATUS
cli_rpc_pipe_open_schannel(struct cli_state
*cli
,
4061 const struct ndr_syntax_id
*interface
,
4062 enum dcerpc_transport_t transport
,
4063 enum pipe_auth_level auth_level
,
4065 struct rpc_pipe_client
**presult
)
4067 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
4068 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
4069 struct rpc_pipe_client
*result
= NULL
;
4074 status
= get_schannel_session_key(cli
, domain
, &neg_flags
,
4076 if (!NT_STATUS_IS_OK(status
)) {
4077 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4078 "key from server %s for domain %s.\n",
4079 cli
->desthost
, domain
));
4083 status
= cli_rpc_pipe_open_schannel_with_key(
4084 cli
, interface
, transport
, auth_level
, domain
, netlogon_pipe
->dc
,
4087 /* Now we've bound using the session key we can close the netlog pipe. */
4088 TALLOC_FREE(netlogon_pipe
);
4090 if (NT_STATUS_IS_OK(status
)) {
4097 /****************************************************************************
4098 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4099 The idea is this can be called with service_princ, username and password all
4100 NULL so long as the caller has a TGT.
4101 ****************************************************************************/
4103 NTSTATUS
cli_rpc_pipe_open_krb5(struct cli_state
*cli
,
4104 const struct ndr_syntax_id
*interface
,
4105 enum pipe_auth_level auth_level
,
4106 const char *service_princ
,
4107 const char *username
,
4108 const char *password
,
4109 struct rpc_pipe_client
**presult
)
4112 struct rpc_pipe_client
*result
;
4113 struct cli_pipe_auth_data
*auth
;
4116 status
= cli_rpc_pipe_open(cli
, NCACN_NP
, interface
, &result
);
4117 if (!NT_STATUS_IS_OK(status
)) {
4121 status
= rpccli_kerberos_bind_data(result
, auth_level
, service_princ
,
4122 username
, password
, &auth
);
4123 if (!NT_STATUS_IS_OK(status
)) {
4124 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4125 nt_errstr(status
)));
4126 TALLOC_FREE(result
);
4130 status
= rpc_pipe_bind(result
, auth
);
4131 if (!NT_STATUS_IS_OK(status
)) {
4132 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4133 "with error %s\n", nt_errstr(status
)));
4134 TALLOC_FREE(result
);
4139 return NT_STATUS_OK
;
4141 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4142 return NT_STATUS_NOT_IMPLEMENTED
;
4146 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
4147 struct rpc_pipe_client
*cli
,
4148 DATA_BLOB
*session_key
)
4150 if (!session_key
|| !cli
) {
4151 return NT_STATUS_INVALID_PARAMETER
;
4155 return NT_STATUS_INVALID_PARAMETER
;
4158 switch (cli
->auth
->auth_type
) {
4159 case PIPE_AUTH_TYPE_SCHANNEL
:
4160 *session_key
= data_blob_talloc(mem_ctx
,
4161 cli
->auth
->a_u
.schannel_auth
->sess_key
, 16);
4163 case PIPE_AUTH_TYPE_NTLMSSP
:
4164 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
4165 *session_key
= data_blob_talloc(mem_ctx
,
4166 cli
->auth
->a_u
.ntlmssp_state
->session_key
.data
,
4167 cli
->auth
->a_u
.ntlmssp_state
->session_key
.length
);
4169 case PIPE_AUTH_TYPE_KRB5
:
4170 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
4171 *session_key
= data_blob_talloc(mem_ctx
,
4172 cli
->auth
->a_u
.kerberos_auth
->session_key
.data
,
4173 cli
->auth
->a_u
.kerberos_auth
->session_key
.length
);
4175 case PIPE_AUTH_TYPE_NONE
:
4176 *session_key
= data_blob_talloc(mem_ctx
,
4177 cli
->auth
->user_session_key
.data
,
4178 cli
->auth
->user_session_key
.length
);
4181 return NT_STATUS_NO_USER_SESSION_KEY
;
4184 return NT_STATUS_OK
;