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 enum pipe_auth_type auth_type,
1998 enum pipe_auth_level auth_level)
2007 DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2008 (unsigned int)cli->fnum,
2010 (unsigned int)auth_type,
2011 (unsigned int)auth_level ));
2013 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2015 rpc_call_id = get_rpc_call_id();
2017 /* Marshall the outgoing data. */
2018 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2019 cli->abstract_syntax,
2020 cli->transfer_syntax,
2024 if (!NT_STATUS_IS_OK(status)) {
2025 prs_mem_free(&rpc_out);
2029 /* Initialize the incoming data struct. */
2030 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2032 /* send data on \PIPE\. receive a response */
2033 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2034 if (!NT_STATUS_IS_OK(status)) {
2035 prs_mem_free(&rpc_out);
2039 prs_mem_free(&rpc_out);
2041 DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2042 "fnum 0x%x bind request returned ok.\n",
2045 (unsigned int)cli->fnum));
2047 /* Unmarshall the RPC header */
2048 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2049 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2050 prs_mem_free(&rbuf);
2051 return NT_STATUS_BUFFER_TOO_SMALL;
2054 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2055 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2056 prs_mem_free(&rbuf);
2057 return NT_STATUS_BUFFER_TOO_SMALL;
2060 if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2061 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2062 prs_mem_free(&rbuf);
2063 return NT_STATUS_BUFFER_TOO_SMALL;
2066 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2067 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2069 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2072 case PIPE_AUTH_TYPE_NONE:
2073 case PIPE_AUTH_TYPE_SCHANNEL:
2074 /* Bind complete. */
2077 case PIPE_AUTH_TYPE_NTLMSSP:
2078 /* Need to send AUTH3 packet - no reply. */
2079 status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
2080 auth_type, auth_level);
2081 if (!NT_STATUS_IS_OK(status)) {
2082 prs_mem_free(&rbuf);
2087 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2088 /* Need to send alter context request and reply. */
2089 status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
2090 cli->abstract_syntax,
2091 cli->transfer_syntax,
2092 auth_type, auth_level);
2093 if (!NT_STATUS_IS_OK(status)) {
2094 prs_mem_free(&rbuf);
2099 case PIPE_AUTH_TYPE_KRB5:
2103 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2104 (unsigned int)auth_type ));
2105 prs_mem_free(&rbuf);
2106 return NT_STATUS_INVALID_INFO_CLASS;
2109 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2110 if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2111 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2112 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2113 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2114 prs_mem_free(&rbuf);
2115 return NT_STATUS_INVALID_PARAMETER;
2118 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2119 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2120 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2121 prs_mem_free(&rbuf);
2122 return NT_STATUS_INVALID_PARAMETER;
2127 /* Pipe is bound - set up auth_type and auth_level data. */
2129 cli->auth->auth_type = auth_type;
2130 cli->auth->auth_level = auth_level;
2132 prs_mem_free(&rbuf);
2133 return NT_STATUS_OK;
2136 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2137 unsigned int timeout)
2139 return cli_set_timeout(cli->cli, timeout);
2142 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2144 return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
2147 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2149 if (!((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2150 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2151 E_md4hash(cli->cli->pwd.password, nt_hash);
2155 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2159 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2164 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2168 ret = cli_close(p->cli, p->fnum);
2170 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s, "
2171 "fnum 0x%x to machine %s. Error was %s\n",
2172 p->pipe_name, (int) p->fnum,
2173 p->desthost, cli_errstr(p->cli)));
2176 if (p->auth->cli_auth_data_free_func) {
2177 (*p->auth->cli_auth_data_free_func)(p->auth);
2180 DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n",
2181 p->pipe_name, p->desthost ));
2183 DLIST_REMOVE(p->cli->pipe_list, p);
2185 return ret ? -1 : 0;
2188 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2189 struct cli_pipe_auth_data **presult)
2191 struct cli_pipe_auth_data *result;
2193 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2194 if (result == NULL) {
2195 return NT_STATUS_NO_MEMORY;
2198 result->auth_type = PIPE_AUTH_TYPE_NONE;
2199 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2201 result->user_name = talloc_strdup(result, "");
2202 result->domain = talloc_strdup(result, "");
2203 if ((result->user_name == NULL) || (result->domain == NULL)) {
2204 TALLOC_FREE(result);
2205 return NT_STATUS_NO_MEMORY;
2209 return NT_STATUS_OK;
2212 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2214 ntlmssp_end(&auth->a_u.ntlmssp_state);
2218 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2219 enum pipe_auth_type auth_type,
2220 enum pipe_auth_level auth_level,
2222 const char *username,
2223 const char *password,
2224 struct cli_pipe_auth_data **presult)
2226 struct cli_pipe_auth_data *result;
2229 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2230 if (result == NULL) {
2231 return NT_STATUS_NO_MEMORY;
2234 result->auth_type = auth_type;
2235 result->auth_level = auth_level;
2237 result->user_name = talloc_strdup(result, username);
2238 result->domain = talloc_strdup(result, domain);
2239 if ((result->user_name == NULL) || (result->domain == NULL)) {
2240 status = NT_STATUS_NO_MEMORY;
2244 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2245 if (!NT_STATUS_IS_OK(status)) {
2249 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2251 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2252 if (!NT_STATUS_IS_OK(status)) {
2256 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2257 if (!NT_STATUS_IS_OK(status)) {
2261 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2262 if (!NT_STATUS_IS_OK(status)) {
2267 * Turn off sign+seal to allow selected auth level to turn it back on.
2269 result->a_u.ntlmssp_state->neg_flags &=
2270 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2272 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2273 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2274 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2275 result->a_u.ntlmssp_state->neg_flags
2276 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2280 return NT_STATUS_OK;
2283 TALLOC_FREE(result);
2287 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2288 enum pipe_auth_level auth_level,
2289 const struct dcinfo *pdc,
2290 struct cli_pipe_auth_data **presult)
2292 struct cli_pipe_auth_data *result;
2294 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2295 if (result == NULL) {
2296 return NT_STATUS_NO_MEMORY;
2299 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2300 result->auth_level = auth_level;
2302 result->user_name = talloc_strdup(result, "");
2303 result->domain = talloc_strdup(result, domain);
2304 if ((result->user_name == NULL) || (result->domain == NULL)) {
2308 result->a_u.schannel_auth = talloc(result,
2309 struct schannel_auth_struct);
2310 if (result->a_u.schannel_auth == NULL) {
2314 memcpy(result->a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2315 result->a_u.schannel_auth->seq_num = 0;
2318 return NT_STATUS_OK;
2321 TALLOC_FREE(result);
2322 return NT_STATUS_NO_MEMORY;
2325 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2327 data_blob_free(&auth->session_key);
2331 NTSTATUS rpccli_krb5_bind_data(TALLOC_CTX *mem_ctx,
2332 enum pipe_auth_level auth_level,
2333 const char *service_princ,
2334 const char *username,
2335 const char *password,
2336 struct cli_pipe_auth_data **presult)
2338 struct cli_pipe_auth_data *result;
2340 if ((username != NULL) && (password != NULL)) {
2341 int ret = kerberos_kinit_password(username, password, 0, NULL);
2343 return NT_STATUS_ACCESS_DENIED;
2347 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2348 if (result == NULL) {
2349 return NT_STATUS_NO_MEMORY;
2352 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2353 result->auth_level = auth_level;
2356 * Username / domain need fixing!
2358 result->user_name = talloc_strdup(result, "");
2359 result->domain = talloc_strdup(result, "");
2360 if ((result->user_name == NULL) || (result->domain == NULL)) {
2364 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2365 result, struct kerberos_auth_struct);
2366 if (result->a_u.kerberos_auth == NULL) {
2369 talloc_set_destructor(result->a_u.kerberos_auth,
2370 cli_auth_kerberos_data_destructor);
2372 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2373 result, service_princ);
2374 if (result->a_u.kerberos_auth->service_principal == NULL) {
2379 return NT_STATUS_OK;
2382 TALLOC_FREE(result);
2383 return NT_STATUS_NO_MEMORY;
2386 /****************************************************************************
2387 Open a named pipe over SMB to a remote server.
2389 * CAVEAT CALLER OF THIS FUNCTION:
2390 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2391 * so be sure that this function is called AFTER any structure (vs pointer)
2392 * assignment of the cli. In particular, libsmbclient does structure
2393 * assignments of cli, which invalidates the data in the returned
2394 * rpc_pipe_client if this function is called before the structure assignment
2397 ****************************************************************************/
2399 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2401 struct rpc_pipe_client *result;
2404 *perr = NT_STATUS_NO_MEMORY;
2406 /* sanity check to protect against crashes */
2409 *perr = NT_STATUS_INVALID_HANDLE;
2413 /* The pipe name index must fall within our array */
2414 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2416 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2417 if (result == NULL) {
2418 *perr = NT_STATUS_NO_MEMORY;
2422 result->auth = TALLOC_ZERO_P(result, struct cli_pipe_auth_data);
2423 if (result->auth == NULL) {
2424 *perr = NT_STATUS_NO_MEMORY;
2425 TALLOC_FREE(result);
2429 result->pipe_name = cli_get_pipe_name(pipe_idx);
2432 result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2433 result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2434 result->auth->auth_type = PIPE_AUTH_TYPE_NONE;
2435 result->auth->auth_level = PIPE_AUTH_LEVEL_NONE;
2437 result->auth->domain = talloc_strdup(result, cli->domain);
2438 result->auth->user_name = talloc_strdup(result, cli->user_name);
2439 result->desthost = talloc_strdup(result, cli->desthost);
2440 result->srv_name_slash = talloc_asprintf_strupper_m(
2441 result, "\\\\%s", result->desthost);
2443 if ((result->auth->domain == NULL)
2444 || (result->auth->user_name == NULL)
2445 || (result->desthost == NULL)
2446 || (result->srv_name_slash == NULL)) {
2447 *perr = NT_STATUS_NO_MEMORY;
2448 TALLOC_FREE(result);
2452 if (pipe_idx == PI_NETLOGON) {
2453 /* Set up a netlogon credential chain for a netlogon pipe. */
2454 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2455 if (result->dc == NULL) {
2456 *perr = NT_STATUS_NO_MEMORY;
2457 TALLOC_FREE(result);
2462 fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2464 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2465 "to machine %s. Error was %s\n",
2466 result->pipe_name, cli->desthost,
2468 *perr = cli_get_nt_error(cli);
2469 talloc_destroy(result);
2473 result->fnum = fnum;
2475 DLIST_ADD(cli->pipe_list, result);
2476 talloc_set_destructor(result, rpc_pipe_destructor);
2478 *perr = NT_STATUS_OK;
2483 /****************************************************************************
2484 Open a named pipe to an SMB server and bind anonymously.
2485 ****************************************************************************/
2487 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2489 struct rpc_pipe_client *result;
2491 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2492 if (result == NULL) {
2496 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
2497 if (!NT_STATUS_IS_OK(*perr)) {
2499 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2500 /* non AD domains just don't have this pipe, avoid
2501 * level 0 statement in that case - gd */
2504 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2505 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2506 TALLOC_FREE(result);
2510 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2511 result->pipe_name, cli->desthost ));
2516 /****************************************************************************
2517 Free function for NTLMSSP auth.
2518 ****************************************************************************/
2520 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
2522 if (auth->a_u.ntlmssp_state) {
2523 ntlmssp_end(&auth->a_u.ntlmssp_state);
2524 auth->a_u.ntlmssp_state = NULL;
2528 /****************************************************************************
2529 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2530 ****************************************************************************/
2532 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2534 enum pipe_auth_type auth_type,
2535 enum pipe_auth_level auth_level,
2537 const char *username,
2538 const char *password,
2541 struct rpc_pipe_client *result;
2542 NTLMSSP_STATE *ntlmssp_state = NULL;
2544 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2545 if (result == NULL) {
2549 result->auth->cli_auth_data_free_func = cli_ntlmssp_auth_free;
2551 TALLOC_FREE(result->auth->domain);
2552 TALLOC_FREE(result->auth->user_name);
2554 result->auth->domain = talloc_strdup(result, domain);
2555 result->auth->user_name = talloc_strdup(result, username);
2557 if ((result->auth->domain == NULL)
2558 || (result->auth->user_name == NULL)) {
2559 *perr = NT_STATUS_NO_MEMORY;
2563 *perr = ntlmssp_client_start(&ntlmssp_state);
2564 if (!NT_STATUS_IS_OK(*perr)) {
2568 result->auth->a_u.ntlmssp_state = ntlmssp_state;
2570 *perr = ntlmssp_set_username(ntlmssp_state, username);
2571 if (!NT_STATUS_IS_OK(*perr)) {
2575 *perr = ntlmssp_set_domain(ntlmssp_state, domain);
2576 if (!NT_STATUS_IS_OK(*perr)) {
2580 if (cli->pwd.null_pwd) {
2581 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
2582 if (!NT_STATUS_IS_OK(*perr)) {
2586 *perr = ntlmssp_set_password(ntlmssp_state, password);
2587 if (!NT_STATUS_IS_OK(*perr)) {
2592 /* Turn off sign+seal to allow selected auth level to turn it back on. */
2593 ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
2595 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2596 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2597 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2598 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2601 *perr = rpc_pipe_bind(result, auth_type, auth_level);
2602 if (!NT_STATUS_IS_OK(*perr)) {
2603 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2604 nt_errstr(*perr) ));
2608 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2609 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2610 result->pipe_name, cli->desthost,
2611 domain, username ));
2617 TALLOC_FREE(result);
2621 /****************************************************************************
2623 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2624 ****************************************************************************/
2626 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2628 enum pipe_auth_level auth_level,
2630 const char *username,
2631 const char *password,
2634 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2636 PIPE_AUTH_TYPE_NTLMSSP,
2644 /****************************************************************************
2646 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2647 ****************************************************************************/
2649 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2651 enum pipe_auth_level auth_level,
2653 const char *username,
2654 const char *password,
2657 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2659 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2667 /****************************************************************************
2668 Get a the schannel session key out of an already opened netlogon pipe.
2669 ****************************************************************************/
2670 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2671 struct cli_state *cli,
2676 uint32 sec_chan_type = 0;
2677 unsigned char machine_pwd[16];
2678 const char *machine_account;
2680 /* Get the machine account credentials from secrets.tdb. */
2681 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2684 DEBUG(0, ("get_schannel_session_key: could not fetch "
2685 "trust account password for domain '%s'\n",
2687 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2691 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2692 cli->desthost, /* server name */
2693 domain, /* domain */
2694 global_myname(), /* client name */
2695 machine_account, /* machine account name */
2700 if (!NT_STATUS_IS_OK(*perr)) {
2701 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2702 "failed with result %s to server %s, domain %s, machine account %s.\n",
2703 nt_errstr(*perr), cli->desthost, domain, machine_account ));
2707 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2708 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2710 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2717 /****************************************************************************
2718 Open a netlogon pipe and get the schannel session key.
2719 Now exposed to external callers.
2720 ****************************************************************************/
2723 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2728 struct rpc_pipe_client *netlogon_pipe = NULL;
2730 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2731 if (!netlogon_pipe) {
2735 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2738 TALLOC_FREE(netlogon_pipe);
2742 return netlogon_pipe;
2745 /****************************************************************************
2747 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2748 using session_key. sign and seal.
2749 ****************************************************************************/
2751 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2753 enum pipe_auth_level auth_level,
2755 const struct dcinfo *pdc,
2758 struct rpc_pipe_client *result;
2760 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2761 if (result == NULL) {
2765 result->auth->a_u.schannel_auth = TALLOC_ZERO_P(
2766 result, struct schannel_auth_struct);
2767 if (!result->auth->a_u.schannel_auth) {
2768 TALLOC_FREE(result);
2769 *perr = NT_STATUS_NO_MEMORY;
2773 TALLOC_FREE(result->auth->domain);
2774 result->auth->domain = talloc_strdup(result, domain);
2775 if (result->auth->domain == NULL) {
2776 TALLOC_FREE(result);
2777 *perr = NT_STATUS_NO_MEMORY;
2781 memcpy(result->auth->a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2783 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
2784 if (!NT_STATUS_IS_OK(*perr)) {
2785 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2786 nt_errstr(*perr) ));
2787 TALLOC_FREE(result);
2791 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2796 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2798 "and bound using schannel.\n",
2799 result->pipe_name, cli->desthost, domain ));
2804 /****************************************************************************
2805 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2806 Fetch the session key ourselves using a temporary netlogon pipe. This
2807 version uses an ntlmssp auth bound netlogon pipe to get the key.
2808 ****************************************************************************/
2810 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2812 const char *username,
2813 const char *password,
2817 struct rpc_pipe_client *netlogon_pipe = NULL;
2819 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2820 if (!netlogon_pipe) {
2824 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2827 TALLOC_FREE(netlogon_pipe);
2831 return netlogon_pipe;
2834 /****************************************************************************
2835 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2836 Fetch the session key ourselves using a temporary netlogon pipe. This version
2837 uses an ntlmssp bind to get the session key.
2838 ****************************************************************************/
2840 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2842 enum pipe_auth_level auth_level,
2844 const char *username,
2845 const char *password,
2848 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2849 struct rpc_pipe_client *netlogon_pipe = NULL;
2850 struct rpc_pipe_client *result = NULL;
2852 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2853 password, &neg_flags, perr);
2854 if (!netlogon_pipe) {
2855 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2856 "key from server %s for domain %s.\n",
2857 cli->desthost, domain ));
2861 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2863 domain, netlogon_pipe->dc, perr);
2865 /* Now we've bound using the session key we can close the netlog pipe. */
2866 TALLOC_FREE(netlogon_pipe);
2871 /****************************************************************************
2872 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2873 Fetch the session key ourselves using a temporary netlogon pipe.
2874 ****************************************************************************/
2876 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2878 enum pipe_auth_level auth_level,
2882 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2883 struct rpc_pipe_client *netlogon_pipe = NULL;
2884 struct rpc_pipe_client *result = NULL;
2886 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2887 if (!netlogon_pipe) {
2888 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2889 "key from server %s for domain %s.\n",
2890 cli->desthost, domain ));
2894 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2896 domain, netlogon_pipe->dc, perr);
2898 /* Now we've bound using the session key we can close the netlog pipe. */
2899 TALLOC_FREE(netlogon_pipe);
2906 /****************************************************************************
2907 Free function for the kerberos spcific data.
2908 ****************************************************************************/
2910 static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
2912 data_blob_free(&a->a_u.kerberos_auth->session_key);
2917 /****************************************************************************
2918 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2919 The idea is this can be called with service_princ, username and password all
2920 NULL so long as the caller has a TGT.
2921 ****************************************************************************/
2923 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2925 enum pipe_auth_level auth_level,
2926 const char *service_princ,
2927 const char *username,
2928 const char *password,
2932 struct rpc_pipe_client *result;
2934 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2935 if (result == NULL) {
2939 /* Default service principal is "desthost$@realm" */
2940 if (!service_princ) {
2941 service_princ = talloc_asprintf(result, "%s$@%s",
2942 cli->desthost, lp_realm() );
2943 if (!service_princ) {
2944 TALLOC_FREE(result);
2949 /* Only get a new TGT if username/password are given. */
2950 if (username && password) {
2951 int ret = kerberos_kinit_password(username, password, 0, NULL);
2953 TALLOC_FREE(result);
2958 result->auth->a_u.kerberos_auth = TALLOC_ZERO_P(
2959 result, struct kerberos_auth_struct);
2960 if (!result->auth->a_u.kerberos_auth) {
2961 TALLOC_FREE(result);
2962 *perr = NT_STATUS_NO_MEMORY;
2966 result->auth->a_u.kerberos_auth->service_principal = service_princ;
2967 result->auth->cli_auth_data_free_func = kerberos_auth_struct_free;
2969 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
2970 if (!NT_STATUS_IS_OK(*perr)) {
2971 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2972 nt_errstr(*perr) ));
2973 TALLOC_FREE(result);
2979 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));