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 2 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, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #define DBGC_CLASS DBGC_RPC_CLI
26 extern struct pipe_id_info pipe_names
[];
28 /********************************************************************
29 Map internal value to wire value.
30 ********************************************************************/
32 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type
)
36 case PIPE_AUTH_TYPE_NONE
:
37 return RPC_ANONYMOUS_AUTH_TYPE
;
39 case PIPE_AUTH_TYPE_NTLMSSP
:
40 return RPC_NTLMSSP_AUTH_TYPE
;
42 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
43 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
44 return RPC_SPNEGO_AUTH_TYPE
;
46 case PIPE_AUTH_TYPE_SCHANNEL
:
47 return RPC_SCHANNEL_AUTH_TYPE
;
49 case PIPE_AUTH_TYPE_KRB5
:
50 return RPC_KRB5_AUTH_TYPE
;
53 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
55 (unsigned int)auth_type
));
61 /********************************************************************
63 ********************************************************************/
65 static uint32
get_rpc_call_id(void)
67 static uint32 call_id
= 0;
71 /*******************************************************************
72 Use SMBreadX to get rest of one fragment's worth of rpc data.
73 Will expand the current_pdu struct to the correct size.
74 ********************************************************************/
76 static NTSTATUS
rpc_read(struct rpc_pipe_client
*cli
,
77 prs_struct
*current_pdu
,
79 uint32
*current_pdu_offset
)
81 size_t size
= (size_t)cli
->max_recv_frag
;
82 uint32 stream_offset
= 0;
85 ssize_t extra_data_size
= ((ssize_t
)*current_pdu_offset
) + ((ssize_t
)data_to_read
) - (ssize_t
)prs_data_size(current_pdu
);
87 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
88 (unsigned int)data_to_read
, (unsigned int)*current_pdu_offset
, (int)extra_data_size
));
91 * Grow the buffer if needed to accommodate the data to be read.
94 if (extra_data_size
> 0) {
95 if(!prs_force_grow(current_pdu
, (uint32
)extra_data_size
)) {
96 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size
));
97 return NT_STATUS_NO_MEMORY
;
99 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size
, prs_data_size(current_pdu
) ));
102 pdata
= prs_data_p(current_pdu
) + *current_pdu_offset
;
105 /* read data using SMBreadX */
106 if (size
> (size_t)data_to_read
) {
107 size
= (size_t)data_to_read
;
110 num_read
= cli_read(cli
->cli
, cli
->fnum
, pdata
,
111 (off_t
)stream_offset
, size
);
113 DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
114 (int)num_read
, (unsigned int)stream_offset
, (unsigned int)data_to_read
));
117 * A dos error of ERRDOS/ERRmoredata is not an error.
119 if (cli_is_dos_error(cli
->cli
)) {
122 cli_dos_error(cli
->cli
, &eclass
, &ecode
);
123 if (eclass
!= ERRDOS
&& ecode
!= ERRmoredata
) {
124 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
125 eclass
, (unsigned int)ecode
,
126 cli_errstr(cli
->cli
),
128 return dos_to_ntstatus(eclass
, ecode
);
133 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
135 if (cli_is_nt_error(cli
->cli
)) {
136 if (!NT_STATUS_EQUAL(cli_nt_error(cli
->cli
), NT_STATUS_BUFFER_TOO_SMALL
)) {
137 DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
138 nt_errstr(cli_nt_error(cli
->cli
)),
140 return cli_nt_error(cli
->cli
);
144 if (num_read
== -1) {
145 DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
147 return cli_get_nt_error(cli
->cli
);
150 data_to_read
-= num_read
;
151 stream_offset
+= num_read
;
154 } while (num_read
> 0 && data_to_read
> 0);
155 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
158 * Update the current offset into current_pdu by the amount read.
160 *current_pdu_offset
+= stream_offset
;
164 /****************************************************************************
165 Try and get a PDU's worth of data from current_pdu. If not, then read more
167 ****************************************************************************/
169 static NTSTATUS
cli_pipe_get_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
, prs_struct
*current_pdu
)
171 NTSTATUS ret
= NT_STATUS_OK
;
172 uint32 current_pdu_len
= prs_data_size(current_pdu
);
174 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
175 if (current_pdu_len
< RPC_HEADER_LEN
) {
176 /* rpc_read expands the current_pdu struct as neccessary. */
177 ret
= rpc_read(cli
, current_pdu
, RPC_HEADER_LEN
- current_pdu_len
, ¤t_pdu_len
);
178 if (!NT_STATUS_IS_OK(ret
)) {
183 /* This next call sets the endian bit correctly in current_pdu. */
184 /* We will propagate this to rbuf later. */
185 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr
, current_pdu
, 0)) {
186 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
187 return NT_STATUS_BUFFER_TOO_SMALL
;
190 /* Ensure we have frag_len bytes of data. */
191 if (current_pdu_len
< prhdr
->frag_len
) {
192 /* rpc_read expands the current_pdu struct as neccessary. */
193 ret
= rpc_read(cli
, current_pdu
, (uint32
)prhdr
->frag_len
- current_pdu_len
, ¤t_pdu_len
);
194 if (!NT_STATUS_IS_OK(ret
)) {
199 if (current_pdu_len
< prhdr
->frag_len
) {
200 return NT_STATUS_BUFFER_TOO_SMALL
;
206 /****************************************************************************
207 NTLMSSP specific sign/seal.
208 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
209 In fact I should probably abstract these into identical pieces of code... JRA.
210 ****************************************************************************/
212 static NTSTATUS
cli_pipe_verify_ntlmssp(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
213 prs_struct
*current_pdu
,
214 uint8
*p_ss_padding_len
)
216 RPC_HDR_AUTH auth_info
;
217 uint32 save_offset
= prs_offset(current_pdu
);
218 uint32 auth_len
= prhdr
->auth_len
;
219 NTLMSSP_STATE
*ntlmssp_state
= cli
->auth
.a_u
.ntlmssp_state
;
220 unsigned char *data
= NULL
;
222 unsigned char *full_packet_data
= NULL
;
223 size_t full_packet_data_len
;
227 if (cli
->auth
.auth_level
== PIPE_AUTH_LEVEL_NONE
|| cli
->auth
.auth_level
== PIPE_AUTH_LEVEL_CONNECT
) {
231 if (!ntlmssp_state
) {
232 return NT_STATUS_INVALID_PARAMETER
;
235 /* Ensure there's enough data for an authenticated response. */
236 if ((auth_len
> RPC_MAX_SIGN_SIZE
) ||
237 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
238 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
239 (unsigned int)auth_len
));
240 return NT_STATUS_BUFFER_TOO_SMALL
;
244 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
245 * after the RPC header.
246 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
247 * functions as NTLMv2 checks the rpc headers also.
250 data
= (unsigned char *)(prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
);
251 data_len
= (size_t)(prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
);
253 full_packet_data
= (unsigned char *)prs_data_p(current_pdu
);
254 full_packet_data_len
= prhdr
->frag_len
- auth_len
;
256 /* Pull the auth header and the following data into a blob. */
257 if(!prs_set_offset(current_pdu
, RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
)) {
258 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
259 (unsigned int)RPC_HEADER_LEN
+ (unsigned int)RPC_HDR_RESP_LEN
+ (unsigned int)data_len
));
260 return NT_STATUS_BUFFER_TOO_SMALL
;
263 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
264 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
265 return NT_STATUS_BUFFER_TOO_SMALL
;
268 auth_blob
.data
= (unsigned char *)prs_data_p(current_pdu
) + prs_offset(current_pdu
);
269 auth_blob
.length
= auth_len
;
271 switch (cli
->auth
.auth_level
) {
272 case PIPE_AUTH_LEVEL_PRIVACY
:
273 /* Data is encrypted. */
274 status
= ntlmssp_unseal_packet(ntlmssp_state
,
277 full_packet_data_len
,
279 if (!NT_STATUS_IS_OK(status
)) {
280 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
281 "packet from remote machine %s on pipe %s "
282 "fnum 0x%x. Error was %s.\n",
285 (unsigned int)cli
->fnum
,
286 nt_errstr(status
) ));
290 case PIPE_AUTH_LEVEL_INTEGRITY
:
291 /* Data is signed. */
292 status
= ntlmssp_check_packet(ntlmssp_state
,
295 full_packet_data_len
,
297 if (!NT_STATUS_IS_OK(status
)) {
298 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
299 "packet from remote machine %s on pipe %s "
300 "fnum 0x%x. Error was %s.\n",
303 (unsigned int)cli
->fnum
,
304 nt_errstr(status
) ));
309 DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n",
310 cli
->auth
.auth_level
));
311 return NT_STATUS_INVALID_INFO_CLASS
;
315 * Return the current pointer to the data offset.
318 if(!prs_set_offset(current_pdu
, save_offset
)) {
319 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
320 (unsigned int)save_offset
));
321 return NT_STATUS_BUFFER_TOO_SMALL
;
325 * Remember the padding length. We must remove it from the real data
326 * stream once the sign/seal is done.
329 *p_ss_padding_len
= auth_info
.auth_pad_len
;
334 /****************************************************************************
335 schannel specific sign/seal.
336 ****************************************************************************/
338 static NTSTATUS
cli_pipe_verify_schannel(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
339 prs_struct
*current_pdu
,
340 uint8
*p_ss_padding_len
)
342 RPC_HDR_AUTH auth_info
;
343 RPC_AUTH_SCHANNEL_CHK schannel_chk
;
344 uint32 auth_len
= prhdr
->auth_len
;
345 uint32 save_offset
= prs_offset(current_pdu
);
346 struct schannel_auth_struct
*schannel_auth
= cli
->auth
.a_u
.schannel_auth
;
349 if (cli
->auth
.auth_level
== PIPE_AUTH_LEVEL_NONE
|| cli
->auth
.auth_level
== PIPE_AUTH_LEVEL_CONNECT
) {
353 if (auth_len
!= RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
) {
354 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len
));
355 return NT_STATUS_INVALID_PARAMETER
;
358 if (!schannel_auth
) {
359 return NT_STATUS_INVALID_PARAMETER
;
362 /* Ensure there's enough data for an authenticated response. */
363 if ((auth_len
> RPC_MAX_SIGN_SIZE
) ||
364 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
365 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
366 (unsigned int)auth_len
));
367 return NT_STATUS_INVALID_PARAMETER
;
370 data_len
= prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
;
372 if(!prs_set_offset(current_pdu
, RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
)) {
373 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
374 (unsigned int)RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
));
375 return NT_STATUS_BUFFER_TOO_SMALL
;
378 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
379 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
380 return NT_STATUS_BUFFER_TOO_SMALL
;
383 if (auth_info
.auth_type
!= RPC_SCHANNEL_AUTH_TYPE
) {
384 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
385 auth_info
.auth_type
));
386 return NT_STATUS_BUFFER_TOO_SMALL
;
389 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
,
390 &schannel_chk
, current_pdu
, 0)) {
391 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
392 return NT_STATUS_BUFFER_TOO_SMALL
;
395 if (!schannel_decode(schannel_auth
,
396 cli
->auth
.auth_level
,
399 prs_data_p(current_pdu
)+RPC_HEADER_LEN
+RPC_HDR_RESP_LEN
,
401 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
402 "Connection to remote machine %s "
403 "pipe %s fnum 0x%x.\n",
406 (unsigned int)cli
->fnum
));
407 return NT_STATUS_INVALID_PARAMETER
;
410 /* The sequence number gets incremented on both send and receive. */
411 schannel_auth
->seq_num
++;
414 * Return the current pointer to the data offset.
417 if(!prs_set_offset(current_pdu
, save_offset
)) {
418 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
419 (unsigned int)save_offset
));
420 return NT_STATUS_BUFFER_TOO_SMALL
;
424 * Remember the padding length. We must remove it from the real data
425 * stream once the sign/seal is done.
428 *p_ss_padding_len
= auth_info
.auth_pad_len
;
433 /****************************************************************************
434 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
435 ****************************************************************************/
437 static NTSTATUS
cli_pipe_validate_rpc_response(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
438 prs_struct
*current_pdu
,
439 uint8
*p_ss_padding_len
)
441 NTSTATUS ret
= NT_STATUS_OK
;
443 /* Paranioa checks for auth_len. */
444 if (prhdr
->auth_len
) {
445 if (prhdr
->auth_len
> prhdr
->frag_len
) {
446 return NT_STATUS_INVALID_PARAMETER
;
449 if (prhdr
->auth_len
+ RPC_HDR_AUTH_LEN
< prhdr
->auth_len
||
450 prhdr
->auth_len
+ RPC_HDR_AUTH_LEN
< RPC_HDR_AUTH_LEN
) {
451 /* Integer wrap attempt. */
452 return NT_STATUS_INVALID_PARAMETER
;
457 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
460 switch(cli
->auth
.auth_type
) {
461 case PIPE_AUTH_TYPE_NONE
:
462 if (prhdr
->auth_len
) {
463 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
464 "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
467 (unsigned int)cli
->fnum
,
468 (unsigned int)prhdr
->auth_len
));
469 return NT_STATUS_INVALID_PARAMETER
;
473 case PIPE_AUTH_TYPE_NTLMSSP
:
474 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
475 ret
= cli_pipe_verify_ntlmssp(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
476 if (!NT_STATUS_IS_OK(ret
)) {
481 case PIPE_AUTH_TYPE_SCHANNEL
:
482 ret
= cli_pipe_verify_schannel(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
483 if (!NT_STATUS_IS_OK(ret
)) {
488 case PIPE_AUTH_TYPE_KRB5
:
489 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
491 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
492 "pipe %s fnum %x - unknown internal auth type %u.\n",
495 (unsigned int)cli
->fnum
,
496 cli
->auth
.auth_type
));
497 return NT_STATUS_INVALID_INFO_CLASS
;
503 /****************************************************************************
504 Do basic authentication checks on an incoming pdu.
505 ****************************************************************************/
507 static NTSTATUS
cli_pipe_validate_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
508 prs_struct
*current_pdu
,
509 uint8 expected_pkt_type
,
512 prs_struct
*return_data
)
515 NTSTATUS ret
= NT_STATUS_OK
;
516 uint32 current_pdu_len
= prs_data_size(current_pdu
);
518 if (current_pdu_len
!= prhdr
->frag_len
) {
519 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
520 (unsigned int)current_pdu_len
, (unsigned int)prhdr
->frag_len
));
521 return NT_STATUS_INVALID_PARAMETER
;
525 * Point the return values at the real data including the RPC
526 * header. Just in case the caller wants it.
528 *ppdata
= prs_data_p(current_pdu
);
529 *pdata_len
= current_pdu_len
;
531 /* Ensure we have the correct type. */
532 switch (prhdr
->pkt_type
) {
533 case RPC_ALTCONTRESP
:
536 /* Alter context and bind ack share the same packet definitions. */
542 RPC_HDR_RESP rhdr_resp
;
543 uint8 ss_padding_len
= 0;
545 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
546 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
547 return NT_STATUS_BUFFER_TOO_SMALL
;
550 /* Here's where we deal with incoming sign/seal. */
551 ret
= cli_pipe_validate_rpc_response(cli
, prhdr
,
552 current_pdu
, &ss_padding_len
);
553 if (!NT_STATUS_IS_OK(ret
)) {
557 /* Point the return values at the NDR data. Remember to remove any ss padding. */
558 *ppdata
= prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
560 if (current_pdu_len
< RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ ss_padding_len
) {
561 return NT_STATUS_BUFFER_TOO_SMALL
;
564 *pdata_len
= current_pdu_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- ss_padding_len
;
566 /* Remember to remove the auth footer. */
567 if (prhdr
->auth_len
) {
568 /* We've already done integer wrap tests on auth_len in
569 cli_pipe_validate_rpc_response(). */
570 if (*pdata_len
< RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
) {
571 return NT_STATUS_BUFFER_TOO_SMALL
;
573 *pdata_len
-= (RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
);
576 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
577 current_pdu_len
, *pdata_len
, ss_padding_len
));
580 * If this is the first reply, and the allocation hint is reasonably, try and
581 * set up the return_data parse_struct to the correct size.
584 if ((prs_data_size(return_data
) == 0) && rhdr_resp
.alloc_hint
&& (rhdr_resp
.alloc_hint
< 15*1024*1024)) {
585 if (!prs_set_buffer_size(return_data
, rhdr_resp
.alloc_hint
)) {
586 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
587 "too large to allocate\n",
588 (unsigned int)rhdr_resp
.alloc_hint
));
589 return NT_STATUS_NO_MEMORY
;
597 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
598 "pipe %s fnum 0x%x!\n",
601 (unsigned int)cli
->fnum
));
602 /* Use this for now... */
603 return NT_STATUS_NETWORK_ACCESS_DENIED
;
607 RPC_HDR_RESP rhdr_resp
;
608 RPC_HDR_FAULT fault_resp
;
610 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
611 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
612 return NT_STATUS_BUFFER_TOO_SMALL
;
615 if(!smb_io_rpc_hdr_fault("fault", &fault_resp
, current_pdu
, 0)) {
616 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
617 return NT_STATUS_BUFFER_TOO_SMALL
;
620 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
621 "pipe %s fnum 0x%x!\n",
622 nt_errstr(fault_resp
.status
),
625 (unsigned int)cli
->fnum
));
626 if (NT_STATUS_IS_OK(fault_resp
.status
)) {
627 return NT_STATUS_UNSUCCESSFUL
;
629 return fault_resp
.status
;
635 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
636 "from remote machine %s pipe %s fnum 0x%x!\n",
637 (unsigned int)prhdr
->pkt_type
,
640 (unsigned int)cli
->fnum
));
641 return NT_STATUS_INVALID_INFO_CLASS
;
644 if (prhdr
->pkt_type
!= expected_pkt_type
) {
645 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
646 "pipe %s fnum %x got an unexpected RPC packet "
647 "type - %u, not %u\n",
650 (unsigned int)cli
->fnum
,
653 return NT_STATUS_INVALID_INFO_CLASS
;
656 /* Do this just before return - we don't want to modify any rpc header
657 data before now as we may have needed to do cryptographic actions on
660 if ((prhdr
->pkt_type
== RPC_BINDACK
) && !(prhdr
->flags
& RPC_FLG_LAST
)) {
661 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
662 "setting fragment first/last ON.\n"));
663 prhdr
->flags
|= RPC_FLG_FIRST
|RPC_FLG_LAST
;
669 /****************************************************************************
670 Ensure we eat the just processed pdu from the current_pdu prs_struct.
671 Normally the frag_len and buffer size will match, but on the first trans
672 reply there is a theoretical chance that buffer size > frag_len, so we must
674 ****************************************************************************/
676 static NTSTATUS
cli_pipe_reset_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
, prs_struct
*current_pdu
)
678 uint32 current_pdu_len
= prs_data_size(current_pdu
);
680 if (current_pdu_len
< prhdr
->frag_len
) {
681 return NT_STATUS_BUFFER_TOO_SMALL
;
685 if (current_pdu_len
== (uint32
)prhdr
->frag_len
) {
686 prs_mem_free(current_pdu
);
687 prs_init(current_pdu
, 0, prs_get_mem_context(current_pdu
), UNMARSHALL
);
688 /* Make current_pdu dynamic with no memory. */
689 prs_give_memory(current_pdu
, 0, 0, True
);
694 * Oh no ! More data in buffer than we processed in current pdu.
695 * Cheat. Move the data down and shrink the buffer.
698 memcpy(prs_data_p(current_pdu
), prs_data_p(current_pdu
) + prhdr
->frag_len
,
699 current_pdu_len
- prhdr
->frag_len
);
701 /* Remember to set the read offset back to zero. */
702 prs_set_offset(current_pdu
, 0);
704 /* Shrink the buffer. */
705 if (!prs_set_buffer_size(current_pdu
, current_pdu_len
- prhdr
->frag_len
)) {
706 return NT_STATUS_BUFFER_TOO_SMALL
;
712 /****************************************************************************
713 Send data on an rpc pipe via trans. The prs_struct data must be the last
714 pdu fragment of an NDR data stream.
716 Receive response data from an rpc pipe, which may be large...
718 Read the first fragment: unfortunately have to use SMBtrans for the first
719 bit, then SMBreadX for subsequent bits.
721 If first fragment received also wasn't the last fragment, continue
722 getting fragments until we _do_ receive the last fragment.
724 Request/Response PDU's look like the following...
726 |<------------------PDU len----------------------------------------------->|
727 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
729 +------------+-----------------+-------------+---------------+-------------+
730 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
731 +------------+-----------------+-------------+---------------+-------------+
733 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
734 signing & sealing being negotiated.
736 ****************************************************************************/
738 static NTSTATUS
rpc_api_pipe(struct rpc_pipe_client
*cli
,
739 prs_struct
*data
, /* Outgoing pdu fragment, already formatted for send. */
740 prs_struct
*rbuf
, /* Incoming reply - return as an NDR stream. */
741 uint8 expected_pkt_type
)
743 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
745 uint32 rparam_len
= 0;
747 char *pdata
= prs_data_p(data
);
748 uint32 data_len
= prs_offset(data
);
750 uint32 rdata_len
= 0;
751 uint32 max_data
= cli
->max_xmit_frag
? cli
->max_xmit_frag
: RPC_MAX_PDU_FRAG_LEN
;
752 uint32 current_rbuf_offset
= 0;
753 prs_struct current_pdu
;
756 /* Ensure we're not sending too much. */
757 SMB_ASSERT(data_len
<= max_data
);
760 /* Set up the current pdu parse struct. */
761 prs_init(¤t_pdu
, 0, prs_get_mem_context(rbuf
), UNMARSHALL
);
763 /* Create setup parameters - must be in native byte order. */
764 setup
[0] = TRANSACT_DCERPCCMD
;
765 setup
[1] = cli
->fnum
; /* Pipe file handle. */
767 DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
770 (unsigned int)cli
->fnum
));
773 * Send the last (or only) fragment of an RPC request. For small
774 * amounts of data (about 1024 bytes or so) the RPC request and response
775 * appears in a SMBtrans request and response.
778 if (!cli_api_pipe(cli
->cli
, "\\PIPE\\",
779 setup
, 2, 0, /* Setup, length, max */
780 NULL
, 0, 0, /* Params, length, max */
781 pdata
, data_len
, max_data
, /* data, length, max */
782 &rparam
, &rparam_len
, /* return params, len */
783 &prdata
, &rdata_len
)) /* return data, len */
785 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x"
786 "returned critical error. Error was %s\n",
789 (unsigned int)cli
->fnum
,
790 cli_errstr(cli
->cli
)));
791 ret
= cli_get_nt_error(cli
->cli
);
797 /* Throw away returned params - we know we won't use them. */
801 if (prdata
== NULL
) {
802 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
803 "fnum 0x%x failed to return data.\n",
806 (unsigned int)cli
->fnum
));
807 /* Yes - some calls can truely return no data... */
808 prs_mem_free(¤t_pdu
);
813 * Give this memory as dynamic to the current pdu.
816 prs_give_memory(¤t_pdu
, prdata
, rdata_len
, True
);
818 /* Ensure we can mess with the return prs_struct. */
819 SMB_ASSERT(UNMARSHALLING(rbuf
));
820 SMB_ASSERT(prs_data_size(rbuf
) == 0);
822 /* Make rbuf dynamic with no memory. */
823 prs_give_memory(rbuf
, 0, 0, True
);
830 /* Ensure we have enough data for a pdu. */
831 ret
= cli_pipe_get_current_pdu(cli
, &rhdr
, ¤t_pdu
);
832 if (!NT_STATUS_IS_OK(ret
)) {
836 /* We pass in rbuf here so if the alloc hint is set correctly
837 we can set the output size and avoid reallocs. */
839 ret
= cli_pipe_validate_current_pdu(cli
, &rhdr
, ¤t_pdu
, expected_pkt_type
,
840 &ret_data
, &ret_data_len
, rbuf
);
842 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
843 prs_data_size(¤t_pdu
), current_rbuf_offset
));
845 if (!NT_STATUS_IS_OK(ret
)) {
849 if ((rhdr
.flags
& RPC_FLG_FIRST
)) {
850 if (rhdr
.pack_type
[0] == 0) {
851 /* Set the data type correctly for big-endian data on the first packet. */
852 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
853 "PDU data format is big-endian.\n",
856 (unsigned int)cli
->fnum
));
858 prs_set_endian_data(rbuf
, RPC_BIG_ENDIAN
);
860 /* Check endianness on subsequent packets. */
861 if (current_pdu
.bigendian_data
!= rbuf
->bigendian_data
) {
862 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
863 rbuf
->bigendian_data
? "big" : "little",
864 current_pdu
.bigendian_data
? "big" : "little" ));
865 ret
= NT_STATUS_INVALID_PARAMETER
;
871 /* Now copy the data portion out of the pdu into rbuf. */
872 if (!prs_force_grow(rbuf
, ret_data_len
)) {
873 ret
= NT_STATUS_NO_MEMORY
;
876 memcpy(prs_data_p(rbuf
)+current_rbuf_offset
, ret_data
, (size_t)ret_data_len
);
877 current_rbuf_offset
+= ret_data_len
;
879 /* See if we've finished with all the data in current_pdu yet ? */
880 ret
= cli_pipe_reset_current_pdu(cli
, &rhdr
, ¤t_pdu
);
881 if (!NT_STATUS_IS_OK(ret
)) {
885 if (rhdr
.flags
& RPC_FLG_LAST
) {
886 break; /* We're done. */
890 DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
893 (unsigned int)cli
->fnum
,
894 (unsigned int)prs_data_size(rbuf
) ));
896 prs_mem_free(¤t_pdu
);
901 prs_mem_free(¤t_pdu
);
906 /*******************************************************************
907 Creates krb5 auth bind.
908 ********************************************************************/
910 static NTSTATUS
create_krb5_auth_bind_req( struct rpc_pipe_client
*cli
,
911 enum pipe_auth_level auth_level
,
912 RPC_HDR_AUTH
*pauth_out
,
913 prs_struct
*auth_data
)
917 struct kerberos_auth_struct
*a
= cli
->auth
.a_u
.kerberos_auth
;
918 DATA_BLOB tkt
= data_blob(NULL
, 0);
919 DATA_BLOB tkt_wrapped
= data_blob(NULL
, 0);
921 /* We may change the pad length before marshalling. */
922 init_rpc_hdr_auth(pauth_out
, RPC_KRB5_AUTH_TYPE
, (int)auth_level
, 0, 1);
924 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
925 a
->service_principal
));
927 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
929 ret
= cli_krb5_get_ticket(a
->service_principal
, 0, &tkt
,
930 &a
->session_key
, (uint32
)AP_OPTS_MUTUAL_REQUIRED
, NULL
);
933 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
935 a
->service_principal
,
936 error_message(ret
) ));
938 data_blob_free(&tkt
);
939 prs_mem_free(auth_data
);
940 return NT_STATUS_INVALID_PARAMETER
;
943 /* wrap that up in a nice GSS-API wrapping */
944 tkt_wrapped
= spnego_gen_krb5_wrap(tkt
, TOK_ID_KRB_AP_REQ
);
946 data_blob_free(&tkt
);
948 /* Auth len in the rpc header doesn't include auth_header. */
949 if (!prs_copy_data_in(auth_data
, (char *)tkt_wrapped
.data
, tkt_wrapped
.length
)) {
950 data_blob_free(&tkt_wrapped
);
951 prs_mem_free(auth_data
);
952 return NT_STATUS_NO_MEMORY
;
955 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
956 dump_data(5, (const char *)tkt_wrapped
.data
, tkt_wrapped
.length
);
958 data_blob_free(&tkt_wrapped
);
961 return NT_STATUS_INVALID_PARAMETER
;
965 /*******************************************************************
966 Creates SPNEGO NTLMSSP auth bind.
967 ********************************************************************/
969 static NTSTATUS
create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
970 enum pipe_auth_level auth_level
,
971 RPC_HDR_AUTH
*pauth_out
,
972 prs_struct
*auth_data
)
975 DATA_BLOB null_blob
= data_blob(NULL
, 0);
976 DATA_BLOB request
= data_blob(NULL
, 0);
977 DATA_BLOB spnego_msg
= data_blob(NULL
, 0);
979 /* We may change the pad length before marshalling. */
980 init_rpc_hdr_auth(pauth_out
, RPC_SPNEGO_AUTH_TYPE
, (int)auth_level
, 0, 1);
982 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
983 nt_status
= ntlmssp_update(cli
->auth
.a_u
.ntlmssp_state
,
987 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
988 data_blob_free(&request
);
989 prs_mem_free(auth_data
);
993 /* Wrap this in SPNEGO. */
994 spnego_msg
= gen_negTokenInit(OID_NTLMSSP
, request
);
996 data_blob_free(&request
);
998 /* Auth len in the rpc header doesn't include auth_header. */
999 if (!prs_copy_data_in(auth_data
, (char *)spnego_msg
.data
, spnego_msg
.length
)) {
1000 data_blob_free(&spnego_msg
);
1001 prs_mem_free(auth_data
);
1002 return NT_STATUS_NO_MEMORY
;
1005 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1006 dump_data(5, (const char *)spnego_msg
.data
, spnego_msg
.length
);
1008 data_blob_free(&spnego_msg
);
1009 return NT_STATUS_OK
;
1012 /*******************************************************************
1013 Creates NTLMSSP auth bind.
1014 ********************************************************************/
1016 static NTSTATUS
create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1017 enum pipe_auth_level auth_level
,
1018 RPC_HDR_AUTH
*pauth_out
,
1019 prs_struct
*auth_data
)
1022 DATA_BLOB null_blob
= data_blob(NULL
, 0);
1023 DATA_BLOB request
= data_blob(NULL
, 0);
1025 /* We may change the pad length before marshalling. */
1026 init_rpc_hdr_auth(pauth_out
, RPC_NTLMSSP_AUTH_TYPE
, (int)auth_level
, 0, 1);
1028 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1029 nt_status
= ntlmssp_update(cli
->auth
.a_u
.ntlmssp_state
,
1033 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1034 data_blob_free(&request
);
1035 prs_mem_free(auth_data
);
1039 /* Auth len in the rpc header doesn't include auth_header. */
1040 if (!prs_copy_data_in(auth_data
, (char *)request
.data
, request
.length
)) {
1041 data_blob_free(&request
);
1042 prs_mem_free(auth_data
);
1043 return NT_STATUS_NO_MEMORY
;
1046 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1047 dump_data(5, (const char *)request
.data
, request
.length
);
1049 data_blob_free(&request
);
1050 return NT_STATUS_OK
;
1053 /*******************************************************************
1054 Creates schannel auth bind.
1055 ********************************************************************/
1057 static NTSTATUS
create_schannel_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1058 enum pipe_auth_level auth_level
,
1059 RPC_HDR_AUTH
*pauth_out
,
1060 prs_struct
*auth_data
)
1062 RPC_AUTH_SCHANNEL_NEG schannel_neg
;
1064 /* We may change the pad length before marshalling. */
1065 init_rpc_hdr_auth(pauth_out
, RPC_SCHANNEL_AUTH_TYPE
, (int)auth_level
, 0, 1);
1067 /* Use lp_workgroup() if domain not specified */
1069 if (!cli
->domain
|| !cli
->domain
[0]) {
1070 cli
->domain
= lp_workgroup();
1073 init_rpc_auth_schannel_neg(&schannel_neg
, cli
->domain
, global_myname());
1076 * Now marshall the data into the auth parse_struct.
1079 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1080 &schannel_neg
, auth_data
, 0)) {
1081 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1082 prs_mem_free(auth_data
);
1083 return NT_STATUS_NO_MEMORY
;
1086 return NT_STATUS_OK
;
1089 /*******************************************************************
1090 Creates the internals of a DCE/RPC bind request or alter context PDU.
1091 ********************************************************************/
1093 static NTSTATUS
create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type
,
1094 prs_struct
*rpc_out
,
1096 RPC_IFACE
*abstract
,
1097 RPC_IFACE
*transfer
,
1098 RPC_HDR_AUTH
*phdr_auth
,
1099 prs_struct
*pauth_info
)
1103 RPC_CONTEXT rpc_ctx
;
1104 uint16 auth_len
= prs_offset(pauth_info
);
1105 uint8 ss_padding_len
= 0;
1106 uint16 frag_len
= 0;
1108 /* create the RPC context. */
1109 init_rpc_context(&rpc_ctx
, 0 /* context id */, abstract
, transfer
);
1111 /* create the bind request RPC_HDR_RB */
1112 init_rpc_hdr_rb(&hdr_rb
, RPC_MAX_PDU_FRAG_LEN
, RPC_MAX_PDU_FRAG_LEN
, 0x0, &rpc_ctx
);
1114 /* Start building the frag length. */
1115 frag_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1117 /* Do we need to pad ? */
1119 uint16 data_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1121 ss_padding_len
= 8 - (data_len
% 8);
1122 phdr_auth
->auth_pad_len
= ss_padding_len
;
1124 frag_len
+= RPC_HDR_AUTH_LEN
+ auth_len
+ ss_padding_len
;
1127 /* Create the request RPC_HDR */
1128 init_rpc_hdr(&hdr
, pkt_type
, RPC_FLG_FIRST
|RPC_FLG_LAST
, rpc_call_id
, frag_len
, auth_len
);
1130 /* Marshall the RPC header */
1131 if(!smb_io_rpc_hdr("hdr" , &hdr
, rpc_out
, 0)) {
1132 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1133 return NT_STATUS_NO_MEMORY
;
1136 /* Marshall the bind request data */
1137 if(!smb_io_rpc_hdr_rb("", &hdr_rb
, rpc_out
, 0)) {
1138 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1139 return NT_STATUS_NO_MEMORY
;
1143 * Grow the outgoing buffer to store any auth info.
1147 if (ss_padding_len
) {
1149 memset(pad
, '\0', 8);
1150 if (!prs_copy_data_in(rpc_out
, pad
, ss_padding_len
)) {
1151 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1152 return NT_STATUS_NO_MEMORY
;
1156 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth
, rpc_out
, 0)) {
1157 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1158 return NT_STATUS_NO_MEMORY
;
1162 if(!prs_append_prs_data( rpc_out
, pauth_info
)) {
1163 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1164 return NT_STATUS_NO_MEMORY
;
1168 return NT_STATUS_OK
;
1171 /*******************************************************************
1172 Creates a DCE/RPC bind request.
1173 ********************************************************************/
1175 static NTSTATUS
create_rpc_bind_req(struct rpc_pipe_client
*cli
,
1176 prs_struct
*rpc_out
,
1178 RPC_IFACE
*abstract
, RPC_IFACE
*transfer
,
1179 enum pipe_auth_type auth_type
,
1180 enum pipe_auth_level auth_level
)
1182 RPC_HDR_AUTH hdr_auth
;
1183 prs_struct auth_info
;
1184 NTSTATUS ret
= NT_STATUS_OK
;
1186 ZERO_STRUCT(hdr_auth
);
1187 prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
);
1189 switch (auth_type
) {
1190 case PIPE_AUTH_TYPE_SCHANNEL
:
1191 ret
= create_schannel_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1192 if (!NT_STATUS_IS_OK(ret
)) {
1193 prs_mem_free(&auth_info
);
1198 case PIPE_AUTH_TYPE_NTLMSSP
:
1199 ret
= create_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1200 if (!NT_STATUS_IS_OK(ret
)) {
1201 prs_mem_free(&auth_info
);
1206 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1207 ret
= create_spnego_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1208 if (!NT_STATUS_IS_OK(ret
)) {
1209 prs_mem_free(&auth_info
);
1214 case PIPE_AUTH_TYPE_KRB5
:
1215 ret
= create_krb5_auth_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1216 if (!NT_STATUS_IS_OK(ret
)) {
1217 prs_mem_free(&auth_info
);
1222 case PIPE_AUTH_TYPE_NONE
:
1226 /* "Can't" happen. */
1227 return NT_STATUS_INVALID_INFO_CLASS
;
1230 ret
= create_bind_or_alt_ctx_internal(RPC_BIND
,
1238 prs_mem_free(&auth_info
);
1242 /*******************************************************************
1243 Create and add the NTLMSSP sign/seal auth header and data.
1244 ********************************************************************/
1246 static NTSTATUS
add_ntlmssp_auth_footer(struct rpc_pipe_client
*cli
,
1248 uint32 ss_padding_len
,
1249 prs_struct
*outgoing_pdu
)
1251 RPC_HDR_AUTH auth_info
;
1253 DATA_BLOB auth_blob
= data_blob(NULL
, 0);
1254 uint16 data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1256 if (!cli
->auth
.a_u
.ntlmssp_state
) {
1257 return NT_STATUS_INVALID_PARAMETER
;
1260 /* Init and marshall the auth header. */
1261 init_rpc_hdr_auth(&auth_info
,
1262 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
.auth_type
),
1263 cli
->auth
.auth_level
,
1265 1 /* context id. */);
1267 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1268 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1269 data_blob_free(&auth_blob
);
1270 return NT_STATUS_NO_MEMORY
;
1273 switch (cli
->auth
.auth_level
) {
1274 case PIPE_AUTH_LEVEL_PRIVACY
:
1275 /* Data portion is encrypted. */
1276 status
= ntlmssp_seal_packet(cli
->auth
.a_u
.ntlmssp_state
,
1277 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1279 (unsigned char *)prs_data_p(outgoing_pdu
),
1280 (size_t)prs_offset(outgoing_pdu
),
1282 if (!NT_STATUS_IS_OK(status
)) {
1283 data_blob_free(&auth_blob
);
1288 case PIPE_AUTH_LEVEL_INTEGRITY
:
1289 /* Data is signed. */
1290 status
= ntlmssp_sign_packet(cli
->auth
.a_u
.ntlmssp_state
,
1291 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1293 (unsigned char *)prs_data_p(outgoing_pdu
),
1294 (size_t)prs_offset(outgoing_pdu
),
1296 if (!NT_STATUS_IS_OK(status
)) {
1297 data_blob_free(&auth_blob
);
1304 smb_panic("bad auth level");
1306 return NT_STATUS_INVALID_PARAMETER
;
1309 /* Finally marshall the blob. */
1311 if (!prs_copy_data_in(outgoing_pdu
, (const char *)auth_blob
.data
, NTLMSSP_SIG_SIZE
)) {
1312 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1313 (unsigned int)NTLMSSP_SIG_SIZE
));
1314 data_blob_free(&auth_blob
);
1315 return NT_STATUS_NO_MEMORY
;
1318 data_blob_free(&auth_blob
);
1319 return NT_STATUS_OK
;
1322 /*******************************************************************
1323 Create and add the schannel sign/seal auth header and data.
1324 ********************************************************************/
1326 static NTSTATUS
add_schannel_auth_footer(struct rpc_pipe_client
*cli
,
1328 uint32 ss_padding_len
,
1329 prs_struct
*outgoing_pdu
)
1331 RPC_HDR_AUTH auth_info
;
1332 RPC_AUTH_SCHANNEL_CHK verf
;
1333 struct schannel_auth_struct
*sas
= cli
->auth
.a_u
.schannel_auth
;
1334 char *data_p
= prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
1335 size_t data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1338 return NT_STATUS_INVALID_PARAMETER
;
1341 /* Init and marshall the auth header. */
1342 init_rpc_hdr_auth(&auth_info
,
1343 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
.auth_type
),
1344 cli
->auth
.auth_level
,
1346 1 /* context id. */);
1348 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1349 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1350 return NT_STATUS_NO_MEMORY
;
1353 switch (cli
->auth
.auth_level
) {
1354 case PIPE_AUTH_LEVEL_PRIVACY
:
1355 case PIPE_AUTH_LEVEL_INTEGRITY
:
1356 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1359 schannel_encode(sas
,
1360 cli
->auth
.auth_level
,
1361 SENDER_IS_INITIATOR
,
1371 smb_panic("bad auth level");
1373 return NT_STATUS_INVALID_PARAMETER
;
1376 /* Finally marshall the blob. */
1377 smb_io_rpc_auth_schannel_chk("",
1378 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
,
1383 return NT_STATUS_OK
;
1386 /*******************************************************************
1387 Calculate how much data we're going to send in this packet, also
1388 work out any sign/seal padding length.
1389 ********************************************************************/
1391 static uint32
calculate_data_len_tosend(struct rpc_pipe_client
*cli
,
1395 uint32
*p_ss_padding
)
1397 uint32 data_space
, data_len
;
1399 switch (cli
->auth
.auth_level
) {
1400 case PIPE_AUTH_LEVEL_NONE
:
1401 case PIPE_AUTH_LEVEL_CONNECT
:
1402 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
;
1403 data_len
= MIN(data_space
, data_left
);
1406 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ data_len
;
1409 case PIPE_AUTH_LEVEL_INTEGRITY
:
1410 case PIPE_AUTH_LEVEL_PRIVACY
:
1411 /* Treat the same for all authenticated rpc requests. */
1412 switch(cli
->auth
.auth_type
) {
1413 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1414 case PIPE_AUTH_TYPE_NTLMSSP
:
1415 *p_auth_len
= NTLMSSP_SIG_SIZE
;
1417 case PIPE_AUTH_TYPE_SCHANNEL
:
1418 *p_auth_len
= RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
;
1421 smb_panic("bad auth type");
1425 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
-
1426 RPC_HDR_AUTH_LEN
- *p_auth_len
;
1428 data_len
= MIN(data_space
, data_left
);
1430 *p_ss_padding
= 8 - (data_len
% 8);
1432 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ /* Normal headers. */
1433 data_len
+ *p_ss_padding
+ /* data plus padding. */
1434 RPC_HDR_AUTH_LEN
+ *p_auth_len
; /* Auth header and auth data. */
1438 smb_panic("bad auth level");
1444 /*******************************************************************
1446 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1447 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1448 and deals with signing/sealing details.
1449 ********************************************************************/
1451 NTSTATUS
rpc_api_pipe_req(struct rpc_pipe_client
*cli
,
1453 prs_struct
*in_data
,
1454 prs_struct
*out_data
)
1457 uint32 data_left
= prs_offset(in_data
);
1458 uint32 alloc_hint
= prs_offset(in_data
);
1459 uint32 data_sent_thistime
= 0;
1460 uint32 current_data_offset
= 0;
1461 uint32 call_id
= get_rpc_call_id();
1463 prs_struct outgoing_pdu
;
1465 memset(pad
, '\0', 8);
1467 if (cli
->max_xmit_frag
< RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ RPC_MAX_SIGN_SIZE
) {
1468 /* Server is screwed up ! */
1469 return NT_STATUS_INVALID_PARAMETER
;
1472 prs_init(&outgoing_pdu
, cli
->max_xmit_frag
, prs_get_mem_context(in_data
), MARSHALL
);
1476 RPC_HDR_REQ hdr_req
;
1477 uint16 auth_len
= 0;
1478 uint16 frag_len
= 0;
1480 uint32 ss_padding
= 0;
1482 data_sent_thistime
= calculate_data_len_tosend(cli
, data_left
,
1483 &frag_len
, &auth_len
, &ss_padding
);
1485 if (current_data_offset
== 0) {
1486 flags
= RPC_FLG_FIRST
;
1489 if (data_sent_thistime
== data_left
) {
1490 flags
|= RPC_FLG_LAST
;
1493 /* Create and marshall the header and request header. */
1494 init_rpc_hdr(&hdr
, RPC_REQUEST
, flags
, call_id
, frag_len
, auth_len
);
1496 if(!smb_io_rpc_hdr("hdr ", &hdr
, &outgoing_pdu
, 0)) {
1497 prs_mem_free(&outgoing_pdu
);
1498 return NT_STATUS_NO_MEMORY
;
1501 /* Create the rpc request RPC_HDR_REQ */
1502 init_rpc_hdr_req(&hdr_req
, alloc_hint
, op_num
);
1504 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req
, &outgoing_pdu
, 0)) {
1505 prs_mem_free(&outgoing_pdu
);
1506 return NT_STATUS_NO_MEMORY
;
1509 /* Copy in the data, plus any ss padding. */
1510 if (!prs_append_some_prs_data(&outgoing_pdu
, in_data
, current_data_offset
, data_sent_thistime
)) {
1511 prs_mem_free(&outgoing_pdu
);
1512 return NT_STATUS_NO_MEMORY
;
1515 /* Copy the sign/seal padding data. */
1517 if (!prs_copy_data_in(&outgoing_pdu
, pad
, ss_padding
)) {
1518 prs_mem_free(&outgoing_pdu
);
1519 return NT_STATUS_NO_MEMORY
;
1523 /* Generate any auth sign/seal and add the auth footer. */
1525 switch (cli
->auth
.auth_type
) {
1526 case PIPE_AUTH_TYPE_NONE
:
1528 case PIPE_AUTH_TYPE_NTLMSSP
:
1529 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1530 ret
= add_ntlmssp_auth_footer(cli
, &hdr
, ss_padding
, &outgoing_pdu
);
1531 if (!NT_STATUS_IS_OK(ret
)) {
1532 prs_mem_free(&outgoing_pdu
);
1536 case PIPE_AUTH_TYPE_SCHANNEL
:
1537 ret
= add_schannel_auth_footer(cli
, &hdr
, ss_padding
, &outgoing_pdu
);
1538 if (!NT_STATUS_IS_OK(ret
)) {
1539 prs_mem_free(&outgoing_pdu
);
1544 smb_panic("bad auth type");
1545 break; /* notreached */
1549 /* Actually send the packet. */
1550 if (flags
& RPC_FLG_LAST
) {
1551 /* Last packet - send the data, get the reply and return. */
1552 ret
= rpc_api_pipe(cli
, &outgoing_pdu
, out_data
, RPC_RESPONSE
);
1553 prs_mem_free(&outgoing_pdu
);
1556 if (DEBUGLEVEL
>= 50) {
1558 /* Also capture received data */
1559 slprintf(dump_name
, sizeof(dump_name
) - 1, "%s/reply_%s_%d",
1560 dyn_LOGFILEBASE
, cli
->pipe_name
, op_num
);
1561 prs_dump(dump_name
, op_num
, out_data
);
1566 /* More packets to come - write and continue. */
1567 ssize_t num_written
= cli_write(cli
->cli
, cli
->fnum
, 8, /* 8 means message mode. */
1568 prs_data_p(&outgoing_pdu
),
1570 (size_t)hdr
.frag_len
);
1572 if (num_written
!= hdr
.frag_len
) {
1573 prs_mem_free(&outgoing_pdu
);
1574 return cli_get_nt_error(cli
->cli
);
1578 current_data_offset
+= data_sent_thistime
;
1579 data_left
-= data_sent_thistime
;
1581 /* Reset the marshalling position back to zero. */
1582 if (!prs_set_offset(&outgoing_pdu
, 0)) {
1583 prs_mem_free(&outgoing_pdu
);
1584 return NT_STATUS_NO_MEMORY
;
1589 /****************************************************************************
1590 Set the handle state.
1591 ****************************************************************************/
1593 static BOOL
rpc_pipe_set_hnd_state(struct rpc_pipe_client
*cli
,
1594 const char *pipe_name
, uint16 device_state
)
1596 BOOL state_set
= False
;
1598 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
1599 char *rparam
= NULL
;
1601 uint32 rparam_len
, rdata_len
;
1603 if (pipe_name
== NULL
)
1606 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1607 cli
->fnum
, pipe_name
, device_state
));
1609 /* create parameters: device state */
1610 SSVAL(param
, 0, device_state
);
1612 /* create setup parameters. */
1614 setup
[1] = cli
->fnum
; /* pipe file handle. got this from an SMBOpenX. */
1616 /* send the data on \PIPE\ */
1617 if (cli_api_pipe(cli
->cli
, "\\PIPE\\",
1618 setup
, 2, 0, /* setup, length, max */
1619 param
, 2, 0, /* param, length, max */
1620 NULL
, 0, 1024, /* data, length, max */
1621 &rparam
, &rparam_len
, /* return param, length */
1622 &rdata
, &rdata_len
)) /* return data, length */
1624 DEBUG(5, ("Set Handle state: return OK\n"));
1635 /****************************************************************************
1636 Check the rpc bind acknowledge response.
1637 ****************************************************************************/
1639 static BOOL
valid_pipe_name(const int pipe_idx
, RPC_IFACE
*abstract
, RPC_IFACE
*transfer
)
1641 if ( pipe_idx
>= PI_MAX_PIPES
) {
1642 DEBUG(0,("valid_pipe_name: Programmer error! Invalid pipe index [%d]\n",
1647 DEBUG(5,("Bind Abstract Syntax: "));
1648 dump_data(5, (char*)&pipe_names
[pipe_idx
].abstr_syntax
,
1649 sizeof(pipe_names
[pipe_idx
].abstr_syntax
));
1650 DEBUG(5,("Bind Transfer Syntax: "));
1651 dump_data(5, (char*)&pipe_names
[pipe_idx
].trans_syntax
,
1652 sizeof(pipe_names
[pipe_idx
].trans_syntax
));
1654 /* copy the required syntaxes out so we can do the right bind */
1656 *transfer
= pipe_names
[pipe_idx
].trans_syntax
;
1657 *abstract
= pipe_names
[pipe_idx
].abstr_syntax
;
1662 /****************************************************************************
1663 Check the rpc bind acknowledge response.
1664 ****************************************************************************/
1666 static BOOL
check_bind_response(RPC_HDR_BA
*hdr_ba
, const int pipe_idx
, RPC_IFACE
*transfer
)
1668 if ( hdr_ba
->addr
.len
== 0) {
1669 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1672 # if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */
1673 if ( !strequal(hdr_ba
->addr
.str
, pipe_names
[pipe_idx
].client_pipe
) &&
1674 !strequal(hdr_ba
->addr
.str
, pipe_names
[pipe_idx
].server_pipe
) )
1676 DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n",
1677 pipe_names
[i
].server_pipe
,hdr_ba
->addr
.str
));
1681 DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", pipe_names
[i
].server_pipe
));
1683 if (pipe_names
[pipe_idx
].server_pipe
== NULL
) {
1684 DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba
->addr
.str
));
1689 /* check the transfer syntax */
1690 if ((hdr_ba
->transfer
.version
!= transfer
->version
) ||
1691 (memcmp(&hdr_ba
->transfer
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
1692 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1696 if (hdr_ba
->res
.num_results
!= 0x1 || hdr_ba
->res
.result
!= 0) {
1697 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1698 hdr_ba
->res
.num_results
, hdr_ba
->res
.reason
));
1701 DEBUG(5,("check_bind_response: accepted!\n"));
1705 /*******************************************************************
1706 Creates a DCE/RPC bind authentication response.
1707 This is the packet that is sent back to the server once we
1708 have received a BIND-ACK, to finish the third leg of
1709 the authentication handshake.
1710 ********************************************************************/
1712 static NTSTATUS
create_rpc_bind_auth3(struct rpc_pipe_client
*cli
,
1714 enum pipe_auth_type auth_type
,
1715 enum pipe_auth_level auth_level
,
1716 DATA_BLOB
*pauth_blob
,
1717 prs_struct
*rpc_out
)
1720 RPC_HDR_AUTH hdr_auth
;
1723 /* Create the request RPC_HDR */
1724 init_rpc_hdr(&hdr
, RPC_AUTH3
, RPC_FLG_FIRST
|RPC_FLG_LAST
, rpc_call_id
,
1725 RPC_HEADER_LEN
+ 4 /* pad */ + RPC_HDR_AUTH_LEN
+ pauth_blob
->length
,
1726 pauth_blob
->length
);
1729 if(!smb_io_rpc_hdr("hdr", &hdr
, rpc_out
, 0)) {
1730 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1731 return NT_STATUS_NO_MEMORY
;
1735 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1736 about padding - shouldn't this pad to length 8 ? JRA.
1739 /* 4 bytes padding. */
1740 if (!prs_uint32("pad", rpc_out
, 0, &pad
)) {
1741 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1742 return NT_STATUS_NO_MEMORY
;
1745 /* Create the request RPC_HDR_AUTHA */
1746 init_rpc_hdr_auth(&hdr_auth
,
1747 map_pipe_auth_type_to_rpc_auth_type(auth_type
),
1750 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rpc_out
, 0)) {
1751 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1752 return NT_STATUS_NO_MEMORY
;
1756 * Append the auth data to the outgoing buffer.
1759 if(!prs_copy_data_in(rpc_out
, (char *)pauth_blob
->data
, pauth_blob
->length
)) {
1760 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1761 return NT_STATUS_NO_MEMORY
;
1764 return NT_STATUS_OK
;
1767 /****************************************************************************
1768 Create and send the third packet in an RPC auth.
1769 ****************************************************************************/
1771 static NTSTATUS
rpc_finish_auth3_bind(struct rpc_pipe_client
*cli
,
1775 enum pipe_auth_type auth_type
,
1776 enum pipe_auth_level auth_level
)
1778 DATA_BLOB server_response
= data_blob(NULL
,0);
1779 DATA_BLOB client_reply
= data_blob(NULL
,0);
1780 RPC_HDR_AUTH hdr_auth
;
1785 if (!phdr
->auth_len
|| (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
1786 return NT_STATUS_INVALID_PARAMETER
;
1789 /* Process the returned NTLMSSP blob first. */
1790 if (!prs_set_offset(rbuf
, phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
1791 return NT_STATUS_INVALID_PARAMETER
;
1794 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rbuf
, 0)) {
1795 return NT_STATUS_INVALID_PARAMETER
;
1798 /* TODO - check auth_type/auth_level match. */
1800 server_response
= data_blob(NULL
, phdr
->auth_len
);
1801 prs_copy_data_out((char *)server_response
.data
, rbuf
, phdr
->auth_len
);
1803 nt_status
= ntlmssp_update(cli
->auth
.a_u
.ntlmssp_state
,
1807 if (!NT_STATUS_IS_OK(nt_status
)) {
1808 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1812 prs_init(&rpc_out
, 0, prs_get_mem_context(rbuf
), MARSHALL
);
1814 nt_status
= create_rpc_bind_auth3(cli
, rpc_call_id
,
1815 auth_type
, auth_level
,
1816 &client_reply
, &rpc_out
);
1818 if (!NT_STATUS_IS_OK(nt_status
)) {
1819 prs_mem_free(&rpc_out
);
1820 data_blob_free(&client_reply
);
1821 data_blob_free(&server_response
);
1825 /* 8 here is named pipe message mode. */
1826 ret
= cli_write(cli
->cli
, cli
->fnum
, 0x8, prs_data_p(&rpc_out
), 0,
1827 (size_t)prs_offset(&rpc_out
));
1829 if (ret
!= (ssize_t
)prs_offset(&rpc_out
)) {
1830 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret
));
1831 prs_mem_free(&rpc_out
);
1832 data_blob_free(&client_reply
);
1833 data_blob_free(&server_response
);
1834 return cli_get_nt_error(cli
->cli
);
1837 DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
1838 "fnum 0x%x sent auth3 response ok.\n",
1841 (unsigned int)cli
->fnum
));
1843 prs_mem_free(&rpc_out
);
1844 data_blob_free(&client_reply
);
1845 data_blob_free(&server_response
);
1846 return NT_STATUS_OK
;
1849 /*******************************************************************
1850 Creates a DCE/RPC bind alter context authentication request which
1851 may contain a spnego auth blobl
1852 ********************************************************************/
1854 static NTSTATUS
create_rpc_alter_context(uint32 rpc_call_id
,
1855 RPC_IFACE
*abstract
,
1856 RPC_IFACE
*transfer
,
1857 enum pipe_auth_level auth_level
,
1858 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
1859 prs_struct
*rpc_out
)
1861 RPC_HDR_AUTH hdr_auth
;
1862 prs_struct auth_info
;
1863 NTSTATUS ret
= NT_STATUS_OK
;
1865 ZERO_STRUCT(hdr_auth
);
1866 prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
);
1868 /* We may change the pad length before marshalling. */
1869 init_rpc_hdr_auth(&hdr_auth
, RPC_SPNEGO_AUTH_TYPE
, (int)auth_level
, 0, 1);
1871 if (pauth_blob
->length
) {
1872 if (!prs_copy_data_in(&auth_info
, (const char *)pauth_blob
->data
, pauth_blob
->length
)) {
1873 prs_mem_free(&auth_info
);
1874 return NT_STATUS_NO_MEMORY
;
1878 ret
= create_bind_or_alt_ctx_internal(RPC_ALTCONT
,
1885 prs_mem_free(&auth_info
);
1889 /*******************************************************************
1890 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1891 and gets a response.
1892 ********************************************************************/
1894 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client
*cli
,
1898 RPC_IFACE
*abstract
,
1899 RPC_IFACE
*transfer
,
1900 enum pipe_auth_type auth_type
,
1901 enum pipe_auth_level auth_level
)
1903 DATA_BLOB server_spnego_response
= data_blob(NULL
,0);
1904 DATA_BLOB server_ntlm_response
= data_blob(NULL
,0);
1905 DATA_BLOB client_reply
= data_blob(NULL
,0);
1906 DATA_BLOB tmp_blob
= data_blob(NULL
, 0);
1907 RPC_HDR_AUTH hdr_auth
;
1911 if (!phdr
->auth_len
|| (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
1912 return NT_STATUS_INVALID_PARAMETER
;
1915 /* Process the returned NTLMSSP blob first. */
1916 if (!prs_set_offset(rbuf
, phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
1917 return NT_STATUS_INVALID_PARAMETER
;
1920 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rbuf
, 0)) {
1921 return NT_STATUS_INVALID_PARAMETER
;
1924 server_spnego_response
= data_blob(NULL
, phdr
->auth_len
);
1925 prs_copy_data_out((char *)server_spnego_response
.data
, rbuf
, phdr
->auth_len
);
1927 /* The server might give us back two challenges - tmp_blob is for the second. */
1928 if (!spnego_parse_challenge(server_spnego_response
, &server_ntlm_response
, &tmp_blob
)) {
1929 data_blob_free(&server_spnego_response
);
1930 data_blob_free(&server_ntlm_response
);
1931 data_blob_free(&tmp_blob
);
1932 return NT_STATUS_INVALID_PARAMETER
;
1935 /* We're finished with the server spnego response and the tmp_blob. */
1936 data_blob_free(&server_spnego_response
);
1937 data_blob_free(&tmp_blob
);
1939 nt_status
= ntlmssp_update(cli
->auth
.a_u
.ntlmssp_state
,
1940 server_ntlm_response
,
1943 /* Finished with the server_ntlm response */
1944 data_blob_free(&server_ntlm_response
);
1946 if (!NT_STATUS_IS_OK(nt_status
)) {
1947 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
1948 data_blob_free(&client_reply
);
1952 /* SPNEGO wrap the client reply. */
1953 tmp_blob
= spnego_gen_auth(client_reply
);
1954 data_blob_free(&client_reply
);
1955 client_reply
= tmp_blob
;
1956 tmp_blob
= data_blob(NULL
,0); /* Ensure it's safe to free this just in case. */
1958 /* Now prepare the alter context pdu. */
1959 prs_init(&rpc_out
, 0, prs_get_mem_context(rbuf
), MARSHALL
);
1961 nt_status
= create_rpc_alter_context(rpc_call_id
,
1968 data_blob_free(&client_reply
);
1970 if (!NT_STATUS_IS_OK(nt_status
)) {
1971 prs_mem_free(&rpc_out
);
1975 /* Initialize the returning data struct. */
1977 prs_init(rbuf
, 0, cli
->cli
->mem_ctx
, UNMARSHALL
);
1979 nt_status
= rpc_api_pipe(cli
, &rpc_out
, rbuf
, RPC_ALTCONTRESP
);
1980 if (!NT_STATUS_IS_OK(nt_status
)) {
1981 prs_mem_free(&rpc_out
);
1985 prs_mem_free(&rpc_out
);
1987 /* Get the auth blob from the reply. */
1988 if(!smb_io_rpc_hdr("rpc_hdr ", phdr
, rbuf
, 0)) {
1989 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
1990 return NT_STATUS_BUFFER_TOO_SMALL
;
1993 if (!prs_set_offset(rbuf
, phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
1994 return NT_STATUS_INVALID_PARAMETER
;
1997 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rbuf
, 0)) {
1998 return NT_STATUS_INVALID_PARAMETER
;
2001 server_spnego_response
= data_blob(NULL
, phdr
->auth_len
);
2002 prs_copy_data_out((char *)server_spnego_response
.data
, rbuf
, phdr
->auth_len
);
2004 /* Check we got a valid auth response. */
2005 if (!spnego_parse_auth_response(server_spnego_response
, NT_STATUS_OK
, &tmp_blob
)) {
2006 data_blob_free(&server_spnego_response
);
2007 data_blob_free(&tmp_blob
);
2008 return NT_STATUS_INVALID_PARAMETER
;
2011 data_blob_free(&server_spnego_response
);
2012 data_blob_free(&tmp_blob
);
2014 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2015 "remote machine %s pipe %s fnum 0x%x.\n",
2018 (unsigned int)cli
->fnum
));
2020 return NT_STATUS_OK
;
2023 /****************************************************************************
2025 ****************************************************************************/
2027 static NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
2028 enum pipe_auth_type auth_type
,
2029 enum pipe_auth_level auth_level
)
2040 DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2041 (unsigned int)cli
->fnum
,
2043 (unsigned int)auth_type
,
2044 (unsigned int)auth_level
));
2046 if (!valid_pipe_name(cli
->pipe_idx
, &abstract
, &transfer
)) {
2047 return NT_STATUS_INVALID_PARAMETER
;
2050 prs_init(&rpc_out
, 0, cli
->cli
->mem_ctx
, MARSHALL
);
2052 rpc_call_id
= get_rpc_call_id();
2054 /* Marshall the outgoing data. */
2055 status
= create_rpc_bind_req(cli
, &rpc_out
, rpc_call_id
,
2056 &abstract
, &transfer
,
2060 if (!NT_STATUS_IS_OK(status
)) {
2061 prs_mem_free(&rpc_out
);
2065 /* Initialize the incoming data struct. */
2066 prs_init(&rbuf
, 0, cli
->cli
->mem_ctx
, UNMARSHALL
);
2068 /* send data on \PIPE\. receive a response */
2069 status
= rpc_api_pipe(cli
, &rpc_out
, &rbuf
, RPC_BINDACK
);
2070 if (!NT_STATUS_IS_OK(status
)) {
2071 prs_mem_free(&rpc_out
);
2075 prs_mem_free(&rpc_out
);
2077 DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2078 "fnum 0x%x bind request returned ok.\n",
2081 (unsigned int)cli
->fnum
));
2083 /* Unmarshall the RPC header */
2084 if(!smb_io_rpc_hdr("hdr" , &hdr
, &rbuf
, 0)) {
2085 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2086 prs_mem_free(&rbuf
);
2087 return NT_STATUS_BUFFER_TOO_SMALL
;
2090 if(!smb_io_rpc_hdr_ba("", &hdr_ba
, &rbuf
, 0)) {
2091 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2092 prs_mem_free(&rbuf
);
2093 return NT_STATUS_BUFFER_TOO_SMALL
;
2096 if(!check_bind_response(&hdr_ba
, cli
->pipe_idx
, &transfer
)) {
2097 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2098 prs_mem_free(&rbuf
);
2099 return NT_STATUS_BUFFER_TOO_SMALL
;
2102 cli
->max_xmit_frag
= hdr_ba
.bba
.max_tsize
;
2103 cli
->max_recv_frag
= hdr_ba
.bba
.max_rsize
;
2105 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2108 case PIPE_AUTH_TYPE_NONE
:
2109 case PIPE_AUTH_TYPE_SCHANNEL
:
2110 /* Bind complete. */
2113 case PIPE_AUTH_TYPE_NTLMSSP
:
2114 /* Need to send AUTH3 packet - no reply. */
2115 status
= rpc_finish_auth3_bind(cli
, &hdr
, &rbuf
, rpc_call_id
,
2116 auth_type
, auth_level
);
2117 if (!NT_STATUS_IS_OK(status
)) {
2118 prs_mem_free(&rbuf
);
2123 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2124 /* Need to send alter context request and reply. */
2125 status
= rpc_finish_spnego_ntlmssp_bind(cli
, &hdr
, &rbuf
, rpc_call_id
,
2126 &abstract
, &transfer
,
2127 auth_type
, auth_level
);
2128 if (!NT_STATUS_IS_OK(status
)) {
2129 prs_mem_free(&rbuf
);
2134 case PIPE_AUTH_TYPE_KRB5
:
2138 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2139 (unsigned int)auth_type
));
2140 prs_mem_free(&rbuf
);
2141 return NT_STATUS_INVALID_INFO_CLASS
;
2144 /* Pipe is bound - set up auth_type and auth_level data. */
2146 cli
->auth
.auth_type
= auth_type
;
2147 cli
->auth
.auth_level
= auth_level
;
2149 prs_mem_free(&rbuf
);
2150 return NT_STATUS_OK
;
2153 /****************************************************************************
2154 Open a named pipe over SMB to a remote server.
2156 * CAVEAT CALLER OF THIS FUNCTION:
2157 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2158 * so be sure that this function is called AFTER any structure (vs pointer)
2159 * assignment of the cli. In particular, libsmbclient does structure
2160 * assignments of cli, which invalidates the data in the returned
2161 * rpc_pipe_client if this function is called before the structure assignment
2164 ****************************************************************************/
2166 static struct rpc_pipe_client
*cli_rpc_pipe_open(struct cli_state
*cli
, int pipe_idx
, NTSTATUS
*perr
)
2168 TALLOC_CTX
*mem_ctx
;
2169 struct rpc_pipe_client
*result
;
2172 *perr
= NT_STATUS_NO_MEMORY
;
2174 /* The pipe name index must fall within our array */
2175 SMB_ASSERT((pipe_idx
>= 0) && (pipe_idx
< PI_MAX_PIPES
));
2177 mem_ctx
= talloc_init("struct rpc_pipe_client");
2178 if (mem_ctx
== NULL
) {
2182 result
= TALLOC_ZERO_P(mem_ctx
, struct rpc_pipe_client
);
2183 if (result
== NULL
) {
2187 result
->mem_ctx
= mem_ctx
;
2189 result
->pipe_name
= cli_get_pipe_name(pipe_idx
);
2191 fnum
= cli_nt_create(cli
, result
->pipe_name
, DESIRED_ACCESS_PIPE
);
2194 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2195 "to machine %s. Error was %s\n",
2196 result
->pipe_name
, cli
->desthost
,
2198 *perr
= cli_get_nt_error(cli
);
2199 talloc_destroy(result
->mem_ctx
);
2203 result
->fnum
= fnum
;
2205 result
->pipe_idx
= pipe_idx
;
2206 result
->auth
.auth_type
= PIPE_AUTH_TYPE_NONE
;
2207 result
->auth
.auth_level
= PIPE_AUTH_LEVEL_NONE
;
2209 if (pipe_idx
== PI_NETLOGON
) {
2210 /* Set up a netlogon credential chain for a netlogon pipe. */
2211 result
->dc
= TALLOC_ZERO_P(mem_ctx
, struct dcinfo
);
2212 if (result
->dc
== NULL
) {
2213 talloc_destroy(result
->mem_ctx
);
2218 DLIST_ADD(cli
->pipe_list
, result
);
2219 *perr
= NT_STATUS_OK
;
2224 /****************************************************************************
2225 Open a named pipe to an SMB server and bind anonymously.
2226 ****************************************************************************/
2228 struct rpc_pipe_client
*cli_rpc_pipe_open_noauth(struct cli_state
*cli
, int pipe_idx
, NTSTATUS
*perr
)
2230 struct rpc_pipe_client
*result
;
2232 result
= cli_rpc_pipe_open(cli
, pipe_idx
, perr
);
2233 if (result
== NULL
) {
2237 *perr
= rpc_pipe_bind(result
, PIPE_AUTH_TYPE_NONE
, PIPE_AUTH_LEVEL_NONE
);
2238 if (!NT_STATUS_IS_OK(*perr
)) {
2239 DEBUG(0, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2240 cli_get_pipe_name(pipe_idx
), nt_errstr(*perr
) ));
2241 cli_rpc_pipe_close(result
);
2245 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2246 result
->pipe_name
, cli
->desthost
));
2251 /****************************************************************************
2252 Free function for NTLMSSP auth.
2253 ****************************************************************************/
2255 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data
*auth
)
2257 if (auth
->a_u
.ntlmssp_state
) {
2258 ntlmssp_end(&auth
->a_u
.ntlmssp_state
);
2259 auth
->a_u
.ntlmssp_state
= NULL
;
2263 /****************************************************************************
2264 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2265 ****************************************************************************/
2267 static struct rpc_pipe_client
*cli_rpc_pipe_open_ntlmssp_internal(struct cli_state
*cli
,
2269 enum pipe_auth_type auth_type
,
2270 enum pipe_auth_level auth_level
,
2272 const char *username
,
2273 const char *password
,
2276 struct rpc_pipe_client
*result
;
2277 NTLMSSP_STATE
*ntlmssp_state
= NULL
;
2279 result
= cli_rpc_pipe_open(cli
, pipe_idx
, perr
);
2280 if (result
== NULL
) {
2284 result
->auth
.cli_auth_data_free_func
= cli_ntlmssp_auth_free
;
2286 result
->domain
= domain
;
2287 result
->user_name
= username
;
2288 pwd_set_cleartext(&result
->pwd
, password
);
2290 *perr
= ntlmssp_client_start(&ntlmssp_state
);
2291 if (!NT_STATUS_IS_OK(*perr
)) {
2295 result
->auth
.a_u
.ntlmssp_state
= ntlmssp_state
;
2297 *perr
= ntlmssp_set_username(ntlmssp_state
, cli
->user_name
);
2298 if (!NT_STATUS_IS_OK(*perr
)) {
2302 *perr
= ntlmssp_set_domain(ntlmssp_state
, cli
->domain
);
2303 if (!NT_STATUS_IS_OK(*perr
)) {
2307 if (cli
->pwd
.null_pwd
) {
2308 *perr
= ntlmssp_set_password(ntlmssp_state
, NULL
);
2309 if (!NT_STATUS_IS_OK(*perr
)) {
2313 *perr
= ntlmssp_set_password(ntlmssp_state
, password
);
2314 if (!NT_STATUS_IS_OK(*perr
)) {
2319 /* Turn off sign+seal to allow selected auth level to turn it back on. */
2320 ntlmssp_state
->neg_flags
&= ~(NTLMSSP_NEGOTIATE_SIGN
|NTLMSSP_NEGOTIATE_SEAL
);
2322 if (auth_level
== PIPE_AUTH_LEVEL_INTEGRITY
) {
2323 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
2324 } else if (auth_level
== PIPE_AUTH_LEVEL_PRIVACY
) {
2325 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SEAL
| NTLMSSP_NEGOTIATE_SIGN
;
2328 *perr
= rpc_pipe_bind(result
, auth_type
, auth_level
);
2329 if (!NT_STATUS_IS_OK(*perr
)) {
2330 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2331 nt_errstr(*perr
) ));
2335 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to machine %s and"
2336 "bound NTLMSSP as user %s\\%s.\n",
2337 result
->pipe_name
, cli
->desthost
,
2338 domain
, username
));
2344 cli_rpc_pipe_close(result
);
2348 /****************************************************************************
2350 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2351 ****************************************************************************/
2353 struct rpc_pipe_client
*cli_rpc_pipe_open_ntlmssp(struct cli_state
*cli
,
2355 enum pipe_auth_level auth_level
,
2357 const char *username
,
2358 const char *password
,
2361 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
2363 PIPE_AUTH_TYPE_NTLMSSP
,
2371 /****************************************************************************
2373 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2374 ****************************************************************************/
2376 struct rpc_pipe_client
*cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state
*cli
,
2378 enum pipe_auth_level auth_level
,
2380 const char *username
,
2381 const char *password
,
2384 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
2386 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
,
2394 /****************************************************************************
2395 Open a netlogon pipe and get the schannel session key.
2396 Now exposed to external callers.
2397 ****************************************************************************/
2399 struct rpc_pipe_client
*get_schannel_session_key(struct cli_state
*cli
,
2404 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
2405 uint32 sec_chan_type
= 0;
2406 unsigned char machine_pwd
[16];
2407 fstring machine_account
;
2409 netlogon_pipe
= cli_rpc_pipe_open_noauth(cli
, PI_NETLOGON
, perr
);
2410 if (!netlogon_pipe
) {
2414 /* Get the machine account credentials from secrets.tdb. */
2415 if (!get_trust_pw(domain
, machine_pwd
, &sec_chan_type
)) {
2416 DEBUG(0, ("get_schannel_session_key: could not fetch "
2417 "trust account password for domain '%s'\n",
2419 cli_rpc_pipe_close(netlogon_pipe
);
2420 *perr
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2424 if ( IS_DC
&& !strequal(domain
, lp_workgroup()) && lp_allow_trusted_domains()) {
2425 fstrcpy( machine_account
, lp_workgroup() );
2427 /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */
2428 if (strequal(domain
, lp_workgroup())) {
2429 fstrcpy(machine_account
, global_myname());
2431 fstrcpy(machine_account
, domain
);
2435 *perr
= rpccli_netlogon_setup_creds(netlogon_pipe
,
2436 cli
->desthost
, /* server name */
2437 domain
, /* domain */
2438 global_myname(), /* client name */
2439 machine_account
, /* machine account name */
2444 if (!NT_STATUS_IS_OK(*perr
)) {
2445 DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds "
2446 "failed with result %s to server %s, domain %s, machine account %s.\n",
2447 nt_errstr(*perr
), cli
->desthost
, domain
, machine_account
));
2448 cli_rpc_pipe_close(netlogon_pipe
);
2452 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
2453 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2455 cli_rpc_pipe_close(netlogon_pipe
);
2456 *perr
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2460 return netlogon_pipe
;
2463 /****************************************************************************
2465 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2466 using session_key. sign and seal.
2467 ****************************************************************************/
2469 struct rpc_pipe_client
*cli_rpc_pipe_open_schannel_with_key(struct cli_state
*cli
,
2471 enum pipe_auth_level auth_level
,
2473 const struct dcinfo
*pdc
,
2476 struct rpc_pipe_client
*result
;
2478 result
= cli_rpc_pipe_open(cli
, pipe_idx
, perr
);
2479 if (result
== NULL
) {
2483 result
->auth
.a_u
.schannel_auth
= TALLOC_ZERO_P(result
->mem_ctx
, struct schannel_auth_struct
);
2484 if (!result
->auth
.a_u
.schannel_auth
) {
2485 cli_rpc_pipe_close(result
);
2486 *perr
= NT_STATUS_NO_MEMORY
;
2490 result
->domain
= domain
;
2491 memcpy(result
->auth
.a_u
.schannel_auth
->sess_key
, pdc
->sess_key
, 16);
2493 *perr
= rpc_pipe_bind(result
, PIPE_AUTH_TYPE_SCHANNEL
, auth_level
);
2494 if (!NT_STATUS_IS_OK(*perr
)) {
2495 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2496 nt_errstr(*perr
) ));
2497 cli_rpc_pipe_close(result
);
2501 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2506 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2508 "and bound using schannel.\n",
2509 result
->pipe_name
, cli
->desthost
, domain
));
2514 /****************************************************************************
2515 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2516 Fetch the session key ourselves using a temporary netlogon pipe. This
2517 version uses an ntlmssp auth bound netlogon pipe to get the key.
2518 ****************************************************************************/
2520 static struct rpc_pipe_client
*get_schannel_session_key_auth_ntlmssp(struct cli_state
*cli
,
2522 const char *username
,
2523 const char *password
,
2527 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
2528 uint32 sec_chan_type
= 0;
2529 unsigned char machine_pwd
[16];
2530 fstring machine_account
;
2532 netlogon_pipe
= cli_rpc_pipe_open_spnego_ntlmssp(cli
, PI_NETLOGON
, PIPE_AUTH_LEVEL_PRIVACY
, domain
, username
, password
, perr
);
2533 if (!netlogon_pipe
) {
2537 /* Get the machine account credentials from secrets.tdb. */
2538 if (!get_trust_pw(domain
, machine_pwd
, &sec_chan_type
)) {
2539 DEBUG(0, ("get_schannel_session_key_auth_ntlmssp: could not fetch "
2540 "trust account password for domain '%s'\n",
2542 cli_rpc_pipe_close(netlogon_pipe
);
2543 *perr
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2547 /* if we are a DC and this is a trusted domain, then we need to use our
2548 domain name in the net_req_auth2() request */
2550 if ( IS_DC
&& !strequal(domain
, lp_workgroup()) && lp_allow_trusted_domains()) {
2551 fstrcpy( machine_account
, lp_workgroup() );
2553 /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */
2554 if (strequal(domain
, lp_workgroup())) {
2555 fstrcpy(machine_account
, global_myname());
2557 fstrcpy(machine_account
, domain
);
2561 *perr
= rpccli_netlogon_setup_creds(netlogon_pipe
,
2562 cli
->desthost
, /* server name */
2563 domain
, /* domain */
2564 global_myname(), /* client name */
2565 machine_account
, /* machine account name */
2570 if (!NT_STATUS_IS_OK(*perr
)) {
2571 DEBUG(3,("get_schannel_session_key_auth_ntlmssp: rpccli_netlogon_setup_creds "
2572 "failed with result %s\n",
2573 nt_errstr(*perr
) ));
2574 cli_rpc_pipe_close(netlogon_pipe
);
2578 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
2579 DEBUG(3, ("get_schannel_session_key_auth_ntlmssp: Server %s did not offer schannel\n",
2581 cli_rpc_pipe_close(netlogon_pipe
);
2582 *perr
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2586 return netlogon_pipe
;
2589 /****************************************************************************
2590 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2591 Fetch the session key ourselves using a temporary netlogon pipe. This version
2592 uses an ntlmssp bind to get the session key.
2593 ****************************************************************************/
2595 struct rpc_pipe_client
*cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
*cli
,
2597 enum pipe_auth_level auth_level
,
2599 const char *username
,
2600 const char *password
,
2603 uint32 neg_flags
= NETLOGON_NEG_AUTH2_FLAGS
|NETLOGON_NEG_SCHANNEL
;
2604 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
2605 struct rpc_pipe_client
*result
= NULL
;
2607 netlogon_pipe
= get_schannel_session_key_auth_ntlmssp(cli
, domain
, username
,
2608 password
, &neg_flags
, perr
);
2609 if (!netlogon_pipe
) {
2610 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2611 "key from server %s for domain %s.\n",
2612 cli
->desthost
, domain
));
2616 result
= cli_rpc_pipe_open_schannel_with_key(cli
, pipe_idx
,
2618 domain
, netlogon_pipe
->dc
, perr
);
2620 /* Now we've bound using the session key we can close the netlog pipe. */
2621 cli_rpc_pipe_close(netlogon_pipe
);
2626 /****************************************************************************
2627 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2628 Fetch the session key ourselves using a temporary netlogon pipe.
2629 ****************************************************************************/
2631 struct rpc_pipe_client
*cli_rpc_pipe_open_schannel(struct cli_state
*cli
,
2633 enum pipe_auth_level auth_level
,
2637 uint32 neg_flags
= NETLOGON_NEG_AUTH2_FLAGS
|NETLOGON_NEG_SCHANNEL
;
2638 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
2639 struct rpc_pipe_client
*result
= NULL
;
2641 netlogon_pipe
= get_schannel_session_key(cli
, domain
, &neg_flags
, perr
);
2642 if (!netlogon_pipe
) {
2643 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2644 "key from server %s for domain %s.\n",
2645 cli
->desthost
, domain
));
2649 result
= cli_rpc_pipe_open_schannel_with_key(cli
, pipe_idx
,
2651 domain
, netlogon_pipe
->dc
, perr
);
2653 /* Now we've bound using the session key we can close the netlog pipe. */
2654 cli_rpc_pipe_close(netlogon_pipe
);
2661 /****************************************************************************
2662 Free function for the kerberos spcific data.
2663 ****************************************************************************/
2665 static void kerberos_auth_struct_free(struct cli_pipe_auth_data
*a
)
2667 data_blob_free(&a
->a_u
.kerberos_auth
->session_key
);
2672 /****************************************************************************
2673 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2674 The idea is this can be called with service_princ, username and password all
2675 NULL so long as the caller has a TGT.
2676 ****************************************************************************/
2678 struct rpc_pipe_client
*cli_rpc_pipe_open_krb5(struct cli_state
*cli
,
2680 enum pipe_auth_level auth_level
,
2681 const char *service_princ
,
2682 const char *username
,
2683 const char *password
,
2687 struct rpc_pipe_client
*result
;
2689 result
= cli_rpc_pipe_open(cli
, pipe_idx
, perr
);
2690 if (result
== NULL
) {
2694 /* Default service principal is "host/server@realm" */
2695 if (!service_princ
) {
2696 service_princ
= talloc_asprintf(result
->mem_ctx
, "host/%s@%s",
2697 cli
->desthost
, lp_realm() );
2698 if (!service_princ
) {
2699 cli_rpc_pipe_close(result
);
2704 /* Only get a new TGT if username/password are given. */
2705 if (username
&& password
) {
2706 int ret
= kerberos_kinit_password(username
, password
, 0, NULL
, NULL
, NULL
, False
, 0);
2708 cli_rpc_pipe_close(result
);
2713 result
->auth
.a_u
.kerberos_auth
= TALLOC_ZERO_P(cli
->mem_ctx
, struct kerberos_auth_struct
);
2714 if (!result
->auth
.a_u
.kerberos_auth
) {
2715 cli_rpc_pipe_close(result
);
2716 *perr
= NT_STATUS_NO_MEMORY
;
2720 result
->auth
.a_u
.kerberos_auth
->service_principal
= service_princ
;
2721 result
->auth
.cli_auth_data_free_func
= kerberos_auth_struct_free
;
2723 *perr
= rpc_pipe_bind(result
, PIPE_AUTH_TYPE_KRB5
, auth_level
);
2724 if (!NT_STATUS_IS_OK(*perr
)) {
2725 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2726 nt_errstr(*perr
) ));
2727 cli_rpc_pipe_close(result
);
2733 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
2738 #if 0 /* Moved to libsmb/clientgen.c */
2739 /****************************************************************************
2741 Close an open named pipe over SMB. Free any authentication data.
2742 ****************************************************************************/
2744 void cli_rpc_pipe_close(struct rpc_pipe_client
*cli
)
2746 if (!cli_close(cli
->cli
, cli
->fnum
)) {
2747 DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s "
2748 "to machine %s. Error was %s\n",
2751 cli_errstr(cli
->cli
)));
2754 if (cli
->auth
.cli_auth_data_free_func
) {
2755 (*cli
->auth
.cli_auth_data_free_func
)(&cli
->auth
);
2757 DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n",
2758 cli
->pipe_name
, cli
->cli
->desthost
));
2760 DLIST_REMOVE(cli
->cli
->pipe_list
, cli
);
2761 talloc_destroy(cli
->mem_ctx
);