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->domain || !cli->domain[0]) {
1071 cli->domain = talloc_strdup(cli, lp_workgroup());
1072 if (cli->domain == NULL) {
1073 return NT_STATUS_NO_MEMORY;
1077 init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
1080 * Now marshall the data into the auth parse_struct.
1083 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1084 &schannel_neg, auth_data, 0)) {
1085 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1086 prs_mem_free(auth_data);
1087 return NT_STATUS_NO_MEMORY;
1090 return NT_STATUS_OK;
1093 /*******************************************************************
1094 Creates the internals of a DCE/RPC bind request or alter context PDU.
1095 ********************************************************************/
1097 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1098 prs_struct *rpc_out,
1100 const RPC_IFACE *abstract,
1101 const RPC_IFACE *transfer,
1102 RPC_HDR_AUTH *phdr_auth,
1103 prs_struct *pauth_info)
1107 RPC_CONTEXT rpc_ctx;
1108 uint16 auth_len = prs_offset(pauth_info);
1109 uint8 ss_padding_len = 0;
1110 uint16 frag_len = 0;
1112 /* create the RPC context. */
1113 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1115 /* create the bind request RPC_HDR_RB */
1116 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1118 /* Start building the frag length. */
1119 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1121 /* Do we need to pad ? */
1123 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1125 ss_padding_len = 8 - (data_len % 8);
1126 phdr_auth->auth_pad_len = ss_padding_len;
1128 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1131 /* Create the request RPC_HDR */
1132 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1134 /* Marshall the RPC header */
1135 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1136 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1137 return NT_STATUS_NO_MEMORY;
1140 /* Marshall the bind request data */
1141 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1142 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1143 return NT_STATUS_NO_MEMORY;
1147 * Grow the outgoing buffer to store any auth info.
1151 if (ss_padding_len) {
1153 memset(pad, '\0', 8);
1154 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1155 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1156 return NT_STATUS_NO_MEMORY;
1160 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1161 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1162 return NT_STATUS_NO_MEMORY;
1166 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1167 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1168 return NT_STATUS_NO_MEMORY;
1172 return NT_STATUS_OK;
1175 /*******************************************************************
1176 Creates a DCE/RPC bind request.
1177 ********************************************************************/
1179 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1180 prs_struct *rpc_out,
1182 const RPC_IFACE *abstract,
1183 const RPC_IFACE *transfer,
1184 enum pipe_auth_type auth_type,
1185 enum pipe_auth_level auth_level)
1187 RPC_HDR_AUTH hdr_auth;
1188 prs_struct auth_info;
1189 NTSTATUS ret = NT_STATUS_OK;
1191 ZERO_STRUCT(hdr_auth);
1192 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1193 return NT_STATUS_NO_MEMORY;
1195 switch (auth_type) {
1196 case PIPE_AUTH_TYPE_SCHANNEL:
1197 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1198 if (!NT_STATUS_IS_OK(ret)) {
1199 prs_mem_free(&auth_info);
1204 case PIPE_AUTH_TYPE_NTLMSSP:
1205 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1206 if (!NT_STATUS_IS_OK(ret)) {
1207 prs_mem_free(&auth_info);
1212 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1213 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1214 if (!NT_STATUS_IS_OK(ret)) {
1215 prs_mem_free(&auth_info);
1220 case PIPE_AUTH_TYPE_KRB5:
1221 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1222 if (!NT_STATUS_IS_OK(ret)) {
1223 prs_mem_free(&auth_info);
1228 case PIPE_AUTH_TYPE_NONE:
1232 /* "Can't" happen. */
1233 return NT_STATUS_INVALID_INFO_CLASS;
1236 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1244 prs_mem_free(&auth_info);
1248 /*******************************************************************
1249 Create and add the NTLMSSP sign/seal auth header and data.
1250 ********************************************************************/
1252 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1254 uint32 ss_padding_len,
1255 prs_struct *outgoing_pdu)
1257 RPC_HDR_AUTH auth_info;
1259 DATA_BLOB auth_blob = data_blob_null;
1260 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1262 if (!cli->auth->a_u.ntlmssp_state) {
1263 return NT_STATUS_INVALID_PARAMETER;
1266 /* Init and marshall the auth header. */
1267 init_rpc_hdr_auth(&auth_info,
1268 map_pipe_auth_type_to_rpc_auth_type(
1269 cli->auth->auth_type),
1270 cli->auth->auth_level,
1272 1 /* context id. */);
1274 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1275 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1276 data_blob_free(&auth_blob);
1277 return NT_STATUS_NO_MEMORY;
1280 switch (cli->auth->auth_level) {
1281 case PIPE_AUTH_LEVEL_PRIVACY:
1282 /* Data portion is encrypted. */
1283 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1284 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1286 (unsigned char *)prs_data_p(outgoing_pdu),
1287 (size_t)prs_offset(outgoing_pdu),
1289 if (!NT_STATUS_IS_OK(status)) {
1290 data_blob_free(&auth_blob);
1295 case PIPE_AUTH_LEVEL_INTEGRITY:
1296 /* Data is signed. */
1297 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1298 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1300 (unsigned char *)prs_data_p(outgoing_pdu),
1301 (size_t)prs_offset(outgoing_pdu),
1303 if (!NT_STATUS_IS_OK(status)) {
1304 data_blob_free(&auth_blob);
1311 smb_panic("bad auth level");
1313 return NT_STATUS_INVALID_PARAMETER;
1316 /* Finally marshall the blob. */
1318 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1319 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1320 (unsigned int)NTLMSSP_SIG_SIZE));
1321 data_blob_free(&auth_blob);
1322 return NT_STATUS_NO_MEMORY;
1325 data_blob_free(&auth_blob);
1326 return NT_STATUS_OK;
1329 /*******************************************************************
1330 Create and add the schannel sign/seal auth header and data.
1331 ********************************************************************/
1333 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1335 uint32 ss_padding_len,
1336 prs_struct *outgoing_pdu)
1338 RPC_HDR_AUTH auth_info;
1339 RPC_AUTH_SCHANNEL_CHK verf;
1340 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1341 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1342 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1345 return NT_STATUS_INVALID_PARAMETER;
1348 /* Init and marshall the auth header. */
1349 init_rpc_hdr_auth(&auth_info,
1350 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1351 cli->auth->auth_level,
1353 1 /* context id. */);
1355 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1356 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1357 return NT_STATUS_NO_MEMORY;
1360 switch (cli->auth->auth_level) {
1361 case PIPE_AUTH_LEVEL_PRIVACY:
1362 case PIPE_AUTH_LEVEL_INTEGRITY:
1363 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1366 schannel_encode(sas,
1367 cli->auth->auth_level,
1368 SENDER_IS_INITIATOR,
1378 smb_panic("bad auth level");
1380 return NT_STATUS_INVALID_PARAMETER;
1383 /* Finally marshall the blob. */
1384 smb_io_rpc_auth_schannel_chk("",
1385 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1390 return NT_STATUS_OK;
1393 /*******************************************************************
1394 Calculate how much data we're going to send in this packet, also
1395 work out any sign/seal padding length.
1396 ********************************************************************/
1398 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1402 uint32 *p_ss_padding)
1404 uint32 data_space, data_len;
1406 switch (cli->auth->auth_level) {
1407 case PIPE_AUTH_LEVEL_NONE:
1408 case PIPE_AUTH_LEVEL_CONNECT:
1409 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1410 data_len = MIN(data_space, data_left);
1413 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1416 case PIPE_AUTH_LEVEL_INTEGRITY:
1417 case PIPE_AUTH_LEVEL_PRIVACY:
1418 /* Treat the same for all authenticated rpc requests. */
1419 switch(cli->auth->auth_type) {
1420 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1421 case PIPE_AUTH_TYPE_NTLMSSP:
1422 *p_auth_len = NTLMSSP_SIG_SIZE;
1424 case PIPE_AUTH_TYPE_SCHANNEL:
1425 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1428 smb_panic("bad auth type");
1432 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1433 RPC_HDR_AUTH_LEN - *p_auth_len;
1435 data_len = MIN(data_space, data_left);
1437 *p_ss_padding = 8 - (data_len % 8);
1439 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1440 data_len + *p_ss_padding + /* data plus padding. */
1441 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1445 smb_panic("bad auth level");
1451 /*******************************************************************
1453 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1454 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1455 and deals with signing/sealing details.
1456 ********************************************************************/
1458 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1460 prs_struct *in_data,
1461 prs_struct *out_data)
1464 uint32 data_left = prs_offset(in_data);
1465 uint32 alloc_hint = prs_offset(in_data);
1466 uint32 data_sent_thistime = 0;
1467 uint32 current_data_offset = 0;
1468 uint32 call_id = get_rpc_call_id();
1470 prs_struct outgoing_pdu;
1472 memset(pad, '\0', 8);
1474 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1475 /* Server is screwed up ! */
1476 return NT_STATUS_INVALID_PARAMETER;
1479 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1480 return NT_STATUS_NO_MEMORY;
1484 RPC_HDR_REQ hdr_req;
1485 uint16 auth_len = 0;
1486 uint16 frag_len = 0;
1488 uint32 ss_padding = 0;
1490 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1491 &frag_len, &auth_len, &ss_padding);
1493 if (current_data_offset == 0) {
1494 flags = RPC_FLG_FIRST;
1497 if (data_sent_thistime == data_left) {
1498 flags |= RPC_FLG_LAST;
1501 /* Create and marshall the header and request header. */
1502 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1504 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1505 prs_mem_free(&outgoing_pdu);
1506 return NT_STATUS_NO_MEMORY;
1509 /* Create the rpc request RPC_HDR_REQ */
1510 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1512 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1513 prs_mem_free(&outgoing_pdu);
1514 return NT_STATUS_NO_MEMORY;
1517 /* Copy in the data, plus any ss padding. */
1518 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1519 prs_mem_free(&outgoing_pdu);
1520 return NT_STATUS_NO_MEMORY;
1523 /* Copy the sign/seal padding data. */
1525 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1526 prs_mem_free(&outgoing_pdu);
1527 return NT_STATUS_NO_MEMORY;
1531 /* Generate any auth sign/seal and add the auth footer. */
1533 switch (cli->auth->auth_type) {
1534 case PIPE_AUTH_TYPE_NONE:
1536 case PIPE_AUTH_TYPE_NTLMSSP:
1537 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1538 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1539 if (!NT_STATUS_IS_OK(ret)) {
1540 prs_mem_free(&outgoing_pdu);
1544 case PIPE_AUTH_TYPE_SCHANNEL:
1545 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1546 if (!NT_STATUS_IS_OK(ret)) {
1547 prs_mem_free(&outgoing_pdu);
1552 smb_panic("bad auth type");
1553 break; /* notreached */
1557 /* Actually send the packet. */
1558 if (flags & RPC_FLG_LAST) {
1559 /* Last packet - send the data, get the reply and return. */
1560 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1561 prs_mem_free(&outgoing_pdu);
1563 if (DEBUGLEVEL >= 50) {
1564 char *dump_name = NULL;
1565 /* Also capture received data */
1566 if (asprintf(&dump_name, "%s/reply_%s_%d",
1567 get_dyn_LOGFILEBASE(), cli->pipe_name,
1569 prs_dump(dump_name, op_num, out_data);
1570 SAFE_FREE(dump_name);
1576 /* More packets to come - write and continue. */
1577 ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */
1578 prs_data_p(&outgoing_pdu),
1580 (size_t)hdr.frag_len);
1582 if (num_written != hdr.frag_len) {
1583 prs_mem_free(&outgoing_pdu);
1584 return cli_get_nt_error(cli->cli);
1588 current_data_offset += data_sent_thistime;
1589 data_left -= data_sent_thistime;
1591 /* Reset the marshalling position back to zero. */
1592 if (!prs_set_offset(&outgoing_pdu, 0)) {
1593 prs_mem_free(&outgoing_pdu);
1594 return NT_STATUS_NO_MEMORY;
1599 /****************************************************************************
1600 Set the handle state.
1601 ****************************************************************************/
1603 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1604 const char *pipe_name, uint16 device_state)
1606 bool state_set = False;
1608 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1609 char *rparam = NULL;
1611 uint32 rparam_len, rdata_len;
1613 if (pipe_name == NULL)
1616 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1617 cli->fnum, pipe_name, device_state));
1619 /* create parameters: device state */
1620 SSVAL(param, 0, device_state);
1622 /* create setup parameters. */
1624 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1626 /* send the data on \PIPE\ */
1627 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1628 setup, 2, 0, /* setup, length, max */
1629 param, 2, 0, /* param, length, max */
1630 NULL, 0, 1024, /* data, length, max */
1631 &rparam, &rparam_len, /* return param, length */
1632 &rdata, &rdata_len)) /* return data, length */
1634 DEBUG(5, ("Set Handle state: return OK\n"));
1645 /****************************************************************************
1646 Check the rpc bind acknowledge response.
1647 ****************************************************************************/
1649 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1651 if ( hdr_ba->addr.len == 0) {
1652 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1655 /* check the transfer syntax */
1656 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1657 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1658 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1662 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1663 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1664 hdr_ba->res.num_results, hdr_ba->res.reason));
1667 DEBUG(5,("check_bind_response: accepted!\n"));
1671 /*******************************************************************
1672 Creates a DCE/RPC bind authentication response.
1673 This is the packet that is sent back to the server once we
1674 have received a BIND-ACK, to finish the third leg of
1675 the authentication handshake.
1676 ********************************************************************/
1678 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1680 enum pipe_auth_type auth_type,
1681 enum pipe_auth_level auth_level,
1682 DATA_BLOB *pauth_blob,
1683 prs_struct *rpc_out)
1686 RPC_HDR_AUTH hdr_auth;
1689 /* Create the request RPC_HDR */
1690 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1691 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1692 pauth_blob->length );
1695 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1696 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1697 return NT_STATUS_NO_MEMORY;
1701 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1702 about padding - shouldn't this pad to length 8 ? JRA.
1705 /* 4 bytes padding. */
1706 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1707 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1708 return NT_STATUS_NO_MEMORY;
1711 /* Create the request RPC_HDR_AUTHA */
1712 init_rpc_hdr_auth(&hdr_auth,
1713 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1716 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1717 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1718 return NT_STATUS_NO_MEMORY;
1722 * Append the auth data to the outgoing buffer.
1725 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1726 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1727 return NT_STATUS_NO_MEMORY;
1730 return NT_STATUS_OK;
1733 /****************************************************************************
1734 Create and send the third packet in an RPC auth.
1735 ****************************************************************************/
1737 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1741 enum pipe_auth_type auth_type,
1742 enum pipe_auth_level auth_level)
1744 DATA_BLOB server_response = data_blob_null;
1745 DATA_BLOB client_reply = data_blob_null;
1746 RPC_HDR_AUTH hdr_auth;
1751 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1752 return NT_STATUS_INVALID_PARAMETER;
1755 /* Process the returned NTLMSSP blob first. */
1756 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1757 return NT_STATUS_INVALID_PARAMETER;
1760 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1761 return NT_STATUS_INVALID_PARAMETER;
1764 /* TODO - check auth_type/auth_level match. */
1766 server_response = data_blob(NULL, phdr->auth_len);
1767 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1769 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1773 if (!NT_STATUS_IS_OK(nt_status)) {
1774 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1775 data_blob_free(&server_response);
1779 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1781 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1782 auth_type, auth_level,
1783 &client_reply, &rpc_out);
1785 if (!NT_STATUS_IS_OK(nt_status)) {
1786 prs_mem_free(&rpc_out);
1787 data_blob_free(&client_reply);
1788 data_blob_free(&server_response);
1792 /* 8 here is named pipe message mode. */
1793 ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
1794 (size_t)prs_offset(&rpc_out));
1796 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1797 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
1798 prs_mem_free(&rpc_out);
1799 data_blob_free(&client_reply);
1800 data_blob_free(&server_response);
1801 return cli_get_nt_error(cli->cli);
1804 DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
1805 "fnum 0x%x sent auth3 response ok.\n",
1808 (unsigned int)cli->fnum));
1810 prs_mem_free(&rpc_out);
1811 data_blob_free(&client_reply);
1812 data_blob_free(&server_response);
1813 return NT_STATUS_OK;
1816 /*******************************************************************
1817 Creates a DCE/RPC bind alter context authentication request which
1818 may contain a spnego auth blobl
1819 ********************************************************************/
1821 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1822 const RPC_IFACE *abstract,
1823 const RPC_IFACE *transfer,
1824 enum pipe_auth_level auth_level,
1825 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1826 prs_struct *rpc_out)
1828 RPC_HDR_AUTH hdr_auth;
1829 prs_struct auth_info;
1830 NTSTATUS ret = NT_STATUS_OK;
1832 ZERO_STRUCT(hdr_auth);
1833 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1834 return NT_STATUS_NO_MEMORY;
1836 /* We may change the pad length before marshalling. */
1837 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1839 if (pauth_blob->length) {
1840 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1841 prs_mem_free(&auth_info);
1842 return NT_STATUS_NO_MEMORY;
1846 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1853 prs_mem_free(&auth_info);
1857 /*******************************************************************
1858 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1859 and gets a response.
1860 ********************************************************************/
1862 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1866 const RPC_IFACE *abstract,
1867 const RPC_IFACE *transfer,
1868 enum pipe_auth_type auth_type,
1869 enum pipe_auth_level auth_level)
1871 DATA_BLOB server_spnego_response = data_blob_null;
1872 DATA_BLOB server_ntlm_response = data_blob_null;
1873 DATA_BLOB client_reply = data_blob_null;
1874 DATA_BLOB tmp_blob = data_blob_null;
1875 RPC_HDR_AUTH hdr_auth;
1879 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1880 return NT_STATUS_INVALID_PARAMETER;
1883 /* Process the returned NTLMSSP blob first. */
1884 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1885 return NT_STATUS_INVALID_PARAMETER;
1888 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1889 return NT_STATUS_INVALID_PARAMETER;
1892 server_spnego_response = data_blob(NULL, phdr->auth_len);
1893 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1895 /* The server might give us back two challenges - tmp_blob is for the second. */
1896 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
1897 data_blob_free(&server_spnego_response);
1898 data_blob_free(&server_ntlm_response);
1899 data_blob_free(&tmp_blob);
1900 return NT_STATUS_INVALID_PARAMETER;
1903 /* We're finished with the server spnego response and the tmp_blob. */
1904 data_blob_free(&server_spnego_response);
1905 data_blob_free(&tmp_blob);
1907 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1908 server_ntlm_response,
1911 /* Finished with the server_ntlm response */
1912 data_blob_free(&server_ntlm_response);
1914 if (!NT_STATUS_IS_OK(nt_status)) {
1915 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
1916 data_blob_free(&client_reply);
1920 /* SPNEGO wrap the client reply. */
1921 tmp_blob = spnego_gen_auth(client_reply);
1922 data_blob_free(&client_reply);
1923 client_reply = tmp_blob;
1924 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
1926 /* Now prepare the alter context pdu. */
1927 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1929 nt_status = create_rpc_alter_context(rpc_call_id,
1936 data_blob_free(&client_reply);
1938 if (!NT_STATUS_IS_OK(nt_status)) {
1939 prs_mem_free(&rpc_out);
1943 /* Initialize the returning data struct. */
1945 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
1947 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
1948 if (!NT_STATUS_IS_OK(nt_status)) {
1949 prs_mem_free(&rpc_out);
1953 prs_mem_free(&rpc_out);
1955 /* Get the auth blob from the reply. */
1956 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
1957 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
1958 return NT_STATUS_BUFFER_TOO_SMALL;
1961 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1962 return NT_STATUS_INVALID_PARAMETER;
1965 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1966 return NT_STATUS_INVALID_PARAMETER;
1969 server_spnego_response = data_blob(NULL, phdr->auth_len);
1970 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1972 /* Check we got a valid auth response. */
1973 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
1974 data_blob_free(&server_spnego_response);
1975 data_blob_free(&tmp_blob);
1976 return NT_STATUS_INVALID_PARAMETER;
1979 data_blob_free(&server_spnego_response);
1980 data_blob_free(&tmp_blob);
1982 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
1983 "remote machine %s pipe %s fnum 0x%x.\n",
1986 (unsigned int)cli->fnum));
1988 return NT_STATUS_OK;
1991 /****************************************************************************
1993 ****************************************************************************/
1995 static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1996 enum pipe_auth_type auth_type,
1997 enum pipe_auth_level auth_level)
2006 DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2007 (unsigned int)cli->fnum,
2009 (unsigned int)auth_type,
2010 (unsigned int)auth_level ));
2012 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2014 rpc_call_id = get_rpc_call_id();
2016 /* Marshall the outgoing data. */
2017 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2018 cli->abstract_syntax,
2019 cli->transfer_syntax,
2023 if (!NT_STATUS_IS_OK(status)) {
2024 prs_mem_free(&rpc_out);
2028 /* Initialize the incoming data struct. */
2029 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2031 /* send data on \PIPE\. receive a response */
2032 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2033 if (!NT_STATUS_IS_OK(status)) {
2034 prs_mem_free(&rpc_out);
2038 prs_mem_free(&rpc_out);
2040 DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2041 "fnum 0x%x bind request returned ok.\n",
2044 (unsigned int)cli->fnum));
2046 /* Unmarshall the RPC header */
2047 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2048 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2049 prs_mem_free(&rbuf);
2050 return NT_STATUS_BUFFER_TOO_SMALL;
2053 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2054 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2055 prs_mem_free(&rbuf);
2056 return NT_STATUS_BUFFER_TOO_SMALL;
2059 if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2060 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2061 prs_mem_free(&rbuf);
2062 return NT_STATUS_BUFFER_TOO_SMALL;
2065 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2066 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2068 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2071 case PIPE_AUTH_TYPE_NONE:
2072 case PIPE_AUTH_TYPE_SCHANNEL:
2073 /* Bind complete. */
2076 case PIPE_AUTH_TYPE_NTLMSSP:
2077 /* Need to send AUTH3 packet - no reply. */
2078 status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
2079 auth_type, auth_level);
2080 if (!NT_STATUS_IS_OK(status)) {
2081 prs_mem_free(&rbuf);
2086 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2087 /* Need to send alter context request and reply. */
2088 status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
2089 cli->abstract_syntax,
2090 cli->transfer_syntax,
2091 auth_type, auth_level);
2092 if (!NT_STATUS_IS_OK(status)) {
2093 prs_mem_free(&rbuf);
2098 case PIPE_AUTH_TYPE_KRB5:
2102 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2103 (unsigned int)auth_type ));
2104 prs_mem_free(&rbuf);
2105 return NT_STATUS_INVALID_INFO_CLASS;
2108 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2109 if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2110 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2111 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2112 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2113 prs_mem_free(&rbuf);
2114 return NT_STATUS_INVALID_PARAMETER;
2117 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2118 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2119 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2120 prs_mem_free(&rbuf);
2121 return NT_STATUS_INVALID_PARAMETER;
2126 /* Pipe is bound - set up auth_type and auth_level data. */
2128 cli->auth->auth_type = auth_type;
2129 cli->auth->auth_level = auth_level;
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 if (p->auth->cli_auth_data_free_func) {
2176 (*p->auth->cli_auth_data_free_func)(p->auth);
2179 DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n",
2180 p->pipe_name, p->desthost ));
2182 DLIST_REMOVE(p->cli->pipe_list, p);
2184 return ret ? -1 : 0;
2187 /****************************************************************************
2188 Open a named pipe over SMB to a remote server.
2190 * CAVEAT CALLER OF THIS FUNCTION:
2191 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2192 * so be sure that this function is called AFTER any structure (vs pointer)
2193 * assignment of the cli. In particular, libsmbclient does structure
2194 * assignments of cli, which invalidates the data in the returned
2195 * rpc_pipe_client if this function is called before the structure assignment
2198 ****************************************************************************/
2200 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2202 struct rpc_pipe_client *result;
2205 *perr = NT_STATUS_NO_MEMORY;
2207 /* sanity check to protect against crashes */
2210 *perr = NT_STATUS_INVALID_HANDLE;
2214 /* The pipe name index must fall within our array */
2215 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2217 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2218 if (result == NULL) {
2219 *perr = NT_STATUS_NO_MEMORY;
2223 result->auth = TALLOC_ZERO_P(result, struct cli_pipe_auth_data);
2224 if (result->auth == NULL) {
2225 *perr = NT_STATUS_NO_MEMORY;
2226 TALLOC_FREE(result);
2230 result->pipe_name = cli_get_pipe_name(pipe_idx);
2233 result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2234 result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2235 result->auth->auth_type = PIPE_AUTH_TYPE_NONE;
2236 result->auth->auth_level = PIPE_AUTH_LEVEL_NONE;
2238 result->domain = talloc_strdup(result, cli->domain);
2239 result->user_name = talloc_strdup(result, cli->user_name);
2240 result->desthost = talloc_strdup(result, cli->desthost);
2241 result->srv_name_slash = talloc_asprintf_strupper_m(
2242 result, "\\\\%s", result->desthost);
2244 if ((result->domain == NULL)
2245 || (result->user_name == NULL)
2246 || (result->desthost == NULL)
2247 || (result->srv_name_slash == NULL)) {
2248 *perr = NT_STATUS_NO_MEMORY;
2249 TALLOC_FREE(result);
2253 if (pipe_idx == PI_NETLOGON) {
2254 /* Set up a netlogon credential chain for a netlogon pipe. */
2255 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2256 if (result->dc == NULL) {
2257 *perr = NT_STATUS_NO_MEMORY;
2258 TALLOC_FREE(result);
2263 fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2265 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2266 "to machine %s. Error was %s\n",
2267 result->pipe_name, cli->desthost,
2269 *perr = cli_get_nt_error(cli);
2270 talloc_destroy(result);
2274 result->fnum = fnum;
2276 DLIST_ADD(cli->pipe_list, result);
2277 talloc_set_destructor(result, rpc_pipe_destructor);
2279 *perr = NT_STATUS_OK;
2284 /****************************************************************************
2285 Open a named pipe to an SMB server and bind anonymously.
2286 ****************************************************************************/
2288 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2290 struct rpc_pipe_client *result;
2292 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2293 if (result == NULL) {
2297 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
2298 if (!NT_STATUS_IS_OK(*perr)) {
2300 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2301 /* non AD domains just don't have this pipe, avoid
2302 * level 0 statement in that case - gd */
2305 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2306 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2307 TALLOC_FREE(result);
2311 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2312 result->pipe_name, cli->desthost ));
2317 /****************************************************************************
2318 Free function for NTLMSSP auth.
2319 ****************************************************************************/
2321 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
2323 if (auth->a_u.ntlmssp_state) {
2324 ntlmssp_end(&auth->a_u.ntlmssp_state);
2325 auth->a_u.ntlmssp_state = NULL;
2329 /****************************************************************************
2330 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2331 ****************************************************************************/
2333 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2335 enum pipe_auth_type auth_type,
2336 enum pipe_auth_level auth_level,
2338 const char *username,
2339 const char *password,
2342 struct rpc_pipe_client *result;
2343 NTLMSSP_STATE *ntlmssp_state = NULL;
2345 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2346 if (result == NULL) {
2350 result->auth->cli_auth_data_free_func = cli_ntlmssp_auth_free;
2352 TALLOC_FREE(result->domain);
2353 TALLOC_FREE(result->user_name);
2355 result->domain = talloc_strdup(result, domain);
2356 result->user_name = talloc_strdup(result, username);
2358 if ((result->domain == NULL) || (result->user_name == NULL)) {
2359 *perr = NT_STATUS_NO_MEMORY;
2363 *perr = ntlmssp_client_start(&ntlmssp_state);
2364 if (!NT_STATUS_IS_OK(*perr)) {
2368 result->auth->a_u.ntlmssp_state = ntlmssp_state;
2370 *perr = ntlmssp_set_username(ntlmssp_state, username);
2371 if (!NT_STATUS_IS_OK(*perr)) {
2375 *perr = ntlmssp_set_domain(ntlmssp_state, domain);
2376 if (!NT_STATUS_IS_OK(*perr)) {
2380 if (cli->pwd.null_pwd) {
2381 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
2382 if (!NT_STATUS_IS_OK(*perr)) {
2386 *perr = ntlmssp_set_password(ntlmssp_state, password);
2387 if (!NT_STATUS_IS_OK(*perr)) {
2392 /* Turn off sign+seal to allow selected auth level to turn it back on. */
2393 ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
2395 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2396 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2397 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2398 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2401 *perr = rpc_pipe_bind(result, auth_type, auth_level);
2402 if (!NT_STATUS_IS_OK(*perr)) {
2403 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2404 nt_errstr(*perr) ));
2408 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2409 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2410 result->pipe_name, cli->desthost,
2411 domain, username ));
2417 TALLOC_FREE(result);
2421 /****************************************************************************
2423 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2424 ****************************************************************************/
2426 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2428 enum pipe_auth_level auth_level,
2430 const char *username,
2431 const char *password,
2434 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2436 PIPE_AUTH_TYPE_NTLMSSP,
2444 /****************************************************************************
2446 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2447 ****************************************************************************/
2449 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2451 enum pipe_auth_level auth_level,
2453 const char *username,
2454 const char *password,
2457 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2459 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2467 /****************************************************************************
2468 Get a the schannel session key out of an already opened netlogon pipe.
2469 ****************************************************************************/
2470 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2471 struct cli_state *cli,
2476 uint32 sec_chan_type = 0;
2477 unsigned char machine_pwd[16];
2478 const char *machine_account;
2480 /* Get the machine account credentials from secrets.tdb. */
2481 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2484 DEBUG(0, ("get_schannel_session_key: could not fetch "
2485 "trust account password for domain '%s'\n",
2487 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2491 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2492 cli->desthost, /* server name */
2493 domain, /* domain */
2494 global_myname(), /* client name */
2495 machine_account, /* machine account name */
2500 if (!NT_STATUS_IS_OK(*perr)) {
2501 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2502 "failed with result %s to server %s, domain %s, machine account %s.\n",
2503 nt_errstr(*perr), cli->desthost, domain, machine_account ));
2507 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2508 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2510 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2517 /****************************************************************************
2518 Open a netlogon pipe and get the schannel session key.
2519 Now exposed to external callers.
2520 ****************************************************************************/
2523 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2528 struct rpc_pipe_client *netlogon_pipe = NULL;
2530 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2531 if (!netlogon_pipe) {
2535 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2538 TALLOC_FREE(netlogon_pipe);
2542 return netlogon_pipe;
2545 /****************************************************************************
2547 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2548 using session_key. sign and seal.
2549 ****************************************************************************/
2551 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2553 enum pipe_auth_level auth_level,
2555 const struct dcinfo *pdc,
2558 struct rpc_pipe_client *result;
2560 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2561 if (result == NULL) {
2565 result->auth->a_u.schannel_auth = TALLOC_ZERO_P(
2566 result, struct schannel_auth_struct);
2567 if (!result->auth->a_u.schannel_auth) {
2568 TALLOC_FREE(result);
2569 *perr = NT_STATUS_NO_MEMORY;
2573 TALLOC_FREE(result->domain);
2574 result->domain = talloc_strdup(result, domain);
2575 if (result->domain == NULL) {
2576 TALLOC_FREE(result);
2577 *perr = NT_STATUS_NO_MEMORY;
2581 memcpy(result->auth->a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2583 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
2584 if (!NT_STATUS_IS_OK(*perr)) {
2585 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2586 nt_errstr(*perr) ));
2587 TALLOC_FREE(result);
2591 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2596 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2598 "and bound using schannel.\n",
2599 result->pipe_name, cli->desthost, domain ));
2604 /****************************************************************************
2605 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2606 Fetch the session key ourselves using a temporary netlogon pipe. This
2607 version uses an ntlmssp auth bound netlogon pipe to get the key.
2608 ****************************************************************************/
2610 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2612 const char *username,
2613 const char *password,
2617 struct rpc_pipe_client *netlogon_pipe = NULL;
2619 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2620 if (!netlogon_pipe) {
2624 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2627 TALLOC_FREE(netlogon_pipe);
2631 return netlogon_pipe;
2634 /****************************************************************************
2635 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2636 Fetch the session key ourselves using a temporary netlogon pipe. This version
2637 uses an ntlmssp bind to get the session key.
2638 ****************************************************************************/
2640 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2642 enum pipe_auth_level auth_level,
2644 const char *username,
2645 const char *password,
2648 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2649 struct rpc_pipe_client *netlogon_pipe = NULL;
2650 struct rpc_pipe_client *result = NULL;
2652 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2653 password, &neg_flags, perr);
2654 if (!netlogon_pipe) {
2655 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2656 "key from server %s for domain %s.\n",
2657 cli->desthost, domain ));
2661 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2663 domain, netlogon_pipe->dc, perr);
2665 /* Now we've bound using the session key we can close the netlog pipe. */
2666 TALLOC_FREE(netlogon_pipe);
2671 /****************************************************************************
2672 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2673 Fetch the session key ourselves using a temporary netlogon pipe.
2674 ****************************************************************************/
2676 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2678 enum pipe_auth_level auth_level,
2682 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2683 struct rpc_pipe_client *netlogon_pipe = NULL;
2684 struct rpc_pipe_client *result = NULL;
2686 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2687 if (!netlogon_pipe) {
2688 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2689 "key from server %s for domain %s.\n",
2690 cli->desthost, domain ));
2694 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2696 domain, netlogon_pipe->dc, perr);
2698 /* Now we've bound using the session key we can close the netlog pipe. */
2699 TALLOC_FREE(netlogon_pipe);
2706 /****************************************************************************
2707 Free function for the kerberos spcific data.
2708 ****************************************************************************/
2710 static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
2712 data_blob_free(&a->a_u.kerberos_auth->session_key);
2717 /****************************************************************************
2718 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2719 The idea is this can be called with service_princ, username and password all
2720 NULL so long as the caller has a TGT.
2721 ****************************************************************************/
2723 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2725 enum pipe_auth_level auth_level,
2726 const char *service_princ,
2727 const char *username,
2728 const char *password,
2732 struct rpc_pipe_client *result;
2734 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2735 if (result == NULL) {
2739 /* Default service principal is "desthost$@realm" */
2740 if (!service_princ) {
2741 service_princ = talloc_asprintf(result, "%s$@%s",
2742 cli->desthost, lp_realm() );
2743 if (!service_princ) {
2744 TALLOC_FREE(result);
2749 /* Only get a new TGT if username/password are given. */
2750 if (username && password) {
2751 int ret = kerberos_kinit_password(username, password, 0, NULL);
2753 TALLOC_FREE(result);
2758 result->auth->a_u.kerberos_auth = TALLOC_ZERO_P(
2759 result, struct kerberos_auth_struct);
2760 if (!result->auth->a_u.kerberos_auth) {
2761 TALLOC_FREE(result);
2762 *perr = NT_STATUS_NO_MEMORY;
2766 result->auth->a_u.kerberos_auth->service_principal = service_princ;
2767 result->auth->cli_auth_data_free_func = kerberos_auth_struct_free;
2769 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
2770 if (!NT_STATUS_IS_OK(*perr)) {
2771 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2772 nt_errstr(*perr) ));
2773 TALLOC_FREE(result);
2779 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));