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"
24 #define DBGC_CLASS DBGC_RPC_CLI
26 /*******************************************************************
27 interface/version dce/rpc pipe identification
28 ********************************************************************/
30 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
31 #define PIPE_SAMR "\\PIPE\\samr"
32 #define PIPE_WINREG "\\PIPE\\winreg"
33 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
34 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
35 #define PIPE_NTLSA "\\PIPE\\ntlsa"
36 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
37 #define PIPE_LSASS "\\PIPE\\lsass"
38 #define PIPE_LSARPC "\\PIPE\\lsarpc"
39 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
40 #define PIPE_NETDFS "\\PIPE\\netdfs"
41 #define PIPE_ECHO "\\PIPE\\rpcecho"
42 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
43 #define PIPE_EPM "\\PIPE\\epmapper"
44 #define PIPE_SVCCTL "\\PIPE\\svcctl"
45 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
46 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
47 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
50 * IMPORTANT!! If you update this structure, make sure to
51 * update the index #defines in smb.h.
54 static const struct pipe_id_info
{
55 /* the names appear not to matter: the syntaxes _do_ matter */
57 const char *client_pipe
;
58 const RPC_IFACE
*abstr_syntax
; /* this one is the abstract syntax id */
61 { PIPE_LSARPC
, &ndr_table_lsarpc
.syntax_id
},
62 { PIPE_LSARPC
, &ndr_table_dssetup
.syntax_id
},
63 { PIPE_SAMR
, &ndr_table_samr
.syntax_id
},
64 { PIPE_NETLOGON
, &ndr_table_netlogon
.syntax_id
},
65 { PIPE_SRVSVC
, &ndr_table_srvsvc
.syntax_id
},
66 { PIPE_WKSSVC
, &ndr_table_wkssvc
.syntax_id
},
67 { PIPE_WINREG
, &ndr_table_winreg
.syntax_id
},
68 { PIPE_SPOOLSS
, &syntax_spoolss
},
69 { PIPE_NETDFS
, &ndr_table_netdfs
.syntax_id
},
70 { PIPE_ECHO
, &ndr_table_rpcecho
.syntax_id
},
71 { PIPE_SHUTDOWN
, &ndr_table_initshutdown
.syntax_id
},
72 { PIPE_SVCCTL
, &ndr_table_svcctl
.syntax_id
},
73 { PIPE_EVENTLOG
, &ndr_table_eventlog
.syntax_id
},
74 { PIPE_NTSVCS
, &ndr_table_ntsvcs
.syntax_id
},
75 { PIPE_EPMAPPER
, &ndr_table_epmapper
.syntax_id
},
76 { PIPE_DRSUAPI
, &ndr_table_drsuapi
.syntax_id
},
80 /****************************************************************************
81 Return the pipe name from the interface.
82 ****************************************************************************/
84 const char *cli_get_pipe_name_from_iface(TALLOC_CTX
*mem_ctx
,
85 struct cli_state
*cli
,
86 const struct ndr_syntax_id
*interface
)
89 for (i
= 0; pipe_names
[i
].client_pipe
; i
++) {
90 if (ndr_syntax_id_equal(pipe_names
[i
].abstr_syntax
,
92 return &pipe_names
[i
].client_pipe
[5];
97 * Here we should ask \\epmapper, but for now our code is only
98 * interested in the known pipes mentioned in pipe_names[]
104 /********************************************************************
105 Map internal value to wire value.
106 ********************************************************************/
108 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type
)
112 case PIPE_AUTH_TYPE_NONE
:
113 return RPC_ANONYMOUS_AUTH_TYPE
;
115 case PIPE_AUTH_TYPE_NTLMSSP
:
116 return RPC_NTLMSSP_AUTH_TYPE
;
118 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
119 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
120 return RPC_SPNEGO_AUTH_TYPE
;
122 case PIPE_AUTH_TYPE_SCHANNEL
:
123 return RPC_SCHANNEL_AUTH_TYPE
;
125 case PIPE_AUTH_TYPE_KRB5
:
126 return RPC_KRB5_AUTH_TYPE
;
129 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
131 (unsigned int)auth_type
));
137 /********************************************************************
138 Pipe description for a DEBUG
139 ********************************************************************/
140 static char *rpccli_pipe_txt(TALLOC_CTX
*mem_ctx
, struct rpc_pipe_client
*cli
)
144 switch (cli
->transport_type
) {
146 result
= talloc_asprintf(mem_ctx
, "host %s, pipe %s, "
149 cli
->trans
.np
.pipe_name
,
150 (unsigned int)(cli
->trans
.np
.fnum
));
153 case NCACN_UNIX_STREAM
:
154 result
= talloc_asprintf(mem_ctx
, "host %s, fd %d",
155 cli
->desthost
, cli
->trans
.sock
.fd
);
158 result
= talloc_asprintf(mem_ctx
, "host %s", cli
->desthost
);
161 SMB_ASSERT(result
!= NULL
);
165 /********************************************************************
167 ********************************************************************/
169 static uint32
get_rpc_call_id(void)
171 static uint32 call_id
= 0;
176 * Realloc pdu to have a least "size" bytes
179 static bool rpc_grow_buffer(prs_struct
*pdu
, size_t size
)
183 if (prs_data_size(pdu
) >= size
) {
187 extra_size
= size
- prs_data_size(pdu
);
189 if (!prs_force_grow(pdu
, extra_size
)) {
190 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
191 "%d bytes.\n", (int)extra_size
));
195 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
196 (int)extra_size
, prs_data_size(pdu
)));
201 /*******************************************************************
202 Use SMBreadX to get rest of one fragment's worth of rpc data.
203 Reads the whole size or give an error message
204 ********************************************************************/
206 struct rpc_read_state
{
207 struct event_context
*ev
;
208 struct rpc_pipe_client
*cli
;
214 static void rpc_read_np_done(struct async_req
*subreq
);
215 static void rpc_read_sock_done(struct async_req
*subreq
);
217 static struct async_req
*rpc_read_send(TALLOC_CTX
*mem_ctx
,
218 struct event_context
*ev
,
219 struct rpc_pipe_client
*cli
,
220 char *data
, size_t size
)
222 struct async_req
*result
, *subreq
;
223 struct rpc_read_state
*state
;
225 result
= async_req_new(mem_ctx
);
226 if (result
== NULL
) {
229 state
= talloc(result
, struct rpc_read_state
);
233 result
->private_data
= state
;
241 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size
));
243 if (cli
->transport_type
== NCACN_NP
) {
244 subreq
= cli_read_andx_send(
245 state
, ev
, cli
->trans
.np
.cli
,
246 cli
->trans
.np
.fnum
, 0, size
);
247 if (subreq
== NULL
) {
248 DEBUG(10, ("cli_read_andx_send failed\n"));
251 subreq
->async
.fn
= rpc_read_np_done
;
252 subreq
->async
.priv
= result
;
256 if ((cli
->transport_type
== NCACN_IP_TCP
)
257 || (cli
->transport_type
== NCACN_UNIX_STREAM
)) {
258 subreq
= recvall_send(state
, ev
, cli
->trans
.sock
.fd
,
260 if (subreq
== NULL
) {
261 DEBUG(10, ("recvall_send failed\n"));
264 subreq
->async
.fn
= rpc_read_sock_done
;
265 subreq
->async
.priv
= result
;
269 if (async_post_status(result
, ev
, NT_STATUS_INVALID_PARAMETER
)) {
277 static void rpc_read_np_done(struct async_req
*subreq
)
279 struct async_req
*req
= talloc_get_type_abort(
280 subreq
->async
.priv
, struct async_req
);
281 struct rpc_read_state
*state
= talloc_get_type_abort(
282 req
->private_data
, struct rpc_read_state
);
287 status
= cli_read_andx_recv(subreq
, &received
, &rcvbuf
);
289 * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a
292 if (NT_STATUS_EQUAL(status
, NT_STATUS_BUFFER_TOO_SMALL
)) {
293 status
= NT_STATUS_OK
;
295 if (!NT_STATUS_IS_OK(status
)) {
297 async_req_error(req
, status
);
301 memcpy(state
->data
+ state
->num_read
, rcvbuf
, received
);
304 state
->num_read
+= received
;
306 if (state
->num_read
== state
->size
) {
311 subreq
= cli_read_andx_send(
312 state
, state
->ev
, state
->cli
->trans
.np
.cli
,
313 state
->cli
->trans
.np
.fnum
, 0,
314 state
->size
- state
->num_read
);
316 if (async_req_nomem(subreq
, req
)) {
320 subreq
->async
.fn
= rpc_read_np_done
;
321 subreq
->async
.priv
= req
;
324 static void rpc_read_sock_done(struct async_req
*subreq
)
326 struct async_req
*req
= talloc_get_type_abort(
327 subreq
->async
.priv
, struct async_req
);
330 status
= recvall_recv(subreq
);
332 if (!NT_STATUS_IS_OK(status
)) {
333 async_req_error(req
, status
);
340 static NTSTATUS
rpc_read_recv(struct async_req
*req
)
342 return async_req_simple_recv(req
);
345 static NTSTATUS
rpc_read(struct rpc_pipe_client
*cli
,
346 char *pdata
, size_t size
)
348 TALLOC_CTX
*frame
= talloc_stackframe();
349 struct event_context
*ev
;
350 struct async_req
*req
;
351 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
353 ev
= event_context_init(frame
);
358 req
= rpc_read_send(frame
, ev
, cli
, pdata
, size
);
363 while (req
->state
< ASYNC_REQ_DONE
) {
367 status
= rpc_read_recv(req
);
373 /****************************************************************************
374 Try and get a PDU's worth of data from current_pdu. If not, then read more
376 ****************************************************************************/
378 static NTSTATUS
cli_pipe_get_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
, prs_struct
*current_pdu
)
380 NTSTATUS ret
= NT_STATUS_OK
;
381 uint32 current_pdu_len
= prs_data_size(current_pdu
);
383 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
384 if (current_pdu_len
< RPC_HEADER_LEN
) {
385 if (!rpc_grow_buffer(current_pdu
, RPC_HEADER_LEN
)) {
386 return NT_STATUS_NO_MEMORY
;
389 prs_data_p(current_pdu
) + current_pdu_len
,
390 RPC_HEADER_LEN
- current_pdu_len
);
391 if (!NT_STATUS_IS_OK(ret
)) {
394 current_pdu_len
= RPC_HEADER_LEN
;
397 /* This next call sets the endian bit correctly in current_pdu. */
398 /* We will propagate this to rbuf later. */
399 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr
, current_pdu
, 0)) {
400 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
401 return NT_STATUS_BUFFER_TOO_SMALL
;
404 if (prhdr
->frag_len
> cli
->max_recv_frag
) {
405 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
406 " we only allow %d\n", (int)prhdr
->frag_len
,
407 (int)cli
->max_recv_frag
));
408 return NT_STATUS_BUFFER_TOO_SMALL
;
411 /* Ensure we have frag_len bytes of data. */
412 if (current_pdu_len
< prhdr
->frag_len
) {
413 if (!rpc_grow_buffer(current_pdu
, prhdr
->frag_len
)) {
414 return NT_STATUS_NO_MEMORY
;
417 prs_data_p(current_pdu
) + current_pdu_len
,
418 prhdr
->frag_len
- current_pdu_len
);
419 if (!NT_STATUS_IS_OK(ret
)) {
427 /****************************************************************************
428 NTLMSSP specific sign/seal.
429 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
430 In fact I should probably abstract these into identical pieces of code... JRA.
431 ****************************************************************************/
433 static NTSTATUS
cli_pipe_verify_ntlmssp(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
434 prs_struct
*current_pdu
,
435 uint8
*p_ss_padding_len
)
437 RPC_HDR_AUTH auth_info
;
438 uint32 save_offset
= prs_offset(current_pdu
);
439 uint32 auth_len
= prhdr
->auth_len
;
440 NTLMSSP_STATE
*ntlmssp_state
= cli
->auth
->a_u
.ntlmssp_state
;
441 unsigned char *data
= NULL
;
443 unsigned char *full_packet_data
= NULL
;
444 size_t full_packet_data_len
;
448 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_NONE
449 || cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_CONNECT
) {
453 if (!ntlmssp_state
) {
454 return NT_STATUS_INVALID_PARAMETER
;
457 /* Ensure there's enough data for an authenticated response. */
458 if ((auth_len
> RPC_MAX_SIGN_SIZE
) ||
459 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
460 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
461 (unsigned int)auth_len
));
462 return NT_STATUS_BUFFER_TOO_SMALL
;
466 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
467 * after the RPC header.
468 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
469 * functions as NTLMv2 checks the rpc headers also.
472 data
= (unsigned char *)(prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
);
473 data_len
= (size_t)(prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
);
475 full_packet_data
= (unsigned char *)prs_data_p(current_pdu
);
476 full_packet_data_len
= prhdr
->frag_len
- auth_len
;
478 /* Pull the auth header and the following data into a blob. */
479 if(!prs_set_offset(current_pdu
, RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
)) {
480 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
481 (unsigned int)RPC_HEADER_LEN
+ (unsigned int)RPC_HDR_RESP_LEN
+ (unsigned int)data_len
));
482 return NT_STATUS_BUFFER_TOO_SMALL
;
485 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
486 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
487 return NT_STATUS_BUFFER_TOO_SMALL
;
490 auth_blob
.data
= (unsigned char *)prs_data_p(current_pdu
) + prs_offset(current_pdu
);
491 auth_blob
.length
= auth_len
;
493 switch (cli
->auth
->auth_level
) {
494 case PIPE_AUTH_LEVEL_PRIVACY
:
495 /* Data is encrypted. */
496 status
= ntlmssp_unseal_packet(ntlmssp_state
,
499 full_packet_data_len
,
501 if (!NT_STATUS_IS_OK(status
)) {
502 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
503 "packet from %s. Error was %s.\n",
504 rpccli_pipe_txt(debug_ctx(), cli
),
505 nt_errstr(status
) ));
509 case PIPE_AUTH_LEVEL_INTEGRITY
:
510 /* Data is signed. */
511 status
= ntlmssp_check_packet(ntlmssp_state
,
514 full_packet_data_len
,
516 if (!NT_STATUS_IS_OK(status
)) {
517 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
518 "packet from %s. Error was %s.\n",
519 rpccli_pipe_txt(debug_ctx(), cli
),
520 nt_errstr(status
) ));
525 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
526 "auth level %d\n", cli
->auth
->auth_level
));
527 return NT_STATUS_INVALID_INFO_CLASS
;
531 * Return the current pointer to the data offset.
534 if(!prs_set_offset(current_pdu
, save_offset
)) {
535 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
536 (unsigned int)save_offset
));
537 return NT_STATUS_BUFFER_TOO_SMALL
;
541 * Remember the padding length. We must remove it from the real data
542 * stream once the sign/seal is done.
545 *p_ss_padding_len
= auth_info
.auth_pad_len
;
550 /****************************************************************************
551 schannel specific sign/seal.
552 ****************************************************************************/
554 static NTSTATUS
cli_pipe_verify_schannel(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
555 prs_struct
*current_pdu
,
556 uint8
*p_ss_padding_len
)
558 RPC_HDR_AUTH auth_info
;
559 RPC_AUTH_SCHANNEL_CHK schannel_chk
;
560 uint32 auth_len
= prhdr
->auth_len
;
561 uint32 save_offset
= prs_offset(current_pdu
);
562 struct schannel_auth_struct
*schannel_auth
=
563 cli
->auth
->a_u
.schannel_auth
;
566 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_NONE
567 || cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_CONNECT
) {
571 if (auth_len
!= RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
) {
572 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len
));
573 return NT_STATUS_INVALID_PARAMETER
;
576 if (!schannel_auth
) {
577 return NT_STATUS_INVALID_PARAMETER
;
580 /* Ensure there's enough data for an authenticated response. */
581 if ((auth_len
> RPC_MAX_SIGN_SIZE
) ||
582 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
583 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
584 (unsigned int)auth_len
));
585 return NT_STATUS_INVALID_PARAMETER
;
588 data_len
= prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
;
590 if(!prs_set_offset(current_pdu
, RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
)) {
591 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
592 (unsigned int)RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
));
593 return NT_STATUS_BUFFER_TOO_SMALL
;
596 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
597 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
598 return NT_STATUS_BUFFER_TOO_SMALL
;
601 if (auth_info
.auth_type
!= RPC_SCHANNEL_AUTH_TYPE
) {
602 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
603 auth_info
.auth_type
));
604 return NT_STATUS_BUFFER_TOO_SMALL
;
607 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
,
608 &schannel_chk
, current_pdu
, 0)) {
609 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
610 return NT_STATUS_BUFFER_TOO_SMALL
;
613 if (!schannel_decode(schannel_auth
,
614 cli
->auth
->auth_level
,
617 prs_data_p(current_pdu
)+RPC_HEADER_LEN
+RPC_HDR_RESP_LEN
,
619 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
620 "Connection to %s.\n",
621 rpccli_pipe_txt(debug_ctx(), cli
)));
622 return NT_STATUS_INVALID_PARAMETER
;
625 /* The sequence number gets incremented on both send and receive. */
626 schannel_auth
->seq_num
++;
629 * Return the current pointer to the data offset.
632 if(!prs_set_offset(current_pdu
, save_offset
)) {
633 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
634 (unsigned int)save_offset
));
635 return NT_STATUS_BUFFER_TOO_SMALL
;
639 * Remember the padding length. We must remove it from the real data
640 * stream once the sign/seal is done.
643 *p_ss_padding_len
= auth_info
.auth_pad_len
;
648 /****************************************************************************
649 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
650 ****************************************************************************/
652 static NTSTATUS
cli_pipe_validate_rpc_response(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
653 prs_struct
*current_pdu
,
654 uint8
*p_ss_padding_len
)
656 NTSTATUS ret
= NT_STATUS_OK
;
658 /* Paranioa checks for auth_len. */
659 if (prhdr
->auth_len
) {
660 if (prhdr
->auth_len
> prhdr
->frag_len
) {
661 return NT_STATUS_INVALID_PARAMETER
;
664 if (prhdr
->auth_len
+ (unsigned int)RPC_HDR_AUTH_LEN
< prhdr
->auth_len
||
665 prhdr
->auth_len
+ (unsigned int)RPC_HDR_AUTH_LEN
< (unsigned int)RPC_HDR_AUTH_LEN
) {
666 /* Integer wrap attempt. */
667 return NT_STATUS_INVALID_PARAMETER
;
672 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
675 switch(cli
->auth
->auth_type
) {
676 case PIPE_AUTH_TYPE_NONE
:
677 if (prhdr
->auth_len
) {
678 DEBUG(3, ("cli_pipe_validate_rpc_response: "
679 "Connection to %s - got non-zero "
681 rpccli_pipe_txt(debug_ctx(), cli
),
682 (unsigned int)prhdr
->auth_len
));
683 return NT_STATUS_INVALID_PARAMETER
;
687 case PIPE_AUTH_TYPE_NTLMSSP
:
688 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
689 ret
= cli_pipe_verify_ntlmssp(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
690 if (!NT_STATUS_IS_OK(ret
)) {
695 case PIPE_AUTH_TYPE_SCHANNEL
:
696 ret
= cli_pipe_verify_schannel(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
697 if (!NT_STATUS_IS_OK(ret
)) {
702 case PIPE_AUTH_TYPE_KRB5
:
703 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
705 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
706 "to %s - unknown internal auth type %u.\n",
707 rpccli_pipe_txt(debug_ctx(), cli
),
708 cli
->auth
->auth_type
));
709 return NT_STATUS_INVALID_INFO_CLASS
;
715 /****************************************************************************
716 Do basic authentication checks on an incoming pdu.
717 ****************************************************************************/
719 static NTSTATUS
cli_pipe_validate_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
720 prs_struct
*current_pdu
,
721 uint8 expected_pkt_type
,
724 prs_struct
*return_data
)
727 NTSTATUS ret
= NT_STATUS_OK
;
728 uint32 current_pdu_len
= prs_data_size(current_pdu
);
730 if (current_pdu_len
!= prhdr
->frag_len
) {
731 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
732 (unsigned int)current_pdu_len
, (unsigned int)prhdr
->frag_len
));
733 return NT_STATUS_INVALID_PARAMETER
;
737 * Point the return values at the real data including the RPC
738 * header. Just in case the caller wants it.
740 *ppdata
= prs_data_p(current_pdu
);
741 *pdata_len
= current_pdu_len
;
743 /* Ensure we have the correct type. */
744 switch (prhdr
->pkt_type
) {
745 case RPC_ALTCONTRESP
:
748 /* Alter context and bind ack share the same packet definitions. */
754 RPC_HDR_RESP rhdr_resp
;
755 uint8 ss_padding_len
= 0;
757 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
758 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
759 return NT_STATUS_BUFFER_TOO_SMALL
;
762 /* Here's where we deal with incoming sign/seal. */
763 ret
= cli_pipe_validate_rpc_response(cli
, prhdr
,
764 current_pdu
, &ss_padding_len
);
765 if (!NT_STATUS_IS_OK(ret
)) {
769 /* Point the return values at the NDR data. Remember to remove any ss padding. */
770 *ppdata
= prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
772 if (current_pdu_len
< RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ ss_padding_len
) {
773 return NT_STATUS_BUFFER_TOO_SMALL
;
776 *pdata_len
= current_pdu_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- ss_padding_len
;
778 /* Remember to remove the auth footer. */
779 if (prhdr
->auth_len
) {
780 /* We've already done integer wrap tests on auth_len in
781 cli_pipe_validate_rpc_response(). */
782 if (*pdata_len
< RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
) {
783 return NT_STATUS_BUFFER_TOO_SMALL
;
785 *pdata_len
-= (RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
);
788 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
789 current_pdu_len
, *pdata_len
, ss_padding_len
));
792 * If this is the first reply, and the allocation hint is reasonably, try and
793 * set up the return_data parse_struct to the correct size.
796 if ((prs_data_size(return_data
) == 0) && rhdr_resp
.alloc_hint
&& (rhdr_resp
.alloc_hint
< 15*1024*1024)) {
797 if (!prs_set_buffer_size(return_data
, rhdr_resp
.alloc_hint
)) {
798 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
799 "too large to allocate\n",
800 (unsigned int)rhdr_resp
.alloc_hint
));
801 return NT_STATUS_NO_MEMORY
;
809 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
810 "received from %s!\n",
811 rpccli_pipe_txt(debug_ctx(), cli
)));
812 /* Use this for now... */
813 return NT_STATUS_NETWORK_ACCESS_DENIED
;
817 RPC_HDR_RESP rhdr_resp
;
818 RPC_HDR_FAULT fault_resp
;
820 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
821 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
822 return NT_STATUS_BUFFER_TOO_SMALL
;
825 if(!smb_io_rpc_hdr_fault("fault", &fault_resp
, current_pdu
, 0)) {
826 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
827 return NT_STATUS_BUFFER_TOO_SMALL
;
830 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
831 "code %s received from %s!\n",
832 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp
.status
)),
833 rpccli_pipe_txt(debug_ctx(), cli
)));
834 if (NT_STATUS_IS_OK(fault_resp
.status
)) {
835 return NT_STATUS_UNSUCCESSFUL
;
837 return fault_resp
.status
;
842 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
844 (unsigned int)prhdr
->pkt_type
,
845 rpccli_pipe_txt(debug_ctx(), cli
)));
846 return NT_STATUS_INVALID_INFO_CLASS
;
849 if (prhdr
->pkt_type
!= expected_pkt_type
) {
850 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
851 "got an unexpected RPC packet type - %u, not %u\n",
852 rpccli_pipe_txt(debug_ctx(), cli
),
855 return NT_STATUS_INVALID_INFO_CLASS
;
858 /* Do this just before return - we don't want to modify any rpc header
859 data before now as we may have needed to do cryptographic actions on
862 if ((prhdr
->pkt_type
== RPC_BINDACK
) && !(prhdr
->flags
& RPC_FLG_LAST
)) {
863 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
864 "setting fragment first/last ON.\n"));
865 prhdr
->flags
|= RPC_FLG_FIRST
|RPC_FLG_LAST
;
871 /****************************************************************************
872 Ensure we eat the just processed pdu from the current_pdu prs_struct.
873 Normally the frag_len and buffer size will match, but on the first trans
874 reply there is a theoretical chance that buffer size > frag_len, so we must
876 ****************************************************************************/
878 static NTSTATUS
cli_pipe_reset_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
, prs_struct
*current_pdu
)
880 uint32 current_pdu_len
= prs_data_size(current_pdu
);
882 if (current_pdu_len
< prhdr
->frag_len
) {
883 return NT_STATUS_BUFFER_TOO_SMALL
;
887 if (current_pdu_len
== (uint32
)prhdr
->frag_len
) {
888 prs_mem_free(current_pdu
);
889 prs_init_empty(current_pdu
, prs_get_mem_context(current_pdu
), UNMARSHALL
);
890 /* Make current_pdu dynamic with no memory. */
891 prs_give_memory(current_pdu
, 0, 0, True
);
896 * Oh no ! More data in buffer than we processed in current pdu.
897 * Cheat. Move the data down and shrink the buffer.
900 memcpy(prs_data_p(current_pdu
), prs_data_p(current_pdu
) + prhdr
->frag_len
,
901 current_pdu_len
- prhdr
->frag_len
);
903 /* Remember to set the read offset back to zero. */
904 prs_set_offset(current_pdu
, 0);
906 /* Shrink the buffer. */
907 if (!prs_set_buffer_size(current_pdu
, current_pdu_len
- prhdr
->frag_len
)) {
908 return NT_STATUS_BUFFER_TOO_SMALL
;
914 /****************************************************************************
915 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
916 ****************************************************************************/
918 static bool cli_api_pipe(struct cli_state
*cli
, const char *pipe_name
,
919 uint16
*setup
, uint32 setup_count
,
920 uint32 max_setup_count
,
921 char *params
, uint32 param_count
,
922 uint32 max_param_count
,
923 char *data
, uint32 data_count
,
924 uint32 max_data_count
,
925 char **rparam
, uint32
*rparam_count
,
926 char **rdata
, uint32
*rdata_count
)
928 cli_send_trans(cli
, SMBtrans
,
930 0,0, /* fid, flags */
931 setup
, setup_count
, max_setup_count
,
932 params
, param_count
, max_param_count
,
933 data
, data_count
, max_data_count
);
935 return (cli_receive_trans(cli
, SMBtrans
,
936 rparam
, (unsigned int *)rparam_count
,
937 rdata
, (unsigned int *)rdata_count
));
940 /****************************************************************************
941 Send data on an rpc pipe via trans. The prs_struct data must be the last
942 pdu fragment of an NDR data stream.
944 Receive response data from an rpc pipe, which may be large...
946 Read the first fragment: unfortunately have to use SMBtrans for the first
947 bit, then SMBreadX for subsequent bits.
949 If first fragment received also wasn't the last fragment, continue
950 getting fragments until we _do_ receive the last fragment.
952 Request/Response PDU's look like the following...
954 |<------------------PDU len----------------------------------------------->|
955 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
957 +------------+-----------------+-------------+---------------+-------------+
958 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
959 +------------+-----------------+-------------+---------------+-------------+
961 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
962 signing & sealing being negotiated.
964 ****************************************************************************/
966 static NTSTATUS
rpc_api_pipe(struct rpc_pipe_client
*cli
,
967 prs_struct
*data
, /* Outgoing pdu fragment, already formatted for send. */
968 prs_struct
*rbuf
, /* Incoming reply - return as an NDR stream. */
969 uint8 expected_pkt_type
)
971 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
973 uint32 rparam_len
= 0;
974 char *pdata
= prs_data_p(data
);
975 uint32 data_len
= prs_offset(data
);
977 uint32 rdata_len
= 0;
978 uint32 max_data
= cli
->max_xmit_frag
? cli
->max_xmit_frag
: RPC_MAX_PDU_FRAG_LEN
;
979 uint32 current_rbuf_offset
= 0;
980 prs_struct current_pdu
;
983 /* Ensure we're not sending too much. */
984 SMB_ASSERT(data_len
<= max_data
);
987 /* Set up the current pdu parse struct. */
988 prs_init_empty(¤t_pdu
, prs_get_mem_context(rbuf
), UNMARSHALL
);
990 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli
)));
992 switch (cli
->transport_type
) {
995 /* Create setup parameters - must be in native byte order. */
996 setup
[0] = TRANSACT_DCERPCCMD
;
997 setup
[1] = cli
->trans
.np
.fnum
; /* Pipe file handle. */
1000 * Send the last (or only) fragment of an RPC request. For
1001 * small amounts of data (about 1024 bytes or so) the RPC
1002 * request and response appears in a SMBtrans request and
1006 if (!cli_api_pipe(cli
->trans
.np
.cli
, "\\PIPE\\",
1007 setup
, 2, 0, /* Setup, length, max */
1008 NULL
, 0, 0, /* Params, length, max */
1009 pdata
, data_len
, max_data
, /* data, length,
1011 &rparam
, &rparam_len
, /* return params,
1013 &prdata
, &rdata_len
)) /* return data, len */
1015 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
1017 rpccli_pipe_txt(debug_ctx(), cli
),
1018 cli_errstr(cli
->trans
.np
.cli
)));
1019 ret
= cli_get_nt_error(cli
->trans
.np
.cli
);
1027 case NCACN_UNIX_STREAM
:
1029 ssize_t nwritten
, nread
;
1030 nwritten
= write_data(cli
->trans
.sock
.fd
, pdata
, data_len
);
1031 if (nwritten
== -1) {
1032 ret
= map_nt_error_from_unix(errno
);
1033 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
1038 prdata
= SMB_MALLOC_ARRAY(char, 1);
1039 if (prdata
== NULL
) {
1040 return NT_STATUS_NO_MEMORY
;
1042 nread
= sys_read(cli
->trans
.sock
.fd
, prdata
, 1);
1047 ret
= NT_STATUS_END_OF_FILE
;
1054 DEBUG(0, ("unknown transport type %d\n",
1055 cli
->transport_type
));
1056 return NT_STATUS_INTERNAL_ERROR
;
1059 /* Throw away returned params - we know we won't use them. */
1063 if (prdata
== NULL
) {
1064 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1065 rpccli_pipe_txt(debug_ctx(), cli
)));
1066 /* Yes - some calls can truely return no data... */
1067 prs_mem_free(¤t_pdu
);
1068 return NT_STATUS_OK
;
1072 * Give this memory as dynamic to the current pdu.
1075 prs_give_memory(¤t_pdu
, prdata
, rdata_len
, True
);
1077 /* Ensure we can mess with the return prs_struct. */
1078 SMB_ASSERT(UNMARSHALLING(rbuf
));
1079 SMB_ASSERT(prs_data_size(rbuf
) == 0);
1081 /* Make rbuf dynamic with no memory. */
1082 prs_give_memory(rbuf
, 0, 0, True
);
1086 char *ret_data
= NULL
;
1087 uint32 ret_data_len
= 0;
1089 /* Ensure we have enough data for a pdu. */
1090 ret
= cli_pipe_get_current_pdu(cli
, &rhdr
, ¤t_pdu
);
1091 if (!NT_STATUS_IS_OK(ret
)) {
1095 /* We pass in rbuf here so if the alloc hint is set correctly
1096 we can set the output size and avoid reallocs. */
1098 ret
= cli_pipe_validate_current_pdu(cli
, &rhdr
, ¤t_pdu
, expected_pkt_type
,
1099 &ret_data
, &ret_data_len
, rbuf
);
1101 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
1102 prs_data_size(¤t_pdu
), current_rbuf_offset
));
1104 if (!NT_STATUS_IS_OK(ret
)) {
1108 if ((rhdr
.flags
& RPC_FLG_FIRST
)) {
1109 if (rhdr
.pack_type
[0] == 0) {
1110 /* Set the data type correctly for big-endian data on the first packet. */
1111 DEBUG(10,("rpc_api_pipe: On %s "
1112 "PDU data format is big-endian.\n",
1113 rpccli_pipe_txt(debug_ctx(), cli
)));
1115 prs_set_endian_data(rbuf
, RPC_BIG_ENDIAN
);
1117 /* Check endianness on subsequent packets. */
1118 if (current_pdu
.bigendian_data
!= rbuf
->bigendian_data
) {
1119 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1120 rbuf
->bigendian_data
? "big" : "little",
1121 current_pdu
.bigendian_data
? "big" : "little" ));
1122 ret
= NT_STATUS_INVALID_PARAMETER
;
1128 /* Now copy the data portion out of the pdu into rbuf. */
1129 if (!prs_force_grow(rbuf
, ret_data_len
)) {
1130 ret
= NT_STATUS_NO_MEMORY
;
1133 memcpy(prs_data_p(rbuf
)+current_rbuf_offset
, ret_data
, (size_t)ret_data_len
);
1134 current_rbuf_offset
+= ret_data_len
;
1136 /* See if we've finished with all the data in current_pdu yet ? */
1137 ret
= cli_pipe_reset_current_pdu(cli
, &rhdr
, ¤t_pdu
);
1138 if (!NT_STATUS_IS_OK(ret
)) {
1142 if (rhdr
.flags
& RPC_FLG_LAST
) {
1143 break; /* We're done. */
1147 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1148 rpccli_pipe_txt(debug_ctx(), cli
),
1149 (unsigned int)prs_data_size(rbuf
) ));
1151 prs_mem_free(¤t_pdu
);
1152 return NT_STATUS_OK
;
1156 prs_mem_free(¤t_pdu
);
1161 /*******************************************************************
1162 Creates krb5 auth bind.
1163 ********************************************************************/
1165 static NTSTATUS
create_krb5_auth_bind_req( struct rpc_pipe_client
*cli
,
1166 enum pipe_auth_level auth_level
,
1167 RPC_HDR_AUTH
*pauth_out
,
1168 prs_struct
*auth_data
)
1172 struct kerberos_auth_struct
*a
= cli
->auth
->a_u
.kerberos_auth
;
1173 DATA_BLOB tkt
= data_blob_null
;
1174 DATA_BLOB tkt_wrapped
= data_blob_null
;
1176 /* We may change the pad length before marshalling. */
1177 init_rpc_hdr_auth(pauth_out
, RPC_KRB5_AUTH_TYPE
, (int)auth_level
, 0, 1);
1179 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1180 a
->service_principal
));
1182 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1184 ret
= cli_krb5_get_ticket(a
->service_principal
, 0, &tkt
,
1185 &a
->session_key
, (uint32
)AP_OPTS_MUTUAL_REQUIRED
, NULL
, NULL
);
1188 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1190 a
->service_principal
,
1191 error_message(ret
) ));
1193 data_blob_free(&tkt
);
1194 prs_mem_free(auth_data
);
1195 return NT_STATUS_INVALID_PARAMETER
;
1198 /* wrap that up in a nice GSS-API wrapping */
1199 tkt_wrapped
= spnego_gen_krb5_wrap(tkt
, TOK_ID_KRB_AP_REQ
);
1201 data_blob_free(&tkt
);
1203 /* Auth len in the rpc header doesn't include auth_header. */
1204 if (!prs_copy_data_in(auth_data
, (char *)tkt_wrapped
.data
, tkt_wrapped
.length
)) {
1205 data_blob_free(&tkt_wrapped
);
1206 prs_mem_free(auth_data
);
1207 return NT_STATUS_NO_MEMORY
;
1210 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1211 dump_data(5, tkt_wrapped
.data
, tkt_wrapped
.length
);
1213 data_blob_free(&tkt_wrapped
);
1214 return NT_STATUS_OK
;
1216 return NT_STATUS_INVALID_PARAMETER
;
1220 /*******************************************************************
1221 Creates SPNEGO NTLMSSP auth bind.
1222 ********************************************************************/
1224 static NTSTATUS
create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1225 enum pipe_auth_level auth_level
,
1226 RPC_HDR_AUTH
*pauth_out
,
1227 prs_struct
*auth_data
)
1230 DATA_BLOB null_blob
= data_blob_null
;
1231 DATA_BLOB request
= data_blob_null
;
1232 DATA_BLOB spnego_msg
= data_blob_null
;
1234 /* We may change the pad length before marshalling. */
1235 init_rpc_hdr_auth(pauth_out
, RPC_SPNEGO_AUTH_TYPE
, (int)auth_level
, 0, 1);
1237 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1238 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1242 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1243 data_blob_free(&request
);
1244 prs_mem_free(auth_data
);
1248 /* Wrap this in SPNEGO. */
1249 spnego_msg
= gen_negTokenInit(OID_NTLMSSP
, request
);
1251 data_blob_free(&request
);
1253 /* Auth len in the rpc header doesn't include auth_header. */
1254 if (!prs_copy_data_in(auth_data
, (char *)spnego_msg
.data
, spnego_msg
.length
)) {
1255 data_blob_free(&spnego_msg
);
1256 prs_mem_free(auth_data
);
1257 return NT_STATUS_NO_MEMORY
;
1260 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1261 dump_data(5, spnego_msg
.data
, spnego_msg
.length
);
1263 data_blob_free(&spnego_msg
);
1264 return NT_STATUS_OK
;
1267 /*******************************************************************
1268 Creates NTLMSSP auth bind.
1269 ********************************************************************/
1271 static NTSTATUS
create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1272 enum pipe_auth_level auth_level
,
1273 RPC_HDR_AUTH
*pauth_out
,
1274 prs_struct
*auth_data
)
1277 DATA_BLOB null_blob
= data_blob_null
;
1278 DATA_BLOB request
= data_blob_null
;
1280 /* We may change the pad length before marshalling. */
1281 init_rpc_hdr_auth(pauth_out
, RPC_NTLMSSP_AUTH_TYPE
, (int)auth_level
, 0, 1);
1283 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1284 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1288 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1289 data_blob_free(&request
);
1290 prs_mem_free(auth_data
);
1294 /* Auth len in the rpc header doesn't include auth_header. */
1295 if (!prs_copy_data_in(auth_data
, (char *)request
.data
, request
.length
)) {
1296 data_blob_free(&request
);
1297 prs_mem_free(auth_data
);
1298 return NT_STATUS_NO_MEMORY
;
1301 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1302 dump_data(5, request
.data
, request
.length
);
1304 data_blob_free(&request
);
1305 return NT_STATUS_OK
;
1308 /*******************************************************************
1309 Creates schannel auth bind.
1310 ********************************************************************/
1312 static NTSTATUS
create_schannel_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1313 enum pipe_auth_level auth_level
,
1314 RPC_HDR_AUTH
*pauth_out
,
1315 prs_struct
*auth_data
)
1317 RPC_AUTH_SCHANNEL_NEG schannel_neg
;
1319 /* We may change the pad length before marshalling. */
1320 init_rpc_hdr_auth(pauth_out
, RPC_SCHANNEL_AUTH_TYPE
, (int)auth_level
, 0, 1);
1322 /* Use lp_workgroup() if domain not specified */
1324 if (!cli
->auth
->domain
|| !cli
->auth
->domain
[0]) {
1325 cli
->auth
->domain
= talloc_strdup(cli
, lp_workgroup());
1326 if (cli
->auth
->domain
== NULL
) {
1327 return NT_STATUS_NO_MEMORY
;
1331 init_rpc_auth_schannel_neg(&schannel_neg
, cli
->auth
->domain
,
1335 * Now marshall the data into the auth parse_struct.
1338 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1339 &schannel_neg
, auth_data
, 0)) {
1340 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1341 prs_mem_free(auth_data
);
1342 return NT_STATUS_NO_MEMORY
;
1345 return NT_STATUS_OK
;
1348 /*******************************************************************
1349 Creates the internals of a DCE/RPC bind request or alter context PDU.
1350 ********************************************************************/
1352 static NTSTATUS
create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type
,
1353 prs_struct
*rpc_out
,
1355 const RPC_IFACE
*abstract
,
1356 const RPC_IFACE
*transfer
,
1357 RPC_HDR_AUTH
*phdr_auth
,
1358 prs_struct
*pauth_info
)
1362 RPC_CONTEXT rpc_ctx
;
1363 uint16 auth_len
= prs_offset(pauth_info
);
1364 uint8 ss_padding_len
= 0;
1365 uint16 frag_len
= 0;
1367 /* create the RPC context. */
1368 init_rpc_context(&rpc_ctx
, 0 /* context id */, abstract
, transfer
);
1370 /* create the bind request RPC_HDR_RB */
1371 init_rpc_hdr_rb(&hdr_rb
, RPC_MAX_PDU_FRAG_LEN
, RPC_MAX_PDU_FRAG_LEN
, 0x0, &rpc_ctx
);
1373 /* Start building the frag length. */
1374 frag_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1376 /* Do we need to pad ? */
1378 uint16 data_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1380 ss_padding_len
= 8 - (data_len
% 8);
1381 phdr_auth
->auth_pad_len
= ss_padding_len
;
1383 frag_len
+= RPC_HDR_AUTH_LEN
+ auth_len
+ ss_padding_len
;
1386 /* Create the request RPC_HDR */
1387 init_rpc_hdr(&hdr
, pkt_type
, RPC_FLG_FIRST
|RPC_FLG_LAST
, rpc_call_id
, frag_len
, auth_len
);
1389 /* Marshall the RPC header */
1390 if(!smb_io_rpc_hdr("hdr" , &hdr
, rpc_out
, 0)) {
1391 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1392 return NT_STATUS_NO_MEMORY
;
1395 /* Marshall the bind request data */
1396 if(!smb_io_rpc_hdr_rb("", &hdr_rb
, rpc_out
, 0)) {
1397 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1398 return NT_STATUS_NO_MEMORY
;
1402 * Grow the outgoing buffer to store any auth info.
1406 if (ss_padding_len
) {
1408 memset(pad
, '\0', 8);
1409 if (!prs_copy_data_in(rpc_out
, pad
, ss_padding_len
)) {
1410 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1411 return NT_STATUS_NO_MEMORY
;
1415 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth
, rpc_out
, 0)) {
1416 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1417 return NT_STATUS_NO_MEMORY
;
1421 if(!prs_append_prs_data( rpc_out
, pauth_info
)) {
1422 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1423 return NT_STATUS_NO_MEMORY
;
1427 return NT_STATUS_OK
;
1430 /*******************************************************************
1431 Creates a DCE/RPC bind request.
1432 ********************************************************************/
1434 static NTSTATUS
create_rpc_bind_req(struct rpc_pipe_client
*cli
,
1435 prs_struct
*rpc_out
,
1437 const RPC_IFACE
*abstract
,
1438 const RPC_IFACE
*transfer
,
1439 enum pipe_auth_type auth_type
,
1440 enum pipe_auth_level auth_level
)
1442 RPC_HDR_AUTH hdr_auth
;
1443 prs_struct auth_info
;
1444 NTSTATUS ret
= NT_STATUS_OK
;
1446 ZERO_STRUCT(hdr_auth
);
1447 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
1448 return NT_STATUS_NO_MEMORY
;
1450 switch (auth_type
) {
1451 case PIPE_AUTH_TYPE_SCHANNEL
:
1452 ret
= create_schannel_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1453 if (!NT_STATUS_IS_OK(ret
)) {
1454 prs_mem_free(&auth_info
);
1459 case PIPE_AUTH_TYPE_NTLMSSP
:
1460 ret
= create_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1461 if (!NT_STATUS_IS_OK(ret
)) {
1462 prs_mem_free(&auth_info
);
1467 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1468 ret
= create_spnego_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1469 if (!NT_STATUS_IS_OK(ret
)) {
1470 prs_mem_free(&auth_info
);
1475 case PIPE_AUTH_TYPE_KRB5
:
1476 ret
= create_krb5_auth_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1477 if (!NT_STATUS_IS_OK(ret
)) {
1478 prs_mem_free(&auth_info
);
1483 case PIPE_AUTH_TYPE_NONE
:
1487 /* "Can't" happen. */
1488 return NT_STATUS_INVALID_INFO_CLASS
;
1491 ret
= create_bind_or_alt_ctx_internal(RPC_BIND
,
1499 prs_mem_free(&auth_info
);
1503 /*******************************************************************
1504 Create and add the NTLMSSP sign/seal auth header and data.
1505 ********************************************************************/
1507 static NTSTATUS
add_ntlmssp_auth_footer(struct rpc_pipe_client
*cli
,
1509 uint32 ss_padding_len
,
1510 prs_struct
*outgoing_pdu
)
1512 RPC_HDR_AUTH auth_info
;
1514 DATA_BLOB auth_blob
= data_blob_null
;
1515 uint16 data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1517 if (!cli
->auth
->a_u
.ntlmssp_state
) {
1518 return NT_STATUS_INVALID_PARAMETER
;
1521 /* Init and marshall the auth header. */
1522 init_rpc_hdr_auth(&auth_info
,
1523 map_pipe_auth_type_to_rpc_auth_type(
1524 cli
->auth
->auth_type
),
1525 cli
->auth
->auth_level
,
1527 1 /* context id. */);
1529 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1530 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1531 data_blob_free(&auth_blob
);
1532 return NT_STATUS_NO_MEMORY
;
1535 switch (cli
->auth
->auth_level
) {
1536 case PIPE_AUTH_LEVEL_PRIVACY
:
1537 /* Data portion is encrypted. */
1538 status
= ntlmssp_seal_packet(cli
->auth
->a_u
.ntlmssp_state
,
1539 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1541 (unsigned char *)prs_data_p(outgoing_pdu
),
1542 (size_t)prs_offset(outgoing_pdu
),
1544 if (!NT_STATUS_IS_OK(status
)) {
1545 data_blob_free(&auth_blob
);
1550 case PIPE_AUTH_LEVEL_INTEGRITY
:
1551 /* Data is signed. */
1552 status
= ntlmssp_sign_packet(cli
->auth
->a_u
.ntlmssp_state
,
1553 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1555 (unsigned char *)prs_data_p(outgoing_pdu
),
1556 (size_t)prs_offset(outgoing_pdu
),
1558 if (!NT_STATUS_IS_OK(status
)) {
1559 data_blob_free(&auth_blob
);
1566 smb_panic("bad auth level");
1568 return NT_STATUS_INVALID_PARAMETER
;
1571 /* Finally marshall the blob. */
1573 if (!prs_copy_data_in(outgoing_pdu
, (const char *)auth_blob
.data
, NTLMSSP_SIG_SIZE
)) {
1574 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1575 (unsigned int)NTLMSSP_SIG_SIZE
));
1576 data_blob_free(&auth_blob
);
1577 return NT_STATUS_NO_MEMORY
;
1580 data_blob_free(&auth_blob
);
1581 return NT_STATUS_OK
;
1584 /*******************************************************************
1585 Create and add the schannel sign/seal auth header and data.
1586 ********************************************************************/
1588 static NTSTATUS
add_schannel_auth_footer(struct rpc_pipe_client
*cli
,
1590 uint32 ss_padding_len
,
1591 prs_struct
*outgoing_pdu
)
1593 RPC_HDR_AUTH auth_info
;
1594 RPC_AUTH_SCHANNEL_CHK verf
;
1595 struct schannel_auth_struct
*sas
= cli
->auth
->a_u
.schannel_auth
;
1596 char *data_p
= prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
1597 size_t data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1600 return NT_STATUS_INVALID_PARAMETER
;
1603 /* Init and marshall the auth header. */
1604 init_rpc_hdr_auth(&auth_info
,
1605 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
->auth_type
),
1606 cli
->auth
->auth_level
,
1608 1 /* context id. */);
1610 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1611 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1612 return NT_STATUS_NO_MEMORY
;
1615 switch (cli
->auth
->auth_level
) {
1616 case PIPE_AUTH_LEVEL_PRIVACY
:
1617 case PIPE_AUTH_LEVEL_INTEGRITY
:
1618 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1621 schannel_encode(sas
,
1622 cli
->auth
->auth_level
,
1623 SENDER_IS_INITIATOR
,
1633 smb_panic("bad auth level");
1635 return NT_STATUS_INVALID_PARAMETER
;
1638 /* Finally marshall the blob. */
1639 smb_io_rpc_auth_schannel_chk("",
1640 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
,
1645 return NT_STATUS_OK
;
1648 /*******************************************************************
1649 Calculate how much data we're going to send in this packet, also
1650 work out any sign/seal padding length.
1651 ********************************************************************/
1653 static uint32
calculate_data_len_tosend(struct rpc_pipe_client
*cli
,
1657 uint32
*p_ss_padding
)
1659 uint32 data_space
, data_len
;
1661 switch (cli
->auth
->auth_level
) {
1662 case PIPE_AUTH_LEVEL_NONE
:
1663 case PIPE_AUTH_LEVEL_CONNECT
:
1664 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
;
1665 data_len
= MIN(data_space
, data_left
);
1668 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ data_len
;
1671 case PIPE_AUTH_LEVEL_INTEGRITY
:
1672 case PIPE_AUTH_LEVEL_PRIVACY
:
1673 /* Treat the same for all authenticated rpc requests. */
1674 switch(cli
->auth
->auth_type
) {
1675 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1676 case PIPE_AUTH_TYPE_NTLMSSP
:
1677 *p_auth_len
= NTLMSSP_SIG_SIZE
;
1679 case PIPE_AUTH_TYPE_SCHANNEL
:
1680 *p_auth_len
= RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
;
1683 smb_panic("bad auth type");
1687 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
-
1688 RPC_HDR_AUTH_LEN
- *p_auth_len
;
1690 data_len
= MIN(data_space
, data_left
);
1692 *p_ss_padding
= 8 - (data_len
% 8);
1694 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ /* Normal headers. */
1695 data_len
+ *p_ss_padding
+ /* data plus padding. */
1696 RPC_HDR_AUTH_LEN
+ *p_auth_len
; /* Auth header and auth data. */
1700 smb_panic("bad auth level");
1706 /*******************************************************************
1708 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1709 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1710 and deals with signing/sealing details.
1711 ********************************************************************/
1713 NTSTATUS
rpc_api_pipe_req(struct rpc_pipe_client
*cli
,
1715 prs_struct
*in_data
,
1716 prs_struct
*out_data
)
1719 uint32 data_left
= prs_offset(in_data
);
1720 uint32 alloc_hint
= prs_offset(in_data
);
1721 uint32 data_sent_thistime
= 0;
1722 uint32 current_data_offset
= 0;
1723 uint32 call_id
= get_rpc_call_id();
1725 prs_struct outgoing_pdu
;
1727 memset(pad
, '\0', 8);
1729 if (cli
->max_xmit_frag
< RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ RPC_MAX_SIGN_SIZE
) {
1730 /* Server is screwed up ! */
1731 return NT_STATUS_INVALID_PARAMETER
;
1734 if (!prs_init(&outgoing_pdu
, cli
->max_xmit_frag
, prs_get_mem_context(in_data
), MARSHALL
))
1735 return NT_STATUS_NO_MEMORY
;
1739 RPC_HDR_REQ hdr_req
;
1740 uint16 auth_len
= 0;
1741 uint16 frag_len
= 0;
1743 uint32 ss_padding
= 0;
1744 ssize_t num_written
;
1746 data_sent_thistime
= calculate_data_len_tosend(cli
, data_left
,
1747 &frag_len
, &auth_len
, &ss_padding
);
1749 if (current_data_offset
== 0) {
1750 flags
= RPC_FLG_FIRST
;
1753 if (data_sent_thistime
== data_left
) {
1754 flags
|= RPC_FLG_LAST
;
1757 /* Create and marshall the header and request header. */
1758 init_rpc_hdr(&hdr
, RPC_REQUEST
, flags
, call_id
, frag_len
, auth_len
);
1760 if(!smb_io_rpc_hdr("hdr ", &hdr
, &outgoing_pdu
, 0)) {
1761 prs_mem_free(&outgoing_pdu
);
1762 return NT_STATUS_NO_MEMORY
;
1765 /* Create the rpc request RPC_HDR_REQ */
1766 init_rpc_hdr_req(&hdr_req
, alloc_hint
, op_num
);
1768 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req
, &outgoing_pdu
, 0)) {
1769 prs_mem_free(&outgoing_pdu
);
1770 return NT_STATUS_NO_MEMORY
;
1773 /* Copy in the data, plus any ss padding. */
1774 if (!prs_append_some_prs_data(&outgoing_pdu
, in_data
, current_data_offset
, data_sent_thistime
)) {
1775 prs_mem_free(&outgoing_pdu
);
1776 return NT_STATUS_NO_MEMORY
;
1779 /* Copy the sign/seal padding data. */
1781 if (!prs_copy_data_in(&outgoing_pdu
, pad
, ss_padding
)) {
1782 prs_mem_free(&outgoing_pdu
);
1783 return NT_STATUS_NO_MEMORY
;
1787 /* Generate any auth sign/seal and add the auth footer. */
1789 switch (cli
->auth
->auth_type
) {
1790 case PIPE_AUTH_TYPE_NONE
:
1792 case PIPE_AUTH_TYPE_NTLMSSP
:
1793 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1794 ret
= add_ntlmssp_auth_footer(cli
, &hdr
, ss_padding
, &outgoing_pdu
);
1795 if (!NT_STATUS_IS_OK(ret
)) {
1796 prs_mem_free(&outgoing_pdu
);
1800 case PIPE_AUTH_TYPE_SCHANNEL
:
1801 ret
= add_schannel_auth_footer(cli
, &hdr
, ss_padding
, &outgoing_pdu
);
1802 if (!NT_STATUS_IS_OK(ret
)) {
1803 prs_mem_free(&outgoing_pdu
);
1808 smb_panic("bad auth type");
1809 break; /* notreached */
1813 /* Actually send the packet. */
1814 if (flags
& RPC_FLG_LAST
) {
1815 /* Last packet - send the data, get the reply and return. */
1816 ret
= rpc_api_pipe(cli
, &outgoing_pdu
, out_data
, RPC_RESPONSE
);
1817 prs_mem_free(&outgoing_pdu
);
1819 if ((DEBUGLEVEL
>= 50)
1820 && (cli
->transport_type
== NCACN_NP
)) {
1821 char *dump_name
= NULL
;
1822 /* Also capture received data */
1823 if (asprintf(&dump_name
, "%s/reply_%s_%d",
1824 get_dyn_LOGFILEBASE(),
1825 cli
->trans
.np
.pipe_name
, op_num
) > 0) {
1826 prs_dump(dump_name
, op_num
, out_data
);
1827 SAFE_FREE(dump_name
);
1834 switch (cli
->transport_type
) {
1836 num_written
= cli_write(cli
->trans
.np
.cli
,
1838 8, /* 8 means message mode. */
1839 prs_data_p(&outgoing_pdu
),
1841 (size_t)hdr
.frag_len
);
1843 if (num_written
!= hdr
.frag_len
) {
1844 prs_mem_free(&outgoing_pdu
);
1845 return cli_get_nt_error(cli
->trans
.np
.cli
);
1849 case NCACN_UNIX_STREAM
:
1850 num_written
= write_data(
1852 prs_data_p(&outgoing_pdu
),
1853 (size_t)hdr
.frag_len
);
1854 if (num_written
!= hdr
.frag_len
) {
1856 status
= map_nt_error_from_unix(errno
);
1857 prs_mem_free(&outgoing_pdu
);
1862 DEBUG(0, ("unknown transport type %d\n",
1863 cli
->transport_type
));
1864 return NT_STATUS_INTERNAL_ERROR
;
1867 current_data_offset
+= data_sent_thistime
;
1868 data_left
-= data_sent_thistime
;
1870 /* Reset the marshalling position back to zero. */
1871 if (!prs_set_offset(&outgoing_pdu
, 0)) {
1872 prs_mem_free(&outgoing_pdu
);
1873 return NT_STATUS_NO_MEMORY
;
1878 /****************************************************************************
1879 Set the handle state.
1880 ****************************************************************************/
1882 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client
*cli
,
1883 const char *pipe_name
, uint16 device_state
)
1885 bool state_set
= False
;
1887 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
1888 char *rparam
= NULL
;
1890 uint32 rparam_len
, rdata_len
;
1892 if (pipe_name
== NULL
)
1895 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1896 cli
->fnum
, pipe_name
, device_state
));
1898 /* create parameters: device state */
1899 SSVAL(param
, 0, device_state
);
1901 /* create setup parameters. */
1903 setup
[1] = cli
->fnum
; /* pipe file handle. got this from an SMBOpenX. */
1905 /* send the data on \PIPE\ */
1906 if (cli_api_pipe(cli
->cli
, "\\PIPE\\",
1907 setup
, 2, 0, /* setup, length, max */
1908 param
, 2, 0, /* param, length, max */
1909 NULL
, 0, 1024, /* data, length, max */
1910 &rparam
, &rparam_len
, /* return param, length */
1911 &rdata
, &rdata_len
)) /* return data, length */
1913 DEBUG(5, ("Set Handle state: return OK\n"));
1924 /****************************************************************************
1925 Check the rpc bind acknowledge response.
1926 ****************************************************************************/
1928 static bool check_bind_response(RPC_HDR_BA
*hdr_ba
, const RPC_IFACE
*transfer
)
1930 if ( hdr_ba
->addr
.len
== 0) {
1931 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1934 /* check the transfer syntax */
1935 if ((hdr_ba
->transfer
.if_version
!= transfer
->if_version
) ||
1936 (memcmp(&hdr_ba
->transfer
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
1937 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1941 if (hdr_ba
->res
.num_results
!= 0x1 || hdr_ba
->res
.result
!= 0) {
1942 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1943 hdr_ba
->res
.num_results
, hdr_ba
->res
.reason
));
1946 DEBUG(5,("check_bind_response: accepted!\n"));
1950 /*******************************************************************
1951 Creates a DCE/RPC bind authentication response.
1952 This is the packet that is sent back to the server once we
1953 have received a BIND-ACK, to finish the third leg of
1954 the authentication handshake.
1955 ********************************************************************/
1957 static NTSTATUS
create_rpc_bind_auth3(struct rpc_pipe_client
*cli
,
1959 enum pipe_auth_type auth_type
,
1960 enum pipe_auth_level auth_level
,
1961 DATA_BLOB
*pauth_blob
,
1962 prs_struct
*rpc_out
)
1965 RPC_HDR_AUTH hdr_auth
;
1968 /* Create the request RPC_HDR */
1969 init_rpc_hdr(&hdr
, RPC_AUTH3
, RPC_FLG_FIRST
|RPC_FLG_LAST
, rpc_call_id
,
1970 RPC_HEADER_LEN
+ 4 /* pad */ + RPC_HDR_AUTH_LEN
+ pauth_blob
->length
,
1971 pauth_blob
->length
);
1974 if(!smb_io_rpc_hdr("hdr", &hdr
, rpc_out
, 0)) {
1975 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1976 return NT_STATUS_NO_MEMORY
;
1980 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1981 about padding - shouldn't this pad to length 8 ? JRA.
1984 /* 4 bytes padding. */
1985 if (!prs_uint32("pad", rpc_out
, 0, &pad
)) {
1986 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1987 return NT_STATUS_NO_MEMORY
;
1990 /* Create the request RPC_HDR_AUTHA */
1991 init_rpc_hdr_auth(&hdr_auth
,
1992 map_pipe_auth_type_to_rpc_auth_type(auth_type
),
1995 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rpc_out
, 0)) {
1996 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1997 return NT_STATUS_NO_MEMORY
;
2001 * Append the auth data to the outgoing buffer.
2004 if(!prs_copy_data_in(rpc_out
, (char *)pauth_blob
->data
, pauth_blob
->length
)) {
2005 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2006 return NT_STATUS_NO_MEMORY
;
2009 return NT_STATUS_OK
;
2012 /****************************************************************************
2013 Create and send the third packet in an RPC auth.
2014 ****************************************************************************/
2016 static NTSTATUS
rpc_finish_auth3_bind(struct rpc_pipe_client
*cli
,
2020 enum pipe_auth_type auth_type
,
2021 enum pipe_auth_level auth_level
)
2023 DATA_BLOB server_response
= data_blob_null
;
2024 DATA_BLOB client_reply
= data_blob_null
;
2025 RPC_HDR_AUTH hdr_auth
;
2030 if (!phdr
->auth_len
|| (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
2031 return NT_STATUS_INVALID_PARAMETER
;
2034 /* Process the returned NTLMSSP blob first. */
2035 if (!prs_set_offset(rbuf
, phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
2036 return NT_STATUS_INVALID_PARAMETER
;
2039 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rbuf
, 0)) {
2040 return NT_STATUS_INVALID_PARAMETER
;
2043 /* TODO - check auth_type/auth_level match. */
2045 server_response
= data_blob(NULL
, phdr
->auth_len
);
2046 prs_copy_data_out((char *)server_response
.data
, rbuf
, phdr
->auth_len
);
2048 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
2052 if (!NT_STATUS_IS_OK(nt_status
)) {
2053 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
2054 data_blob_free(&server_response
);
2058 prs_init_empty(&rpc_out
, prs_get_mem_context(rbuf
), MARSHALL
);
2060 nt_status
= create_rpc_bind_auth3(cli
, rpc_call_id
,
2061 auth_type
, auth_level
,
2062 &client_reply
, &rpc_out
);
2064 if (!NT_STATUS_IS_OK(nt_status
)) {
2065 prs_mem_free(&rpc_out
);
2066 data_blob_free(&client_reply
);
2067 data_blob_free(&server_response
);
2071 switch (cli
->transport_type
) {
2073 /* 8 here is named pipe message mode. */
2074 ret
= cli_write(cli
->trans
.np
.cli
, cli
->trans
.np
.fnum
,
2075 0x8, prs_data_p(&rpc_out
), 0,
2076 (size_t)prs_offset(&rpc_out
));
2079 if (ret
!= (ssize_t
)prs_offset(&rpc_out
)) {
2080 nt_status
= cli_get_nt_error(cli
->trans
.np
.cli
);
2083 case NCACN_UNIX_STREAM
:
2084 ret
= write_data(cli
->trans
.sock
.fd
, prs_data_p(&rpc_out
),
2085 (size_t)prs_offset(&rpc_out
));
2086 if (ret
!= (ssize_t
)prs_offset(&rpc_out
)) {
2087 nt_status
= map_nt_error_from_unix(errno
);
2091 DEBUG(0, ("unknown transport type %d\n", cli
->transport_type
));
2092 return NT_STATUS_INTERNAL_ERROR
;
2095 if (ret
!= (ssize_t
)prs_offset(&rpc_out
)) {
2096 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
2097 nt_errstr(nt_status
)));
2098 prs_mem_free(&rpc_out
);
2099 data_blob_free(&client_reply
);
2100 data_blob_free(&server_response
);
2104 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2105 rpccli_pipe_txt(debug_ctx(), cli
)));
2107 prs_mem_free(&rpc_out
);
2108 data_blob_free(&client_reply
);
2109 data_blob_free(&server_response
);
2110 return NT_STATUS_OK
;
2113 /*******************************************************************
2114 Creates a DCE/RPC bind alter context authentication request which
2115 may contain a spnego auth blobl
2116 ********************************************************************/
2118 static NTSTATUS
create_rpc_alter_context(uint32 rpc_call_id
,
2119 const RPC_IFACE
*abstract
,
2120 const RPC_IFACE
*transfer
,
2121 enum pipe_auth_level auth_level
,
2122 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
2123 prs_struct
*rpc_out
)
2125 RPC_HDR_AUTH hdr_auth
;
2126 prs_struct auth_info
;
2127 NTSTATUS ret
= NT_STATUS_OK
;
2129 ZERO_STRUCT(hdr_auth
);
2130 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
2131 return NT_STATUS_NO_MEMORY
;
2133 /* We may change the pad length before marshalling. */
2134 init_rpc_hdr_auth(&hdr_auth
, RPC_SPNEGO_AUTH_TYPE
, (int)auth_level
, 0, 1);
2136 if (pauth_blob
->length
) {
2137 if (!prs_copy_data_in(&auth_info
, (const char *)pauth_blob
->data
, pauth_blob
->length
)) {
2138 prs_mem_free(&auth_info
);
2139 return NT_STATUS_NO_MEMORY
;
2143 ret
= create_bind_or_alt_ctx_internal(RPC_ALTCONT
,
2150 prs_mem_free(&auth_info
);
2154 /*******************************************************************
2155 Third leg of the SPNEGO bind mechanism - sends alter context PDU
2156 and gets a response.
2157 ********************************************************************/
2159 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client
*cli
,
2163 const RPC_IFACE
*abstract
,
2164 const RPC_IFACE
*transfer
,
2165 enum pipe_auth_type auth_type
,
2166 enum pipe_auth_level auth_level
)
2168 DATA_BLOB server_spnego_response
= data_blob_null
;
2169 DATA_BLOB server_ntlm_response
= data_blob_null
;
2170 DATA_BLOB client_reply
= data_blob_null
;
2171 DATA_BLOB tmp_blob
= data_blob_null
;
2172 RPC_HDR_AUTH hdr_auth
;
2176 if (!phdr
->auth_len
|| (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
2177 return NT_STATUS_INVALID_PARAMETER
;
2180 /* Process the returned NTLMSSP blob first. */
2181 if (!prs_set_offset(rbuf
, phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
2182 return NT_STATUS_INVALID_PARAMETER
;
2185 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rbuf
, 0)) {
2186 return NT_STATUS_INVALID_PARAMETER
;
2189 server_spnego_response
= data_blob(NULL
, phdr
->auth_len
);
2190 prs_copy_data_out((char *)server_spnego_response
.data
, rbuf
, phdr
->auth_len
);
2192 /* The server might give us back two challenges - tmp_blob is for the second. */
2193 if (!spnego_parse_challenge(server_spnego_response
, &server_ntlm_response
, &tmp_blob
)) {
2194 data_blob_free(&server_spnego_response
);
2195 data_blob_free(&server_ntlm_response
);
2196 data_blob_free(&tmp_blob
);
2197 return NT_STATUS_INVALID_PARAMETER
;
2200 /* We're finished with the server spnego response and the tmp_blob. */
2201 data_blob_free(&server_spnego_response
);
2202 data_blob_free(&tmp_blob
);
2204 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
2205 server_ntlm_response
,
2208 /* Finished with the server_ntlm response */
2209 data_blob_free(&server_ntlm_response
);
2211 if (!NT_STATUS_IS_OK(nt_status
)) {
2212 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2213 data_blob_free(&client_reply
);
2217 /* SPNEGO wrap the client reply. */
2218 tmp_blob
= spnego_gen_auth(client_reply
);
2219 data_blob_free(&client_reply
);
2220 client_reply
= tmp_blob
;
2221 tmp_blob
= data_blob_null
; /* Ensure it's safe to free this just in case. */
2223 /* Now prepare the alter context pdu. */
2224 prs_init_empty(&rpc_out
, prs_get_mem_context(rbuf
), MARSHALL
);
2226 nt_status
= create_rpc_alter_context(rpc_call_id
,
2233 data_blob_free(&client_reply
);
2235 if (!NT_STATUS_IS_OK(nt_status
)) {
2236 prs_mem_free(&rpc_out
);
2240 /* Initialize the returning data struct. */
2242 prs_init_empty(rbuf
, talloc_tos(), UNMARSHALL
);
2244 nt_status
= rpc_api_pipe(cli
, &rpc_out
, rbuf
, RPC_ALTCONTRESP
);
2245 prs_mem_free(&rpc_out
);
2246 if (!NT_STATUS_IS_OK(nt_status
)) {
2250 /* Get the auth blob from the reply. */
2251 if(!smb_io_rpc_hdr("rpc_hdr ", phdr
, rbuf
, 0)) {
2252 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2253 return NT_STATUS_BUFFER_TOO_SMALL
;
2256 if (!prs_set_offset(rbuf
, phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
2257 return NT_STATUS_INVALID_PARAMETER
;
2260 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rbuf
, 0)) {
2261 return NT_STATUS_INVALID_PARAMETER
;
2264 server_spnego_response
= data_blob(NULL
, phdr
->auth_len
);
2265 prs_copy_data_out((char *)server_spnego_response
.data
, rbuf
, phdr
->auth_len
);
2267 /* Check we got a valid auth response. */
2268 if (!spnego_parse_auth_response(server_spnego_response
, NT_STATUS_OK
, OID_NTLMSSP
, &tmp_blob
)) {
2269 data_blob_free(&server_spnego_response
);
2270 data_blob_free(&tmp_blob
);
2271 return NT_STATUS_INVALID_PARAMETER
;
2274 data_blob_free(&server_spnego_response
);
2275 data_blob_free(&tmp_blob
);
2277 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2278 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli
)));
2280 return NT_STATUS_OK
;
2283 /****************************************************************************
2285 ****************************************************************************/
2287 NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2288 struct cli_pipe_auth_data
*auth
)
2297 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2298 rpccli_pipe_txt(debug_ctx(), cli
),
2299 (unsigned int)auth
->auth_type
,
2300 (unsigned int)auth
->auth_level
));
2302 cli
->auth
= talloc_move(cli
, &auth
);
2304 prs_init_empty(&rpc_out
, talloc_tos(), MARSHALL
);
2306 rpc_call_id
= get_rpc_call_id();
2308 /* Marshall the outgoing data. */
2309 status
= create_rpc_bind_req(cli
, &rpc_out
, rpc_call_id
,
2310 &cli
->abstract_syntax
,
2311 &cli
->transfer_syntax
,
2312 cli
->auth
->auth_type
,
2313 cli
->auth
->auth_level
);
2315 if (!NT_STATUS_IS_OK(status
)) {
2316 prs_mem_free(&rpc_out
);
2320 /* Initialize the incoming data struct. */
2321 prs_init_empty(&rbuf
, talloc_tos(), UNMARSHALL
);
2323 /* send data on \PIPE\. receive a response */
2324 status
= rpc_api_pipe(cli
, &rpc_out
, &rbuf
, RPC_BINDACK
);
2325 prs_mem_free(&rpc_out
);
2326 if (!NT_STATUS_IS_OK(status
)) {
2330 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2331 rpccli_pipe_txt(debug_ctx(), cli
)));
2333 /* Unmarshall the RPC header */
2334 if(!smb_io_rpc_hdr("hdr" , &hdr
, &rbuf
, 0)) {
2335 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2336 prs_mem_free(&rbuf
);
2337 return NT_STATUS_BUFFER_TOO_SMALL
;
2340 if(!smb_io_rpc_hdr_ba("", &hdr_ba
, &rbuf
, 0)) {
2341 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2342 prs_mem_free(&rbuf
);
2343 return NT_STATUS_BUFFER_TOO_SMALL
;
2346 if(!check_bind_response(&hdr_ba
, &cli
->transfer_syntax
)) {
2347 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2348 prs_mem_free(&rbuf
);
2349 return NT_STATUS_BUFFER_TOO_SMALL
;
2352 cli
->max_xmit_frag
= hdr_ba
.bba
.max_tsize
;
2353 cli
->max_recv_frag
= hdr_ba
.bba
.max_rsize
;
2355 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2356 switch(cli
->auth
->auth_type
) {
2358 case PIPE_AUTH_TYPE_NONE
:
2359 case PIPE_AUTH_TYPE_SCHANNEL
:
2360 /* Bind complete. */
2363 case PIPE_AUTH_TYPE_NTLMSSP
:
2364 /* Need to send AUTH3 packet - no reply. */
2365 status
= rpc_finish_auth3_bind(
2366 cli
, &hdr
, &rbuf
, rpc_call_id
,
2367 cli
->auth
->auth_type
,
2368 cli
->auth
->auth_level
);
2369 if (!NT_STATUS_IS_OK(status
)) {
2370 prs_mem_free(&rbuf
);
2375 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2376 /* Need to send alter context request and reply. */
2377 status
= rpc_finish_spnego_ntlmssp_bind(
2378 cli
, &hdr
, &rbuf
, rpc_call_id
,
2379 &cli
->abstract_syntax
, &cli
->transfer_syntax
,
2380 cli
->auth
->auth_type
, cli
->auth
->auth_level
);
2381 if (!NT_STATUS_IS_OK(status
)) {
2382 prs_mem_free(&rbuf
);
2387 case PIPE_AUTH_TYPE_KRB5
:
2391 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2392 "%u\n", (unsigned int)cli
->auth
->auth_type
));
2393 prs_mem_free(&rbuf
);
2394 return NT_STATUS_INVALID_INFO_CLASS
;
2397 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2398 if (cli
->auth
->auth_type
== PIPE_AUTH_TYPE_NTLMSSP
2399 || cli
->auth
->auth_type
== PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
) {
2400 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_INTEGRITY
) {
2401 if (!(cli
->auth
->a_u
.ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_SIGN
)) {
2402 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2403 prs_mem_free(&rbuf
);
2404 return NT_STATUS_INVALID_PARAMETER
;
2407 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_INTEGRITY
) {
2408 if (!(cli
->auth
->a_u
.ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_SEAL
)) {
2409 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2410 prs_mem_free(&rbuf
);
2411 return NT_STATUS_INVALID_PARAMETER
;
2416 prs_mem_free(&rbuf
);
2417 return NT_STATUS_OK
;
2420 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*cli
,
2421 unsigned int timeout
)
2423 return cli_set_timeout(cli
->trans
.np
.cli
, timeout
);
2426 bool rpccli_get_pwd_hash(struct rpc_pipe_client
*cli
, uint8_t nt_hash
[16])
2428 if ((cli
->auth
->auth_type
== PIPE_AUTH_TYPE_NTLMSSP
)
2429 || (cli
->auth
->auth_type
== PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
)) {
2430 memcpy(nt_hash
, cli
->auth
->a_u
.ntlmssp_state
->nt_hash
, 16);
2434 if (cli
->transport_type
== NCACN_NP
) {
2435 E_md4hash(cli
->trans
.np
.cli
->pwd
.password
, nt_hash
);
2442 struct cli_state
*rpc_pipe_np_smb_conn(struct rpc_pipe_client
*p
)
2444 if (p
->transport_type
== NCACN_NP
) {
2445 return p
->trans
.np
.cli
;
2450 static int rpc_pipe_destructor(struct rpc_pipe_client
*p
)
2452 if (p
->transport_type
== NCACN_NP
) {
2454 ret
= cli_close(p
->trans
.np
.cli
, p
->trans
.np
.fnum
);
2456 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2457 "pipe %s. Error was %s\n",
2458 rpccli_pipe_txt(debug_ctx(), p
),
2459 cli_errstr(p
->trans
.np
.cli
)));
2462 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2463 rpccli_pipe_txt(debug_ctx(), p
)));
2465 DLIST_REMOVE(p
->trans
.np
.cli
->pipe_list
, p
);
2466 return ret
? -1 : 0;
2472 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
2473 struct cli_pipe_auth_data
**presult
)
2475 struct cli_pipe_auth_data
*result
;
2477 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
2478 if (result
== NULL
) {
2479 return NT_STATUS_NO_MEMORY
;
2482 result
->auth_type
= PIPE_AUTH_TYPE_NONE
;
2483 result
->auth_level
= PIPE_AUTH_LEVEL_NONE
;
2485 result
->user_name
= talloc_strdup(result
, "");
2486 result
->domain
= talloc_strdup(result
, "");
2487 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2488 TALLOC_FREE(result
);
2489 return NT_STATUS_NO_MEMORY
;
2493 return NT_STATUS_OK
;
2496 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data
*auth
)
2498 ntlmssp_end(&auth
->a_u
.ntlmssp_state
);
2502 NTSTATUS
rpccli_ntlmssp_bind_data(TALLOC_CTX
*mem_ctx
,
2503 enum pipe_auth_type auth_type
,
2504 enum pipe_auth_level auth_level
,
2506 const char *username
,
2507 const char *password
,
2508 struct cli_pipe_auth_data
**presult
)
2510 struct cli_pipe_auth_data
*result
;
2513 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
2514 if (result
== NULL
) {
2515 return NT_STATUS_NO_MEMORY
;
2518 result
->auth_type
= auth_type
;
2519 result
->auth_level
= auth_level
;
2521 result
->user_name
= talloc_strdup(result
, username
);
2522 result
->domain
= talloc_strdup(result
, domain
);
2523 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2524 status
= NT_STATUS_NO_MEMORY
;
2528 status
= ntlmssp_client_start(&result
->a_u
.ntlmssp_state
);
2529 if (!NT_STATUS_IS_OK(status
)) {
2533 talloc_set_destructor(result
, cli_auth_ntlmssp_data_destructor
);
2535 status
= ntlmssp_set_username(result
->a_u
.ntlmssp_state
, username
);
2536 if (!NT_STATUS_IS_OK(status
)) {
2540 status
= ntlmssp_set_domain(result
->a_u
.ntlmssp_state
, domain
);
2541 if (!NT_STATUS_IS_OK(status
)) {
2545 status
= ntlmssp_set_password(result
->a_u
.ntlmssp_state
, password
);
2546 if (!NT_STATUS_IS_OK(status
)) {
2551 * Turn off sign+seal to allow selected auth level to turn it back on.
2553 result
->a_u
.ntlmssp_state
->neg_flags
&=
2554 ~(NTLMSSP_NEGOTIATE_SIGN
| NTLMSSP_NEGOTIATE_SEAL
);
2556 if (auth_level
== PIPE_AUTH_LEVEL_INTEGRITY
) {
2557 result
->a_u
.ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
2558 } else if (auth_level
== PIPE_AUTH_LEVEL_PRIVACY
) {
2559 result
->a_u
.ntlmssp_state
->neg_flags
2560 |= NTLMSSP_NEGOTIATE_SEAL
| NTLMSSP_NEGOTIATE_SIGN
;
2564 return NT_STATUS_OK
;
2567 TALLOC_FREE(result
);
2571 NTSTATUS
rpccli_schannel_bind_data(TALLOC_CTX
*mem_ctx
, const char *domain
,
2572 enum pipe_auth_level auth_level
,
2573 const uint8_t sess_key
[16],
2574 struct cli_pipe_auth_data
**presult
)
2576 struct cli_pipe_auth_data
*result
;
2578 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
2579 if (result
== NULL
) {
2580 return NT_STATUS_NO_MEMORY
;
2583 result
->auth_type
= PIPE_AUTH_TYPE_SCHANNEL
;
2584 result
->auth_level
= auth_level
;
2586 result
->user_name
= talloc_strdup(result
, "");
2587 result
->domain
= talloc_strdup(result
, domain
);
2588 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2592 result
->a_u
.schannel_auth
= talloc(result
,
2593 struct schannel_auth_struct
);
2594 if (result
->a_u
.schannel_auth
== NULL
) {
2598 memcpy(result
->a_u
.schannel_auth
->sess_key
, sess_key
,
2599 sizeof(result
->a_u
.schannel_auth
->sess_key
));
2600 result
->a_u
.schannel_auth
->seq_num
= 0;
2603 return NT_STATUS_OK
;
2606 TALLOC_FREE(result
);
2607 return NT_STATUS_NO_MEMORY
;
2611 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct
*auth
)
2613 data_blob_free(&auth
->session_key
);
2618 NTSTATUS
rpccli_kerberos_bind_data(TALLOC_CTX
*mem_ctx
,
2619 enum pipe_auth_level auth_level
,
2620 const char *service_princ
,
2621 const char *username
,
2622 const char *password
,
2623 struct cli_pipe_auth_data
**presult
)
2626 struct cli_pipe_auth_data
*result
;
2628 if ((username
!= NULL
) && (password
!= NULL
)) {
2629 int ret
= kerberos_kinit_password(username
, password
, 0, NULL
);
2631 return NT_STATUS_ACCESS_DENIED
;
2635 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
2636 if (result
== NULL
) {
2637 return NT_STATUS_NO_MEMORY
;
2640 result
->auth_type
= PIPE_AUTH_TYPE_KRB5
;
2641 result
->auth_level
= auth_level
;
2644 * Username / domain need fixing!
2646 result
->user_name
= talloc_strdup(result
, "");
2647 result
->domain
= talloc_strdup(result
, "");
2648 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2652 result
->a_u
.kerberos_auth
= TALLOC_ZERO_P(
2653 result
, struct kerberos_auth_struct
);
2654 if (result
->a_u
.kerberos_auth
== NULL
) {
2657 talloc_set_destructor(result
->a_u
.kerberos_auth
,
2658 cli_auth_kerberos_data_destructor
);
2660 result
->a_u
.kerberos_auth
->service_principal
= talloc_strdup(
2661 result
, service_princ
);
2662 if (result
->a_u
.kerberos_auth
->service_principal
== NULL
) {
2667 return NT_STATUS_OK
;
2670 TALLOC_FREE(result
);
2671 return NT_STATUS_NO_MEMORY
;
2673 return NT_STATUS_NOT_SUPPORTED
;
2677 static int rpc_pipe_sock_destructor(struct rpc_pipe_client
*p
)
2679 close(p
->trans
.sock
.fd
);
2684 * Create an rpc pipe client struct, connecting to a tcp port.
2686 static NTSTATUS
rpc_pipe_open_tcp_port(TALLOC_CTX
*mem_ctx
, const char *host
,
2688 const struct ndr_syntax_id
*abstract_syntax
,
2689 struct rpc_pipe_client
**presult
)
2691 struct rpc_pipe_client
*result
;
2692 struct sockaddr_storage addr
;
2695 result
= TALLOC_ZERO_P(mem_ctx
, struct rpc_pipe_client
);
2696 if (result
== NULL
) {
2697 return NT_STATUS_NO_MEMORY
;
2700 result
->transport_type
= NCACN_IP_TCP
;
2702 result
->abstract_syntax
= *abstract_syntax
;
2703 result
->transfer_syntax
= ndr_transfer_syntax
;
2705 result
->desthost
= talloc_strdup(result
, host
);
2706 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2707 result
, "\\\\%s", result
->desthost
);
2708 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2709 status
= NT_STATUS_NO_MEMORY
;
2713 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2714 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
2716 if (!resolve_name(host
, &addr
, 0)) {
2717 status
= NT_STATUS_NOT_FOUND
;
2721 status
= open_socket_out(&addr
, port
, 60, &result
->trans
.sock
.fd
);
2722 if (!NT_STATUS_IS_OK(status
)) {
2726 talloc_set_destructor(result
, rpc_pipe_sock_destructor
);
2729 return NT_STATUS_OK
;
2732 TALLOC_FREE(result
);
2737 * Determine the tcp port on which a dcerpc interface is listening
2738 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2741 static NTSTATUS
rpc_pipe_get_tcp_port(const char *host
,
2742 const struct ndr_syntax_id
*abstract_syntax
,
2746 struct rpc_pipe_client
*epm_pipe
= NULL
;
2747 struct cli_pipe_auth_data
*auth
= NULL
;
2748 struct dcerpc_binding
*map_binding
= NULL
;
2749 struct dcerpc_binding
*res_binding
= NULL
;
2750 struct epm_twr_t
*map_tower
= NULL
;
2751 struct epm_twr_t
*res_towers
= NULL
;
2752 struct policy_handle
*entry_handle
= NULL
;
2753 uint32_t num_towers
= 0;
2754 uint32_t max_towers
= 1;
2755 struct epm_twr_p_t towers
;
2756 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2758 if (pport
== NULL
) {
2759 status
= NT_STATUS_INVALID_PARAMETER
;
2763 /* open the connection to the endpoint mapper */
2764 status
= rpc_pipe_open_tcp_port(tmp_ctx
, host
, 135,
2765 &ndr_table_epmapper
.syntax_id
,
2768 if (!NT_STATUS_IS_OK(status
)) {
2772 status
= rpccli_anon_bind_data(tmp_ctx
, &auth
);
2773 if (!NT_STATUS_IS_OK(status
)) {
2777 status
= rpc_pipe_bind(epm_pipe
, auth
);
2778 if (!NT_STATUS_IS_OK(status
)) {
2782 /* create tower for asking the epmapper */
2784 map_binding
= TALLOC_ZERO_P(tmp_ctx
, struct dcerpc_binding
);
2785 if (map_binding
== NULL
) {
2786 status
= NT_STATUS_NO_MEMORY
;
2790 map_binding
->transport
= NCACN_IP_TCP
;
2791 map_binding
->object
= *abstract_syntax
;
2792 map_binding
->host
= host
; /* needed? */
2793 map_binding
->endpoint
= "0"; /* correct? needed? */
2795 map_tower
= TALLOC_ZERO_P(tmp_ctx
, struct epm_twr_t
);
2796 if (map_tower
== NULL
) {
2797 status
= NT_STATUS_NO_MEMORY
;
2801 status
= dcerpc_binding_build_tower(tmp_ctx
, map_binding
,
2802 &(map_tower
->tower
));
2803 if (!NT_STATUS_IS_OK(status
)) {
2807 /* allocate further parameters for the epm_Map call */
2809 res_towers
= TALLOC_ARRAY(tmp_ctx
, struct epm_twr_t
, max_towers
);
2810 if (res_towers
== NULL
) {
2811 status
= NT_STATUS_NO_MEMORY
;
2814 towers
.twr
= res_towers
;
2816 entry_handle
= TALLOC_ZERO_P(tmp_ctx
, struct policy_handle
);
2817 if (entry_handle
== NULL
) {
2818 status
= NT_STATUS_NO_MEMORY
;
2822 /* ask the endpoint mapper for the port */
2824 status
= rpccli_epm_Map(epm_pipe
,
2826 CONST_DISCARD(struct GUID
*,
2827 &(abstract_syntax
->uuid
)),
2834 if (!NT_STATUS_IS_OK(status
)) {
2838 if (num_towers
!= 1) {
2839 status
= NT_STATUS_UNSUCCESSFUL
;
2843 /* extract the port from the answer */
2845 status
= dcerpc_binding_from_tower(tmp_ctx
,
2846 &(towers
.twr
->tower
),
2848 if (!NT_STATUS_IS_OK(status
)) {
2852 /* are further checks here necessary? */
2853 if (res_binding
->transport
!= NCACN_IP_TCP
) {
2854 status
= NT_STATUS_UNSUCCESSFUL
;
2858 *pport
= (uint16_t)atoi(res_binding
->endpoint
);
2861 TALLOC_FREE(tmp_ctx
);
2866 * Create a rpc pipe client struct, connecting to a host via tcp.
2867 * The port is determined by asking the endpoint mapper on the given
2870 NTSTATUS
rpc_pipe_open_tcp(TALLOC_CTX
*mem_ctx
, const char *host
,
2871 const struct ndr_syntax_id
*abstract_syntax
,
2872 struct rpc_pipe_client
**presult
)
2879 status
= rpc_pipe_get_tcp_port(host
, abstract_syntax
, &port
);
2880 if (!NT_STATUS_IS_OK(status
)) {
2884 status
= rpc_pipe_open_tcp_port(mem_ctx
, host
, port
,
2885 abstract_syntax
, presult
);
2891 /********************************************************************
2892 Create a rpc pipe client struct, connecting to a unix domain socket
2893 ********************************************************************/
2894 NTSTATUS
rpc_pipe_open_ncalrpc(TALLOC_CTX
*mem_ctx
, const char *socket_path
,
2895 const struct ndr_syntax_id
*abstract_syntax
,
2896 struct rpc_pipe_client
**presult
)
2898 struct rpc_pipe_client
*result
;
2899 struct sockaddr_un addr
;
2902 result
= talloc_zero(mem_ctx
, struct rpc_pipe_client
);
2903 if (result
== NULL
) {
2904 return NT_STATUS_NO_MEMORY
;
2907 result
->transport_type
= NCACN_UNIX_STREAM
;
2909 result
->abstract_syntax
= *abstract_syntax
;
2910 result
->transfer_syntax
= ndr_transfer_syntax
;
2912 result
->desthost
= talloc_get_myname(result
);
2913 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2914 result
, "\\\\%s", result
->desthost
);
2915 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2916 status
= NT_STATUS_NO_MEMORY
;
2920 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
2921 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
2923 result
->trans
.sock
.fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
2924 if (result
->trans
.sock
.fd
== -1) {
2925 status
= map_nt_error_from_unix(errno
);
2929 talloc_set_destructor(result
, rpc_pipe_sock_destructor
);
2932 addr
.sun_family
= AF_UNIX
;
2933 strncpy(addr
.sun_path
, socket_path
, sizeof(addr
.sun_path
));
2935 if (sys_connect(result
->trans
.sock
.fd
,
2936 (struct sockaddr
*)&addr
) == -1) {
2937 DEBUG(0, ("connect(%s) failed: %s\n", socket_path
,
2939 close(result
->trans
.sock
.fd
);
2940 return map_nt_error_from_unix(errno
);
2944 return NT_STATUS_OK
;
2947 TALLOC_FREE(result
);
2952 /****************************************************************************
2953 Open a named pipe over SMB to a remote server.
2955 * CAVEAT CALLER OF THIS FUNCTION:
2956 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2957 * so be sure that this function is called AFTER any structure (vs pointer)
2958 * assignment of the cli. In particular, libsmbclient does structure
2959 * assignments of cli, which invalidates the data in the returned
2960 * rpc_pipe_client if this function is called before the structure assignment
2963 ****************************************************************************/
2965 static NTSTATUS
rpc_pipe_open_np(struct cli_state
*cli
,
2966 const struct ndr_syntax_id
*abstract_syntax
,
2967 struct rpc_pipe_client
**presult
)
2969 struct rpc_pipe_client
*result
;
2972 /* sanity check to protect against crashes */
2975 return NT_STATUS_INVALID_HANDLE
;
2978 result
= TALLOC_ZERO_P(NULL
, struct rpc_pipe_client
);
2979 if (result
== NULL
) {
2980 return NT_STATUS_NO_MEMORY
;
2983 result
->transport_type
= NCACN_NP
;
2985 result
->trans
.np
.pipe_name
= cli_get_pipe_name_from_iface(
2986 result
, cli
, abstract_syntax
);
2987 if (result
->trans
.np
.pipe_name
== NULL
) {
2988 DEBUG(1, ("Could not find pipe for interface\n"));
2989 TALLOC_FREE(result
);
2990 return NT_STATUS_INVALID_PARAMETER
;
2993 result
->trans
.np
.cli
= cli
;
2994 result
->abstract_syntax
= *abstract_syntax
;
2995 result
->transfer_syntax
= ndr_transfer_syntax
;
2996 result
->desthost
= talloc_strdup(result
, cli
->desthost
);
2997 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2998 result
, "\\\\%s", result
->desthost
);
3000 result
->max_xmit_frag
= RPC_MAX_PDU_FRAG_LEN
;
3001 result
->max_recv_frag
= RPC_MAX_PDU_FRAG_LEN
;
3003 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
3004 TALLOC_FREE(result
);
3005 return NT_STATUS_NO_MEMORY
;
3008 fnum
= cli_nt_create(cli
, result
->trans
.np
.pipe_name
,
3009 DESIRED_ACCESS_PIPE
);
3011 DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
3012 "to machine %s. Error was %s\n",
3013 result
->trans
.np
.pipe_name
, cli
->desthost
,
3015 TALLOC_FREE(result
);
3016 return cli_get_nt_error(cli
);
3019 result
->trans
.np
.fnum
= fnum
;
3021 DLIST_ADD(cli
->pipe_list
, result
);
3022 talloc_set_destructor(result
, rpc_pipe_destructor
);
3025 return NT_STATUS_OK
;
3028 /****************************************************************************
3029 Open a pipe to a remote server.
3030 ****************************************************************************/
3032 static NTSTATUS
cli_rpc_pipe_open(struct cli_state
*cli
,
3033 const struct ndr_syntax_id
*interface
,
3034 struct rpc_pipe_client
**presult
)
3036 if (ndr_syntax_id_equal(interface
, &ndr_table_drsuapi
.syntax_id
)) {
3038 * We should have a better way to figure out this drsuapi
3041 return rpc_pipe_open_tcp(NULL
, cli
->desthost
, interface
,
3045 return rpc_pipe_open_np(cli
, interface
, presult
);
3048 /****************************************************************************
3049 Open a named pipe to an SMB server and bind anonymously.
3050 ****************************************************************************/
3052 NTSTATUS
cli_rpc_pipe_open_noauth(struct cli_state
*cli
,
3053 const struct ndr_syntax_id
*interface
,
3054 struct rpc_pipe_client
**presult
)
3056 struct rpc_pipe_client
*result
;
3057 struct cli_pipe_auth_data
*auth
;
3060 status
= cli_rpc_pipe_open(cli
, interface
, &result
);
3061 if (!NT_STATUS_IS_OK(status
)) {
3065 status
= rpccli_anon_bind_data(result
, &auth
);
3066 if (!NT_STATUS_IS_OK(status
)) {
3067 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3068 nt_errstr(status
)));
3069 TALLOC_FREE(result
);
3074 * This is a bit of an abstraction violation due to the fact that an
3075 * anonymous bind on an authenticated SMB inherits the user/domain
3076 * from the enclosing SMB creds
3079 TALLOC_FREE(auth
->user_name
);
3080 TALLOC_FREE(auth
->domain
);
3082 auth
->user_name
= talloc_strdup(auth
, cli
->user_name
);
3083 auth
->domain
= talloc_strdup(auth
, cli
->domain
);
3084 auth
->user_session_key
= data_blob_talloc(auth
,
3085 cli
->user_session_key
.data
,
3086 cli
->user_session_key
.length
);
3088 if ((auth
->user_name
== NULL
) || (auth
->domain
== NULL
)) {
3089 TALLOC_FREE(result
);
3090 return NT_STATUS_NO_MEMORY
;
3093 status
= rpc_pipe_bind(result
, auth
);
3094 if (!NT_STATUS_IS_OK(status
)) {
3096 if (ndr_syntax_id_equal(interface
,
3097 &ndr_table_dssetup
.syntax_id
)) {
3098 /* non AD domains just don't have this pipe, avoid
3099 * level 0 statement in that case - gd */
3102 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3103 "%s failed with error %s\n",
3104 cli_get_pipe_name_from_iface(debug_ctx(), cli
,
3106 nt_errstr(status
) ));
3107 TALLOC_FREE(result
);
3111 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3112 "%s and bound anonymously.\n", result
->trans
.np
.pipe_name
,
3116 return NT_STATUS_OK
;
3119 /****************************************************************************
3120 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3121 ****************************************************************************/
3123 static NTSTATUS
cli_rpc_pipe_open_ntlmssp_internal(struct cli_state
*cli
,
3124 const struct ndr_syntax_id
*interface
,
3125 enum pipe_auth_type auth_type
,
3126 enum pipe_auth_level auth_level
,
3128 const char *username
,
3129 const char *password
,
3130 struct rpc_pipe_client
**presult
)
3132 struct rpc_pipe_client
*result
;
3133 struct cli_pipe_auth_data
*auth
;
3136 status
= cli_rpc_pipe_open(cli
, interface
, &result
);
3137 if (!NT_STATUS_IS_OK(status
)) {
3141 status
= rpccli_ntlmssp_bind_data(
3142 result
, auth_type
, auth_level
, domain
, username
,
3143 cli
->pwd
.null_pwd
? NULL
: password
, &auth
);
3144 if (!NT_STATUS_IS_OK(status
)) {
3145 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3146 nt_errstr(status
)));
3150 status
= rpc_pipe_bind(result
, auth
);
3151 if (!NT_STATUS_IS_OK(status
)) {
3152 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3153 nt_errstr(status
) ));
3157 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3158 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3159 result
->trans
.np
.pipe_name
, cli
->desthost
,
3160 domain
, username
));
3163 return NT_STATUS_OK
;
3167 TALLOC_FREE(result
);
3171 /****************************************************************************
3173 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3174 ****************************************************************************/
3176 NTSTATUS
cli_rpc_pipe_open_ntlmssp(struct cli_state
*cli
,
3177 const struct ndr_syntax_id
*interface
,
3178 enum pipe_auth_level auth_level
,
3180 const char *username
,
3181 const char *password
,
3182 struct rpc_pipe_client
**presult
)
3184 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3186 PIPE_AUTH_TYPE_NTLMSSP
,
3194 /****************************************************************************
3196 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3197 ****************************************************************************/
3199 NTSTATUS
cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state
*cli
,
3200 const struct ndr_syntax_id
*interface
,
3201 enum pipe_auth_level auth_level
,
3203 const char *username
,
3204 const char *password
,
3205 struct rpc_pipe_client
**presult
)
3207 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
3209 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
,
3217 /****************************************************************************
3218 Get a the schannel session key out of an already opened netlogon pipe.
3219 ****************************************************************************/
3220 static NTSTATUS
get_schannel_session_key_common(struct rpc_pipe_client
*netlogon_pipe
,
3221 struct cli_state
*cli
,
3225 uint32 sec_chan_type
= 0;
3226 unsigned char machine_pwd
[16];
3227 const char *machine_account
;
3230 /* Get the machine account credentials from secrets.tdb. */
3231 if (!get_trust_pw_hash(domain
, machine_pwd
, &machine_account
,
3234 DEBUG(0, ("get_schannel_session_key: could not fetch "
3235 "trust account password for domain '%s'\n",
3237 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3240 status
= rpccli_netlogon_setup_creds(netlogon_pipe
,
3241 cli
->desthost
, /* server name */
3242 domain
, /* domain */
3243 global_myname(), /* client name */
3244 machine_account
, /* machine account name */
3249 if (!NT_STATUS_IS_OK(status
)) {
3250 DEBUG(3, ("get_schannel_session_key_common: "
3251 "rpccli_netlogon_setup_creds failed with result %s "
3252 "to server %s, domain %s, machine account %s.\n",
3253 nt_errstr(status
), cli
->desthost
, domain
,
3258 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
3259 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3261 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3264 return NT_STATUS_OK
;;
3267 /****************************************************************************
3268 Open a netlogon pipe and get the schannel session key.
3269 Now exposed to external callers.
3270 ****************************************************************************/
3273 NTSTATUS
get_schannel_session_key(struct cli_state
*cli
,
3276 struct rpc_pipe_client
**presult
)
3278 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3281 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
.syntax_id
,
3283 if (!NT_STATUS_IS_OK(status
)) {
3287 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
3289 if (!NT_STATUS_IS_OK(status
)) {
3290 TALLOC_FREE(netlogon_pipe
);
3294 *presult
= netlogon_pipe
;
3295 return NT_STATUS_OK
;
3298 /****************************************************************************
3300 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3301 using session_key. sign and seal.
3302 ****************************************************************************/
3304 NTSTATUS
cli_rpc_pipe_open_schannel_with_key(struct cli_state
*cli
,
3305 const struct ndr_syntax_id
*interface
,
3306 enum pipe_auth_level auth_level
,
3308 const struct dcinfo
*pdc
,
3309 struct rpc_pipe_client
**presult
)
3311 struct rpc_pipe_client
*result
;
3312 struct cli_pipe_auth_data
*auth
;
3315 status
= cli_rpc_pipe_open(cli
, interface
, &result
);
3316 if (!NT_STATUS_IS_OK(status
)) {
3320 status
= rpccli_schannel_bind_data(result
, domain
, auth_level
,
3321 pdc
->sess_key
, &auth
);
3322 if (!NT_STATUS_IS_OK(status
)) {
3323 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3324 nt_errstr(status
)));
3325 TALLOC_FREE(result
);
3329 status
= rpc_pipe_bind(result
, auth
);
3330 if (!NT_STATUS_IS_OK(status
)) {
3331 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3332 "cli_rpc_pipe_bind failed with error %s\n",
3333 nt_errstr(status
) ));
3334 TALLOC_FREE(result
);
3339 * The credentials on a new netlogon pipe are the ones we are passed
3340 * in - copy them over.
3342 result
->dc
= (struct dcinfo
*)talloc_memdup(result
, pdc
, sizeof(*pdc
));
3343 if (result
->dc
== NULL
) {
3344 DEBUG(0, ("talloc failed\n"));
3345 TALLOC_FREE(result
);
3346 return NT_STATUS_NO_MEMORY
;
3349 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3351 "and bound using schannel.\n",
3352 result
->trans
.np
.pipe_name
, cli
->desthost
, domain
));
3355 return NT_STATUS_OK
;
3358 /****************************************************************************
3359 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3360 Fetch the session key ourselves using a temporary netlogon pipe. This
3361 version uses an ntlmssp auth bound netlogon pipe to get the key.
3362 ****************************************************************************/
3364 static NTSTATUS
get_schannel_session_key_auth_ntlmssp(struct cli_state
*cli
,
3366 const char *username
,
3367 const char *password
,
3369 struct rpc_pipe_client
**presult
)
3371 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3374 status
= cli_rpc_pipe_open_spnego_ntlmssp(
3375 cli
, &ndr_table_netlogon
.syntax_id
, PIPE_AUTH_LEVEL_PRIVACY
,
3376 domain
, username
, password
, &netlogon_pipe
);
3377 if (!NT_STATUS_IS_OK(status
)) {
3381 status
= get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
3383 if (!NT_STATUS_IS_OK(status
)) {
3384 TALLOC_FREE(netlogon_pipe
);
3388 *presult
= netlogon_pipe
;
3389 return NT_STATUS_OK
;
3392 /****************************************************************************
3393 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3394 Fetch the session key ourselves using a temporary netlogon pipe. This version
3395 uses an ntlmssp bind to get the session key.
3396 ****************************************************************************/
3398 NTSTATUS
cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
*cli
,
3399 const struct ndr_syntax_id
*interface
,
3400 enum pipe_auth_level auth_level
,
3402 const char *username
,
3403 const char *password
,
3404 struct rpc_pipe_client
**presult
)
3406 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
3407 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3408 struct rpc_pipe_client
*result
= NULL
;
3411 status
= get_schannel_session_key_auth_ntlmssp(
3412 cli
, domain
, username
, password
, &neg_flags
, &netlogon_pipe
);
3413 if (!NT_STATUS_IS_OK(status
)) {
3414 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3415 "key from server %s for domain %s.\n",
3416 cli
->desthost
, domain
));
3420 status
= cli_rpc_pipe_open_schannel_with_key(
3421 cli
, interface
, auth_level
, domain
, netlogon_pipe
->dc
,
3424 /* Now we've bound using the session key we can close the netlog pipe. */
3425 TALLOC_FREE(netlogon_pipe
);
3427 if (NT_STATUS_IS_OK(status
)) {
3433 /****************************************************************************
3434 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3435 Fetch the session key ourselves using a temporary netlogon pipe.
3436 ****************************************************************************/
3438 NTSTATUS
cli_rpc_pipe_open_schannel(struct cli_state
*cli
,
3439 const struct ndr_syntax_id
*interface
,
3440 enum pipe_auth_level auth_level
,
3442 struct rpc_pipe_client
**presult
)
3444 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
3445 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
3446 struct rpc_pipe_client
*result
= NULL
;
3449 status
= get_schannel_session_key(cli
, domain
, &neg_flags
,
3451 if (!NT_STATUS_IS_OK(status
)) {
3452 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3453 "key from server %s for domain %s.\n",
3454 cli
->desthost
, domain
));
3458 status
= cli_rpc_pipe_open_schannel_with_key(
3459 cli
, interface
, auth_level
, domain
, netlogon_pipe
->dc
,
3462 /* Now we've bound using the session key we can close the netlog pipe. */
3463 TALLOC_FREE(netlogon_pipe
);
3465 if (NT_STATUS_IS_OK(status
)) {
3469 return NT_STATUS_OK
;
3472 /****************************************************************************
3473 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3474 The idea is this can be called with service_princ, username and password all
3475 NULL so long as the caller has a TGT.
3476 ****************************************************************************/
3478 NTSTATUS
cli_rpc_pipe_open_krb5(struct cli_state
*cli
,
3479 const struct ndr_syntax_id
*interface
,
3480 enum pipe_auth_level auth_level
,
3481 const char *service_princ
,
3482 const char *username
,
3483 const char *password
,
3484 struct rpc_pipe_client
**presult
)
3487 struct rpc_pipe_client
*result
;
3488 struct cli_pipe_auth_data
*auth
;
3491 status
= cli_rpc_pipe_open(cli
, interface
, &result
);
3492 if (!NT_STATUS_IS_OK(status
)) {
3496 status
= rpccli_kerberos_bind_data(result
, auth_level
, service_princ
,
3497 username
, password
, &auth
);
3498 if (!NT_STATUS_IS_OK(status
)) {
3499 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3500 nt_errstr(status
)));
3501 TALLOC_FREE(result
);
3505 status
= rpc_pipe_bind(result
, auth
);
3506 if (!NT_STATUS_IS_OK(status
)) {
3507 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3508 "with error %s\n", nt_errstr(status
)));
3509 TALLOC_FREE(result
);
3514 return NT_STATUS_OK
;
3516 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3517 return NT_STATUS_NOT_IMPLEMENTED
;
3521 NTSTATUS
cli_get_session_key(TALLOC_CTX
*mem_ctx
,
3522 struct rpc_pipe_client
*cli
,
3523 DATA_BLOB
*session_key
)
3525 if (!session_key
|| !cli
) {
3526 return NT_STATUS_INVALID_PARAMETER
;
3530 return NT_STATUS_INVALID_PARAMETER
;
3533 switch (cli
->auth
->auth_type
) {
3534 case PIPE_AUTH_TYPE_SCHANNEL
:
3535 *session_key
= data_blob_talloc(mem_ctx
,
3536 cli
->auth
->a_u
.schannel_auth
->sess_key
, 16);
3538 case PIPE_AUTH_TYPE_NTLMSSP
:
3539 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
3540 *session_key
= data_blob_talloc(mem_ctx
,
3541 cli
->auth
->a_u
.ntlmssp_state
->session_key
.data
,
3542 cli
->auth
->a_u
.ntlmssp_state
->session_key
.length
);
3544 case PIPE_AUTH_TYPE_KRB5
:
3545 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
3546 *session_key
= data_blob_talloc(mem_ctx
,
3547 cli
->auth
->a_u
.kerberos_auth
->session_key
.data
,
3548 cli
->auth
->a_u
.kerberos_auth
->session_key
.length
);
3550 case PIPE_AUTH_TYPE_NONE
:
3551 *session_key
= data_blob_talloc(mem_ctx
,
3552 cli
->auth
->user_session_key
.data
,
3553 cli
->auth
->user_session_key
.length
);
3556 return NT_STATUS_NO_USER_SESSION_KEY
;
3559 return NT_STATUS_OK
;