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 || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
230 if (!ntlmssp_state) {
231 return NT_STATUS_INVALID_PARAMETER;
234 /* Ensure there's enough data for an authenticated response. */
235 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
236 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
237 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
238 (unsigned int)auth_len ));
239 return NT_STATUS_BUFFER_TOO_SMALL;
243 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
244 * after the RPC header.
245 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
246 * functions as NTLMv2 checks the rpc headers also.
249 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
250 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
252 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
253 full_packet_data_len = prhdr->frag_len - auth_len;
255 /* Pull the auth header and the following data into a blob. */
256 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
257 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
258 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
259 return NT_STATUS_BUFFER_TOO_SMALL;
262 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
263 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
264 return NT_STATUS_BUFFER_TOO_SMALL;
267 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
268 auth_blob.length = auth_len;
270 switch (cli->auth.auth_level) {
271 case PIPE_AUTH_LEVEL_PRIVACY:
272 /* Data is encrypted. */
273 status = ntlmssp_unseal_packet(ntlmssp_state,
276 full_packet_data_len,
278 if (!NT_STATUS_IS_OK(status)) {
279 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
280 "packet from remote machine %s on pipe %s "
281 "fnum 0x%x. Error was %s.\n",
284 (unsigned int)cli->fnum,
285 nt_errstr(status) ));
289 case PIPE_AUTH_LEVEL_INTEGRITY:
290 /* Data is signed. */
291 status = ntlmssp_check_packet(ntlmssp_state,
294 full_packet_data_len,
296 if (!NT_STATUS_IS_OK(status)) {
297 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
298 "packet from remote machine %s on pipe %s "
299 "fnum 0x%x. Error was %s.\n",
302 (unsigned int)cli->fnum,
303 nt_errstr(status) ));
308 DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n",
309 cli->auth.auth_level ));
310 return NT_STATUS_INVALID_INFO_CLASS;
314 * Return the current pointer to the data offset.
317 if(!prs_set_offset(current_pdu, save_offset)) {
318 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
319 (unsigned int)save_offset ));
320 return NT_STATUS_BUFFER_TOO_SMALL;
324 * Remember the padding length. We must remove it from the real data
325 * stream once the sign/seal is done.
328 *p_ss_padding_len = auth_info.auth_pad_len;
333 /****************************************************************************
334 schannel specific sign/seal.
335 ****************************************************************************/
337 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
338 prs_struct *current_pdu,
339 uint8 *p_ss_padding_len)
341 RPC_HDR_AUTH auth_info;
342 RPC_AUTH_SCHANNEL_CHK schannel_chk;
343 uint32 auth_len = prhdr->auth_len;
344 uint32 save_offset = prs_offset(current_pdu);
345 struct schannel_auth_struct *schannel_auth = cli->auth.a_u.schannel_auth;
348 if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
352 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
353 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
354 return NT_STATUS_INVALID_PARAMETER;
357 if (!schannel_auth) {
358 return NT_STATUS_INVALID_PARAMETER;
361 /* Ensure there's enough data for an authenticated response. */
362 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
363 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
364 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
365 (unsigned int)auth_len ));
366 return NT_STATUS_INVALID_PARAMETER;
369 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
371 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
372 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
373 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
374 return NT_STATUS_BUFFER_TOO_SMALL;
377 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
378 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
379 return NT_STATUS_BUFFER_TOO_SMALL;
382 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
383 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
384 auth_info.auth_type));
385 return NT_STATUS_BUFFER_TOO_SMALL;
388 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
389 &schannel_chk, current_pdu, 0)) {
390 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
391 return NT_STATUS_BUFFER_TOO_SMALL;
394 if (!schannel_decode(schannel_auth,
395 cli->auth.auth_level,
398 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
400 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
401 "Connection to remote machine %s "
402 "pipe %s fnum 0x%x.\n",
405 (unsigned int)cli->fnum ));
406 return NT_STATUS_INVALID_PARAMETER;
409 /* The sequence number gets incremented on both send and receive. */
410 schannel_auth->seq_num++;
413 * Return the current pointer to the data offset.
416 if(!prs_set_offset(current_pdu, save_offset)) {
417 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
418 (unsigned int)save_offset ));
419 return NT_STATUS_BUFFER_TOO_SMALL;
423 * Remember the padding length. We must remove it from the real data
424 * stream once the sign/seal is done.
427 *p_ss_padding_len = auth_info.auth_pad_len;
432 /****************************************************************************
433 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
434 ****************************************************************************/
436 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
437 prs_struct *current_pdu,
438 uint8 *p_ss_padding_len)
440 NTSTATUS ret = NT_STATUS_OK;
442 /* Paranioa checks for auth_len. */
443 if (prhdr->auth_len) {
444 if (prhdr->auth_len > prhdr->frag_len) {
445 return NT_STATUS_INVALID_PARAMETER;
448 if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len ||
449 prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) {
450 /* Integer wrap attempt. */
451 return NT_STATUS_INVALID_PARAMETER;
456 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
459 switch(cli->auth.auth_type) {
460 case PIPE_AUTH_TYPE_NONE:
461 if (prhdr->auth_len) {
462 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
463 "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
466 (unsigned int)cli->fnum,
467 (unsigned int)prhdr->auth_len ));
468 return NT_STATUS_INVALID_PARAMETER;
472 case PIPE_AUTH_TYPE_NTLMSSP:
473 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
474 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
475 if (!NT_STATUS_IS_OK(ret)) {
480 case PIPE_AUTH_TYPE_SCHANNEL:
481 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
482 if (!NT_STATUS_IS_OK(ret)) {
487 case PIPE_AUTH_TYPE_KRB5:
488 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
490 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
491 "pipe %s fnum %x - unknown internal auth type %u.\n",
494 (unsigned int)cli->fnum,
495 cli->auth.auth_type ));
496 return NT_STATUS_INVALID_INFO_CLASS;
502 /****************************************************************************
503 Do basic authentication checks on an incoming pdu.
504 ****************************************************************************/
506 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
507 prs_struct *current_pdu,
508 uint8 expected_pkt_type,
511 prs_struct *return_data)
514 NTSTATUS ret = NT_STATUS_OK;
515 uint32 current_pdu_len = prs_data_size(current_pdu);
517 if (current_pdu_len != prhdr->frag_len) {
518 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
519 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
520 return NT_STATUS_INVALID_PARAMETER;
524 * Point the return values at the real data including the RPC
525 * header. Just in case the caller wants it.
527 *ppdata = prs_data_p(current_pdu);
528 *pdata_len = current_pdu_len;
530 /* Ensure we have the correct type. */
531 switch (prhdr->pkt_type) {
532 case RPC_ALTCONTRESP:
535 /* Alter context and bind ack share the same packet definitions. */
541 RPC_HDR_RESP rhdr_resp;
542 uint8 ss_padding_len = 0;
544 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
545 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
546 return NT_STATUS_BUFFER_TOO_SMALL;
549 /* Here's where we deal with incoming sign/seal. */
550 ret = cli_pipe_validate_rpc_response(cli, prhdr,
551 current_pdu, &ss_padding_len);
552 if (!NT_STATUS_IS_OK(ret)) {
556 /* Point the return values at the NDR data. Remember to remove any ss padding. */
557 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
559 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
560 return NT_STATUS_BUFFER_TOO_SMALL;
563 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
565 /* Remember to remove the auth footer. */
566 if (prhdr->auth_len) {
567 /* We've already done integer wrap tests on auth_len in
568 cli_pipe_validate_rpc_response(). */
569 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
570 return NT_STATUS_BUFFER_TOO_SMALL;
572 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
575 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
576 current_pdu_len, *pdata_len, ss_padding_len ));
579 * If this is the first reply, and the allocation hint is reasonably, try and
580 * set up the return_data parse_struct to the correct size.
583 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
584 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
585 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
586 "too large to allocate\n",
587 (unsigned int)rhdr_resp.alloc_hint ));
588 return NT_STATUS_NO_MEMORY;
596 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
597 "pipe %s fnum 0x%x!\n",
600 (unsigned int)cli->fnum));
601 /* Use this for now... */
602 return NT_STATUS_NETWORK_ACCESS_DENIED;
606 RPC_HDR_RESP rhdr_resp;
607 RPC_HDR_FAULT fault_resp;
609 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
610 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
611 return NT_STATUS_BUFFER_TOO_SMALL;
614 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
615 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
616 return NT_STATUS_BUFFER_TOO_SMALL;
619 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
620 "pipe %s fnum 0x%x!\n",
621 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
624 (unsigned int)cli->fnum));
625 if (NT_STATUS_IS_OK(fault_resp.status)) {
626 return NT_STATUS_UNSUCCESSFUL;
628 return fault_resp.status;
634 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
635 "from remote machine %s pipe %s fnum 0x%x!\n",
636 (unsigned int)prhdr->pkt_type,
639 (unsigned int)cli->fnum));
640 return NT_STATUS_INVALID_INFO_CLASS;
643 if (prhdr->pkt_type != expected_pkt_type) {
644 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
645 "pipe %s fnum %x got an unexpected RPC packet "
646 "type - %u, not %u\n",
649 (unsigned int)cli->fnum,
652 return NT_STATUS_INVALID_INFO_CLASS;
655 /* Do this just before return - we don't want to modify any rpc header
656 data before now as we may have needed to do cryptographic actions on
659 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
660 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
661 "setting fragment first/last ON.\n"));
662 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
668 /****************************************************************************
669 Ensure we eat the just processed pdu from the current_pdu prs_struct.
670 Normally the frag_len and buffer size will match, but on the first trans
671 reply there is a theoretical chance that buffer size > frag_len, so we must
673 ****************************************************************************/
675 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
677 uint32 current_pdu_len = prs_data_size(current_pdu);
679 if (current_pdu_len < prhdr->frag_len) {
680 return NT_STATUS_BUFFER_TOO_SMALL;
684 if (current_pdu_len == (uint32)prhdr->frag_len) {
685 prs_mem_free(current_pdu);
686 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
687 /* Make current_pdu dynamic with no memory. */
688 prs_give_memory(current_pdu, 0, 0, True);
693 * Oh no ! More data in buffer than we processed in current pdu.
694 * Cheat. Move the data down and shrink the buffer.
697 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
698 current_pdu_len - prhdr->frag_len);
700 /* Remember to set the read offset back to zero. */
701 prs_set_offset(current_pdu, 0);
703 /* Shrink the buffer. */
704 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
705 return NT_STATUS_BUFFER_TOO_SMALL;
711 /****************************************************************************
712 Send data on an rpc pipe via trans. The prs_struct data must be the last
713 pdu fragment of an NDR data stream.
715 Receive response data from an rpc pipe, which may be large...
717 Read the first fragment: unfortunately have to use SMBtrans for the first
718 bit, then SMBreadX for subsequent bits.
720 If first fragment received also wasn't the last fragment, continue
721 getting fragments until we _do_ receive the last fragment.
723 Request/Response PDU's look like the following...
725 |<------------------PDU len----------------------------------------------->|
726 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
728 +------------+-----------------+-------------+---------------+-------------+
729 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
730 +------------+-----------------+-------------+---------------+-------------+
732 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
733 signing & sealing being negotiated.
735 ****************************************************************************/
737 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
738 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
739 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
740 uint8 expected_pkt_type)
742 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
744 uint32 rparam_len = 0;
746 char *pdata = prs_data_p(data);
747 uint32 data_len = prs_offset(data);
749 uint32 rdata_len = 0;
750 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
751 uint32 current_rbuf_offset = 0;
752 prs_struct current_pdu;
755 /* Ensure we're not sending too much. */
756 SMB_ASSERT(data_len <= max_data);
759 /* Set up the current pdu parse struct. */
760 prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
762 /* Create setup parameters - must be in native byte order. */
763 setup[0] = TRANSACT_DCERPCCMD;
764 setup[1] = cli->fnum; /* Pipe file handle. */
766 DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
769 (unsigned int)cli->fnum ));
772 * Send the last (or only) fragment of an RPC request. For small
773 * amounts of data (about 1024 bytes or so) the RPC request and response
774 * appears in a SMBtrans request and response.
777 if (!cli_api_pipe(cli->cli, "\\PIPE\\",
778 setup, 2, 0, /* Setup, length, max */
779 NULL, 0, 0, /* Params, length, max */
780 pdata, data_len, max_data, /* data, length, max */
781 &rparam, &rparam_len, /* return params, len */
782 &prdata, &rdata_len)) /* return data, len */
784 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x "
785 "returned critical error. Error was %s\n",
788 (unsigned int)cli->fnum,
789 cli_errstr(cli->cli)));
790 ret = cli_get_nt_error(cli->cli);
796 /* Throw away returned params - we know we won't use them. */
800 if (prdata == NULL) {
801 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
802 "fnum 0x%x failed to return data.\n",
805 (unsigned int)cli->fnum));
806 /* Yes - some calls can truely return no data... */
807 prs_mem_free(¤t_pdu);
812 * Give this memory as dynamic to the current pdu.
815 prs_give_memory(¤t_pdu, prdata, rdata_len, True);
817 /* Ensure we can mess with the return prs_struct. */
818 SMB_ASSERT(UNMARSHALLING(rbuf));
819 SMB_ASSERT(prs_data_size(rbuf) == 0);
821 /* Make rbuf dynamic with no memory. */
822 prs_give_memory(rbuf, 0, 0, True);
829 /* Ensure we have enough data for a pdu. */
830 ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu);
831 if (!NT_STATUS_IS_OK(ret)) {
835 /* We pass in rbuf here so if the alloc hint is set correctly
836 we can set the output size and avoid reallocs. */
838 ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type,
839 &ret_data, &ret_data_len, rbuf);
841 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
842 prs_data_size(¤t_pdu), current_rbuf_offset ));
844 if (!NT_STATUS_IS_OK(ret)) {
848 if ((rhdr.flags & RPC_FLG_FIRST)) {
849 if (rhdr.pack_type[0] == 0) {
850 /* Set the data type correctly for big-endian data on the first packet. */
851 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
852 "PDU data format is big-endian.\n",
855 (unsigned int)cli->fnum));
857 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
859 /* Check endianness on subsequent packets. */
860 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
861 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
862 rbuf->bigendian_data ? "big" : "little",
863 current_pdu.bigendian_data ? "big" : "little" ));
864 ret = NT_STATUS_INVALID_PARAMETER;
870 /* Now copy the data portion out of the pdu into rbuf. */
871 if (!prs_force_grow(rbuf, ret_data_len)) {
872 ret = NT_STATUS_NO_MEMORY;
875 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
876 current_rbuf_offset += ret_data_len;
878 /* See if we've finished with all the data in current_pdu yet ? */
879 ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu);
880 if (!NT_STATUS_IS_OK(ret)) {
884 if (rhdr.flags & RPC_FLG_LAST) {
885 break; /* We're done. */
889 DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
892 (unsigned int)cli->fnum,
893 (unsigned int)prs_data_size(rbuf) ));
895 prs_mem_free(¤t_pdu);
900 prs_mem_free(¤t_pdu);
905 /*******************************************************************
906 Creates krb5 auth bind.
907 ********************************************************************/
909 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
910 enum pipe_auth_level auth_level,
911 RPC_HDR_AUTH *pauth_out,
912 prs_struct *auth_data)
916 struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth;
917 DATA_BLOB tkt = data_blob_null;
918 DATA_BLOB tkt_wrapped = data_blob_null;
920 /* We may change the pad length before marshalling. */
921 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
923 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
924 a->service_principal ));
926 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
928 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
929 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
932 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
934 a->service_principal,
935 error_message(ret) ));
937 data_blob_free(&tkt);
938 prs_mem_free(auth_data);
939 return NT_STATUS_INVALID_PARAMETER;
942 /* wrap that up in a nice GSS-API wrapping */
943 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
945 data_blob_free(&tkt);
947 /* Auth len in the rpc header doesn't include auth_header. */
948 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
949 data_blob_free(&tkt_wrapped);
950 prs_mem_free(auth_data);
951 return NT_STATUS_NO_MEMORY;
954 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
955 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
957 data_blob_free(&tkt_wrapped);
960 return NT_STATUS_INVALID_PARAMETER;
964 /*******************************************************************
965 Creates SPNEGO NTLMSSP auth bind.
966 ********************************************************************/
968 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
969 enum pipe_auth_level auth_level,
970 RPC_HDR_AUTH *pauth_out,
971 prs_struct *auth_data)
974 DATA_BLOB null_blob = data_blob_null;
975 DATA_BLOB request = data_blob_null;
976 DATA_BLOB spnego_msg = data_blob_null;
978 /* We may change the pad length before marshalling. */
979 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
981 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
982 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
986 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
987 data_blob_free(&request);
988 prs_mem_free(auth_data);
992 /* Wrap this in SPNEGO. */
993 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
995 data_blob_free(&request);
997 /* Auth len in the rpc header doesn't include auth_header. */
998 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
999 data_blob_free(&spnego_msg);
1000 prs_mem_free(auth_data);
1001 return NT_STATUS_NO_MEMORY;
1004 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1005 dump_data(5, spnego_msg.data, spnego_msg.length);
1007 data_blob_free(&spnego_msg);
1008 return NT_STATUS_OK;
1011 /*******************************************************************
1012 Creates NTLMSSP auth bind.
1013 ********************************************************************/
1015 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1016 enum pipe_auth_level auth_level,
1017 RPC_HDR_AUTH *pauth_out,
1018 prs_struct *auth_data)
1021 DATA_BLOB null_blob = data_blob_null;
1022 DATA_BLOB request = data_blob_null;
1024 /* We may change the pad length before marshalling. */
1025 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1027 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1028 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1032 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1033 data_blob_free(&request);
1034 prs_mem_free(auth_data);
1038 /* Auth len in the rpc header doesn't include auth_header. */
1039 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1040 data_blob_free(&request);
1041 prs_mem_free(auth_data);
1042 return NT_STATUS_NO_MEMORY;
1045 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1046 dump_data(5, request.data, request.length);
1048 data_blob_free(&request);
1049 return NT_STATUS_OK;
1052 /*******************************************************************
1053 Creates schannel auth bind.
1054 ********************************************************************/
1056 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1057 enum pipe_auth_level auth_level,
1058 RPC_HDR_AUTH *pauth_out,
1059 prs_struct *auth_data)
1061 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1063 /* We may change the pad length before marshalling. */
1064 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1066 /* Use lp_workgroup() if domain not specified */
1068 if (!cli->domain || !cli->domain[0]) {
1069 cli->domain = lp_workgroup();
1072 init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
1075 * Now marshall the data into the auth parse_struct.
1078 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1079 &schannel_neg, auth_data, 0)) {
1080 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1081 prs_mem_free(auth_data);
1082 return NT_STATUS_NO_MEMORY;
1085 return NT_STATUS_OK;
1088 /*******************************************************************
1089 Creates the internals of a DCE/RPC bind request or alter context PDU.
1090 ********************************************************************/
1092 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1093 prs_struct *rpc_out,
1095 RPC_IFACE *abstract,
1096 RPC_IFACE *transfer,
1097 RPC_HDR_AUTH *phdr_auth,
1098 prs_struct *pauth_info)
1102 RPC_CONTEXT rpc_ctx;
1103 uint16 auth_len = prs_offset(pauth_info);
1104 uint8 ss_padding_len = 0;
1105 uint16 frag_len = 0;
1107 /* create the RPC context. */
1108 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1110 /* create the bind request RPC_HDR_RB */
1111 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1113 /* Start building the frag length. */
1114 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1116 /* Do we need to pad ? */
1118 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1120 ss_padding_len = 8 - (data_len % 8);
1121 phdr_auth->auth_pad_len = ss_padding_len;
1123 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1126 /* Create the request RPC_HDR */
1127 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1129 /* Marshall the RPC header */
1130 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1131 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1132 return NT_STATUS_NO_MEMORY;
1135 /* Marshall the bind request data */
1136 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1137 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1138 return NT_STATUS_NO_MEMORY;
1142 * Grow the outgoing buffer to store any auth info.
1146 if (ss_padding_len) {
1148 memset(pad, '\0', 8);
1149 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1150 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1151 return NT_STATUS_NO_MEMORY;
1155 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1156 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1157 return NT_STATUS_NO_MEMORY;
1161 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1162 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1163 return NT_STATUS_NO_MEMORY;
1167 return NT_STATUS_OK;
1170 /*******************************************************************
1171 Creates a DCE/RPC bind request.
1172 ********************************************************************/
1174 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1175 prs_struct *rpc_out,
1177 RPC_IFACE *abstract, RPC_IFACE *transfer,
1178 enum pipe_auth_type auth_type,
1179 enum pipe_auth_level auth_level)
1181 RPC_HDR_AUTH hdr_auth;
1182 prs_struct auth_info;
1183 NTSTATUS ret = NT_STATUS_OK;
1185 ZERO_STRUCT(hdr_auth);
1186 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1187 return NT_STATUS_NO_MEMORY;
1189 switch (auth_type) {
1190 case PIPE_AUTH_TYPE_SCHANNEL:
1191 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1192 if (!NT_STATUS_IS_OK(ret)) {
1193 prs_mem_free(&auth_info);
1198 case PIPE_AUTH_TYPE_NTLMSSP:
1199 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1200 if (!NT_STATUS_IS_OK(ret)) {
1201 prs_mem_free(&auth_info);
1206 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1207 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1208 if (!NT_STATUS_IS_OK(ret)) {
1209 prs_mem_free(&auth_info);
1214 case PIPE_AUTH_TYPE_KRB5:
1215 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1216 if (!NT_STATUS_IS_OK(ret)) {
1217 prs_mem_free(&auth_info);
1222 case PIPE_AUTH_TYPE_NONE:
1226 /* "Can't" happen. */
1227 return NT_STATUS_INVALID_INFO_CLASS;
1230 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1238 prs_mem_free(&auth_info);
1242 /*******************************************************************
1243 Create and add the NTLMSSP sign/seal auth header and data.
1244 ********************************************************************/
1246 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1248 uint32 ss_padding_len,
1249 prs_struct *outgoing_pdu)
1251 RPC_HDR_AUTH auth_info;
1253 DATA_BLOB auth_blob = data_blob_null;
1254 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1256 if (!cli->auth.a_u.ntlmssp_state) {
1257 return NT_STATUS_INVALID_PARAMETER;
1260 /* Init and marshall the auth header. */
1261 init_rpc_hdr_auth(&auth_info,
1262 map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1263 cli->auth.auth_level,
1265 1 /* context id. */);
1267 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1268 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1269 data_blob_free(&auth_blob);
1270 return NT_STATUS_NO_MEMORY;
1273 switch (cli->auth.auth_level) {
1274 case PIPE_AUTH_LEVEL_PRIVACY:
1275 /* Data portion is encrypted. */
1276 status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state,
1277 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1279 (unsigned char *)prs_data_p(outgoing_pdu),
1280 (size_t)prs_offset(outgoing_pdu),
1282 if (!NT_STATUS_IS_OK(status)) {
1283 data_blob_free(&auth_blob);
1288 case PIPE_AUTH_LEVEL_INTEGRITY:
1289 /* Data is signed. */
1290 status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state,
1291 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1293 (unsigned char *)prs_data_p(outgoing_pdu),
1294 (size_t)prs_offset(outgoing_pdu),
1296 if (!NT_STATUS_IS_OK(status)) {
1297 data_blob_free(&auth_blob);
1304 smb_panic("bad auth level");
1306 return NT_STATUS_INVALID_PARAMETER;
1309 /* Finally marshall the blob. */
1311 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1312 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1313 (unsigned int)NTLMSSP_SIG_SIZE));
1314 data_blob_free(&auth_blob);
1315 return NT_STATUS_NO_MEMORY;
1318 data_blob_free(&auth_blob);
1319 return NT_STATUS_OK;
1322 /*******************************************************************
1323 Create and add the schannel sign/seal auth header and data.
1324 ********************************************************************/
1326 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1328 uint32 ss_padding_len,
1329 prs_struct *outgoing_pdu)
1331 RPC_HDR_AUTH auth_info;
1332 RPC_AUTH_SCHANNEL_CHK verf;
1333 struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth;
1334 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1335 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1338 return NT_STATUS_INVALID_PARAMETER;
1341 /* Init and marshall the auth header. */
1342 init_rpc_hdr_auth(&auth_info,
1343 map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1344 cli->auth.auth_level,
1346 1 /* context id. */);
1348 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1349 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1350 return NT_STATUS_NO_MEMORY;
1353 switch (cli->auth.auth_level) {
1354 case PIPE_AUTH_LEVEL_PRIVACY:
1355 case PIPE_AUTH_LEVEL_INTEGRITY:
1356 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1359 schannel_encode(sas,
1360 cli->auth.auth_level,
1361 SENDER_IS_INITIATOR,
1371 smb_panic("bad auth level");
1373 return NT_STATUS_INVALID_PARAMETER;
1376 /* Finally marshall the blob. */
1377 smb_io_rpc_auth_schannel_chk("",
1378 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1383 return NT_STATUS_OK;
1386 /*******************************************************************
1387 Calculate how much data we're going to send in this packet, also
1388 work out any sign/seal padding length.
1389 ********************************************************************/
1391 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1395 uint32 *p_ss_padding)
1397 uint32 data_space, data_len;
1399 switch (cli->auth.auth_level) {
1400 case PIPE_AUTH_LEVEL_NONE:
1401 case PIPE_AUTH_LEVEL_CONNECT:
1402 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1403 data_len = MIN(data_space, data_left);
1406 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1409 case PIPE_AUTH_LEVEL_INTEGRITY:
1410 case PIPE_AUTH_LEVEL_PRIVACY:
1411 /* Treat the same for all authenticated rpc requests. */
1412 switch(cli->auth.auth_type) {
1413 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1414 case PIPE_AUTH_TYPE_NTLMSSP:
1415 *p_auth_len = NTLMSSP_SIG_SIZE;
1417 case PIPE_AUTH_TYPE_SCHANNEL:
1418 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1421 smb_panic("bad auth type");
1425 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1426 RPC_HDR_AUTH_LEN - *p_auth_len;
1428 data_len = MIN(data_space, data_left);
1430 *p_ss_padding = 8 - (data_len % 8);
1432 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1433 data_len + *p_ss_padding + /* data plus padding. */
1434 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1438 smb_panic("bad auth level");
1444 /*******************************************************************
1446 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1447 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1448 and deals with signing/sealing details.
1449 ********************************************************************/
1451 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1453 prs_struct *in_data,
1454 prs_struct *out_data)
1457 uint32 data_left = prs_offset(in_data);
1458 uint32 alloc_hint = prs_offset(in_data);
1459 uint32 data_sent_thistime = 0;
1460 uint32 current_data_offset = 0;
1461 uint32 call_id = get_rpc_call_id();
1463 prs_struct outgoing_pdu;
1465 memset(pad, '\0', 8);
1467 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1468 /* Server is screwed up ! */
1469 return NT_STATUS_INVALID_PARAMETER;
1472 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1473 return NT_STATUS_NO_MEMORY;
1477 RPC_HDR_REQ hdr_req;
1478 uint16 auth_len = 0;
1479 uint16 frag_len = 0;
1481 uint32 ss_padding = 0;
1483 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1484 &frag_len, &auth_len, &ss_padding);
1486 if (current_data_offset == 0) {
1487 flags = RPC_FLG_FIRST;
1490 if (data_sent_thistime == data_left) {
1491 flags |= RPC_FLG_LAST;
1494 /* Create and marshall the header and request header. */
1495 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1497 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1498 prs_mem_free(&outgoing_pdu);
1499 return NT_STATUS_NO_MEMORY;
1502 /* Create the rpc request RPC_HDR_REQ */
1503 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1505 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1506 prs_mem_free(&outgoing_pdu);
1507 return NT_STATUS_NO_MEMORY;
1510 /* Copy in the data, plus any ss padding. */
1511 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1512 prs_mem_free(&outgoing_pdu);
1513 return NT_STATUS_NO_MEMORY;
1516 /* Copy the sign/seal padding data. */
1518 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1519 prs_mem_free(&outgoing_pdu);
1520 return NT_STATUS_NO_MEMORY;
1524 /* Generate any auth sign/seal and add the auth footer. */
1526 switch (cli->auth.auth_type) {
1527 case PIPE_AUTH_TYPE_NONE:
1529 case PIPE_AUTH_TYPE_NTLMSSP:
1530 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1531 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1532 if (!NT_STATUS_IS_OK(ret)) {
1533 prs_mem_free(&outgoing_pdu);
1537 case PIPE_AUTH_TYPE_SCHANNEL:
1538 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1539 if (!NT_STATUS_IS_OK(ret)) {
1540 prs_mem_free(&outgoing_pdu);
1545 smb_panic("bad auth type");
1546 break; /* notreached */
1550 /* Actually send the packet. */
1551 if (flags & RPC_FLG_LAST) {
1552 /* Last packet - send the data, get the reply and return. */
1553 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1554 prs_mem_free(&outgoing_pdu);
1556 if (DEBUGLEVEL >= 50) {
1557 char *dump_name = NULL;
1558 /* Also capture received data */
1559 if (asprintf(&dump_name, "%s/reply_%s_%d",
1560 get_dyn_LOGFILEBASE(), cli->pipe_name,
1562 prs_dump(dump_name, op_num, out_data);
1563 SAFE_FREE(dump_name);
1569 /* More packets to come - write and continue. */
1570 ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */
1571 prs_data_p(&outgoing_pdu),
1573 (size_t)hdr.frag_len);
1575 if (num_written != hdr.frag_len) {
1576 prs_mem_free(&outgoing_pdu);
1577 return cli_get_nt_error(cli->cli);
1581 current_data_offset += data_sent_thistime;
1582 data_left -= data_sent_thistime;
1584 /* Reset the marshalling position back to zero. */
1585 if (!prs_set_offset(&outgoing_pdu, 0)) {
1586 prs_mem_free(&outgoing_pdu);
1587 return NT_STATUS_NO_MEMORY;
1592 /****************************************************************************
1593 Set the handle state.
1594 ****************************************************************************/
1596 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1597 const char *pipe_name, uint16 device_state)
1599 bool state_set = False;
1601 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1602 char *rparam = NULL;
1604 uint32 rparam_len, rdata_len;
1606 if (pipe_name == NULL)
1609 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1610 cli->fnum, pipe_name, device_state));
1612 /* create parameters: device state */
1613 SSVAL(param, 0, device_state);
1615 /* create setup parameters. */
1617 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1619 /* send the data on \PIPE\ */
1620 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1621 setup, 2, 0, /* setup, length, max */
1622 param, 2, 0, /* param, length, max */
1623 NULL, 0, 1024, /* data, length, max */
1624 &rparam, &rparam_len, /* return param, length */
1625 &rdata, &rdata_len)) /* return data, length */
1627 DEBUG(5, ("Set Handle state: return OK\n"));
1638 /****************************************************************************
1639 Check the rpc bind acknowledge response.
1640 ****************************************************************************/
1642 static bool valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer)
1644 if ( pipe_idx >= PI_MAX_PIPES ) {
1645 DEBUG(0,("valid_pipe_name: Programmer error! Invalid pipe index [%d]\n",
1650 DEBUG(5,("Bind Abstract Syntax: "));
1651 dump_data(5, (uint8 *)&pipe_names[pipe_idx].abstr_syntax,
1652 sizeof(pipe_names[pipe_idx].abstr_syntax));
1653 DEBUG(5,("Bind Transfer Syntax: "));
1654 dump_data(5, (uint8 *)&pipe_names[pipe_idx].trans_syntax,
1655 sizeof(pipe_names[pipe_idx].trans_syntax));
1657 /* copy the required syntaxes out so we can do the right bind */
1659 *transfer = *pipe_names[pipe_idx].trans_syntax;
1660 *abstract = *pipe_names[pipe_idx].abstr_syntax;
1665 /****************************************************************************
1666 Check the rpc bind acknowledge response.
1667 ****************************************************************************/
1669 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer)
1671 if ( hdr_ba->addr.len == 0) {
1672 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1675 /* check the transfer syntax */
1676 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1677 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1678 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1682 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1683 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1684 hdr_ba->res.num_results, hdr_ba->res.reason));
1687 DEBUG(5,("check_bind_response: accepted!\n"));
1691 /*******************************************************************
1692 Creates a DCE/RPC bind authentication response.
1693 This is the packet that is sent back to the server once we
1694 have received a BIND-ACK, to finish the third leg of
1695 the authentication handshake.
1696 ********************************************************************/
1698 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1700 enum pipe_auth_type auth_type,
1701 enum pipe_auth_level auth_level,
1702 DATA_BLOB *pauth_blob,
1703 prs_struct *rpc_out)
1706 RPC_HDR_AUTH hdr_auth;
1709 /* Create the request RPC_HDR */
1710 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1711 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1712 pauth_blob->length );
1715 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1716 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1717 return NT_STATUS_NO_MEMORY;
1721 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1722 about padding - shouldn't this pad to length 8 ? JRA.
1725 /* 4 bytes padding. */
1726 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1727 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1728 return NT_STATUS_NO_MEMORY;
1731 /* Create the request RPC_HDR_AUTHA */
1732 init_rpc_hdr_auth(&hdr_auth,
1733 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1736 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1737 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1738 return NT_STATUS_NO_MEMORY;
1742 * Append the auth data to the outgoing buffer.
1745 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1746 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1747 return NT_STATUS_NO_MEMORY;
1750 return NT_STATUS_OK;
1753 /****************************************************************************
1754 Create and send the third packet in an RPC auth.
1755 ****************************************************************************/
1757 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1761 enum pipe_auth_type auth_type,
1762 enum pipe_auth_level auth_level)
1764 DATA_BLOB server_response = data_blob_null;
1765 DATA_BLOB client_reply = data_blob_null;
1766 RPC_HDR_AUTH hdr_auth;
1771 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1772 return NT_STATUS_INVALID_PARAMETER;
1775 /* Process the returned NTLMSSP blob first. */
1776 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1777 return NT_STATUS_INVALID_PARAMETER;
1780 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1781 return NT_STATUS_INVALID_PARAMETER;
1784 /* TODO - check auth_type/auth_level match. */
1786 server_response = data_blob(NULL, phdr->auth_len);
1787 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1789 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1793 if (!NT_STATUS_IS_OK(nt_status)) {
1794 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1795 data_blob_free(&server_response);
1799 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1801 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1802 auth_type, auth_level,
1803 &client_reply, &rpc_out);
1805 if (!NT_STATUS_IS_OK(nt_status)) {
1806 prs_mem_free(&rpc_out);
1807 data_blob_free(&client_reply);
1808 data_blob_free(&server_response);
1812 /* 8 here is named pipe message mode. */
1813 ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
1814 (size_t)prs_offset(&rpc_out));
1816 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1817 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
1818 prs_mem_free(&rpc_out);
1819 data_blob_free(&client_reply);
1820 data_blob_free(&server_response);
1821 return cli_get_nt_error(cli->cli);
1824 DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
1825 "fnum 0x%x sent auth3 response ok.\n",
1828 (unsigned int)cli->fnum));
1830 prs_mem_free(&rpc_out);
1831 data_blob_free(&client_reply);
1832 data_blob_free(&server_response);
1833 return NT_STATUS_OK;
1836 /*******************************************************************
1837 Creates a DCE/RPC bind alter context authentication request which
1838 may contain a spnego auth blobl
1839 ********************************************************************/
1841 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1842 RPC_IFACE *abstract,
1843 RPC_IFACE *transfer,
1844 enum pipe_auth_level auth_level,
1845 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1846 prs_struct *rpc_out)
1848 RPC_HDR_AUTH hdr_auth;
1849 prs_struct auth_info;
1850 NTSTATUS ret = NT_STATUS_OK;
1852 ZERO_STRUCT(hdr_auth);
1853 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1854 return NT_STATUS_NO_MEMORY;
1856 /* We may change the pad length before marshalling. */
1857 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1859 if (pauth_blob->length) {
1860 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1861 prs_mem_free(&auth_info);
1862 return NT_STATUS_NO_MEMORY;
1866 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1873 prs_mem_free(&auth_info);
1877 /*******************************************************************
1878 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1879 and gets a response.
1880 ********************************************************************/
1882 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1886 RPC_IFACE *abstract,
1887 RPC_IFACE *transfer,
1888 enum pipe_auth_type auth_type,
1889 enum pipe_auth_level auth_level)
1891 DATA_BLOB server_spnego_response = data_blob_null;
1892 DATA_BLOB server_ntlm_response = data_blob_null;
1893 DATA_BLOB client_reply = data_blob_null;
1894 DATA_BLOB tmp_blob = data_blob_null;
1895 RPC_HDR_AUTH hdr_auth;
1899 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1900 return NT_STATUS_INVALID_PARAMETER;
1903 /* Process the returned NTLMSSP blob first. */
1904 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1905 return NT_STATUS_INVALID_PARAMETER;
1908 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1909 return NT_STATUS_INVALID_PARAMETER;
1912 server_spnego_response = data_blob(NULL, phdr->auth_len);
1913 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1915 /* The server might give us back two challenges - tmp_blob is for the second. */
1916 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
1917 data_blob_free(&server_spnego_response);
1918 data_blob_free(&server_ntlm_response);
1919 data_blob_free(&tmp_blob);
1920 return NT_STATUS_INVALID_PARAMETER;
1923 /* We're finished with the server spnego response and the tmp_blob. */
1924 data_blob_free(&server_spnego_response);
1925 data_blob_free(&tmp_blob);
1927 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1928 server_ntlm_response,
1931 /* Finished with the server_ntlm response */
1932 data_blob_free(&server_ntlm_response);
1934 if (!NT_STATUS_IS_OK(nt_status)) {
1935 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
1936 data_blob_free(&client_reply);
1940 /* SPNEGO wrap the client reply. */
1941 tmp_blob = spnego_gen_auth(client_reply);
1942 data_blob_free(&client_reply);
1943 client_reply = tmp_blob;
1944 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
1946 /* Now prepare the alter context pdu. */
1947 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1949 nt_status = create_rpc_alter_context(rpc_call_id,
1956 data_blob_free(&client_reply);
1958 if (!NT_STATUS_IS_OK(nt_status)) {
1959 prs_mem_free(&rpc_out);
1963 /* Initialize the returning data struct. */
1965 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
1967 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
1968 if (!NT_STATUS_IS_OK(nt_status)) {
1969 prs_mem_free(&rpc_out);
1973 prs_mem_free(&rpc_out);
1975 /* Get the auth blob from the reply. */
1976 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
1977 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
1978 return NT_STATUS_BUFFER_TOO_SMALL;
1981 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1982 return NT_STATUS_INVALID_PARAMETER;
1985 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1986 return NT_STATUS_INVALID_PARAMETER;
1989 server_spnego_response = data_blob(NULL, phdr->auth_len);
1990 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1992 /* Check we got a valid auth response. */
1993 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
1994 data_blob_free(&server_spnego_response);
1995 data_blob_free(&tmp_blob);
1996 return NT_STATUS_INVALID_PARAMETER;
1999 data_blob_free(&server_spnego_response);
2000 data_blob_free(&tmp_blob);
2002 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2003 "remote machine %s pipe %s fnum 0x%x.\n",
2006 (unsigned int)cli->fnum));
2008 return NT_STATUS_OK;
2011 /****************************************************************************
2013 ****************************************************************************/
2015 static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2016 enum pipe_auth_type auth_type,
2017 enum pipe_auth_level auth_level)
2028 DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2029 (unsigned int)cli->fnum,
2031 (unsigned int)auth_type,
2032 (unsigned int)auth_level ));
2034 if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) {
2035 return NT_STATUS_INVALID_PARAMETER;
2038 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2040 rpc_call_id = get_rpc_call_id();
2042 /* Marshall the outgoing data. */
2043 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2044 &abstract, &transfer,
2048 if (!NT_STATUS_IS_OK(status)) {
2049 prs_mem_free(&rpc_out);
2053 /* Initialize the incoming data struct. */
2054 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2056 /* send data on \PIPE\. receive a response */
2057 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2058 if (!NT_STATUS_IS_OK(status)) {
2059 prs_mem_free(&rpc_out);
2063 prs_mem_free(&rpc_out);
2065 DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2066 "fnum 0x%x bind request returned ok.\n",
2069 (unsigned int)cli->fnum));
2071 /* Unmarshall the RPC header */
2072 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2073 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2074 prs_mem_free(&rbuf);
2075 return NT_STATUS_BUFFER_TOO_SMALL;
2078 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2079 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2080 prs_mem_free(&rbuf);
2081 return NT_STATUS_BUFFER_TOO_SMALL;
2084 if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) {
2085 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2086 prs_mem_free(&rbuf);
2087 return NT_STATUS_BUFFER_TOO_SMALL;
2090 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2091 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2093 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2096 case PIPE_AUTH_TYPE_NONE:
2097 case PIPE_AUTH_TYPE_SCHANNEL:
2098 /* Bind complete. */
2101 case PIPE_AUTH_TYPE_NTLMSSP:
2102 /* Need to send AUTH3 packet - no reply. */
2103 status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
2104 auth_type, auth_level);
2105 if (!NT_STATUS_IS_OK(status)) {
2106 prs_mem_free(&rbuf);
2111 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2112 /* Need to send alter context request and reply. */
2113 status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
2114 &abstract, &transfer,
2115 auth_type, auth_level);
2116 if (!NT_STATUS_IS_OK(status)) {
2117 prs_mem_free(&rbuf);
2122 case PIPE_AUTH_TYPE_KRB5:
2126 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2127 (unsigned int)auth_type ));
2128 prs_mem_free(&rbuf);
2129 return NT_STATUS_INVALID_INFO_CLASS;
2132 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2133 if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2134 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2135 if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2136 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2137 prs_mem_free(&rbuf);
2138 return NT_STATUS_INVALID_PARAMETER;
2141 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2142 if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2143 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2144 prs_mem_free(&rbuf);
2145 return NT_STATUS_INVALID_PARAMETER;
2150 /* Pipe is bound - set up auth_type and auth_level data. */
2152 cli->auth.auth_type = auth_type;
2153 cli->auth.auth_level = auth_level;
2155 prs_mem_free(&rbuf);
2156 return NT_STATUS_OK;
2159 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2160 unsigned int timeout)
2162 return cli_set_timeout(cli->cli, timeout);
2165 /****************************************************************************
2166 Open a named pipe over SMB to a remote server.
2168 * CAVEAT CALLER OF THIS FUNCTION:
2169 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2170 * so be sure that this function is called AFTER any structure (vs pointer)
2171 * assignment of the cli. In particular, libsmbclient does structure
2172 * assignments of cli, which invalidates the data in the returned
2173 * rpc_pipe_client if this function is called before the structure assignment
2176 ****************************************************************************/
2178 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2180 struct rpc_pipe_client *result;
2183 *perr = NT_STATUS_NO_MEMORY;
2185 /* sanity check to protect against crashes */
2188 *perr = NT_STATUS_INVALID_HANDLE;
2192 /* The pipe name index must fall within our array */
2193 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2195 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2196 if (result == NULL) {
2200 result->pipe_name = cli_get_pipe_name(pipe_idx);
2202 fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2205 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2206 "to machine %s. Error was %s\n",
2207 result->pipe_name, cli->desthost,
2209 *perr = cli_get_nt_error(cli);
2210 talloc_destroy(result);
2214 result->fnum = fnum;
2216 result->pipe_idx = pipe_idx;
2217 result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
2218 result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
2220 result->desthost = talloc_strdup(result, cli->desthost);
2221 if (result->desthost == NULL) {
2222 TALLOC_FREE(result);
2226 result->srv_name_slash = talloc_asprintf_strupper_m(
2227 result, "\\\\%s", result->desthost);
2228 if (result->srv_name_slash == NULL) {
2229 TALLOC_FREE(result);
2233 if (pipe_idx == PI_NETLOGON) {
2234 /* Set up a netlogon credential chain for a netlogon pipe. */
2235 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2236 if (result->dc == NULL) {
2237 talloc_destroy(result);
2242 DLIST_ADD(cli->pipe_list, result);
2243 *perr = NT_STATUS_OK;
2248 /****************************************************************************
2249 Open a named pipe to an SMB server and bind anonymously.
2250 ****************************************************************************/
2252 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2254 struct rpc_pipe_client *result;
2256 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2257 if (result == NULL) {
2261 result->domain = talloc_strdup(result, cli->domain);
2262 result->user_name = talloc_strdup(result, cli->user_name);
2264 if ((result->domain == NULL) || (result->user_name == NULL)) {
2265 *perr = NT_STATUS_NO_MEMORY;
2266 cli_rpc_pipe_close(result);
2270 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
2271 if (!NT_STATUS_IS_OK(*perr)) {
2273 if (pipe_idx == PI_DSSETUP) {
2274 /* non AD domains just don't have this pipe, avoid
2275 * level 0 statement in that case - gd */
2278 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2279 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2280 cli_rpc_pipe_close(result);
2284 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2285 result->pipe_name, cli->desthost ));
2290 /****************************************************************************
2291 Free function for NTLMSSP auth.
2292 ****************************************************************************/
2294 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
2296 if (auth->a_u.ntlmssp_state) {
2297 ntlmssp_end(&auth->a_u.ntlmssp_state);
2298 auth->a_u.ntlmssp_state = NULL;
2302 /****************************************************************************
2303 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2304 ****************************************************************************/
2306 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2308 enum pipe_auth_type auth_type,
2309 enum pipe_auth_level auth_level,
2311 const char *username,
2312 const char *password,
2315 struct rpc_pipe_client *result;
2316 NTLMSSP_STATE *ntlmssp_state = NULL;
2318 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2319 if (result == NULL) {
2323 result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
2325 result->domain = talloc_strdup(result, domain);
2326 result->user_name = talloc_strdup(result, username);
2328 if ((result->domain == NULL) || (result->user_name == NULL)) {
2329 *perr = NT_STATUS_NO_MEMORY;
2333 pwd_set_cleartext(&result->pwd, password);
2335 *perr = ntlmssp_client_start(&ntlmssp_state);
2336 if (!NT_STATUS_IS_OK(*perr)) {
2340 result->auth.a_u.ntlmssp_state = ntlmssp_state;
2342 *perr = ntlmssp_set_username(ntlmssp_state, username);
2343 if (!NT_STATUS_IS_OK(*perr)) {
2347 *perr = ntlmssp_set_domain(ntlmssp_state, domain);
2348 if (!NT_STATUS_IS_OK(*perr)) {
2352 if (cli->pwd.null_pwd) {
2353 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
2354 if (!NT_STATUS_IS_OK(*perr)) {
2358 *perr = ntlmssp_set_password(ntlmssp_state, password);
2359 if (!NT_STATUS_IS_OK(*perr)) {
2364 /* Turn off sign+seal to allow selected auth level to turn it back on. */
2365 ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
2367 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2368 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2369 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2370 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2373 *perr = rpc_pipe_bind(result, auth_type, auth_level);
2374 if (!NT_STATUS_IS_OK(*perr)) {
2375 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2376 nt_errstr(*perr) ));
2380 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2381 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2382 result->pipe_name, cli->desthost,
2383 domain, username ));
2389 cli_rpc_pipe_close(result);
2393 /****************************************************************************
2395 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2396 ****************************************************************************/
2398 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2400 enum pipe_auth_level auth_level,
2402 const char *username,
2403 const char *password,
2406 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2408 PIPE_AUTH_TYPE_NTLMSSP,
2416 /****************************************************************************
2418 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2419 ****************************************************************************/
2421 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2423 enum pipe_auth_level auth_level,
2425 const char *username,
2426 const char *password,
2429 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2431 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2439 /****************************************************************************
2440 Get a the schannel session key out of an already opened netlogon pipe.
2441 ****************************************************************************/
2442 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2443 struct cli_state *cli,
2448 uint32 sec_chan_type = 0;
2449 unsigned char machine_pwd[16];
2450 const char *machine_account;
2452 /* Get the machine account credentials from secrets.tdb. */
2453 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2456 DEBUG(0, ("get_schannel_session_key: could not fetch "
2457 "trust account password for domain '%s'\n",
2459 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2463 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2464 cli->desthost, /* server name */
2465 domain, /* domain */
2466 global_myname(), /* client name */
2467 machine_account, /* machine account name */
2472 if (!NT_STATUS_IS_OK(*perr)) {
2473 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2474 "failed with result %s to server %s, domain %s, machine account %s.\n",
2475 nt_errstr(*perr), cli->desthost, domain, machine_account ));
2479 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2480 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2482 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2489 /****************************************************************************
2490 Open a netlogon pipe and get the schannel session key.
2491 Now exposed to external callers.
2492 ****************************************************************************/
2495 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2500 struct rpc_pipe_client *netlogon_pipe = NULL;
2502 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2503 if (!netlogon_pipe) {
2507 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2510 cli_rpc_pipe_close(netlogon_pipe);
2514 return netlogon_pipe;
2517 /****************************************************************************
2519 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2520 using session_key. sign and seal.
2521 ****************************************************************************/
2523 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2525 enum pipe_auth_level auth_level,
2527 const struct dcinfo *pdc,
2530 struct rpc_pipe_client *result;
2532 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2533 if (result == NULL) {
2537 result->auth.a_u.schannel_auth = TALLOC_ZERO_P(
2538 result, struct schannel_auth_struct);
2539 if (!result->auth.a_u.schannel_auth) {
2540 cli_rpc_pipe_close(result);
2541 *perr = NT_STATUS_NO_MEMORY;
2545 result->domain = domain;
2546 memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2548 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
2549 if (!NT_STATUS_IS_OK(*perr)) {
2550 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2551 nt_errstr(*perr) ));
2552 cli_rpc_pipe_close(result);
2556 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2561 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2563 "and bound using schannel.\n",
2564 result->pipe_name, cli->desthost, domain ));
2569 /****************************************************************************
2570 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2571 Fetch the session key ourselves using a temporary netlogon pipe. This
2572 version uses an ntlmssp auth bound netlogon pipe to get the key.
2573 ****************************************************************************/
2575 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2577 const char *username,
2578 const char *password,
2582 struct rpc_pipe_client *netlogon_pipe = NULL;
2584 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2585 if (!netlogon_pipe) {
2589 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2592 cli_rpc_pipe_close(netlogon_pipe);
2596 return netlogon_pipe;
2599 /****************************************************************************
2600 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2601 Fetch the session key ourselves using a temporary netlogon pipe. This version
2602 uses an ntlmssp bind to get the session key.
2603 ****************************************************************************/
2605 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2607 enum pipe_auth_level auth_level,
2609 const char *username,
2610 const char *password,
2613 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2614 struct rpc_pipe_client *netlogon_pipe = NULL;
2615 struct rpc_pipe_client *result = NULL;
2617 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2618 password, &neg_flags, perr);
2619 if (!netlogon_pipe) {
2620 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2621 "key from server %s for domain %s.\n",
2622 cli->desthost, domain ));
2626 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2628 domain, netlogon_pipe->dc, perr);
2630 /* Now we've bound using the session key we can close the netlog pipe. */
2631 cli_rpc_pipe_close(netlogon_pipe);
2636 /****************************************************************************
2637 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2638 Fetch the session key ourselves using a temporary netlogon pipe.
2639 ****************************************************************************/
2641 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2643 enum pipe_auth_level auth_level,
2647 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2648 struct rpc_pipe_client *netlogon_pipe = NULL;
2649 struct rpc_pipe_client *result = NULL;
2651 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2652 if (!netlogon_pipe) {
2653 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2654 "key from server %s for domain %s.\n",
2655 cli->desthost, domain ));
2659 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2661 domain, netlogon_pipe->dc, perr);
2663 /* Now we've bound using the session key we can close the netlog pipe. */
2664 cli_rpc_pipe_close(netlogon_pipe);
2671 /****************************************************************************
2672 Free function for the kerberos spcific data.
2673 ****************************************************************************/
2675 static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
2677 data_blob_free(&a->a_u.kerberos_auth->session_key);
2682 /****************************************************************************
2683 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2684 The idea is this can be called with service_princ, username and password all
2685 NULL so long as the caller has a TGT.
2686 ****************************************************************************/
2688 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2690 enum pipe_auth_level auth_level,
2691 const char *service_princ,
2692 const char *username,
2693 const char *password,
2697 struct rpc_pipe_client *result;
2699 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2700 if (result == NULL) {
2704 /* Default service principal is "desthost$@realm" */
2705 if (!service_princ) {
2706 service_princ = talloc_asprintf(result, "%s$@%s",
2707 cli->desthost, lp_realm() );
2708 if (!service_princ) {
2709 cli_rpc_pipe_close(result);
2714 /* Only get a new TGT if username/password are given. */
2715 if (username && password) {
2716 int ret = kerberos_kinit_password(username, password, 0, NULL);
2718 cli_rpc_pipe_close(result);
2723 result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(
2724 result, struct kerberos_auth_struct);
2725 if (!result->auth.a_u.kerberos_auth) {
2726 cli_rpc_pipe_close(result);
2727 *perr = NT_STATUS_NO_MEMORY;
2731 result->auth.a_u.kerberos_auth->service_principal = service_princ;
2732 result->auth.cli_auth_data_free_func = kerberos_auth_struct_free;
2734 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
2735 if (!NT_STATUS_IS_OK(*perr)) {
2736 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2737 nt_errstr(*perr) ));
2738 cli_rpc_pipe_close(result);
2744 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));