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/>.
23 #define DBGC_CLASS DBGC_RPC_CLI
25 extern struct pipe_id_info pipe_names
[];
27 /********************************************************************
28 Map internal value to wire value.
29 ********************************************************************/
31 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type
)
35 case PIPE_AUTH_TYPE_NONE
:
36 return RPC_ANONYMOUS_AUTH_TYPE
;
38 case PIPE_AUTH_TYPE_NTLMSSP
:
39 return RPC_NTLMSSP_AUTH_TYPE
;
41 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
42 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
43 return RPC_SPNEGO_AUTH_TYPE
;
45 case PIPE_AUTH_TYPE_SCHANNEL
:
46 return RPC_SCHANNEL_AUTH_TYPE
;
48 case PIPE_AUTH_TYPE_KRB5
:
49 return RPC_KRB5_AUTH_TYPE
;
52 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
54 (unsigned int)auth_type
));
60 /********************************************************************
62 ********************************************************************/
64 static uint32
get_rpc_call_id(void)
66 static uint32 call_id
= 0;
70 /*******************************************************************
71 Use SMBreadX to get rest of one fragment's worth of rpc data.
72 Will expand the current_pdu struct to the correct size.
73 ********************************************************************/
75 static NTSTATUS
rpc_read(struct rpc_pipe_client
*cli
,
76 prs_struct
*current_pdu
,
78 uint32
*current_pdu_offset
)
80 size_t size
= (size_t)cli
->max_recv_frag
;
81 uint32 stream_offset
= 0;
84 ssize_t extra_data_size
= ((ssize_t
)*current_pdu_offset
) + ((ssize_t
)data_to_read
) - (ssize_t
)prs_data_size(current_pdu
);
86 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
87 (unsigned int)data_to_read
, (unsigned int)*current_pdu_offset
, (int)extra_data_size
));
90 * Grow the buffer if needed to accommodate the data to be read.
93 if (extra_data_size
> 0) {
94 if(!prs_force_grow(current_pdu
, (uint32
)extra_data_size
)) {
95 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size
));
96 return NT_STATUS_NO_MEMORY
;
98 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size
, prs_data_size(current_pdu
) ));
101 pdata
= prs_data_p(current_pdu
) + *current_pdu_offset
;
104 /* read data using SMBreadX */
105 if (size
> (size_t)data_to_read
) {
106 size
= (size_t)data_to_read
;
109 num_read
= cli_read(cli
->cli
, cli
->fnum
, pdata
,
110 (off_t
)stream_offset
, size
);
112 DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
113 (int)num_read
, (unsigned int)stream_offset
, (unsigned int)data_to_read
));
116 * A dos error of ERRDOS/ERRmoredata is not an error.
118 if (cli_is_dos_error(cli
->cli
)) {
121 cli_dos_error(cli
->cli
, &eclass
, &ecode
);
122 if (eclass
!= ERRDOS
&& ecode
!= ERRmoredata
) {
123 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
124 eclass
, (unsigned int)ecode
,
125 cli_errstr(cli
->cli
),
127 return dos_to_ntstatus(eclass
, ecode
);
132 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
134 if (cli_is_nt_error(cli
->cli
)) {
135 if (!NT_STATUS_EQUAL(cli_nt_error(cli
->cli
), NT_STATUS_BUFFER_TOO_SMALL
)) {
136 DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
137 nt_errstr(cli_nt_error(cli
->cli
)),
139 return cli_nt_error(cli
->cli
);
143 if (num_read
== -1) {
144 DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
146 return cli_get_nt_error(cli
->cli
);
149 data_to_read
-= num_read
;
150 stream_offset
+= num_read
;
153 } while (num_read
> 0 && data_to_read
> 0);
154 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
157 * Update the current offset into current_pdu by the amount read.
159 *current_pdu_offset
+= stream_offset
;
163 /****************************************************************************
164 Try and get a PDU's worth of data from current_pdu. If not, then read more
166 ****************************************************************************/
168 static NTSTATUS
cli_pipe_get_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
, prs_struct
*current_pdu
)
170 NTSTATUS ret
= NT_STATUS_OK
;
171 uint32 current_pdu_len
= prs_data_size(current_pdu
);
173 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
174 if (current_pdu_len
< RPC_HEADER_LEN
) {
175 /* rpc_read expands the current_pdu struct as neccessary. */
176 ret
= rpc_read(cli
, current_pdu
, RPC_HEADER_LEN
- current_pdu_len
, ¤t_pdu_len
);
177 if (!NT_STATUS_IS_OK(ret
)) {
182 /* This next call sets the endian bit correctly in current_pdu. */
183 /* We will propagate this to rbuf later. */
184 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr
, current_pdu
, 0)) {
185 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
186 return NT_STATUS_BUFFER_TOO_SMALL
;
189 /* Ensure we have frag_len bytes of data. */
190 if (current_pdu_len
< prhdr
->frag_len
) {
191 /* rpc_read expands the current_pdu struct as neccessary. */
192 ret
= rpc_read(cli
, current_pdu
, (uint32
)prhdr
->frag_len
- current_pdu_len
, ¤t_pdu_len
);
193 if (!NT_STATUS_IS_OK(ret
)) {
198 if (current_pdu_len
< prhdr
->frag_len
) {
199 return NT_STATUS_BUFFER_TOO_SMALL
;
205 /****************************************************************************
206 NTLMSSP specific sign/seal.
207 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
208 In fact I should probably abstract these into identical pieces of code... JRA.
209 ****************************************************************************/
211 static NTSTATUS
cli_pipe_verify_ntlmssp(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
212 prs_struct
*current_pdu
,
213 uint8
*p_ss_padding_len
)
215 RPC_HDR_AUTH auth_info
;
216 uint32 save_offset
= prs_offset(current_pdu
);
217 uint32 auth_len
= prhdr
->auth_len
;
218 NTLMSSP_STATE
*ntlmssp_state
= cli
->auth
->a_u
.ntlmssp_state
;
219 unsigned char *data
= NULL
;
221 unsigned char *full_packet_data
= NULL
;
222 size_t full_packet_data_len
;
226 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_NONE
227 || 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 "
310 "auth level %d\n", 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
=
347 cli
->auth
->a_u
.schannel_auth
;
350 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_NONE
351 || cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_CONNECT
) {
355 if (auth_len
!= RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
) {
356 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len
));
357 return NT_STATUS_INVALID_PARAMETER
;
360 if (!schannel_auth
) {
361 return NT_STATUS_INVALID_PARAMETER
;
364 /* Ensure there's enough data for an authenticated response. */
365 if ((auth_len
> RPC_MAX_SIGN_SIZE
) ||
366 (RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ RPC_HDR_AUTH_LEN
+ auth_len
> prhdr
->frag_len
)) {
367 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
368 (unsigned int)auth_len
));
369 return NT_STATUS_INVALID_PARAMETER
;
372 data_len
= prhdr
->frag_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- RPC_HDR_AUTH_LEN
- auth_len
;
374 if(!prs_set_offset(current_pdu
, RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
)) {
375 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
376 (unsigned int)RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ data_len
));
377 return NT_STATUS_BUFFER_TOO_SMALL
;
380 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, current_pdu
, 0)) {
381 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
382 return NT_STATUS_BUFFER_TOO_SMALL
;
385 if (auth_info
.auth_type
!= RPC_SCHANNEL_AUTH_TYPE
) {
386 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
387 auth_info
.auth_type
));
388 return NT_STATUS_BUFFER_TOO_SMALL
;
391 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
,
392 &schannel_chk
, current_pdu
, 0)) {
393 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
394 return NT_STATUS_BUFFER_TOO_SMALL
;
397 if (!schannel_decode(schannel_auth
,
398 cli
->auth
->auth_level
,
401 prs_data_p(current_pdu
)+RPC_HEADER_LEN
+RPC_HDR_RESP_LEN
,
403 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
404 "Connection to remote machine %s "
405 "pipe %s fnum 0x%x.\n",
408 (unsigned int)cli
->fnum
));
409 return NT_STATUS_INVALID_PARAMETER
;
412 /* The sequence number gets incremented on both send and receive. */
413 schannel_auth
->seq_num
++;
416 * Return the current pointer to the data offset.
419 if(!prs_set_offset(current_pdu
, save_offset
)) {
420 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
421 (unsigned int)save_offset
));
422 return NT_STATUS_BUFFER_TOO_SMALL
;
426 * Remember the padding length. We must remove it from the real data
427 * stream once the sign/seal is done.
430 *p_ss_padding_len
= auth_info
.auth_pad_len
;
435 /****************************************************************************
436 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
437 ****************************************************************************/
439 static NTSTATUS
cli_pipe_validate_rpc_response(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
440 prs_struct
*current_pdu
,
441 uint8
*p_ss_padding_len
)
443 NTSTATUS ret
= NT_STATUS_OK
;
445 /* Paranioa checks for auth_len. */
446 if (prhdr
->auth_len
) {
447 if (prhdr
->auth_len
> prhdr
->frag_len
) {
448 return NT_STATUS_INVALID_PARAMETER
;
451 if (prhdr
->auth_len
+ RPC_HDR_AUTH_LEN
< prhdr
->auth_len
||
452 prhdr
->auth_len
+ RPC_HDR_AUTH_LEN
< RPC_HDR_AUTH_LEN
) {
453 /* Integer wrap attempt. */
454 return NT_STATUS_INVALID_PARAMETER
;
459 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
462 switch(cli
->auth
->auth_type
) {
463 case PIPE_AUTH_TYPE_NONE
:
464 if (prhdr
->auth_len
) {
465 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
466 "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
469 (unsigned int)cli
->fnum
,
470 (unsigned int)prhdr
->auth_len
));
471 return NT_STATUS_INVALID_PARAMETER
;
475 case PIPE_AUTH_TYPE_NTLMSSP
:
476 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
477 ret
= cli_pipe_verify_ntlmssp(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
478 if (!NT_STATUS_IS_OK(ret
)) {
483 case PIPE_AUTH_TYPE_SCHANNEL
:
484 ret
= cli_pipe_verify_schannel(cli
, prhdr
, current_pdu
, p_ss_padding_len
);
485 if (!NT_STATUS_IS_OK(ret
)) {
490 case PIPE_AUTH_TYPE_KRB5
:
491 case PIPE_AUTH_TYPE_SPNEGO_KRB5
:
493 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
494 "to remote machine %s pipe %s fnum %x - "
495 "unknown internal auth type %u.\n",
496 cli
->desthost
, cli
->pipe_name
,
497 (unsigned int)cli
->fnum
,
498 cli
->auth
->auth_type
));
499 return NT_STATUS_INVALID_INFO_CLASS
;
505 /****************************************************************************
506 Do basic authentication checks on an incoming pdu.
507 ****************************************************************************/
509 static NTSTATUS
cli_pipe_validate_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
,
510 prs_struct
*current_pdu
,
511 uint8 expected_pkt_type
,
514 prs_struct
*return_data
)
517 NTSTATUS ret
= NT_STATUS_OK
;
518 uint32 current_pdu_len
= prs_data_size(current_pdu
);
520 if (current_pdu_len
!= prhdr
->frag_len
) {
521 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
522 (unsigned int)current_pdu_len
, (unsigned int)prhdr
->frag_len
));
523 return NT_STATUS_INVALID_PARAMETER
;
527 * Point the return values at the real data including the RPC
528 * header. Just in case the caller wants it.
530 *ppdata
= prs_data_p(current_pdu
);
531 *pdata_len
= current_pdu_len
;
533 /* Ensure we have the correct type. */
534 switch (prhdr
->pkt_type
) {
535 case RPC_ALTCONTRESP
:
538 /* Alter context and bind ack share the same packet definitions. */
544 RPC_HDR_RESP rhdr_resp
;
545 uint8 ss_padding_len
= 0;
547 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
548 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
549 return NT_STATUS_BUFFER_TOO_SMALL
;
552 /* Here's where we deal with incoming sign/seal. */
553 ret
= cli_pipe_validate_rpc_response(cli
, prhdr
,
554 current_pdu
, &ss_padding_len
);
555 if (!NT_STATUS_IS_OK(ret
)) {
559 /* Point the return values at the NDR data. Remember to remove any ss padding. */
560 *ppdata
= prs_data_p(current_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
562 if (current_pdu_len
< RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
+ ss_padding_len
) {
563 return NT_STATUS_BUFFER_TOO_SMALL
;
566 *pdata_len
= current_pdu_len
- RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
- ss_padding_len
;
568 /* Remember to remove the auth footer. */
569 if (prhdr
->auth_len
) {
570 /* We've already done integer wrap tests on auth_len in
571 cli_pipe_validate_rpc_response(). */
572 if (*pdata_len
< RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
) {
573 return NT_STATUS_BUFFER_TOO_SMALL
;
575 *pdata_len
-= (RPC_HDR_AUTH_LEN
+ prhdr
->auth_len
);
578 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
579 current_pdu_len
, *pdata_len
, ss_padding_len
));
582 * If this is the first reply, and the allocation hint is reasonably, try and
583 * set up the return_data parse_struct to the correct size.
586 if ((prs_data_size(return_data
) == 0) && rhdr_resp
.alloc_hint
&& (rhdr_resp
.alloc_hint
< 15*1024*1024)) {
587 if (!prs_set_buffer_size(return_data
, rhdr_resp
.alloc_hint
)) {
588 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
589 "too large to allocate\n",
590 (unsigned int)rhdr_resp
.alloc_hint
));
591 return NT_STATUS_NO_MEMORY
;
599 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
600 "pipe %s fnum 0x%x!\n",
603 (unsigned int)cli
->fnum
));
604 /* Use this for now... */
605 return NT_STATUS_NETWORK_ACCESS_DENIED
;
609 RPC_HDR_RESP rhdr_resp
;
610 RPC_HDR_FAULT fault_resp
;
612 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp
, current_pdu
, 0)) {
613 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
614 return NT_STATUS_BUFFER_TOO_SMALL
;
617 if(!smb_io_rpc_hdr_fault("fault", &fault_resp
, current_pdu
, 0)) {
618 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
619 return NT_STATUS_BUFFER_TOO_SMALL
;
622 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
623 "pipe %s fnum 0x%x!\n",
624 dcerpc_errstr(NT_STATUS_V(fault_resp
.status
)),
627 (unsigned int)cli
->fnum
));
628 if (NT_STATUS_IS_OK(fault_resp
.status
)) {
629 return NT_STATUS_UNSUCCESSFUL
;
631 return fault_resp
.status
;
636 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
637 "from remote machine %s pipe %s fnum 0x%x!\n",
638 (unsigned int)prhdr
->pkt_type
,
641 (unsigned int)cli
->fnum
));
642 return NT_STATUS_INVALID_INFO_CLASS
;
645 if (prhdr
->pkt_type
!= expected_pkt_type
) {
646 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
647 "pipe %s fnum %x got an unexpected RPC packet "
648 "type - %u, not %u\n",
651 (unsigned int)cli
->fnum
,
654 return NT_STATUS_INVALID_INFO_CLASS
;
657 /* Do this just before return - we don't want to modify any rpc header
658 data before now as we may have needed to do cryptographic actions on
661 if ((prhdr
->pkt_type
== RPC_BINDACK
) && !(prhdr
->flags
& RPC_FLG_LAST
)) {
662 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
663 "setting fragment first/last ON.\n"));
664 prhdr
->flags
|= RPC_FLG_FIRST
|RPC_FLG_LAST
;
670 /****************************************************************************
671 Ensure we eat the just processed pdu from the current_pdu prs_struct.
672 Normally the frag_len and buffer size will match, but on the first trans
673 reply there is a theoretical chance that buffer size > frag_len, so we must
675 ****************************************************************************/
677 static NTSTATUS
cli_pipe_reset_current_pdu(struct rpc_pipe_client
*cli
, RPC_HDR
*prhdr
, prs_struct
*current_pdu
)
679 uint32 current_pdu_len
= prs_data_size(current_pdu
);
681 if (current_pdu_len
< prhdr
->frag_len
) {
682 return NT_STATUS_BUFFER_TOO_SMALL
;
686 if (current_pdu_len
== (uint32
)prhdr
->frag_len
) {
687 prs_mem_free(current_pdu
);
688 prs_init_empty(current_pdu
, prs_get_mem_context(current_pdu
), UNMARSHALL
);
689 /* Make current_pdu dynamic with no memory. */
690 prs_give_memory(current_pdu
, 0, 0, True
);
695 * Oh no ! More data in buffer than we processed in current pdu.
696 * Cheat. Move the data down and shrink the buffer.
699 memcpy(prs_data_p(current_pdu
), prs_data_p(current_pdu
) + prhdr
->frag_len
,
700 current_pdu_len
- prhdr
->frag_len
);
702 /* Remember to set the read offset back to zero. */
703 prs_set_offset(current_pdu
, 0);
705 /* Shrink the buffer. */
706 if (!prs_set_buffer_size(current_pdu
, current_pdu_len
- prhdr
->frag_len
)) {
707 return NT_STATUS_BUFFER_TOO_SMALL
;
713 /****************************************************************************
714 Send data on an rpc pipe via trans. The prs_struct data must be the last
715 pdu fragment of an NDR data stream.
717 Receive response data from an rpc pipe, which may be large...
719 Read the first fragment: unfortunately have to use SMBtrans for the first
720 bit, then SMBreadX for subsequent bits.
722 If first fragment received also wasn't the last fragment, continue
723 getting fragments until we _do_ receive the last fragment.
725 Request/Response PDU's look like the following...
727 |<------------------PDU len----------------------------------------------->|
728 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
730 +------------+-----------------+-------------+---------------+-------------+
731 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
732 +------------+-----------------+-------------+---------------+-------------+
734 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
735 signing & sealing being negotiated.
737 ****************************************************************************/
739 static NTSTATUS
rpc_api_pipe(struct rpc_pipe_client
*cli
,
740 prs_struct
*data
, /* Outgoing pdu fragment, already formatted for send. */
741 prs_struct
*rbuf
, /* Incoming reply - return as an NDR stream. */
742 uint8 expected_pkt_type
)
744 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
746 uint32 rparam_len
= 0;
748 char *pdata
= prs_data_p(data
);
749 uint32 data_len
= prs_offset(data
);
751 uint32 rdata_len
= 0;
752 uint32 max_data
= cli
->max_xmit_frag
? cli
->max_xmit_frag
: RPC_MAX_PDU_FRAG_LEN
;
753 uint32 current_rbuf_offset
= 0;
754 prs_struct current_pdu
;
757 /* Ensure we're not sending too much. */
758 SMB_ASSERT(data_len
<= max_data
);
761 /* Set up the current pdu parse struct. */
762 prs_init_empty(¤t_pdu
, prs_get_mem_context(rbuf
), UNMARSHALL
);
764 /* Create setup parameters - must be in native byte order. */
765 setup
[0] = TRANSACT_DCERPCCMD
;
766 setup
[1] = cli
->fnum
; /* Pipe file handle. */
768 DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
771 (unsigned int)cli
->fnum
));
774 * Send the last (or only) fragment of an RPC request. For small
775 * amounts of data (about 1024 bytes or so) the RPC request and response
776 * appears in a SMBtrans request and response.
779 if (!cli_api_pipe(cli
->cli
, "\\PIPE\\",
780 setup
, 2, 0, /* Setup, length, max */
781 NULL
, 0, 0, /* Params, length, max */
782 pdata
, data_len
, max_data
, /* data, length, max */
783 &rparam
, &rparam_len
, /* return params, len */
784 &prdata
, &rdata_len
)) /* return data, len */
786 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x "
787 "returned critical error. Error was %s\n",
790 (unsigned int)cli
->fnum
,
791 cli_errstr(cli
->cli
)));
792 ret
= cli_get_nt_error(cli
->cli
);
798 /* Throw away returned params - we know we won't use them. */
802 if (prdata
== NULL
) {
803 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
804 "fnum 0x%x failed to return data.\n",
807 (unsigned int)cli
->fnum
));
808 /* Yes - some calls can truely return no data... */
809 prs_mem_free(¤t_pdu
);
814 * Give this memory as dynamic to the current pdu.
817 prs_give_memory(¤t_pdu
, prdata
, rdata_len
, True
);
819 /* Ensure we can mess with the return prs_struct. */
820 SMB_ASSERT(UNMARSHALLING(rbuf
));
821 SMB_ASSERT(prs_data_size(rbuf
) == 0);
823 /* Make rbuf dynamic with no memory. */
824 prs_give_memory(rbuf
, 0, 0, True
);
831 /* Ensure we have enough data for a pdu. */
832 ret
= cli_pipe_get_current_pdu(cli
, &rhdr
, ¤t_pdu
);
833 if (!NT_STATUS_IS_OK(ret
)) {
837 /* We pass in rbuf here so if the alloc hint is set correctly
838 we can set the output size and avoid reallocs. */
840 ret
= cli_pipe_validate_current_pdu(cli
, &rhdr
, ¤t_pdu
, expected_pkt_type
,
841 &ret_data
, &ret_data_len
, rbuf
);
843 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
844 prs_data_size(¤t_pdu
), current_rbuf_offset
));
846 if (!NT_STATUS_IS_OK(ret
)) {
850 if ((rhdr
.flags
& RPC_FLG_FIRST
)) {
851 if (rhdr
.pack_type
[0] == 0) {
852 /* Set the data type correctly for big-endian data on the first packet. */
853 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
854 "PDU data format is big-endian.\n",
857 (unsigned int)cli
->fnum
));
859 prs_set_endian_data(rbuf
, RPC_BIG_ENDIAN
);
861 /* Check endianness on subsequent packets. */
862 if (current_pdu
.bigendian_data
!= rbuf
->bigendian_data
) {
863 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
864 rbuf
->bigendian_data
? "big" : "little",
865 current_pdu
.bigendian_data
? "big" : "little" ));
866 ret
= NT_STATUS_INVALID_PARAMETER
;
872 /* Now copy the data portion out of the pdu into rbuf. */
873 if (!prs_force_grow(rbuf
, ret_data_len
)) {
874 ret
= NT_STATUS_NO_MEMORY
;
877 memcpy(prs_data_p(rbuf
)+current_rbuf_offset
, ret_data
, (size_t)ret_data_len
);
878 current_rbuf_offset
+= ret_data_len
;
880 /* See if we've finished with all the data in current_pdu yet ? */
881 ret
= cli_pipe_reset_current_pdu(cli
, &rhdr
, ¤t_pdu
);
882 if (!NT_STATUS_IS_OK(ret
)) {
886 if (rhdr
.flags
& RPC_FLG_LAST
) {
887 break; /* We're done. */
891 DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
894 (unsigned int)cli
->fnum
,
895 (unsigned int)prs_data_size(rbuf
) ));
897 prs_mem_free(¤t_pdu
);
902 prs_mem_free(¤t_pdu
);
907 /*******************************************************************
908 Creates krb5 auth bind.
909 ********************************************************************/
911 static NTSTATUS
create_krb5_auth_bind_req( struct rpc_pipe_client
*cli
,
912 enum pipe_auth_level auth_level
,
913 RPC_HDR_AUTH
*pauth_out
,
914 prs_struct
*auth_data
)
918 struct kerberos_auth_struct
*a
= cli
->auth
->a_u
.kerberos_auth
;
919 DATA_BLOB tkt
= data_blob_null
;
920 DATA_BLOB tkt_wrapped
= data_blob_null
;
922 /* We may change the pad length before marshalling. */
923 init_rpc_hdr_auth(pauth_out
, RPC_KRB5_AUTH_TYPE
, (int)auth_level
, 0, 1);
925 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
926 a
->service_principal
));
928 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
930 ret
= cli_krb5_get_ticket(a
->service_principal
, 0, &tkt
,
931 &a
->session_key
, (uint32
)AP_OPTS_MUTUAL_REQUIRED
, NULL
, NULL
);
934 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
936 a
->service_principal
,
937 error_message(ret
) ));
939 data_blob_free(&tkt
);
940 prs_mem_free(auth_data
);
941 return NT_STATUS_INVALID_PARAMETER
;
944 /* wrap that up in a nice GSS-API wrapping */
945 tkt_wrapped
= spnego_gen_krb5_wrap(tkt
, TOK_ID_KRB_AP_REQ
);
947 data_blob_free(&tkt
);
949 /* Auth len in the rpc header doesn't include auth_header. */
950 if (!prs_copy_data_in(auth_data
, (char *)tkt_wrapped
.data
, tkt_wrapped
.length
)) {
951 data_blob_free(&tkt_wrapped
);
952 prs_mem_free(auth_data
);
953 return NT_STATUS_NO_MEMORY
;
956 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
957 dump_data(5, tkt_wrapped
.data
, tkt_wrapped
.length
);
959 data_blob_free(&tkt_wrapped
);
962 return NT_STATUS_INVALID_PARAMETER
;
966 /*******************************************************************
967 Creates SPNEGO NTLMSSP auth bind.
968 ********************************************************************/
970 static NTSTATUS
create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
971 enum pipe_auth_level auth_level
,
972 RPC_HDR_AUTH
*pauth_out
,
973 prs_struct
*auth_data
)
976 DATA_BLOB null_blob
= data_blob_null
;
977 DATA_BLOB request
= data_blob_null
;
978 DATA_BLOB spnego_msg
= data_blob_null
;
980 /* We may change the pad length before marshalling. */
981 init_rpc_hdr_auth(pauth_out
, RPC_SPNEGO_AUTH_TYPE
, (int)auth_level
, 0, 1);
983 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
984 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
988 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
989 data_blob_free(&request
);
990 prs_mem_free(auth_data
);
994 /* Wrap this in SPNEGO. */
995 spnego_msg
= gen_negTokenInit(OID_NTLMSSP
, request
);
997 data_blob_free(&request
);
999 /* Auth len in the rpc header doesn't include auth_header. */
1000 if (!prs_copy_data_in(auth_data
, (char *)spnego_msg
.data
, spnego_msg
.length
)) {
1001 data_blob_free(&spnego_msg
);
1002 prs_mem_free(auth_data
);
1003 return NT_STATUS_NO_MEMORY
;
1006 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1007 dump_data(5, spnego_msg
.data
, spnego_msg
.length
);
1009 data_blob_free(&spnego_msg
);
1010 return NT_STATUS_OK
;
1013 /*******************************************************************
1014 Creates NTLMSSP auth bind.
1015 ********************************************************************/
1017 static NTSTATUS
create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1018 enum pipe_auth_level auth_level
,
1019 RPC_HDR_AUTH
*pauth_out
,
1020 prs_struct
*auth_data
)
1023 DATA_BLOB null_blob
= data_blob_null
;
1024 DATA_BLOB request
= data_blob_null
;
1026 /* We may change the pad length before marshalling. */
1027 init_rpc_hdr_auth(pauth_out
, RPC_NTLMSSP_AUTH_TYPE
, (int)auth_level
, 0, 1);
1029 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1030 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1034 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1035 data_blob_free(&request
);
1036 prs_mem_free(auth_data
);
1040 /* Auth len in the rpc header doesn't include auth_header. */
1041 if (!prs_copy_data_in(auth_data
, (char *)request
.data
, request
.length
)) {
1042 data_blob_free(&request
);
1043 prs_mem_free(auth_data
);
1044 return NT_STATUS_NO_MEMORY
;
1047 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1048 dump_data(5, request
.data
, request
.length
);
1050 data_blob_free(&request
);
1051 return NT_STATUS_OK
;
1054 /*******************************************************************
1055 Creates schannel auth bind.
1056 ********************************************************************/
1058 static NTSTATUS
create_schannel_auth_rpc_bind_req( struct rpc_pipe_client
*cli
,
1059 enum pipe_auth_level auth_level
,
1060 RPC_HDR_AUTH
*pauth_out
,
1061 prs_struct
*auth_data
)
1063 RPC_AUTH_SCHANNEL_NEG schannel_neg
;
1065 /* We may change the pad length before marshalling. */
1066 init_rpc_hdr_auth(pauth_out
, RPC_SCHANNEL_AUTH_TYPE
, (int)auth_level
, 0, 1);
1068 /* Use lp_workgroup() if domain not specified */
1070 if (!cli
->auth
->domain
|| !cli
->auth
->domain
[0]) {
1071 cli
->auth
->domain
= talloc_strdup(cli
, lp_workgroup());
1072 if (cli
->auth
->domain
== NULL
) {
1073 return NT_STATUS_NO_MEMORY
;
1077 init_rpc_auth_schannel_neg(&schannel_neg
, cli
->auth
->domain
,
1081 * Now marshall the data into the auth parse_struct.
1084 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1085 &schannel_neg
, auth_data
, 0)) {
1086 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1087 prs_mem_free(auth_data
);
1088 return NT_STATUS_NO_MEMORY
;
1091 return NT_STATUS_OK
;
1094 /*******************************************************************
1095 Creates the internals of a DCE/RPC bind request or alter context PDU.
1096 ********************************************************************/
1098 static NTSTATUS
create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type
,
1099 prs_struct
*rpc_out
,
1101 const RPC_IFACE
*abstract
,
1102 const RPC_IFACE
*transfer
,
1103 RPC_HDR_AUTH
*phdr_auth
,
1104 prs_struct
*pauth_info
)
1108 RPC_CONTEXT rpc_ctx
;
1109 uint16 auth_len
= prs_offset(pauth_info
);
1110 uint8 ss_padding_len
= 0;
1111 uint16 frag_len
= 0;
1113 /* create the RPC context. */
1114 init_rpc_context(&rpc_ctx
, 0 /* context id */, abstract
, transfer
);
1116 /* create the bind request RPC_HDR_RB */
1117 init_rpc_hdr_rb(&hdr_rb
, RPC_MAX_PDU_FRAG_LEN
, RPC_MAX_PDU_FRAG_LEN
, 0x0, &rpc_ctx
);
1119 /* Start building the frag length. */
1120 frag_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1122 /* Do we need to pad ? */
1124 uint16 data_len
= RPC_HEADER_LEN
+ RPC_HDR_RB_LEN(&hdr_rb
);
1126 ss_padding_len
= 8 - (data_len
% 8);
1127 phdr_auth
->auth_pad_len
= ss_padding_len
;
1129 frag_len
+= RPC_HDR_AUTH_LEN
+ auth_len
+ ss_padding_len
;
1132 /* Create the request RPC_HDR */
1133 init_rpc_hdr(&hdr
, pkt_type
, RPC_FLG_FIRST
|RPC_FLG_LAST
, rpc_call_id
, frag_len
, auth_len
);
1135 /* Marshall the RPC header */
1136 if(!smb_io_rpc_hdr("hdr" , &hdr
, rpc_out
, 0)) {
1137 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1138 return NT_STATUS_NO_MEMORY
;
1141 /* Marshall the bind request data */
1142 if(!smb_io_rpc_hdr_rb("", &hdr_rb
, rpc_out
, 0)) {
1143 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1144 return NT_STATUS_NO_MEMORY
;
1148 * Grow the outgoing buffer to store any auth info.
1152 if (ss_padding_len
) {
1154 memset(pad
, '\0', 8);
1155 if (!prs_copy_data_in(rpc_out
, pad
, ss_padding_len
)) {
1156 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1157 return NT_STATUS_NO_MEMORY
;
1161 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth
, rpc_out
, 0)) {
1162 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1163 return NT_STATUS_NO_MEMORY
;
1167 if(!prs_append_prs_data( rpc_out
, pauth_info
)) {
1168 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1169 return NT_STATUS_NO_MEMORY
;
1173 return NT_STATUS_OK
;
1176 /*******************************************************************
1177 Creates a DCE/RPC bind request.
1178 ********************************************************************/
1180 static NTSTATUS
create_rpc_bind_req(struct rpc_pipe_client
*cli
,
1181 prs_struct
*rpc_out
,
1183 const RPC_IFACE
*abstract
,
1184 const RPC_IFACE
*transfer
,
1185 enum pipe_auth_type auth_type
,
1186 enum pipe_auth_level auth_level
)
1188 RPC_HDR_AUTH hdr_auth
;
1189 prs_struct auth_info
;
1190 NTSTATUS ret
= NT_STATUS_OK
;
1192 ZERO_STRUCT(hdr_auth
);
1193 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
1194 return NT_STATUS_NO_MEMORY
;
1196 switch (auth_type
) {
1197 case PIPE_AUTH_TYPE_SCHANNEL
:
1198 ret
= create_schannel_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1199 if (!NT_STATUS_IS_OK(ret
)) {
1200 prs_mem_free(&auth_info
);
1205 case PIPE_AUTH_TYPE_NTLMSSP
:
1206 ret
= create_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1207 if (!NT_STATUS_IS_OK(ret
)) {
1208 prs_mem_free(&auth_info
);
1213 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1214 ret
= create_spnego_ntlmssp_auth_rpc_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1215 if (!NT_STATUS_IS_OK(ret
)) {
1216 prs_mem_free(&auth_info
);
1221 case PIPE_AUTH_TYPE_KRB5
:
1222 ret
= create_krb5_auth_bind_req(cli
, auth_level
, &hdr_auth
, &auth_info
);
1223 if (!NT_STATUS_IS_OK(ret
)) {
1224 prs_mem_free(&auth_info
);
1229 case PIPE_AUTH_TYPE_NONE
:
1233 /* "Can't" happen. */
1234 return NT_STATUS_INVALID_INFO_CLASS
;
1237 ret
= create_bind_or_alt_ctx_internal(RPC_BIND
,
1245 prs_mem_free(&auth_info
);
1249 /*******************************************************************
1250 Create and add the NTLMSSP sign/seal auth header and data.
1251 ********************************************************************/
1253 static NTSTATUS
add_ntlmssp_auth_footer(struct rpc_pipe_client
*cli
,
1255 uint32 ss_padding_len
,
1256 prs_struct
*outgoing_pdu
)
1258 RPC_HDR_AUTH auth_info
;
1260 DATA_BLOB auth_blob
= data_blob_null
;
1261 uint16 data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1263 if (!cli
->auth
->a_u
.ntlmssp_state
) {
1264 return NT_STATUS_INVALID_PARAMETER
;
1267 /* Init and marshall the auth header. */
1268 init_rpc_hdr_auth(&auth_info
,
1269 map_pipe_auth_type_to_rpc_auth_type(
1270 cli
->auth
->auth_type
),
1271 cli
->auth
->auth_level
,
1273 1 /* context id. */);
1275 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1276 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1277 data_blob_free(&auth_blob
);
1278 return NT_STATUS_NO_MEMORY
;
1281 switch (cli
->auth
->auth_level
) {
1282 case PIPE_AUTH_LEVEL_PRIVACY
:
1283 /* Data portion is encrypted. */
1284 status
= ntlmssp_seal_packet(cli
->auth
->a_u
.ntlmssp_state
,
1285 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1287 (unsigned char *)prs_data_p(outgoing_pdu
),
1288 (size_t)prs_offset(outgoing_pdu
),
1290 if (!NT_STATUS_IS_OK(status
)) {
1291 data_blob_free(&auth_blob
);
1296 case PIPE_AUTH_LEVEL_INTEGRITY
:
1297 /* Data is signed. */
1298 status
= ntlmssp_sign_packet(cli
->auth
->a_u
.ntlmssp_state
,
1299 (unsigned char *)prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
,
1301 (unsigned char *)prs_data_p(outgoing_pdu
),
1302 (size_t)prs_offset(outgoing_pdu
),
1304 if (!NT_STATUS_IS_OK(status
)) {
1305 data_blob_free(&auth_blob
);
1312 smb_panic("bad auth level");
1314 return NT_STATUS_INVALID_PARAMETER
;
1317 /* Finally marshall the blob. */
1319 if (!prs_copy_data_in(outgoing_pdu
, (const char *)auth_blob
.data
, NTLMSSP_SIG_SIZE
)) {
1320 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1321 (unsigned int)NTLMSSP_SIG_SIZE
));
1322 data_blob_free(&auth_blob
);
1323 return NT_STATUS_NO_MEMORY
;
1326 data_blob_free(&auth_blob
);
1327 return NT_STATUS_OK
;
1330 /*******************************************************************
1331 Create and add the schannel sign/seal auth header and data.
1332 ********************************************************************/
1334 static NTSTATUS
add_schannel_auth_footer(struct rpc_pipe_client
*cli
,
1336 uint32 ss_padding_len
,
1337 prs_struct
*outgoing_pdu
)
1339 RPC_HDR_AUTH auth_info
;
1340 RPC_AUTH_SCHANNEL_CHK verf
;
1341 struct schannel_auth_struct
*sas
= cli
->auth
->a_u
.schannel_auth
;
1342 char *data_p
= prs_data_p(outgoing_pdu
) + RPC_HEADER_LEN
+ RPC_HDR_RESP_LEN
;
1343 size_t data_and_pad_len
= prs_offset(outgoing_pdu
) - RPC_HEADER_LEN
- RPC_HDR_RESP_LEN
;
1346 return NT_STATUS_INVALID_PARAMETER
;
1349 /* Init and marshall the auth header. */
1350 init_rpc_hdr_auth(&auth_info
,
1351 map_pipe_auth_type_to_rpc_auth_type(cli
->auth
->auth_type
),
1352 cli
->auth
->auth_level
,
1354 1 /* context id. */);
1356 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, outgoing_pdu
, 0)) {
1357 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1358 return NT_STATUS_NO_MEMORY
;
1361 switch (cli
->auth
->auth_level
) {
1362 case PIPE_AUTH_LEVEL_PRIVACY
:
1363 case PIPE_AUTH_LEVEL_INTEGRITY
:
1364 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1367 schannel_encode(sas
,
1368 cli
->auth
->auth_level
,
1369 SENDER_IS_INITIATOR
,
1379 smb_panic("bad auth level");
1381 return NT_STATUS_INVALID_PARAMETER
;
1384 /* Finally marshall the blob. */
1385 smb_io_rpc_auth_schannel_chk("",
1386 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
,
1391 return NT_STATUS_OK
;
1394 /*******************************************************************
1395 Calculate how much data we're going to send in this packet, also
1396 work out any sign/seal padding length.
1397 ********************************************************************/
1399 static uint32
calculate_data_len_tosend(struct rpc_pipe_client
*cli
,
1403 uint32
*p_ss_padding
)
1405 uint32 data_space
, data_len
;
1407 switch (cli
->auth
->auth_level
) {
1408 case PIPE_AUTH_LEVEL_NONE
:
1409 case PIPE_AUTH_LEVEL_CONNECT
:
1410 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
;
1411 data_len
= MIN(data_space
, data_left
);
1414 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ data_len
;
1417 case PIPE_AUTH_LEVEL_INTEGRITY
:
1418 case PIPE_AUTH_LEVEL_PRIVACY
:
1419 /* Treat the same for all authenticated rpc requests. */
1420 switch(cli
->auth
->auth_type
) {
1421 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1422 case PIPE_AUTH_TYPE_NTLMSSP
:
1423 *p_auth_len
= NTLMSSP_SIG_SIZE
;
1425 case PIPE_AUTH_TYPE_SCHANNEL
:
1426 *p_auth_len
= RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN
;
1429 smb_panic("bad auth type");
1433 data_space
= cli
->max_xmit_frag
- RPC_HEADER_LEN
- RPC_HDR_REQ_LEN
-
1434 RPC_HDR_AUTH_LEN
- *p_auth_len
;
1436 data_len
= MIN(data_space
, data_left
);
1438 *p_ss_padding
= 8 - (data_len
% 8);
1440 *p_frag_len
= RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ /* Normal headers. */
1441 data_len
+ *p_ss_padding
+ /* data plus padding. */
1442 RPC_HDR_AUTH_LEN
+ *p_auth_len
; /* Auth header and auth data. */
1446 smb_panic("bad auth level");
1452 /*******************************************************************
1454 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1455 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1456 and deals with signing/sealing details.
1457 ********************************************************************/
1459 NTSTATUS
rpc_api_pipe_req(struct rpc_pipe_client
*cli
,
1461 prs_struct
*in_data
,
1462 prs_struct
*out_data
)
1465 uint32 data_left
= prs_offset(in_data
);
1466 uint32 alloc_hint
= prs_offset(in_data
);
1467 uint32 data_sent_thistime
= 0;
1468 uint32 current_data_offset
= 0;
1469 uint32 call_id
= get_rpc_call_id();
1471 prs_struct outgoing_pdu
;
1473 memset(pad
, '\0', 8);
1475 if (cli
->max_xmit_frag
< RPC_HEADER_LEN
+ RPC_HDR_REQ_LEN
+ RPC_MAX_SIGN_SIZE
) {
1476 /* Server is screwed up ! */
1477 return NT_STATUS_INVALID_PARAMETER
;
1480 if (!prs_init(&outgoing_pdu
, cli
->max_xmit_frag
, prs_get_mem_context(in_data
), MARSHALL
))
1481 return NT_STATUS_NO_MEMORY
;
1485 RPC_HDR_REQ hdr_req
;
1486 uint16 auth_len
= 0;
1487 uint16 frag_len
= 0;
1489 uint32 ss_padding
= 0;
1491 data_sent_thistime
= calculate_data_len_tosend(cli
, data_left
,
1492 &frag_len
, &auth_len
, &ss_padding
);
1494 if (current_data_offset
== 0) {
1495 flags
= RPC_FLG_FIRST
;
1498 if (data_sent_thistime
== data_left
) {
1499 flags
|= RPC_FLG_LAST
;
1502 /* Create and marshall the header and request header. */
1503 init_rpc_hdr(&hdr
, RPC_REQUEST
, flags
, call_id
, frag_len
, auth_len
);
1505 if(!smb_io_rpc_hdr("hdr ", &hdr
, &outgoing_pdu
, 0)) {
1506 prs_mem_free(&outgoing_pdu
);
1507 return NT_STATUS_NO_MEMORY
;
1510 /* Create the rpc request RPC_HDR_REQ */
1511 init_rpc_hdr_req(&hdr_req
, alloc_hint
, op_num
);
1513 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req
, &outgoing_pdu
, 0)) {
1514 prs_mem_free(&outgoing_pdu
);
1515 return NT_STATUS_NO_MEMORY
;
1518 /* Copy in the data, plus any ss padding. */
1519 if (!prs_append_some_prs_data(&outgoing_pdu
, in_data
, current_data_offset
, data_sent_thistime
)) {
1520 prs_mem_free(&outgoing_pdu
);
1521 return NT_STATUS_NO_MEMORY
;
1524 /* Copy the sign/seal padding data. */
1526 if (!prs_copy_data_in(&outgoing_pdu
, pad
, ss_padding
)) {
1527 prs_mem_free(&outgoing_pdu
);
1528 return NT_STATUS_NO_MEMORY
;
1532 /* Generate any auth sign/seal and add the auth footer. */
1534 switch (cli
->auth
->auth_type
) {
1535 case PIPE_AUTH_TYPE_NONE
:
1537 case PIPE_AUTH_TYPE_NTLMSSP
:
1538 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
1539 ret
= add_ntlmssp_auth_footer(cli
, &hdr
, ss_padding
, &outgoing_pdu
);
1540 if (!NT_STATUS_IS_OK(ret
)) {
1541 prs_mem_free(&outgoing_pdu
);
1545 case PIPE_AUTH_TYPE_SCHANNEL
:
1546 ret
= add_schannel_auth_footer(cli
, &hdr
, ss_padding
, &outgoing_pdu
);
1547 if (!NT_STATUS_IS_OK(ret
)) {
1548 prs_mem_free(&outgoing_pdu
);
1553 smb_panic("bad auth type");
1554 break; /* notreached */
1558 /* Actually send the packet. */
1559 if (flags
& RPC_FLG_LAST
) {
1560 /* Last packet - send the data, get the reply and return. */
1561 ret
= rpc_api_pipe(cli
, &outgoing_pdu
, out_data
, RPC_RESPONSE
);
1562 prs_mem_free(&outgoing_pdu
);
1564 if (DEBUGLEVEL
>= 50) {
1565 char *dump_name
= NULL
;
1566 /* Also capture received data */
1567 if (asprintf(&dump_name
, "%s/reply_%s_%d",
1568 get_dyn_LOGFILEBASE(), cli
->pipe_name
,
1570 prs_dump(dump_name
, op_num
, out_data
);
1571 SAFE_FREE(dump_name
);
1577 /* More packets to come - write and continue. */
1578 ssize_t num_written
= cli_write(cli
->cli
, cli
->fnum
, 8, /* 8 means message mode. */
1579 prs_data_p(&outgoing_pdu
),
1581 (size_t)hdr
.frag_len
);
1583 if (num_written
!= hdr
.frag_len
) {
1584 prs_mem_free(&outgoing_pdu
);
1585 return cli_get_nt_error(cli
->cli
);
1589 current_data_offset
+= data_sent_thistime
;
1590 data_left
-= data_sent_thistime
;
1592 /* Reset the marshalling position back to zero. */
1593 if (!prs_set_offset(&outgoing_pdu
, 0)) {
1594 prs_mem_free(&outgoing_pdu
);
1595 return NT_STATUS_NO_MEMORY
;
1600 /****************************************************************************
1601 Set the handle state.
1602 ****************************************************************************/
1604 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client
*cli
,
1605 const char *pipe_name
, uint16 device_state
)
1607 bool state_set
= False
;
1609 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
1610 char *rparam
= NULL
;
1612 uint32 rparam_len
, rdata_len
;
1614 if (pipe_name
== NULL
)
1617 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1618 cli
->fnum
, pipe_name
, device_state
));
1620 /* create parameters: device state */
1621 SSVAL(param
, 0, device_state
);
1623 /* create setup parameters. */
1625 setup
[1] = cli
->fnum
; /* pipe file handle. got this from an SMBOpenX. */
1627 /* send the data on \PIPE\ */
1628 if (cli_api_pipe(cli
->cli
, "\\PIPE\\",
1629 setup
, 2, 0, /* setup, length, max */
1630 param
, 2, 0, /* param, length, max */
1631 NULL
, 0, 1024, /* data, length, max */
1632 &rparam
, &rparam_len
, /* return param, length */
1633 &rdata
, &rdata_len
)) /* return data, length */
1635 DEBUG(5, ("Set Handle state: return OK\n"));
1646 /****************************************************************************
1647 Check the rpc bind acknowledge response.
1648 ****************************************************************************/
1650 static bool check_bind_response(RPC_HDR_BA
*hdr_ba
, const RPC_IFACE
*transfer
)
1652 if ( hdr_ba
->addr
.len
== 0) {
1653 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1656 /* check the transfer syntax */
1657 if ((hdr_ba
->transfer
.if_version
!= transfer
->if_version
) ||
1658 (memcmp(&hdr_ba
->transfer
.uuid
, &transfer
->uuid
, sizeof(transfer
->uuid
)) !=0)) {
1659 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1663 if (hdr_ba
->res
.num_results
!= 0x1 || hdr_ba
->res
.result
!= 0) {
1664 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1665 hdr_ba
->res
.num_results
, hdr_ba
->res
.reason
));
1668 DEBUG(5,("check_bind_response: accepted!\n"));
1672 /*******************************************************************
1673 Creates a DCE/RPC bind authentication response.
1674 This is the packet that is sent back to the server once we
1675 have received a BIND-ACK, to finish the third leg of
1676 the authentication handshake.
1677 ********************************************************************/
1679 static NTSTATUS
create_rpc_bind_auth3(struct rpc_pipe_client
*cli
,
1681 enum pipe_auth_type auth_type
,
1682 enum pipe_auth_level auth_level
,
1683 DATA_BLOB
*pauth_blob
,
1684 prs_struct
*rpc_out
)
1687 RPC_HDR_AUTH hdr_auth
;
1690 /* Create the request RPC_HDR */
1691 init_rpc_hdr(&hdr
, RPC_AUTH3
, RPC_FLG_FIRST
|RPC_FLG_LAST
, rpc_call_id
,
1692 RPC_HEADER_LEN
+ 4 /* pad */ + RPC_HDR_AUTH_LEN
+ pauth_blob
->length
,
1693 pauth_blob
->length
);
1696 if(!smb_io_rpc_hdr("hdr", &hdr
, rpc_out
, 0)) {
1697 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1698 return NT_STATUS_NO_MEMORY
;
1702 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1703 about padding - shouldn't this pad to length 8 ? JRA.
1706 /* 4 bytes padding. */
1707 if (!prs_uint32("pad", rpc_out
, 0, &pad
)) {
1708 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1709 return NT_STATUS_NO_MEMORY
;
1712 /* Create the request RPC_HDR_AUTHA */
1713 init_rpc_hdr_auth(&hdr_auth
,
1714 map_pipe_auth_type_to_rpc_auth_type(auth_type
),
1717 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rpc_out
, 0)) {
1718 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1719 return NT_STATUS_NO_MEMORY
;
1723 * Append the auth data to the outgoing buffer.
1726 if(!prs_copy_data_in(rpc_out
, (char *)pauth_blob
->data
, pauth_blob
->length
)) {
1727 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1728 return NT_STATUS_NO_MEMORY
;
1731 return NT_STATUS_OK
;
1734 /****************************************************************************
1735 Create and send the third packet in an RPC auth.
1736 ****************************************************************************/
1738 static NTSTATUS
rpc_finish_auth3_bind(struct rpc_pipe_client
*cli
,
1742 enum pipe_auth_type auth_type
,
1743 enum pipe_auth_level auth_level
)
1745 DATA_BLOB server_response
= data_blob_null
;
1746 DATA_BLOB client_reply
= data_blob_null
;
1747 RPC_HDR_AUTH hdr_auth
;
1752 if (!phdr
->auth_len
|| (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
1753 return NT_STATUS_INVALID_PARAMETER
;
1756 /* Process the returned NTLMSSP blob first. */
1757 if (!prs_set_offset(rbuf
, phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
1758 return NT_STATUS_INVALID_PARAMETER
;
1761 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rbuf
, 0)) {
1762 return NT_STATUS_INVALID_PARAMETER
;
1765 /* TODO - check auth_type/auth_level match. */
1767 server_response
= data_blob(NULL
, phdr
->auth_len
);
1768 prs_copy_data_out((char *)server_response
.data
, rbuf
, phdr
->auth_len
);
1770 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1774 if (!NT_STATUS_IS_OK(nt_status
)) {
1775 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1776 data_blob_free(&server_response
);
1780 prs_init_empty(&rpc_out
, prs_get_mem_context(rbuf
), MARSHALL
);
1782 nt_status
= create_rpc_bind_auth3(cli
, rpc_call_id
,
1783 auth_type
, auth_level
,
1784 &client_reply
, &rpc_out
);
1786 if (!NT_STATUS_IS_OK(nt_status
)) {
1787 prs_mem_free(&rpc_out
);
1788 data_blob_free(&client_reply
);
1789 data_blob_free(&server_response
);
1793 /* 8 here is named pipe message mode. */
1794 ret
= cli_write(cli
->cli
, cli
->fnum
, 0x8, prs_data_p(&rpc_out
), 0,
1795 (size_t)prs_offset(&rpc_out
));
1797 if (ret
!= (ssize_t
)prs_offset(&rpc_out
)) {
1798 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret
));
1799 prs_mem_free(&rpc_out
);
1800 data_blob_free(&client_reply
);
1801 data_blob_free(&server_response
);
1802 return cli_get_nt_error(cli
->cli
);
1805 DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
1806 "fnum 0x%x sent auth3 response ok.\n",
1809 (unsigned int)cli
->fnum
));
1811 prs_mem_free(&rpc_out
);
1812 data_blob_free(&client_reply
);
1813 data_blob_free(&server_response
);
1814 return NT_STATUS_OK
;
1817 /*******************************************************************
1818 Creates a DCE/RPC bind alter context authentication request which
1819 may contain a spnego auth blobl
1820 ********************************************************************/
1822 static NTSTATUS
create_rpc_alter_context(uint32 rpc_call_id
,
1823 const RPC_IFACE
*abstract
,
1824 const RPC_IFACE
*transfer
,
1825 enum pipe_auth_level auth_level
,
1826 const DATA_BLOB
*pauth_blob
, /* spnego auth blob already created. */
1827 prs_struct
*rpc_out
)
1829 RPC_HDR_AUTH hdr_auth
;
1830 prs_struct auth_info
;
1831 NTSTATUS ret
= NT_STATUS_OK
;
1833 ZERO_STRUCT(hdr_auth
);
1834 if (!prs_init(&auth_info
, RPC_HDR_AUTH_LEN
, prs_get_mem_context(rpc_out
), MARSHALL
))
1835 return NT_STATUS_NO_MEMORY
;
1837 /* We may change the pad length before marshalling. */
1838 init_rpc_hdr_auth(&hdr_auth
, RPC_SPNEGO_AUTH_TYPE
, (int)auth_level
, 0, 1);
1840 if (pauth_blob
->length
) {
1841 if (!prs_copy_data_in(&auth_info
, (const char *)pauth_blob
->data
, pauth_blob
->length
)) {
1842 prs_mem_free(&auth_info
);
1843 return NT_STATUS_NO_MEMORY
;
1847 ret
= create_bind_or_alt_ctx_internal(RPC_ALTCONT
,
1854 prs_mem_free(&auth_info
);
1858 /*******************************************************************
1859 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1860 and gets a response.
1861 ********************************************************************/
1863 static NTSTATUS
rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client
*cli
,
1867 const RPC_IFACE
*abstract
,
1868 const RPC_IFACE
*transfer
,
1869 enum pipe_auth_type auth_type
,
1870 enum pipe_auth_level auth_level
)
1872 DATA_BLOB server_spnego_response
= data_blob_null
;
1873 DATA_BLOB server_ntlm_response
= data_blob_null
;
1874 DATA_BLOB client_reply
= data_blob_null
;
1875 DATA_BLOB tmp_blob
= data_blob_null
;
1876 RPC_HDR_AUTH hdr_auth
;
1880 if (!phdr
->auth_len
|| (phdr
->frag_len
< phdr
->auth_len
+ RPC_HDR_AUTH_LEN
)) {
1881 return NT_STATUS_INVALID_PARAMETER
;
1884 /* Process the returned NTLMSSP blob first. */
1885 if (!prs_set_offset(rbuf
, phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
1886 return NT_STATUS_INVALID_PARAMETER
;
1889 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rbuf
, 0)) {
1890 return NT_STATUS_INVALID_PARAMETER
;
1893 server_spnego_response
= data_blob(NULL
, phdr
->auth_len
);
1894 prs_copy_data_out((char *)server_spnego_response
.data
, rbuf
, phdr
->auth_len
);
1896 /* The server might give us back two challenges - tmp_blob is for the second. */
1897 if (!spnego_parse_challenge(server_spnego_response
, &server_ntlm_response
, &tmp_blob
)) {
1898 data_blob_free(&server_spnego_response
);
1899 data_blob_free(&server_ntlm_response
);
1900 data_blob_free(&tmp_blob
);
1901 return NT_STATUS_INVALID_PARAMETER
;
1904 /* We're finished with the server spnego response and the tmp_blob. */
1905 data_blob_free(&server_spnego_response
);
1906 data_blob_free(&tmp_blob
);
1908 nt_status
= ntlmssp_update(cli
->auth
->a_u
.ntlmssp_state
,
1909 server_ntlm_response
,
1912 /* Finished with the server_ntlm response */
1913 data_blob_free(&server_ntlm_response
);
1915 if (!NT_STATUS_IS_OK(nt_status
)) {
1916 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
1917 data_blob_free(&client_reply
);
1921 /* SPNEGO wrap the client reply. */
1922 tmp_blob
= spnego_gen_auth(client_reply
);
1923 data_blob_free(&client_reply
);
1924 client_reply
= tmp_blob
;
1925 tmp_blob
= data_blob_null
; /* Ensure it's safe to free this just in case. */
1927 /* Now prepare the alter context pdu. */
1928 prs_init_empty(&rpc_out
, prs_get_mem_context(rbuf
), MARSHALL
);
1930 nt_status
= create_rpc_alter_context(rpc_call_id
,
1937 data_blob_free(&client_reply
);
1939 if (!NT_STATUS_IS_OK(nt_status
)) {
1940 prs_mem_free(&rpc_out
);
1944 /* Initialize the returning data struct. */
1946 prs_init_empty(rbuf
, talloc_tos(), UNMARSHALL
);
1948 nt_status
= rpc_api_pipe(cli
, &rpc_out
, rbuf
, RPC_ALTCONTRESP
);
1949 if (!NT_STATUS_IS_OK(nt_status
)) {
1950 prs_mem_free(&rpc_out
);
1954 prs_mem_free(&rpc_out
);
1956 /* Get the auth blob from the reply. */
1957 if(!smb_io_rpc_hdr("rpc_hdr ", phdr
, rbuf
, 0)) {
1958 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
1959 return NT_STATUS_BUFFER_TOO_SMALL
;
1962 if (!prs_set_offset(rbuf
, phdr
->frag_len
- phdr
->auth_len
- RPC_HDR_AUTH_LEN
)) {
1963 return NT_STATUS_INVALID_PARAMETER
;
1966 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, rbuf
, 0)) {
1967 return NT_STATUS_INVALID_PARAMETER
;
1970 server_spnego_response
= data_blob(NULL
, phdr
->auth_len
);
1971 prs_copy_data_out((char *)server_spnego_response
.data
, rbuf
, phdr
->auth_len
);
1973 /* Check we got a valid auth response. */
1974 if (!spnego_parse_auth_response(server_spnego_response
, NT_STATUS_OK
, OID_NTLMSSP
, &tmp_blob
)) {
1975 data_blob_free(&server_spnego_response
);
1976 data_blob_free(&tmp_blob
);
1977 return NT_STATUS_INVALID_PARAMETER
;
1980 data_blob_free(&server_spnego_response
);
1981 data_blob_free(&tmp_blob
);
1983 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
1984 "remote machine %s pipe %s fnum 0x%x.\n",
1987 (unsigned int)cli
->fnum
));
1989 return NT_STATUS_OK
;
1992 /****************************************************************************
1994 ****************************************************************************/
1996 static NTSTATUS
rpc_pipe_bind(struct rpc_pipe_client
*cli
,
1997 struct cli_pipe_auth_data
*auth
)
2006 DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2007 (unsigned int)cli
->fnum
,
2009 (unsigned int)auth
->auth_type
,
2010 (unsigned int)auth
->auth_level
));
2012 cli
->auth
= talloc_move(cli
, &auth
);
2014 prs_init_empty(&rpc_out
, talloc_tos(), MARSHALL
);
2016 rpc_call_id
= get_rpc_call_id();
2018 /* Marshall the outgoing data. */
2019 status
= create_rpc_bind_req(cli
, &rpc_out
, rpc_call_id
,
2020 cli
->abstract_syntax
,
2021 cli
->transfer_syntax
,
2022 cli
->auth
->auth_type
,
2023 cli
->auth
->auth_level
);
2025 if (!NT_STATUS_IS_OK(status
)) {
2026 prs_mem_free(&rpc_out
);
2030 /* Initialize the incoming data struct. */
2031 prs_init_empty(&rbuf
, talloc_tos(), UNMARSHALL
);
2033 /* send data on \PIPE\. receive a response */
2034 status
= rpc_api_pipe(cli
, &rpc_out
, &rbuf
, RPC_BINDACK
);
2035 if (!NT_STATUS_IS_OK(status
)) {
2036 prs_mem_free(&rpc_out
);
2040 prs_mem_free(&rpc_out
);
2042 DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2043 "fnum 0x%x bind request returned ok.\n",
2046 (unsigned int)cli
->fnum
));
2048 /* Unmarshall the RPC header */
2049 if(!smb_io_rpc_hdr("hdr" , &hdr
, &rbuf
, 0)) {
2050 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2051 prs_mem_free(&rbuf
);
2052 return NT_STATUS_BUFFER_TOO_SMALL
;
2055 if(!smb_io_rpc_hdr_ba("", &hdr_ba
, &rbuf
, 0)) {
2056 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2057 prs_mem_free(&rbuf
);
2058 return NT_STATUS_BUFFER_TOO_SMALL
;
2061 if(!check_bind_response(&hdr_ba
, cli
->transfer_syntax
)) {
2062 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2063 prs_mem_free(&rbuf
);
2064 return NT_STATUS_BUFFER_TOO_SMALL
;
2067 cli
->max_xmit_frag
= hdr_ba
.bba
.max_tsize
;
2068 cli
->max_recv_frag
= hdr_ba
.bba
.max_rsize
;
2070 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2071 switch(cli
->auth
->auth_type
) {
2073 case PIPE_AUTH_TYPE_NONE
:
2074 case PIPE_AUTH_TYPE_SCHANNEL
:
2075 /* Bind complete. */
2078 case PIPE_AUTH_TYPE_NTLMSSP
:
2079 /* Need to send AUTH3 packet - no reply. */
2080 status
= rpc_finish_auth3_bind(
2081 cli
, &hdr
, &rbuf
, rpc_call_id
,
2082 cli
->auth
->auth_type
,
2083 cli
->auth
->auth_level
);
2084 if (!NT_STATUS_IS_OK(status
)) {
2085 prs_mem_free(&rbuf
);
2090 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
:
2091 /* Need to send alter context request and reply. */
2092 status
= rpc_finish_spnego_ntlmssp_bind(
2093 cli
, &hdr
, &rbuf
, rpc_call_id
,
2094 cli
->abstract_syntax
, cli
->transfer_syntax
,
2095 cli
->auth
->auth_type
, cli
->auth
->auth_level
);
2096 if (!NT_STATUS_IS_OK(status
)) {
2097 prs_mem_free(&rbuf
);
2102 case PIPE_AUTH_TYPE_KRB5
:
2106 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2107 "%u\n", (unsigned int)cli
->auth
->auth_type
));
2108 prs_mem_free(&rbuf
);
2109 return NT_STATUS_INVALID_INFO_CLASS
;
2112 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2113 if (cli
->auth
->auth_type
== PIPE_AUTH_TYPE_NTLMSSP
2114 || cli
->auth
->auth_type
== PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
) {
2115 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_INTEGRITY
) {
2116 if (!(cli
->auth
->a_u
.ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_SIGN
)) {
2117 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2118 prs_mem_free(&rbuf
);
2119 return NT_STATUS_INVALID_PARAMETER
;
2122 if (cli
->auth
->auth_level
== PIPE_AUTH_LEVEL_INTEGRITY
) {
2123 if (!(cli
->auth
->a_u
.ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_SEAL
)) {
2124 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2125 prs_mem_free(&rbuf
);
2126 return NT_STATUS_INVALID_PARAMETER
;
2131 prs_mem_free(&rbuf
);
2132 return NT_STATUS_OK
;
2135 unsigned int rpccli_set_timeout(struct rpc_pipe_client
*cli
,
2136 unsigned int timeout
)
2138 return cli_set_timeout(cli
->cli
, timeout
);
2141 bool rpccli_is_pipe_idx(struct rpc_pipe_client
*cli
, int pipe_idx
)
2143 return (cli
->abstract_syntax
== pipe_names
[pipe_idx
].abstr_syntax
);
2146 bool rpccli_get_pwd_hash(struct rpc_pipe_client
*cli
, uint8_t nt_hash
[16])
2148 if (!((cli
->auth
->auth_type
== PIPE_AUTH_TYPE_NTLMSSP
)
2149 || (cli
->auth
->auth_type
== PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
))) {
2150 E_md4hash(cli
->cli
->pwd
.password
, nt_hash
);
2154 memcpy(nt_hash
, cli
->auth
->a_u
.ntlmssp_state
->nt_hash
, 16);
2158 struct cli_state
*rpc_pipe_np_smb_conn(struct rpc_pipe_client
*p
)
2163 static int rpc_pipe_destructor(struct rpc_pipe_client
*p
)
2167 ret
= cli_close(p
->cli
, p
->fnum
);
2169 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s, "
2170 "fnum 0x%x to machine %s. Error was %s\n",
2171 p
->pipe_name
, (int) p
->fnum
,
2172 p
->desthost
, cli_errstr(p
->cli
)));
2175 DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n",
2176 p
->pipe_name
, p
->desthost
));
2178 DLIST_REMOVE(p
->cli
->pipe_list
, p
);
2180 return ret
? -1 : 0;
2183 NTSTATUS
rpccli_anon_bind_data(TALLOC_CTX
*mem_ctx
,
2184 struct cli_pipe_auth_data
**presult
)
2186 struct cli_pipe_auth_data
*result
;
2188 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
2189 if (result
== NULL
) {
2190 return NT_STATUS_NO_MEMORY
;
2193 result
->auth_type
= PIPE_AUTH_TYPE_NONE
;
2194 result
->auth_level
= PIPE_AUTH_LEVEL_NONE
;
2196 result
->user_name
= talloc_strdup(result
, "");
2197 result
->domain
= talloc_strdup(result
, "");
2198 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2199 TALLOC_FREE(result
);
2200 return NT_STATUS_NO_MEMORY
;
2204 return NT_STATUS_OK
;
2207 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data
*auth
)
2209 ntlmssp_end(&auth
->a_u
.ntlmssp_state
);
2213 NTSTATUS
rpccli_ntlmssp_bind_data(TALLOC_CTX
*mem_ctx
,
2214 enum pipe_auth_type auth_type
,
2215 enum pipe_auth_level auth_level
,
2217 const char *username
,
2218 const char *password
,
2219 struct cli_pipe_auth_data
**presult
)
2221 struct cli_pipe_auth_data
*result
;
2224 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
2225 if (result
== NULL
) {
2226 return NT_STATUS_NO_MEMORY
;
2229 result
->auth_type
= auth_type
;
2230 result
->auth_level
= auth_level
;
2232 result
->user_name
= talloc_strdup(result
, username
);
2233 result
->domain
= talloc_strdup(result
, domain
);
2234 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2235 status
= NT_STATUS_NO_MEMORY
;
2239 status
= ntlmssp_client_start(&result
->a_u
.ntlmssp_state
);
2240 if (!NT_STATUS_IS_OK(status
)) {
2244 talloc_set_destructor(result
, cli_auth_ntlmssp_data_destructor
);
2246 status
= ntlmssp_set_username(result
->a_u
.ntlmssp_state
, username
);
2247 if (!NT_STATUS_IS_OK(status
)) {
2251 status
= ntlmssp_set_domain(result
->a_u
.ntlmssp_state
, domain
);
2252 if (!NT_STATUS_IS_OK(status
)) {
2256 status
= ntlmssp_set_password(result
->a_u
.ntlmssp_state
, password
);
2257 if (!NT_STATUS_IS_OK(status
)) {
2262 * Turn off sign+seal to allow selected auth level to turn it back on.
2264 result
->a_u
.ntlmssp_state
->neg_flags
&=
2265 ~(NTLMSSP_NEGOTIATE_SIGN
| NTLMSSP_NEGOTIATE_SEAL
);
2267 if (auth_level
== PIPE_AUTH_LEVEL_INTEGRITY
) {
2268 result
->a_u
.ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
2269 } else if (auth_level
== PIPE_AUTH_LEVEL_PRIVACY
) {
2270 result
->a_u
.ntlmssp_state
->neg_flags
2271 |= NTLMSSP_NEGOTIATE_SEAL
| NTLMSSP_NEGOTIATE_SIGN
;
2275 return NT_STATUS_OK
;
2278 TALLOC_FREE(result
);
2282 NTSTATUS
rpccli_schannel_bind_data(TALLOC_CTX
*mem_ctx
, const char *domain
,
2283 enum pipe_auth_level auth_level
,
2284 const struct dcinfo
*pdc
,
2285 struct cli_pipe_auth_data
**presult
)
2287 struct cli_pipe_auth_data
*result
;
2289 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
2290 if (result
== NULL
) {
2291 return NT_STATUS_NO_MEMORY
;
2294 result
->auth_type
= PIPE_AUTH_TYPE_SCHANNEL
;
2295 result
->auth_level
= auth_level
;
2297 result
->user_name
= talloc_strdup(result
, "");
2298 result
->domain
= talloc_strdup(result
, domain
);
2299 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2303 result
->a_u
.schannel_auth
= talloc(result
,
2304 struct schannel_auth_struct
);
2305 if (result
->a_u
.schannel_auth
== NULL
) {
2309 memcpy(result
->a_u
.schannel_auth
->sess_key
, pdc
->sess_key
, 16);
2310 result
->a_u
.schannel_auth
->seq_num
= 0;
2313 return NT_STATUS_OK
;
2316 TALLOC_FREE(result
);
2317 return NT_STATUS_NO_MEMORY
;
2320 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct
*auth
)
2322 data_blob_free(&auth
->session_key
);
2326 NTSTATUS
rpccli_kerberos_bind_data(TALLOC_CTX
*mem_ctx
,
2327 enum pipe_auth_level auth_level
,
2328 const char *service_princ
,
2329 const char *username
,
2330 const char *password
,
2331 struct cli_pipe_auth_data
**presult
)
2333 struct cli_pipe_auth_data
*result
;
2335 if ((username
!= NULL
) && (password
!= NULL
)) {
2336 int ret
= kerberos_kinit_password(username
, password
, 0, NULL
);
2338 return NT_STATUS_ACCESS_DENIED
;
2342 result
= talloc(mem_ctx
, struct cli_pipe_auth_data
);
2343 if (result
== NULL
) {
2344 return NT_STATUS_NO_MEMORY
;
2347 result
->auth_type
= PIPE_AUTH_TYPE_KRB5
;
2348 result
->auth_level
= auth_level
;
2351 * Username / domain need fixing!
2353 result
->user_name
= talloc_strdup(result
, "");
2354 result
->domain
= talloc_strdup(result
, "");
2355 if ((result
->user_name
== NULL
) || (result
->domain
== NULL
)) {
2359 result
->a_u
.kerberos_auth
= TALLOC_ZERO_P(
2360 result
, struct kerberos_auth_struct
);
2361 if (result
->a_u
.kerberos_auth
== NULL
) {
2364 talloc_set_destructor(result
->a_u
.kerberos_auth
,
2365 cli_auth_kerberos_data_destructor
);
2367 result
->a_u
.kerberos_auth
->service_principal
= talloc_strdup(
2368 result
, service_princ
);
2369 if (result
->a_u
.kerberos_auth
->service_principal
== NULL
) {
2374 return NT_STATUS_OK
;
2377 TALLOC_FREE(result
);
2378 return NT_STATUS_NO_MEMORY
;
2381 /****************************************************************************
2382 Open a named pipe over SMB to a remote server.
2384 * CAVEAT CALLER OF THIS FUNCTION:
2385 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2386 * so be sure that this function is called AFTER any structure (vs pointer)
2387 * assignment of the cli. In particular, libsmbclient does structure
2388 * assignments of cli, which invalidates the data in the returned
2389 * rpc_pipe_client if this function is called before the structure assignment
2392 ****************************************************************************/
2394 static struct rpc_pipe_client
*cli_rpc_pipe_open(struct cli_state
*cli
, int pipe_idx
, NTSTATUS
*perr
)
2396 struct rpc_pipe_client
*result
;
2399 *perr
= NT_STATUS_NO_MEMORY
;
2401 /* sanity check to protect against crashes */
2404 *perr
= NT_STATUS_INVALID_HANDLE
;
2408 /* The pipe name index must fall within our array */
2409 SMB_ASSERT((pipe_idx
>= 0) && (pipe_idx
< PI_MAX_PIPES
));
2411 result
= TALLOC_ZERO_P(NULL
, struct rpc_pipe_client
);
2412 if (result
== NULL
) {
2413 *perr
= NT_STATUS_NO_MEMORY
;
2417 result
->pipe_name
= cli_get_pipe_name(pipe_idx
);
2420 result
->abstract_syntax
= pipe_names
[pipe_idx
].abstr_syntax
;
2421 result
->transfer_syntax
= pipe_names
[pipe_idx
].trans_syntax
;
2422 result
->desthost
= talloc_strdup(result
, cli
->desthost
);
2423 result
->srv_name_slash
= talloc_asprintf_strupper_m(
2424 result
, "\\\\%s", result
->desthost
);
2426 if ((result
->desthost
== NULL
) || (result
->srv_name_slash
== NULL
)) {
2427 *perr
= NT_STATUS_NO_MEMORY
;
2428 TALLOC_FREE(result
);
2432 if (pipe_idx
== PI_NETLOGON
) {
2433 /* Set up a netlogon credential chain for a netlogon pipe. */
2434 result
->dc
= TALLOC_ZERO_P(result
, struct dcinfo
);
2435 if (result
->dc
== NULL
) {
2436 *perr
= NT_STATUS_NO_MEMORY
;
2437 TALLOC_FREE(result
);
2442 fnum
= cli_nt_create(cli
, result
->pipe_name
, DESIRED_ACCESS_PIPE
);
2444 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2445 "to machine %s. Error was %s\n",
2446 result
->pipe_name
, cli
->desthost
,
2448 *perr
= cli_get_nt_error(cli
);
2449 talloc_destroy(result
);
2453 result
->fnum
= fnum
;
2455 DLIST_ADD(cli
->pipe_list
, result
);
2456 talloc_set_destructor(result
, rpc_pipe_destructor
);
2458 *perr
= NT_STATUS_OK
;
2463 /****************************************************************************
2464 Open a named pipe to an SMB server and bind anonymously.
2465 ****************************************************************************/
2467 struct rpc_pipe_client
*cli_rpc_pipe_open_noauth(struct cli_state
*cli
, int pipe_idx
, NTSTATUS
*perr
)
2469 struct rpc_pipe_client
*result
;
2470 struct cli_pipe_auth_data
*auth
;
2472 result
= cli_rpc_pipe_open(cli
, pipe_idx
, perr
);
2473 if (result
== NULL
) {
2477 *perr
= rpccli_anon_bind_data(result
, &auth
);
2478 if (!NT_STATUS_IS_OK(*perr
)) {
2479 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2481 TALLOC_FREE(result
);
2485 *perr
= rpc_pipe_bind(result
, auth
);
2486 if (!NT_STATUS_IS_OK(*perr
)) {
2488 if (rpccli_is_pipe_idx(result
, PI_DSSETUP
)) {
2489 /* non AD domains just don't have this pipe, avoid
2490 * level 0 statement in that case - gd */
2493 DEBUG(lvl
, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2494 cli_get_pipe_name(pipe_idx
), nt_errstr(*perr
) ));
2495 TALLOC_FREE(result
);
2499 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2500 result
->pipe_name
, cli
->desthost
));
2505 /****************************************************************************
2506 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2507 ****************************************************************************/
2509 static struct rpc_pipe_client
*cli_rpc_pipe_open_ntlmssp_internal(struct cli_state
*cli
,
2511 enum pipe_auth_type auth_type
,
2512 enum pipe_auth_level auth_level
,
2514 const char *username
,
2515 const char *password
,
2518 struct rpc_pipe_client
*result
;
2519 struct cli_pipe_auth_data
*auth
;
2521 result
= cli_rpc_pipe_open(cli
, pipe_idx
, perr
);
2522 if (result
== NULL
) {
2526 *perr
= rpccli_ntlmssp_bind_data(
2527 result
, auth_type
, auth_level
, domain
, username
,
2528 cli
->pwd
.null_pwd
? NULL
: password
, &auth
);
2529 if (!NT_STATUS_IS_OK(*perr
)) {
2530 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2532 TALLOC_FREE(result
);
2536 *perr
= rpc_pipe_bind(result
, auth
);
2537 if (!NT_STATUS_IS_OK(*perr
)) {
2538 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2539 nt_errstr(*perr
) ));
2543 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2544 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2545 result
->pipe_name
, cli
->desthost
,
2546 domain
, username
));
2552 TALLOC_FREE(result
);
2556 /****************************************************************************
2558 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2559 ****************************************************************************/
2561 struct rpc_pipe_client
*cli_rpc_pipe_open_ntlmssp(struct cli_state
*cli
,
2563 enum pipe_auth_level auth_level
,
2565 const char *username
,
2566 const char *password
,
2569 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
2571 PIPE_AUTH_TYPE_NTLMSSP
,
2579 /****************************************************************************
2581 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2582 ****************************************************************************/
2584 struct rpc_pipe_client
*cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state
*cli
,
2586 enum pipe_auth_level auth_level
,
2588 const char *username
,
2589 const char *password
,
2592 return cli_rpc_pipe_open_ntlmssp_internal(cli
,
2594 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
,
2602 /****************************************************************************
2603 Get a the schannel session key out of an already opened netlogon pipe.
2604 ****************************************************************************/
2605 static bool get_schannel_session_key_common(struct rpc_pipe_client
*netlogon_pipe
,
2606 struct cli_state
*cli
,
2611 uint32 sec_chan_type
= 0;
2612 unsigned char machine_pwd
[16];
2613 const char *machine_account
;
2615 /* Get the machine account credentials from secrets.tdb. */
2616 if (!get_trust_pw_hash(domain
, machine_pwd
, &machine_account
,
2619 DEBUG(0, ("get_schannel_session_key: could not fetch "
2620 "trust account password for domain '%s'\n",
2622 *perr
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2626 *perr
= rpccli_netlogon_setup_creds(netlogon_pipe
,
2627 cli
->desthost
, /* server name */
2628 domain
, /* domain */
2629 global_myname(), /* client name */
2630 machine_account
, /* machine account name */
2635 if (!NT_STATUS_IS_OK(*perr
)) {
2636 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2637 "failed with result %s to server %s, domain %s, machine account %s.\n",
2638 nt_errstr(*perr
), cli
->desthost
, domain
, machine_account
));
2642 if (((*pneg_flags
) & NETLOGON_NEG_SCHANNEL
) == 0) {
2643 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2645 *perr
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2652 /****************************************************************************
2653 Open a netlogon pipe and get the schannel session key.
2654 Now exposed to external callers.
2655 ****************************************************************************/
2658 struct rpc_pipe_client
*get_schannel_session_key(struct cli_state
*cli
,
2663 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
2665 netlogon_pipe
= cli_rpc_pipe_open_noauth(cli
, PI_NETLOGON
, perr
);
2666 if (!netlogon_pipe
) {
2670 if (!get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
2673 TALLOC_FREE(netlogon_pipe
);
2677 return netlogon_pipe
;
2680 /****************************************************************************
2682 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2683 using session_key. sign and seal.
2684 ****************************************************************************/
2686 struct rpc_pipe_client
*cli_rpc_pipe_open_schannel_with_key(struct cli_state
*cli
,
2688 enum pipe_auth_level auth_level
,
2690 const struct dcinfo
*pdc
,
2693 struct rpc_pipe_client
*result
;
2694 struct cli_pipe_auth_data
*auth
;
2696 result
= cli_rpc_pipe_open(cli
, pipe_idx
, perr
);
2697 if (result
== NULL
) {
2701 *perr
= rpccli_schannel_bind_data(result
, domain
, auth_level
,
2703 if (!NT_STATUS_IS_OK(*perr
)) {
2704 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2706 TALLOC_FREE(result
);
2710 *perr
= rpc_pipe_bind(result
, auth
);
2711 if (!NT_STATUS_IS_OK(*perr
)) {
2712 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2713 nt_errstr(*perr
) ));
2714 TALLOC_FREE(result
);
2718 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2723 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2725 "and bound using schannel.\n",
2726 result
->pipe_name
, cli
->desthost
, domain
));
2731 /****************************************************************************
2732 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2733 Fetch the session key ourselves using a temporary netlogon pipe. This
2734 version uses an ntlmssp auth bound netlogon pipe to get the key.
2735 ****************************************************************************/
2737 static struct rpc_pipe_client
*get_schannel_session_key_auth_ntlmssp(struct cli_state
*cli
,
2739 const char *username
,
2740 const char *password
,
2744 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
2746 netlogon_pipe
= cli_rpc_pipe_open_spnego_ntlmssp(cli
, PI_NETLOGON
, PIPE_AUTH_LEVEL_PRIVACY
, domain
, username
, password
, perr
);
2747 if (!netlogon_pipe
) {
2751 if (!get_schannel_session_key_common(netlogon_pipe
, cli
, domain
,
2754 TALLOC_FREE(netlogon_pipe
);
2758 return netlogon_pipe
;
2761 /****************************************************************************
2762 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2763 Fetch the session key ourselves using a temporary netlogon pipe. This version
2764 uses an ntlmssp bind to get the session key.
2765 ****************************************************************************/
2767 struct rpc_pipe_client
*cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
*cli
,
2769 enum pipe_auth_level auth_level
,
2771 const char *username
,
2772 const char *password
,
2775 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
2776 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
2777 struct rpc_pipe_client
*result
= NULL
;
2779 netlogon_pipe
= get_schannel_session_key_auth_ntlmssp(cli
, domain
, username
,
2780 password
, &neg_flags
, perr
);
2781 if (!netlogon_pipe
) {
2782 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2783 "key from server %s for domain %s.\n",
2784 cli
->desthost
, domain
));
2788 result
= cli_rpc_pipe_open_schannel_with_key(cli
, pipe_idx
,
2790 domain
, netlogon_pipe
->dc
, perr
);
2792 /* Now we've bound using the session key we can close the netlog pipe. */
2793 TALLOC_FREE(netlogon_pipe
);
2798 /****************************************************************************
2799 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2800 Fetch the session key ourselves using a temporary netlogon pipe.
2801 ****************************************************************************/
2803 struct rpc_pipe_client
*cli_rpc_pipe_open_schannel(struct cli_state
*cli
,
2805 enum pipe_auth_level auth_level
,
2809 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
2810 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
2811 struct rpc_pipe_client
*result
= NULL
;
2813 netlogon_pipe
= get_schannel_session_key(cli
, domain
, &neg_flags
, perr
);
2814 if (!netlogon_pipe
) {
2815 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2816 "key from server %s for domain %s.\n",
2817 cli
->desthost
, domain
));
2821 result
= cli_rpc_pipe_open_schannel_with_key(cli
, pipe_idx
,
2823 domain
, netlogon_pipe
->dc
, perr
);
2825 /* Now we've bound using the session key we can close the netlog pipe. */
2826 TALLOC_FREE(netlogon_pipe
);
2831 /****************************************************************************
2832 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2833 The idea is this can be called with service_princ, username and password all
2834 NULL so long as the caller has a TGT.
2835 ****************************************************************************/
2837 struct rpc_pipe_client
*cli_rpc_pipe_open_krb5(struct cli_state
*cli
,
2839 enum pipe_auth_level auth_level
,
2840 const char *service_princ
,
2841 const char *username
,
2842 const char *password
,
2846 struct rpc_pipe_client
*result
;
2847 struct cli_pipe_auth_data
*auth
;
2849 result
= cli_rpc_pipe_open(cli
, pipe_idx
, perr
);
2850 if (result
== NULL
) {
2854 *perr
= rpccli_kerberos_bind_data(result
, auth_level
, service_princ
,
2855 username
, password
, &auth
);
2856 if (!NT_STATUS_IS_OK(*perr
)) {
2857 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
2859 TALLOC_FREE(result
);
2863 *perr
= rpc_pipe_bind(result
, auth
);
2864 if (!NT_STATUS_IS_OK(*perr
)) {
2865 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2866 nt_errstr(*perr
) ));
2867 TALLOC_FREE(result
);
2873 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));