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/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
24 #define DBGC_CLASS DBGC_RPC_CLI
26 extern struct pipe_id_info pipe_names[];
28 /********************************************************************
29 Map internal value to wire value.
30 ********************************************************************/
32 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
36 case PIPE_AUTH_TYPE_NONE:
37 return RPC_ANONYMOUS_AUTH_TYPE;
39 case PIPE_AUTH_TYPE_NTLMSSP:
40 return RPC_NTLMSSP_AUTH_TYPE;
42 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
43 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
44 return RPC_SPNEGO_AUTH_TYPE;
46 case PIPE_AUTH_TYPE_SCHANNEL:
47 return RPC_SCHANNEL_AUTH_TYPE;
49 case PIPE_AUTH_TYPE_KRB5:
50 return RPC_KRB5_AUTH_TYPE;
53 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
55 (unsigned int)auth_type ));
61 /********************************************************************
62 Pipe description for a DEBUG
63 ********************************************************************/
64 static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli)
68 switch (cli->transport_type) {
70 result = talloc_asprintf(mem_ctx, "host %s, pipe %s, "
73 cli->trans.np.pipe_name,
74 (unsigned int)(cli->trans.np.fnum));
77 case NCACN_UNIX_STREAM:
78 result = talloc_asprintf(mem_ctx, "host %s, fd %d",
79 cli->desthost, cli->trans.sock.fd);
82 result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
85 SMB_ASSERT(result != NULL);
89 /********************************************************************
91 ********************************************************************/
93 static uint32 get_rpc_call_id(void)
95 static uint32 call_id = 0;
99 /*******************************************************************
100 Read from a RPC named pipe
101 ********************************************************************/
102 static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name,
103 int fnum, char *buf, off_t offset, size_t size,
108 num_read = cli_read(cli, fnum, buf, offset, size);
110 DEBUG(5,("rpc_read_np: num_read = %d, read offset: %u, to read: %u\n",
111 (int)num_read, (unsigned int)offset, (unsigned int)size));
114 * A dos error of ERRDOS/ERRmoredata is not an error.
116 if (cli_is_dos_error(cli)) {
119 cli_dos_error(cli, &eclass, &ecode);
120 if (eclass != ERRDOS && ecode != ERRmoredata) {
121 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read "
122 "on fnum 0x%x\n", eclass, (unsigned int)ecode,
123 cli_errstr(cli), fnum));
124 return dos_to_ntstatus(eclass, ecode);
129 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
131 if (cli_is_nt_error(cli)) {
132 if (!NT_STATUS_EQUAL(cli_nt_error(cli),
133 NT_STATUS_BUFFER_TOO_SMALL)) {
134 DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum "
135 "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum));
136 return cli_nt_error(cli);
140 if (num_read == -1) {
141 DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned "
143 return cli_get_nt_error(cli);
146 *pnum_read = num_read;
151 /*******************************************************************
152 Use SMBreadX to get rest of one fragment's worth of rpc data.
153 Will expand the current_pdu struct to the correct size.
154 ********************************************************************/
156 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
157 prs_struct *current_pdu,
159 uint32 *current_pdu_offset)
161 size_t size = (size_t)cli->max_recv_frag;
162 uint32 stream_offset = 0;
163 ssize_t num_read = 0;
165 ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
167 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
168 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
171 * Grow the buffer if needed to accommodate the data to be read.
174 if (extra_data_size > 0) {
175 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
176 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
177 return NT_STATUS_NO_MEMORY;
179 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
182 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
187 /* read data using SMBreadX */
188 if (size > (size_t)data_to_read) {
189 size = (size_t)data_to_read;
192 switch (cli->transport_type) {
194 status = rpc_read_np(cli->trans.np.cli,
195 cli->trans.np.pipe_name,
196 cli->trans.np.fnum, pdata,
197 (off_t)stream_offset, size,
201 case NCACN_UNIX_STREAM:
202 status = NT_STATUS_OK;
203 num_read = sys_read(cli->trans.sock.fd, pdata, size);
204 if (num_read == -1) {
205 status = map_nt_error_from_unix(errno);
208 status = NT_STATUS_END_OF_FILE;
212 DEBUG(0, ("unknown transport type %d\n",
213 cli->transport_type));
214 return NT_STATUS_INTERNAL_ERROR;
217 data_to_read -= num_read;
218 stream_offset += num_read;
221 } while (num_read > 0 && data_to_read > 0);
222 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
225 * Update the current offset into current_pdu by the amount read.
227 *current_pdu_offset += stream_offset;
231 /****************************************************************************
232 Try and get a PDU's worth of data from current_pdu. If not, then read more
234 ****************************************************************************/
236 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
238 NTSTATUS ret = NT_STATUS_OK;
239 uint32 current_pdu_len = prs_data_size(current_pdu);
241 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
242 if (current_pdu_len < RPC_HEADER_LEN) {
243 /* rpc_read expands the current_pdu struct as neccessary. */
244 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, ¤t_pdu_len);
245 if (!NT_STATUS_IS_OK(ret)) {
250 /* This next call sets the endian bit correctly in current_pdu. */
251 /* We will propagate this to rbuf later. */
252 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
253 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
254 return NT_STATUS_BUFFER_TOO_SMALL;
257 /* Ensure we have frag_len bytes of data. */
258 if (current_pdu_len < prhdr->frag_len) {
259 /* rpc_read expands the current_pdu struct as neccessary. */
260 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, ¤t_pdu_len);
261 if (!NT_STATUS_IS_OK(ret)) {
266 if (current_pdu_len < prhdr->frag_len) {
267 return NT_STATUS_BUFFER_TOO_SMALL;
273 /****************************************************************************
274 NTLMSSP specific sign/seal.
275 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
276 In fact I should probably abstract these into identical pieces of code... JRA.
277 ****************************************************************************/
279 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
280 prs_struct *current_pdu,
281 uint8 *p_ss_padding_len)
283 RPC_HDR_AUTH auth_info;
284 uint32 save_offset = prs_offset(current_pdu);
285 uint32 auth_len = prhdr->auth_len;
286 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
287 unsigned char *data = NULL;
289 unsigned char *full_packet_data = NULL;
290 size_t full_packet_data_len;
294 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
295 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
299 if (!ntlmssp_state) {
300 return NT_STATUS_INVALID_PARAMETER;
303 /* Ensure there's enough data for an authenticated response. */
304 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
305 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
306 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
307 (unsigned int)auth_len ));
308 return NT_STATUS_BUFFER_TOO_SMALL;
312 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
313 * after the RPC header.
314 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
315 * functions as NTLMv2 checks the rpc headers also.
318 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
319 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
321 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
322 full_packet_data_len = prhdr->frag_len - auth_len;
324 /* Pull the auth header and the following data into a blob. */
325 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
326 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
327 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
328 return NT_STATUS_BUFFER_TOO_SMALL;
331 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
332 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
333 return NT_STATUS_BUFFER_TOO_SMALL;
336 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
337 auth_blob.length = auth_len;
339 switch (cli->auth->auth_level) {
340 case PIPE_AUTH_LEVEL_PRIVACY:
341 /* Data is encrypted. */
342 status = ntlmssp_unseal_packet(ntlmssp_state,
345 full_packet_data_len,
347 if (!NT_STATUS_IS_OK(status)) {
348 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
349 "packet from %s. Error was %s.\n",
350 rpccli_pipe_txt(debug_ctx(), cli),
351 nt_errstr(status) ));
355 case PIPE_AUTH_LEVEL_INTEGRITY:
356 /* Data is signed. */
357 status = ntlmssp_check_packet(ntlmssp_state,
360 full_packet_data_len,
362 if (!NT_STATUS_IS_OK(status)) {
363 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
364 "packet from %s. Error was %s.\n",
365 rpccli_pipe_txt(debug_ctx(), cli),
366 nt_errstr(status) ));
371 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
372 "auth level %d\n", cli->auth->auth_level));
373 return NT_STATUS_INVALID_INFO_CLASS;
377 * Return the current pointer to the data offset.
380 if(!prs_set_offset(current_pdu, save_offset)) {
381 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
382 (unsigned int)save_offset ));
383 return NT_STATUS_BUFFER_TOO_SMALL;
387 * Remember the padding length. We must remove it from the real data
388 * stream once the sign/seal is done.
391 *p_ss_padding_len = auth_info.auth_pad_len;
396 /****************************************************************************
397 schannel specific sign/seal.
398 ****************************************************************************/
400 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
401 prs_struct *current_pdu,
402 uint8 *p_ss_padding_len)
404 RPC_HDR_AUTH auth_info;
405 RPC_AUTH_SCHANNEL_CHK schannel_chk;
406 uint32 auth_len = prhdr->auth_len;
407 uint32 save_offset = prs_offset(current_pdu);
408 struct schannel_auth_struct *schannel_auth =
409 cli->auth->a_u.schannel_auth;
412 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
413 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
417 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
418 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
419 return NT_STATUS_INVALID_PARAMETER;
422 if (!schannel_auth) {
423 return NT_STATUS_INVALID_PARAMETER;
426 /* Ensure there's enough data for an authenticated response. */
427 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
428 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
429 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
430 (unsigned int)auth_len ));
431 return NT_STATUS_INVALID_PARAMETER;
434 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
436 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
437 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
438 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
439 return NT_STATUS_BUFFER_TOO_SMALL;
442 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
443 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
444 return NT_STATUS_BUFFER_TOO_SMALL;
447 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
448 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
449 auth_info.auth_type));
450 return NT_STATUS_BUFFER_TOO_SMALL;
453 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
454 &schannel_chk, current_pdu, 0)) {
455 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
456 return NT_STATUS_BUFFER_TOO_SMALL;
459 if (!schannel_decode(schannel_auth,
460 cli->auth->auth_level,
463 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
465 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
466 "Connection to %s.\n",
467 rpccli_pipe_txt(debug_ctx(), cli)));
468 return NT_STATUS_INVALID_PARAMETER;
471 /* The sequence number gets incremented on both send and receive. */
472 schannel_auth->seq_num++;
475 * Return the current pointer to the data offset.
478 if(!prs_set_offset(current_pdu, save_offset)) {
479 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
480 (unsigned int)save_offset ));
481 return NT_STATUS_BUFFER_TOO_SMALL;
485 * Remember the padding length. We must remove it from the real data
486 * stream once the sign/seal is done.
489 *p_ss_padding_len = auth_info.auth_pad_len;
494 /****************************************************************************
495 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
496 ****************************************************************************/
498 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
499 prs_struct *current_pdu,
500 uint8 *p_ss_padding_len)
502 NTSTATUS ret = NT_STATUS_OK;
504 /* Paranioa checks for auth_len. */
505 if (prhdr->auth_len) {
506 if (prhdr->auth_len > prhdr->frag_len) {
507 return NT_STATUS_INVALID_PARAMETER;
510 if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len ||
511 prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) {
512 /* Integer wrap attempt. */
513 return NT_STATUS_INVALID_PARAMETER;
518 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
521 switch(cli->auth->auth_type) {
522 case PIPE_AUTH_TYPE_NONE:
523 if (prhdr->auth_len) {
524 DEBUG(3, ("cli_pipe_validate_rpc_response: "
525 "Connection to %s - got non-zero "
527 rpccli_pipe_txt(debug_ctx(), cli),
528 (unsigned int)prhdr->auth_len ));
529 return NT_STATUS_INVALID_PARAMETER;
533 case PIPE_AUTH_TYPE_NTLMSSP:
534 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
535 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
536 if (!NT_STATUS_IS_OK(ret)) {
541 case PIPE_AUTH_TYPE_SCHANNEL:
542 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
543 if (!NT_STATUS_IS_OK(ret)) {
548 case PIPE_AUTH_TYPE_KRB5:
549 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
551 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
552 "to %s - unknown internal auth type %u.\n",
553 rpccli_pipe_txt(debug_ctx(), cli),
554 cli->auth->auth_type ));
555 return NT_STATUS_INVALID_INFO_CLASS;
561 /****************************************************************************
562 Do basic authentication checks on an incoming pdu.
563 ****************************************************************************/
565 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
566 prs_struct *current_pdu,
567 uint8 expected_pkt_type,
570 prs_struct *return_data)
573 NTSTATUS ret = NT_STATUS_OK;
574 uint32 current_pdu_len = prs_data_size(current_pdu);
576 if (current_pdu_len != prhdr->frag_len) {
577 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
578 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
579 return NT_STATUS_INVALID_PARAMETER;
583 * Point the return values at the real data including the RPC
584 * header. Just in case the caller wants it.
586 *ppdata = prs_data_p(current_pdu);
587 *pdata_len = current_pdu_len;
589 /* Ensure we have the correct type. */
590 switch (prhdr->pkt_type) {
591 case RPC_ALTCONTRESP:
594 /* Alter context and bind ack share the same packet definitions. */
600 RPC_HDR_RESP rhdr_resp;
601 uint8 ss_padding_len = 0;
603 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
604 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
605 return NT_STATUS_BUFFER_TOO_SMALL;
608 /* Here's where we deal with incoming sign/seal. */
609 ret = cli_pipe_validate_rpc_response(cli, prhdr,
610 current_pdu, &ss_padding_len);
611 if (!NT_STATUS_IS_OK(ret)) {
615 /* Point the return values at the NDR data. Remember to remove any ss padding. */
616 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
618 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
619 return NT_STATUS_BUFFER_TOO_SMALL;
622 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
624 /* Remember to remove the auth footer. */
625 if (prhdr->auth_len) {
626 /* We've already done integer wrap tests on auth_len in
627 cli_pipe_validate_rpc_response(). */
628 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
629 return NT_STATUS_BUFFER_TOO_SMALL;
631 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
634 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
635 current_pdu_len, *pdata_len, ss_padding_len ));
638 * If this is the first reply, and the allocation hint is reasonably, try and
639 * set up the return_data parse_struct to the correct size.
642 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
643 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
644 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
645 "too large to allocate\n",
646 (unsigned int)rhdr_resp.alloc_hint ));
647 return NT_STATUS_NO_MEMORY;
655 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
656 "received from %s!\n",
657 rpccli_pipe_txt(debug_ctx(), cli)));
658 /* Use this for now... */
659 return NT_STATUS_NETWORK_ACCESS_DENIED;
663 RPC_HDR_RESP rhdr_resp;
664 RPC_HDR_FAULT fault_resp;
666 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
667 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
668 return NT_STATUS_BUFFER_TOO_SMALL;
671 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
672 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
673 return NT_STATUS_BUFFER_TOO_SMALL;
676 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
677 "code %s received from %s!\n",
678 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
679 rpccli_pipe_txt(debug_ctx(), cli)));
680 if (NT_STATUS_IS_OK(fault_resp.status)) {
681 return NT_STATUS_UNSUCCESSFUL;
683 return fault_resp.status;
688 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
690 (unsigned int)prhdr->pkt_type,
691 rpccli_pipe_txt(debug_ctx(), cli)));
692 return NT_STATUS_INVALID_INFO_CLASS;
695 if (prhdr->pkt_type != expected_pkt_type) {
696 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
697 "got an unexpected RPC packet type - %u, not %u\n",
698 rpccli_pipe_txt(debug_ctx(), cli),
701 return NT_STATUS_INVALID_INFO_CLASS;
704 /* Do this just before return - we don't want to modify any rpc header
705 data before now as we may have needed to do cryptographic actions on
708 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
709 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
710 "setting fragment first/last ON.\n"));
711 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
717 /****************************************************************************
718 Ensure we eat the just processed pdu from the current_pdu prs_struct.
719 Normally the frag_len and buffer size will match, but on the first trans
720 reply there is a theoretical chance that buffer size > frag_len, so we must
722 ****************************************************************************/
724 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
726 uint32 current_pdu_len = prs_data_size(current_pdu);
728 if (current_pdu_len < prhdr->frag_len) {
729 return NT_STATUS_BUFFER_TOO_SMALL;
733 if (current_pdu_len == (uint32)prhdr->frag_len) {
734 prs_mem_free(current_pdu);
735 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
736 /* Make current_pdu dynamic with no memory. */
737 prs_give_memory(current_pdu, 0, 0, True);
742 * Oh no ! More data in buffer than we processed in current pdu.
743 * Cheat. Move the data down and shrink the buffer.
746 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
747 current_pdu_len - prhdr->frag_len);
749 /* Remember to set the read offset back to zero. */
750 prs_set_offset(current_pdu, 0);
752 /* Shrink the buffer. */
753 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
754 return NT_STATUS_BUFFER_TOO_SMALL;
760 /****************************************************************************
761 Send data on an rpc pipe via trans. The prs_struct data must be the last
762 pdu fragment of an NDR data stream.
764 Receive response data from an rpc pipe, which may be large...
766 Read the first fragment: unfortunately have to use SMBtrans for the first
767 bit, then SMBreadX for subsequent bits.
769 If first fragment received also wasn't the last fragment, continue
770 getting fragments until we _do_ receive the last fragment.
772 Request/Response PDU's look like the following...
774 |<------------------PDU len----------------------------------------------->|
775 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
777 +------------+-----------------+-------------+---------------+-------------+
778 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
779 +------------+-----------------+-------------+---------------+-------------+
781 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
782 signing & sealing being negotiated.
784 ****************************************************************************/
786 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
787 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
788 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
789 uint8 expected_pkt_type)
791 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
793 uint32 rparam_len = 0;
794 char *pdata = prs_data_p(data);
795 uint32 data_len = prs_offset(data);
797 uint32 rdata_len = 0;
798 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
799 uint32 current_rbuf_offset = 0;
800 prs_struct current_pdu;
803 /* Ensure we're not sending too much. */
804 SMB_ASSERT(data_len <= max_data);
807 /* Set up the current pdu parse struct. */
808 prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
810 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
812 switch (cli->transport_type) {
815 /* Create setup parameters - must be in native byte order. */
816 setup[0] = TRANSACT_DCERPCCMD;
817 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
820 * Send the last (or only) fragment of an RPC request. For
821 * small amounts of data (about 1024 bytes or so) the RPC
822 * request and response appears in a SMBtrans request and
826 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
827 setup, 2, 0, /* Setup, length, max */
828 NULL, 0, 0, /* Params, length, max */
829 pdata, data_len, max_data, /* data, length,
831 &rparam, &rparam_len, /* return params,
833 &prdata, &rdata_len)) /* return data, len */
835 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
837 rpccli_pipe_txt(debug_ctx(), cli),
838 cli_errstr(cli->trans.np.cli)));
839 ret = cli_get_nt_error(cli->trans.np.cli);
847 case NCACN_UNIX_STREAM:
849 ssize_t nwritten, nread;
850 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
851 if (nwritten == -1) {
852 ret = map_nt_error_from_unix(errno);
853 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
858 prdata = SMB_MALLOC_ARRAY(char, 1);
859 if (prdata == NULL) {
860 return NT_STATUS_NO_MEMORY;
862 nread = sys_read(cli->trans.sock.fd, prdata, 1);
867 ret = NT_STATUS_END_OF_FILE;
874 DEBUG(0, ("unknown transport type %d\n",
875 cli->transport_type));
876 return NT_STATUS_INTERNAL_ERROR;
879 /* Throw away returned params - we know we won't use them. */
883 if (prdata == NULL) {
884 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
885 rpccli_pipe_txt(debug_ctx(), cli)));
886 /* Yes - some calls can truely return no data... */
887 prs_mem_free(¤t_pdu);
892 * Give this memory as dynamic to the current pdu.
895 prs_give_memory(¤t_pdu, prdata, rdata_len, True);
897 /* Ensure we can mess with the return prs_struct. */
898 SMB_ASSERT(UNMARSHALLING(rbuf));
899 SMB_ASSERT(prs_data_size(rbuf) == 0);
901 /* Make rbuf dynamic with no memory. */
902 prs_give_memory(rbuf, 0, 0, True);
909 /* Ensure we have enough data for a pdu. */
910 ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu);
911 if (!NT_STATUS_IS_OK(ret)) {
915 /* We pass in rbuf here so if the alloc hint is set correctly
916 we can set the output size and avoid reallocs. */
918 ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type,
919 &ret_data, &ret_data_len, rbuf);
921 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
922 prs_data_size(¤t_pdu), current_rbuf_offset ));
924 if (!NT_STATUS_IS_OK(ret)) {
928 if ((rhdr.flags & RPC_FLG_FIRST)) {
929 if (rhdr.pack_type[0] == 0) {
930 /* Set the data type correctly for big-endian data on the first packet. */
931 DEBUG(10,("rpc_api_pipe: On %s "
932 "PDU data format is big-endian.\n",
933 rpccli_pipe_txt(debug_ctx(), cli)));
935 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
937 /* Check endianness on subsequent packets. */
938 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
939 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
940 rbuf->bigendian_data ? "big" : "little",
941 current_pdu.bigendian_data ? "big" : "little" ));
942 ret = NT_STATUS_INVALID_PARAMETER;
948 /* Now copy the data portion out of the pdu into rbuf. */
949 if (!prs_force_grow(rbuf, ret_data_len)) {
950 ret = NT_STATUS_NO_MEMORY;
953 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
954 current_rbuf_offset += ret_data_len;
956 /* See if we've finished with all the data in current_pdu yet ? */
957 ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu);
958 if (!NT_STATUS_IS_OK(ret)) {
962 if (rhdr.flags & RPC_FLG_LAST) {
963 break; /* We're done. */
967 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
968 rpccli_pipe_txt(debug_ctx(), cli),
969 (unsigned int)prs_data_size(rbuf) ));
971 prs_mem_free(¤t_pdu);
976 prs_mem_free(¤t_pdu);
981 /*******************************************************************
982 Creates krb5 auth bind.
983 ********************************************************************/
985 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
986 enum pipe_auth_level auth_level,
987 RPC_HDR_AUTH *pauth_out,
988 prs_struct *auth_data)
992 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
993 DATA_BLOB tkt = data_blob_null;
994 DATA_BLOB tkt_wrapped = data_blob_null;
996 /* We may change the pad length before marshalling. */
997 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
999 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1000 a->service_principal ));
1002 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1004 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1005 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1008 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1010 a->service_principal,
1011 error_message(ret) ));
1013 data_blob_free(&tkt);
1014 prs_mem_free(auth_data);
1015 return NT_STATUS_INVALID_PARAMETER;
1018 /* wrap that up in a nice GSS-API wrapping */
1019 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1021 data_blob_free(&tkt);
1023 /* Auth len in the rpc header doesn't include auth_header. */
1024 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1025 data_blob_free(&tkt_wrapped);
1026 prs_mem_free(auth_data);
1027 return NT_STATUS_NO_MEMORY;
1030 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1031 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1033 data_blob_free(&tkt_wrapped);
1034 return NT_STATUS_OK;
1036 return NT_STATUS_INVALID_PARAMETER;
1040 /*******************************************************************
1041 Creates SPNEGO NTLMSSP auth bind.
1042 ********************************************************************/
1044 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1045 enum pipe_auth_level auth_level,
1046 RPC_HDR_AUTH *pauth_out,
1047 prs_struct *auth_data)
1050 DATA_BLOB null_blob = data_blob_null;
1051 DATA_BLOB request = data_blob_null;
1052 DATA_BLOB spnego_msg = data_blob_null;
1054 /* We may change the pad length before marshalling. */
1055 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1057 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1058 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1062 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1063 data_blob_free(&request);
1064 prs_mem_free(auth_data);
1068 /* Wrap this in SPNEGO. */
1069 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1071 data_blob_free(&request);
1073 /* Auth len in the rpc header doesn't include auth_header. */
1074 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1075 data_blob_free(&spnego_msg);
1076 prs_mem_free(auth_data);
1077 return NT_STATUS_NO_MEMORY;
1080 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1081 dump_data(5, spnego_msg.data, spnego_msg.length);
1083 data_blob_free(&spnego_msg);
1084 return NT_STATUS_OK;
1087 /*******************************************************************
1088 Creates NTLMSSP auth bind.
1089 ********************************************************************/
1091 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1092 enum pipe_auth_level auth_level,
1093 RPC_HDR_AUTH *pauth_out,
1094 prs_struct *auth_data)
1097 DATA_BLOB null_blob = data_blob_null;
1098 DATA_BLOB request = data_blob_null;
1100 /* We may change the pad length before marshalling. */
1101 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1103 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1104 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1108 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1109 data_blob_free(&request);
1110 prs_mem_free(auth_data);
1114 /* Auth len in the rpc header doesn't include auth_header. */
1115 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1116 data_blob_free(&request);
1117 prs_mem_free(auth_data);
1118 return NT_STATUS_NO_MEMORY;
1121 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1122 dump_data(5, request.data, request.length);
1124 data_blob_free(&request);
1125 return NT_STATUS_OK;
1128 /*******************************************************************
1129 Creates schannel auth bind.
1130 ********************************************************************/
1132 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1133 enum pipe_auth_level auth_level,
1134 RPC_HDR_AUTH *pauth_out,
1135 prs_struct *auth_data)
1137 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1139 /* We may change the pad length before marshalling. */
1140 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1142 /* Use lp_workgroup() if domain not specified */
1144 if (!cli->auth->domain || !cli->auth->domain[0]) {
1145 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1146 if (cli->auth->domain == NULL) {
1147 return NT_STATUS_NO_MEMORY;
1151 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1155 * Now marshall the data into the auth parse_struct.
1158 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1159 &schannel_neg, auth_data, 0)) {
1160 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1161 prs_mem_free(auth_data);
1162 return NT_STATUS_NO_MEMORY;
1165 return NT_STATUS_OK;
1168 /*******************************************************************
1169 Creates the internals of a DCE/RPC bind request or alter context PDU.
1170 ********************************************************************/
1172 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1173 prs_struct *rpc_out,
1175 const RPC_IFACE *abstract,
1176 const RPC_IFACE *transfer,
1177 RPC_HDR_AUTH *phdr_auth,
1178 prs_struct *pauth_info)
1182 RPC_CONTEXT rpc_ctx;
1183 uint16 auth_len = prs_offset(pauth_info);
1184 uint8 ss_padding_len = 0;
1185 uint16 frag_len = 0;
1187 /* create the RPC context. */
1188 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1190 /* create the bind request RPC_HDR_RB */
1191 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1193 /* Start building the frag length. */
1194 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1196 /* Do we need to pad ? */
1198 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1200 ss_padding_len = 8 - (data_len % 8);
1201 phdr_auth->auth_pad_len = ss_padding_len;
1203 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1206 /* Create the request RPC_HDR */
1207 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1209 /* Marshall the RPC header */
1210 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1211 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1212 return NT_STATUS_NO_MEMORY;
1215 /* Marshall the bind request data */
1216 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1217 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1218 return NT_STATUS_NO_MEMORY;
1222 * Grow the outgoing buffer to store any auth info.
1226 if (ss_padding_len) {
1228 memset(pad, '\0', 8);
1229 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1230 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1231 return NT_STATUS_NO_MEMORY;
1235 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1236 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1237 return NT_STATUS_NO_MEMORY;
1241 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1242 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1243 return NT_STATUS_NO_MEMORY;
1247 return NT_STATUS_OK;
1250 /*******************************************************************
1251 Creates a DCE/RPC bind request.
1252 ********************************************************************/
1254 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1255 prs_struct *rpc_out,
1257 const RPC_IFACE *abstract,
1258 const RPC_IFACE *transfer,
1259 enum pipe_auth_type auth_type,
1260 enum pipe_auth_level auth_level)
1262 RPC_HDR_AUTH hdr_auth;
1263 prs_struct auth_info;
1264 NTSTATUS ret = NT_STATUS_OK;
1266 ZERO_STRUCT(hdr_auth);
1267 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1268 return NT_STATUS_NO_MEMORY;
1270 switch (auth_type) {
1271 case PIPE_AUTH_TYPE_SCHANNEL:
1272 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1273 if (!NT_STATUS_IS_OK(ret)) {
1274 prs_mem_free(&auth_info);
1279 case PIPE_AUTH_TYPE_NTLMSSP:
1280 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1281 if (!NT_STATUS_IS_OK(ret)) {
1282 prs_mem_free(&auth_info);
1287 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1288 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1289 if (!NT_STATUS_IS_OK(ret)) {
1290 prs_mem_free(&auth_info);
1295 case PIPE_AUTH_TYPE_KRB5:
1296 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1297 if (!NT_STATUS_IS_OK(ret)) {
1298 prs_mem_free(&auth_info);
1303 case PIPE_AUTH_TYPE_NONE:
1307 /* "Can't" happen. */
1308 return NT_STATUS_INVALID_INFO_CLASS;
1311 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1319 prs_mem_free(&auth_info);
1323 /*******************************************************************
1324 Create and add the NTLMSSP sign/seal auth header and data.
1325 ********************************************************************/
1327 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1329 uint32 ss_padding_len,
1330 prs_struct *outgoing_pdu)
1332 RPC_HDR_AUTH auth_info;
1334 DATA_BLOB auth_blob = data_blob_null;
1335 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1337 if (!cli->auth->a_u.ntlmssp_state) {
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(
1344 cli->auth->auth_type),
1345 cli->auth->auth_level,
1347 1 /* context id. */);
1349 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1350 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1351 data_blob_free(&auth_blob);
1352 return NT_STATUS_NO_MEMORY;
1355 switch (cli->auth->auth_level) {
1356 case PIPE_AUTH_LEVEL_PRIVACY:
1357 /* Data portion is encrypted. */
1358 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1359 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1361 (unsigned char *)prs_data_p(outgoing_pdu),
1362 (size_t)prs_offset(outgoing_pdu),
1364 if (!NT_STATUS_IS_OK(status)) {
1365 data_blob_free(&auth_blob);
1370 case PIPE_AUTH_LEVEL_INTEGRITY:
1371 /* Data is signed. */
1372 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1373 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1375 (unsigned char *)prs_data_p(outgoing_pdu),
1376 (size_t)prs_offset(outgoing_pdu),
1378 if (!NT_STATUS_IS_OK(status)) {
1379 data_blob_free(&auth_blob);
1386 smb_panic("bad auth level");
1388 return NT_STATUS_INVALID_PARAMETER;
1391 /* Finally marshall the blob. */
1393 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1394 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1395 (unsigned int)NTLMSSP_SIG_SIZE));
1396 data_blob_free(&auth_blob);
1397 return NT_STATUS_NO_MEMORY;
1400 data_blob_free(&auth_blob);
1401 return NT_STATUS_OK;
1404 /*******************************************************************
1405 Create and add the schannel sign/seal auth header and data.
1406 ********************************************************************/
1408 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1410 uint32 ss_padding_len,
1411 prs_struct *outgoing_pdu)
1413 RPC_HDR_AUTH auth_info;
1414 RPC_AUTH_SCHANNEL_CHK verf;
1415 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1416 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1417 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1420 return NT_STATUS_INVALID_PARAMETER;
1423 /* Init and marshall the auth header. */
1424 init_rpc_hdr_auth(&auth_info,
1425 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1426 cli->auth->auth_level,
1428 1 /* context id. */);
1430 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1431 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1432 return NT_STATUS_NO_MEMORY;
1435 switch (cli->auth->auth_level) {
1436 case PIPE_AUTH_LEVEL_PRIVACY:
1437 case PIPE_AUTH_LEVEL_INTEGRITY:
1438 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1441 schannel_encode(sas,
1442 cli->auth->auth_level,
1443 SENDER_IS_INITIATOR,
1453 smb_panic("bad auth level");
1455 return NT_STATUS_INVALID_PARAMETER;
1458 /* Finally marshall the blob. */
1459 smb_io_rpc_auth_schannel_chk("",
1460 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1465 return NT_STATUS_OK;
1468 /*******************************************************************
1469 Calculate how much data we're going to send in this packet, also
1470 work out any sign/seal padding length.
1471 ********************************************************************/
1473 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1477 uint32 *p_ss_padding)
1479 uint32 data_space, data_len;
1481 switch (cli->auth->auth_level) {
1482 case PIPE_AUTH_LEVEL_NONE:
1483 case PIPE_AUTH_LEVEL_CONNECT:
1484 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1485 data_len = MIN(data_space, data_left);
1488 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1491 case PIPE_AUTH_LEVEL_INTEGRITY:
1492 case PIPE_AUTH_LEVEL_PRIVACY:
1493 /* Treat the same for all authenticated rpc requests. */
1494 switch(cli->auth->auth_type) {
1495 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1496 case PIPE_AUTH_TYPE_NTLMSSP:
1497 *p_auth_len = NTLMSSP_SIG_SIZE;
1499 case PIPE_AUTH_TYPE_SCHANNEL:
1500 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1503 smb_panic("bad auth type");
1507 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1508 RPC_HDR_AUTH_LEN - *p_auth_len;
1510 data_len = MIN(data_space, data_left);
1512 *p_ss_padding = 8 - (data_len % 8);
1514 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1515 data_len + *p_ss_padding + /* data plus padding. */
1516 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1520 smb_panic("bad auth level");
1526 /*******************************************************************
1528 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1529 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1530 and deals with signing/sealing details.
1531 ********************************************************************/
1533 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1535 prs_struct *in_data,
1536 prs_struct *out_data)
1539 uint32 data_left = prs_offset(in_data);
1540 uint32 alloc_hint = prs_offset(in_data);
1541 uint32 data_sent_thistime = 0;
1542 uint32 current_data_offset = 0;
1543 uint32 call_id = get_rpc_call_id();
1545 prs_struct outgoing_pdu;
1547 memset(pad, '\0', 8);
1549 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1550 /* Server is screwed up ! */
1551 return NT_STATUS_INVALID_PARAMETER;
1554 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1555 return NT_STATUS_NO_MEMORY;
1559 RPC_HDR_REQ hdr_req;
1560 uint16 auth_len = 0;
1561 uint16 frag_len = 0;
1563 uint32 ss_padding = 0;
1565 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1566 &frag_len, &auth_len, &ss_padding);
1568 if (current_data_offset == 0) {
1569 flags = RPC_FLG_FIRST;
1572 if (data_sent_thistime == data_left) {
1573 flags |= RPC_FLG_LAST;
1576 /* Create and marshall the header and request header. */
1577 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1579 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1580 prs_mem_free(&outgoing_pdu);
1581 return NT_STATUS_NO_MEMORY;
1584 /* Create the rpc request RPC_HDR_REQ */
1585 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1587 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1588 prs_mem_free(&outgoing_pdu);
1589 return NT_STATUS_NO_MEMORY;
1592 /* Copy in the data, plus any ss padding. */
1593 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1594 prs_mem_free(&outgoing_pdu);
1595 return NT_STATUS_NO_MEMORY;
1598 /* Copy the sign/seal padding data. */
1600 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1601 prs_mem_free(&outgoing_pdu);
1602 return NT_STATUS_NO_MEMORY;
1606 /* Generate any auth sign/seal and add the auth footer. */
1608 switch (cli->auth->auth_type) {
1609 case PIPE_AUTH_TYPE_NONE:
1611 case PIPE_AUTH_TYPE_NTLMSSP:
1612 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1613 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1614 if (!NT_STATUS_IS_OK(ret)) {
1615 prs_mem_free(&outgoing_pdu);
1619 case PIPE_AUTH_TYPE_SCHANNEL:
1620 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1621 if (!NT_STATUS_IS_OK(ret)) {
1622 prs_mem_free(&outgoing_pdu);
1627 smb_panic("bad auth type");
1628 break; /* notreached */
1632 /* Actually send the packet. */
1633 if (flags & RPC_FLG_LAST) {
1634 /* Last packet - send the data, get the reply and return. */
1635 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1636 prs_mem_free(&outgoing_pdu);
1638 if ((DEBUGLEVEL >= 50)
1639 && (cli->transport_type == NCACN_NP)) {
1640 char *dump_name = NULL;
1641 /* Also capture received data */
1642 if (asprintf(&dump_name, "%s/reply_%s_%d",
1643 get_dyn_LOGFILEBASE(),
1644 cli->trans.np.pipe_name, op_num) > 0) {
1645 prs_dump(dump_name, op_num, out_data);
1646 SAFE_FREE(dump_name);
1652 /* More packets to come - write and continue. */
1653 ssize_t num_written;
1655 switch (cli->transport_type) {
1657 num_written = cli_write(cli->trans.np.cli,
1659 8, /* 8 means message mode. */
1660 prs_data_p(&outgoing_pdu),
1662 (size_t)hdr.frag_len);
1664 if (num_written != hdr.frag_len) {
1665 prs_mem_free(&outgoing_pdu);
1666 return cli_get_nt_error(
1671 case NCACN_UNIX_STREAM:
1672 num_written = write_data(
1674 prs_data_p(&outgoing_pdu),
1675 (size_t)hdr.frag_len);
1676 if (num_written != hdr.frag_len) {
1678 status = map_nt_error_from_unix(errno);
1679 prs_mem_free(&outgoing_pdu);
1684 DEBUG(0, ("unknown transport type %d\n",
1685 cli->transport_type));
1686 return NT_STATUS_INTERNAL_ERROR;
1690 current_data_offset += data_sent_thistime;
1691 data_left -= data_sent_thistime;
1693 /* Reset the marshalling position back to zero. */
1694 if (!prs_set_offset(&outgoing_pdu, 0)) {
1695 prs_mem_free(&outgoing_pdu);
1696 return NT_STATUS_NO_MEMORY;
1701 /****************************************************************************
1702 Set the handle state.
1703 ****************************************************************************/
1705 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1706 const char *pipe_name, uint16 device_state)
1708 bool state_set = False;
1710 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1711 char *rparam = NULL;
1713 uint32 rparam_len, rdata_len;
1715 if (pipe_name == NULL)
1718 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1719 cli->fnum, pipe_name, device_state));
1721 /* create parameters: device state */
1722 SSVAL(param, 0, device_state);
1724 /* create setup parameters. */
1726 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1728 /* send the data on \PIPE\ */
1729 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1730 setup, 2, 0, /* setup, length, max */
1731 param, 2, 0, /* param, length, max */
1732 NULL, 0, 1024, /* data, length, max */
1733 &rparam, &rparam_len, /* return param, length */
1734 &rdata, &rdata_len)) /* return data, length */
1736 DEBUG(5, ("Set Handle state: return OK\n"));
1747 /****************************************************************************
1748 Check the rpc bind acknowledge response.
1749 ****************************************************************************/
1751 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1753 if ( hdr_ba->addr.len == 0) {
1754 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1757 /* check the transfer syntax */
1758 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1759 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1760 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1764 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1765 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1766 hdr_ba->res.num_results, hdr_ba->res.reason));
1769 DEBUG(5,("check_bind_response: accepted!\n"));
1773 /*******************************************************************
1774 Creates a DCE/RPC bind authentication response.
1775 This is the packet that is sent back to the server once we
1776 have received a BIND-ACK, to finish the third leg of
1777 the authentication handshake.
1778 ********************************************************************/
1780 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1782 enum pipe_auth_type auth_type,
1783 enum pipe_auth_level auth_level,
1784 DATA_BLOB *pauth_blob,
1785 prs_struct *rpc_out)
1788 RPC_HDR_AUTH hdr_auth;
1791 /* Create the request RPC_HDR */
1792 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1793 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1794 pauth_blob->length );
1797 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1798 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1799 return NT_STATUS_NO_MEMORY;
1803 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1804 about padding - shouldn't this pad to length 8 ? JRA.
1807 /* 4 bytes padding. */
1808 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1809 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1810 return NT_STATUS_NO_MEMORY;
1813 /* Create the request RPC_HDR_AUTHA */
1814 init_rpc_hdr_auth(&hdr_auth,
1815 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1818 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1819 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1820 return NT_STATUS_NO_MEMORY;
1824 * Append the auth data to the outgoing buffer.
1827 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1828 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1829 return NT_STATUS_NO_MEMORY;
1832 return NT_STATUS_OK;
1835 /****************************************************************************
1836 Create and send the third packet in an RPC auth.
1837 ****************************************************************************/
1839 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1843 enum pipe_auth_type auth_type,
1844 enum pipe_auth_level auth_level)
1846 DATA_BLOB server_response = data_blob_null;
1847 DATA_BLOB client_reply = data_blob_null;
1848 RPC_HDR_AUTH hdr_auth;
1853 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1854 return NT_STATUS_INVALID_PARAMETER;
1857 /* Process the returned NTLMSSP blob first. */
1858 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1859 return NT_STATUS_INVALID_PARAMETER;
1862 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1863 return NT_STATUS_INVALID_PARAMETER;
1866 /* TODO - check auth_type/auth_level match. */
1868 server_response = data_blob(NULL, phdr->auth_len);
1869 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1871 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1875 if (!NT_STATUS_IS_OK(nt_status)) {
1876 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1877 data_blob_free(&server_response);
1881 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1883 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1884 auth_type, auth_level,
1885 &client_reply, &rpc_out);
1887 if (!NT_STATUS_IS_OK(nt_status)) {
1888 prs_mem_free(&rpc_out);
1889 data_blob_free(&client_reply);
1890 data_blob_free(&server_response);
1894 switch (cli->transport_type) {
1896 /* 8 here is named pipe message mode. */
1897 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
1898 0x8, prs_data_p(&rpc_out), 0,
1899 (size_t)prs_offset(&rpc_out));
1902 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1903 nt_status = cli_get_nt_error(cli->trans.np.cli);
1906 case NCACN_UNIX_STREAM:
1907 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
1908 (size_t)prs_offset(&rpc_out));
1909 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1910 nt_status = map_nt_error_from_unix(errno);
1914 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
1915 return NT_STATUS_INTERNAL_ERROR;
1918 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1919 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
1920 nt_errstr(nt_status)));
1921 prs_mem_free(&rpc_out);
1922 data_blob_free(&client_reply);
1923 data_blob_free(&server_response);
1927 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
1928 rpccli_pipe_txt(debug_ctx(), cli)));
1930 prs_mem_free(&rpc_out);
1931 data_blob_free(&client_reply);
1932 data_blob_free(&server_response);
1933 return NT_STATUS_OK;
1936 /*******************************************************************
1937 Creates a DCE/RPC bind alter context authentication request which
1938 may contain a spnego auth blobl
1939 ********************************************************************/
1941 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1942 const RPC_IFACE *abstract,
1943 const RPC_IFACE *transfer,
1944 enum pipe_auth_level auth_level,
1945 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1946 prs_struct *rpc_out)
1948 RPC_HDR_AUTH hdr_auth;
1949 prs_struct auth_info;
1950 NTSTATUS ret = NT_STATUS_OK;
1952 ZERO_STRUCT(hdr_auth);
1953 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1954 return NT_STATUS_NO_MEMORY;
1956 /* We may change the pad length before marshalling. */
1957 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1959 if (pauth_blob->length) {
1960 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1961 prs_mem_free(&auth_info);
1962 return NT_STATUS_NO_MEMORY;
1966 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1973 prs_mem_free(&auth_info);
1977 /*******************************************************************
1978 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1979 and gets a response.
1980 ********************************************************************/
1982 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1986 const RPC_IFACE *abstract,
1987 const RPC_IFACE *transfer,
1988 enum pipe_auth_type auth_type,
1989 enum pipe_auth_level auth_level)
1991 DATA_BLOB server_spnego_response = data_blob_null;
1992 DATA_BLOB server_ntlm_response = data_blob_null;
1993 DATA_BLOB client_reply = data_blob_null;
1994 DATA_BLOB tmp_blob = data_blob_null;
1995 RPC_HDR_AUTH hdr_auth;
1999 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2000 return NT_STATUS_INVALID_PARAMETER;
2003 /* Process the returned NTLMSSP blob first. */
2004 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2005 return NT_STATUS_INVALID_PARAMETER;
2008 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2009 return NT_STATUS_INVALID_PARAMETER;
2012 server_spnego_response = data_blob(NULL, phdr->auth_len);
2013 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2015 /* The server might give us back two challenges - tmp_blob is for the second. */
2016 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2017 data_blob_free(&server_spnego_response);
2018 data_blob_free(&server_ntlm_response);
2019 data_blob_free(&tmp_blob);
2020 return NT_STATUS_INVALID_PARAMETER;
2023 /* We're finished with the server spnego response and the tmp_blob. */
2024 data_blob_free(&server_spnego_response);
2025 data_blob_free(&tmp_blob);
2027 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2028 server_ntlm_response,
2031 /* Finished with the server_ntlm response */
2032 data_blob_free(&server_ntlm_response);
2034 if (!NT_STATUS_IS_OK(nt_status)) {
2035 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2036 data_blob_free(&client_reply);
2040 /* SPNEGO wrap the client reply. */
2041 tmp_blob = spnego_gen_auth(client_reply);
2042 data_blob_free(&client_reply);
2043 client_reply = tmp_blob;
2044 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2046 /* Now prepare the alter context pdu. */
2047 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2049 nt_status = create_rpc_alter_context(rpc_call_id,
2056 data_blob_free(&client_reply);
2058 if (!NT_STATUS_IS_OK(nt_status)) {
2059 prs_mem_free(&rpc_out);
2063 /* Initialize the returning data struct. */
2065 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2067 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2068 if (!NT_STATUS_IS_OK(nt_status)) {
2069 prs_mem_free(&rpc_out);
2073 prs_mem_free(&rpc_out);
2075 /* Get the auth blob from the reply. */
2076 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2077 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2078 return NT_STATUS_BUFFER_TOO_SMALL;
2081 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2082 return NT_STATUS_INVALID_PARAMETER;
2085 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2086 return NT_STATUS_INVALID_PARAMETER;
2089 server_spnego_response = data_blob(NULL, phdr->auth_len);
2090 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2092 /* Check we got a valid auth response. */
2093 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2094 data_blob_free(&server_spnego_response);
2095 data_blob_free(&tmp_blob);
2096 return NT_STATUS_INVALID_PARAMETER;
2099 data_blob_free(&server_spnego_response);
2100 data_blob_free(&tmp_blob);
2102 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2103 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2105 return NT_STATUS_OK;
2108 /****************************************************************************
2110 ****************************************************************************/
2112 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2113 struct cli_pipe_auth_data *auth)
2122 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2123 rpccli_pipe_txt(debug_ctx(), cli),
2124 (unsigned int)auth->auth_type,
2125 (unsigned int)auth->auth_level ));
2127 cli->auth = talloc_move(cli, &auth);
2129 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2131 rpc_call_id = get_rpc_call_id();
2133 /* Marshall the outgoing data. */
2134 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2135 cli->abstract_syntax,
2136 cli->transfer_syntax,
2137 cli->auth->auth_type,
2138 cli->auth->auth_level);
2140 if (!NT_STATUS_IS_OK(status)) {
2141 prs_mem_free(&rpc_out);
2145 /* Initialize the incoming data struct. */
2146 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2148 /* send data on \PIPE\. receive a response */
2149 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2150 if (!NT_STATUS_IS_OK(status)) {
2151 prs_mem_free(&rpc_out);
2155 prs_mem_free(&rpc_out);
2157 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2158 rpccli_pipe_txt(debug_ctx(), cli)));
2160 /* Unmarshall the RPC header */
2161 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2162 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2163 prs_mem_free(&rbuf);
2164 return NT_STATUS_BUFFER_TOO_SMALL;
2167 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2168 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2169 prs_mem_free(&rbuf);
2170 return NT_STATUS_BUFFER_TOO_SMALL;
2173 if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2174 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2175 prs_mem_free(&rbuf);
2176 return NT_STATUS_BUFFER_TOO_SMALL;
2179 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2180 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2182 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2183 switch(cli->auth->auth_type) {
2185 case PIPE_AUTH_TYPE_NONE:
2186 case PIPE_AUTH_TYPE_SCHANNEL:
2187 /* Bind complete. */
2190 case PIPE_AUTH_TYPE_NTLMSSP:
2191 /* Need to send AUTH3 packet - no reply. */
2192 status = rpc_finish_auth3_bind(
2193 cli, &hdr, &rbuf, rpc_call_id,
2194 cli->auth->auth_type,
2195 cli->auth->auth_level);
2196 if (!NT_STATUS_IS_OK(status)) {
2197 prs_mem_free(&rbuf);
2202 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2203 /* Need to send alter context request and reply. */
2204 status = rpc_finish_spnego_ntlmssp_bind(
2205 cli, &hdr, &rbuf, rpc_call_id,
2206 cli->abstract_syntax, cli->transfer_syntax,
2207 cli->auth->auth_type, cli->auth->auth_level);
2208 if (!NT_STATUS_IS_OK(status)) {
2209 prs_mem_free(&rbuf);
2214 case PIPE_AUTH_TYPE_KRB5:
2218 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2219 "%u\n", (unsigned int)cli->auth->auth_type));
2220 prs_mem_free(&rbuf);
2221 return NT_STATUS_INVALID_INFO_CLASS;
2224 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2225 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2226 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2227 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2228 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2229 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2230 prs_mem_free(&rbuf);
2231 return NT_STATUS_INVALID_PARAMETER;
2234 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2235 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2236 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2237 prs_mem_free(&rbuf);
2238 return NT_STATUS_INVALID_PARAMETER;
2243 prs_mem_free(&rbuf);
2244 return NT_STATUS_OK;
2247 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2248 unsigned int timeout)
2250 return cli_set_timeout(cli->trans.np.cli, timeout);
2253 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2255 return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
2258 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2260 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2261 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2262 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2266 if (cli->transport_type == NCACN_NP) {
2267 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2274 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2276 if (p->transport_type == NCACN_NP) {
2277 return p->trans.np.cli;
2282 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2284 if (p->transport_type == NCACN_NP) {
2286 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2288 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2289 "pipe %s. Error was %s\n",
2290 rpccli_pipe_txt(debug_ctx(), p),
2291 cli_errstr(p->trans.np.cli)));
2294 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2295 rpccli_pipe_txt(debug_ctx(), p)));
2297 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2298 return ret ? -1 : 0;
2304 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2305 struct cli_pipe_auth_data **presult)
2307 struct cli_pipe_auth_data *result;
2309 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2310 if (result == NULL) {
2311 return NT_STATUS_NO_MEMORY;
2314 result->auth_type = PIPE_AUTH_TYPE_NONE;
2315 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2317 result->user_name = talloc_strdup(result, "");
2318 result->domain = talloc_strdup(result, "");
2319 if ((result->user_name == NULL) || (result->domain == NULL)) {
2320 TALLOC_FREE(result);
2321 return NT_STATUS_NO_MEMORY;
2325 return NT_STATUS_OK;
2328 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2330 ntlmssp_end(&auth->a_u.ntlmssp_state);
2334 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2335 enum pipe_auth_type auth_type,
2336 enum pipe_auth_level auth_level,
2338 const char *username,
2339 const char *password,
2340 struct cli_pipe_auth_data **presult)
2342 struct cli_pipe_auth_data *result;
2345 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2346 if (result == NULL) {
2347 return NT_STATUS_NO_MEMORY;
2350 result->auth_type = auth_type;
2351 result->auth_level = auth_level;
2353 result->user_name = talloc_strdup(result, username);
2354 result->domain = talloc_strdup(result, domain);
2355 if ((result->user_name == NULL) || (result->domain == NULL)) {
2356 status = NT_STATUS_NO_MEMORY;
2360 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2361 if (!NT_STATUS_IS_OK(status)) {
2365 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2367 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2368 if (!NT_STATUS_IS_OK(status)) {
2372 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2373 if (!NT_STATUS_IS_OK(status)) {
2377 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2378 if (!NT_STATUS_IS_OK(status)) {
2383 * Turn off sign+seal to allow selected auth level to turn it back on.
2385 result->a_u.ntlmssp_state->neg_flags &=
2386 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2388 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2389 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2390 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2391 result->a_u.ntlmssp_state->neg_flags
2392 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2396 return NT_STATUS_OK;
2399 TALLOC_FREE(result);
2403 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2404 enum pipe_auth_level auth_level,
2405 const uint8_t sess_key[16],
2406 struct cli_pipe_auth_data **presult)
2408 struct cli_pipe_auth_data *result;
2410 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2411 if (result == NULL) {
2412 return NT_STATUS_NO_MEMORY;
2415 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2416 result->auth_level = auth_level;
2418 result->user_name = talloc_strdup(result, "");
2419 result->domain = talloc_strdup(result, domain);
2420 if ((result->user_name == NULL) || (result->domain == NULL)) {
2424 result->a_u.schannel_auth = talloc(result,
2425 struct schannel_auth_struct);
2426 if (result->a_u.schannel_auth == NULL) {
2430 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2431 sizeof(result->a_u.schannel_auth->sess_key));
2432 result->a_u.schannel_auth->seq_num = 0;
2435 return NT_STATUS_OK;
2438 TALLOC_FREE(result);
2439 return NT_STATUS_NO_MEMORY;
2442 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2444 data_blob_free(&auth->session_key);
2448 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2449 enum pipe_auth_level auth_level,
2450 const char *service_princ,
2451 const char *username,
2452 const char *password,
2453 struct cli_pipe_auth_data **presult)
2456 struct cli_pipe_auth_data *result;
2458 if ((username != NULL) && (password != NULL)) {
2459 int ret = kerberos_kinit_password(username, password, 0, NULL);
2461 return NT_STATUS_ACCESS_DENIED;
2465 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2466 if (result == NULL) {
2467 return NT_STATUS_NO_MEMORY;
2470 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2471 result->auth_level = auth_level;
2474 * Username / domain need fixing!
2476 result->user_name = talloc_strdup(result, "");
2477 result->domain = talloc_strdup(result, "");
2478 if ((result->user_name == NULL) || (result->domain == NULL)) {
2482 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2483 result, struct kerberos_auth_struct);
2484 if (result->a_u.kerberos_auth == NULL) {
2487 talloc_set_destructor(result->a_u.kerberos_auth,
2488 cli_auth_kerberos_data_destructor);
2490 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2491 result, service_princ);
2492 if (result->a_u.kerberos_auth->service_principal == NULL) {
2497 return NT_STATUS_OK;
2500 TALLOC_FREE(result);
2501 return NT_STATUS_NO_MEMORY;
2503 return NT_STATUS_NOT_SUPPORTED;
2507 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2509 close(p->trans.sock.fd);
2514 * Create an rpc pipe client struct, connecting to a tcp port.
2516 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2518 const struct ndr_syntax_id *abstract_syntax,
2519 struct rpc_pipe_client **presult)
2521 struct rpc_pipe_client *result;
2522 struct sockaddr_storage addr;
2525 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2526 if (result == NULL) {
2527 return NT_STATUS_NO_MEMORY;
2530 result->transport_type = NCACN_IP_TCP;
2532 result->abstract_syntax = abstract_syntax;
2533 result->transfer_syntax = &ndr_transfer_syntax;
2535 result->desthost = talloc_strdup(result, host);
2536 result->srv_name_slash = talloc_asprintf_strupper_m(
2537 result, "\\\\%s", result->desthost);
2538 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2539 status = NT_STATUS_NO_MEMORY;
2543 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2544 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2546 if (!resolve_name(host, &addr, 0)) {
2547 status = NT_STATUS_NOT_FOUND;
2551 result->trans.sock.fd = open_socket_out(SOCK_STREAM, &addr, port, 60);
2552 if (result->trans.sock.fd == -1) {
2553 status = map_nt_error_from_unix(errno);
2557 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2560 return NT_STATUS_OK;
2563 TALLOC_FREE(result);
2568 * Determine the tcp port on which a dcerpc interface is listening
2569 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2572 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2573 const struct ndr_syntax_id *abstract_syntax,
2577 struct rpc_pipe_client *epm_pipe = NULL;
2578 struct cli_pipe_auth_data *auth = NULL;
2579 struct dcerpc_binding *map_binding = NULL;
2580 struct dcerpc_binding *res_binding = NULL;
2581 struct epm_twr_t *map_tower = NULL;
2582 struct epm_twr_t *res_towers = NULL;
2583 struct policy_handle *entry_handle = NULL;
2584 uint32_t num_towers = 0;
2585 uint32_t max_towers = 1;
2586 struct epm_twr_p_t towers;
2587 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2589 if (pport == NULL) {
2590 status = NT_STATUS_INVALID_PARAMETER;
2594 /* open the connection to the endpoint mapper */
2595 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2596 &ndr_table_epmapper.syntax_id,
2599 if (!NT_STATUS_IS_OK(status)) {
2603 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2604 if (!NT_STATUS_IS_OK(status)) {
2608 status = rpc_pipe_bind(epm_pipe, auth);
2609 if (!NT_STATUS_IS_OK(status)) {
2613 /* create tower for asking the epmapper */
2615 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2616 if (map_binding == NULL) {
2617 status = NT_STATUS_NO_MEMORY;
2621 map_binding->transport = NCACN_IP_TCP;
2622 map_binding->object = *abstract_syntax;
2623 map_binding->host = host; /* needed? */
2624 map_binding->endpoint = "0"; /* correct? needed? */
2626 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2627 if (map_tower == NULL) {
2628 status = NT_STATUS_NO_MEMORY;
2632 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2633 &(map_tower->tower));
2634 if (!NT_STATUS_IS_OK(status)) {
2638 /* allocate further parameters for the epm_Map call */
2640 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2641 if (res_towers == NULL) {
2642 status = NT_STATUS_NO_MEMORY;
2645 towers.twr = res_towers;
2647 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2648 if (entry_handle == NULL) {
2649 status = NT_STATUS_NO_MEMORY;
2653 /* ask the endpoint mapper for the port */
2655 status = rpccli_epm_Map(epm_pipe,
2657 CONST_DISCARD(struct GUID *,
2658 &(abstract_syntax->uuid)),
2665 if (!NT_STATUS_IS_OK(status)) {
2669 if (num_towers != 1) {
2670 status = NT_STATUS_UNSUCCESSFUL;
2674 /* extract the port from the answer */
2676 status = dcerpc_binding_from_tower(tmp_ctx,
2677 &(towers.twr->tower),
2679 if (!NT_STATUS_IS_OK(status)) {
2683 /* are further checks here necessary? */
2684 if (res_binding->transport != NCACN_IP_TCP) {
2685 status = NT_STATUS_UNSUCCESSFUL;
2689 *pport = (uint16_t)atoi(res_binding->endpoint);
2692 TALLOC_FREE(tmp_ctx);
2697 * Create a rpc pipe client struct, connecting to a host via tcp.
2698 * The port is determined by asking the endpoint mapper on the given
2701 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2702 const struct ndr_syntax_id *abstract_syntax,
2703 struct rpc_pipe_client **presult)
2710 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2711 if (!NT_STATUS_IS_OK(status)) {
2715 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2716 abstract_syntax, presult);
2722 /********************************************************************
2723 Create a rpc pipe client struct, connecting to a unix domain socket
2724 ********************************************************************/
2725 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2726 const struct ndr_syntax_id *abstract_syntax,
2727 struct rpc_pipe_client **presult)
2729 struct rpc_pipe_client *result;
2730 struct sockaddr_un addr;
2733 result = talloc(mem_ctx, struct rpc_pipe_client);
2734 if (result == NULL) {
2735 return NT_STATUS_NO_MEMORY;
2738 result->transport_type = NCACN_UNIX_STREAM;
2740 result->abstract_syntax = abstract_syntax;
2741 result->transfer_syntax = &ndr_transfer_syntax;
2743 result->desthost = get_myname(result);
2744 result->srv_name_slash = talloc_asprintf_strupper_m(
2745 result, "\\\\%s", result->desthost);
2746 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2747 status = NT_STATUS_NO_MEMORY;
2751 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2752 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2754 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2755 if (result->trans.sock.fd == -1) {
2756 status = map_nt_error_from_unix(errno);
2760 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2762 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2763 if (result->dc == NULL) {
2764 status = NT_STATUS_NO_MEMORY;
2769 addr.sun_family = AF_UNIX;
2770 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2772 if (sys_connect(result->trans.sock.fd,
2773 (struct sockaddr *)&addr) == -1) {
2774 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2776 close(result->trans.sock.fd);
2777 return map_nt_error_from_unix(errno);
2781 return NT_STATUS_OK;
2784 TALLOC_FREE(result);
2789 /****************************************************************************
2790 Open a named pipe over SMB to a remote server.
2792 * CAVEAT CALLER OF THIS FUNCTION:
2793 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2794 * so be sure that this function is called AFTER any structure (vs pointer)
2795 * assignment of the cli. In particular, libsmbclient does structure
2796 * assignments of cli, which invalidates the data in the returned
2797 * rpc_pipe_client if this function is called before the structure assignment
2800 ****************************************************************************/
2802 static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2804 struct rpc_pipe_client *result;
2807 *perr = NT_STATUS_NO_MEMORY;
2809 /* sanity check to protect against crashes */
2812 *perr = NT_STATUS_INVALID_HANDLE;
2816 /* The pipe name index must fall within our array */
2817 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2819 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2820 if (result == NULL) {
2821 *perr = NT_STATUS_NO_MEMORY;
2825 result->transport_type = NCACN_NP;
2827 result->trans.np.pipe_name = cli_get_pipe_name(pipe_idx);
2829 result->trans.np.cli = cli;
2830 result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2831 result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2832 result->desthost = talloc_strdup(result, cli->desthost);
2833 result->srv_name_slash = talloc_asprintf_strupper_m(
2834 result, "\\\\%s", result->desthost);
2836 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2837 *perr = NT_STATUS_NO_MEMORY;
2838 TALLOC_FREE(result);
2842 if (pipe_idx == PI_NETLOGON) {
2843 /* Set up a netlogon credential chain for a netlogon pipe. */
2844 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2845 if (result->dc == NULL) {
2846 *perr = NT_STATUS_NO_MEMORY;
2847 TALLOC_FREE(result);
2852 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2853 DESIRED_ACCESS_PIPE);
2855 DEBUG(1,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
2856 "to machine %s. Error was %s\n",
2857 result->trans.np.pipe_name, cli->desthost,
2859 *perr = cli_get_nt_error(cli);
2860 talloc_destroy(result);
2864 result->trans.np.fnum = fnum;
2866 DLIST_ADD(cli->pipe_list, result);
2867 talloc_set_destructor(result, rpc_pipe_destructor);
2869 *perr = NT_STATUS_OK;
2874 /****************************************************************************
2875 Open a pipe to a remote server.
2876 ****************************************************************************/
2878 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli,
2882 struct rpc_pipe_client *result = NULL;
2884 *perr = NT_STATUS_PIPE_NOT_AVAILABLE;
2888 *perr = rpc_pipe_open_tcp(NULL, cli->desthost,
2889 &ndr_table_drsuapi.syntax_id,
2891 if (!NT_STATUS_IS_OK(*perr)) {
2896 result = rpc_pipe_open_np(cli, pipe_idx, perr);
2897 if (result == NULL) {
2903 *perr = NT_STATUS_OK;
2908 /****************************************************************************
2909 Open a named pipe to an SMB server and bind anonymously.
2910 ****************************************************************************/
2912 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2914 struct rpc_pipe_client *result;
2915 struct cli_pipe_auth_data *auth;
2917 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2918 if (result == NULL) {
2922 *perr = rpccli_anon_bind_data(result, &auth);
2923 if (!NT_STATUS_IS_OK(*perr)) {
2924 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2926 TALLOC_FREE(result);
2931 * This is a bit of an abstraction violation due to the fact that an
2932 * anonymous bind on an authenticated SMB inherits the user/domain
2933 * from the enclosing SMB creds
2936 TALLOC_FREE(auth->user_name);
2937 TALLOC_FREE(auth->domain);
2939 auth->user_name = talloc_strdup(auth, cli->user_name);
2940 auth->domain = talloc_strdup(auth, cli->domain);
2942 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2943 *perr = NT_STATUS_NO_MEMORY;
2944 TALLOC_FREE(result);
2948 *perr = rpc_pipe_bind(result, auth);
2949 if (!NT_STATUS_IS_OK(*perr)) {
2951 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2952 /* non AD domains just don't have this pipe, avoid
2953 * level 0 statement in that case - gd */
2956 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2957 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2958 TALLOC_FREE(result);
2962 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2963 "%s and bound anonymously.\n", result->trans.np.pipe_name,
2969 /****************************************************************************
2970 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2971 ****************************************************************************/
2973 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2975 enum pipe_auth_type auth_type,
2976 enum pipe_auth_level auth_level,
2978 const char *username,
2979 const char *password,
2982 struct rpc_pipe_client *result;
2983 struct cli_pipe_auth_data *auth;
2985 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2986 if (result == NULL) {
2990 *perr = rpccli_ntlmssp_bind_data(
2991 result, auth_type, auth_level, domain, username,
2992 cli->pwd.null_pwd ? NULL : password, &auth);
2993 if (!NT_STATUS_IS_OK(*perr)) {
2994 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2996 TALLOC_FREE(result);
3000 *perr = rpc_pipe_bind(result, auth);
3001 if (!NT_STATUS_IS_OK(*perr)) {
3002 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3003 nt_errstr(*perr) ));
3007 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3008 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3009 result->trans.np.pipe_name, cli->desthost,
3010 domain, username ));
3016 TALLOC_FREE(result);
3020 /****************************************************************************
3022 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3023 ****************************************************************************/
3025 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3027 enum pipe_auth_level auth_level,
3029 const char *username,
3030 const char *password,
3033 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3035 PIPE_AUTH_TYPE_NTLMSSP,
3043 /****************************************************************************
3045 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3046 ****************************************************************************/
3048 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3050 enum pipe_auth_level auth_level,
3052 const char *username,
3053 const char *password,
3056 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3058 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3066 /****************************************************************************
3067 Get a the schannel session key out of an already opened netlogon pipe.
3068 ****************************************************************************/
3069 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3070 struct cli_state *cli,
3075 uint32 sec_chan_type = 0;
3076 unsigned char machine_pwd[16];
3077 const char *machine_account;
3079 /* Get the machine account credentials from secrets.tdb. */
3080 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3083 DEBUG(0, ("get_schannel_session_key: could not fetch "
3084 "trust account password for domain '%s'\n",
3086 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3090 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
3091 cli->desthost, /* server name */
3092 domain, /* domain */
3093 global_myname(), /* client name */
3094 machine_account, /* machine account name */
3099 if (!NT_STATUS_IS_OK(*perr)) {
3100 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
3101 "failed with result %s to server %s, domain %s, machine account %s.\n",
3102 nt_errstr(*perr), cli->desthost, domain, machine_account ));
3106 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3107 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3109 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
3116 /****************************************************************************
3117 Open a netlogon pipe and get the schannel session key.
3118 Now exposed to external callers.
3119 ****************************************************************************/
3122 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
3127 struct rpc_pipe_client *netlogon_pipe = NULL;
3129 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
3130 if (!netlogon_pipe) {
3134 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
3137 TALLOC_FREE(netlogon_pipe);
3141 return netlogon_pipe;
3144 /****************************************************************************
3146 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3147 using session_key. sign and seal.
3148 ****************************************************************************/
3150 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3152 enum pipe_auth_level auth_level,
3154 const struct dcinfo *pdc,
3157 struct rpc_pipe_client *result;
3158 struct cli_pipe_auth_data *auth;
3160 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3161 if (result == NULL) {
3165 *perr = rpccli_schannel_bind_data(result, domain, auth_level,
3166 pdc->sess_key, &auth);
3167 if (!NT_STATUS_IS_OK(*perr)) {
3168 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3170 TALLOC_FREE(result);
3174 *perr = rpc_pipe_bind(result, auth);
3175 if (!NT_STATUS_IS_OK(*perr)) {
3176 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
3177 nt_errstr(*perr) ));
3178 TALLOC_FREE(result);
3182 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
3187 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3189 "and bound using schannel.\n",
3190 result->trans.np.pipe_name, cli->desthost, domain ));
3195 /****************************************************************************
3196 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3197 Fetch the session key ourselves using a temporary netlogon pipe. This
3198 version uses an ntlmssp auth bound netlogon pipe to get the key.
3199 ****************************************************************************/
3201 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3203 const char *username,
3204 const char *password,
3208 struct rpc_pipe_client *netlogon_pipe = NULL;
3210 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
3211 if (!netlogon_pipe) {
3215 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
3218 TALLOC_FREE(netlogon_pipe);
3222 return netlogon_pipe;
3225 /****************************************************************************
3226 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3227 Fetch the session key ourselves using a temporary netlogon pipe. This version
3228 uses an ntlmssp bind to get the session key.
3229 ****************************************************************************/
3231 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3233 enum pipe_auth_level auth_level,
3235 const char *username,
3236 const char *password,
3239 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3240 struct rpc_pipe_client *netlogon_pipe = NULL;
3241 struct rpc_pipe_client *result = NULL;
3243 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
3244 password, &neg_flags, perr);
3245 if (!netlogon_pipe) {
3246 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3247 "key from server %s for domain %s.\n",
3248 cli->desthost, domain ));
3252 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
3254 domain, netlogon_pipe->dc, perr);
3256 /* Now we've bound using the session key we can close the netlog pipe. */
3257 TALLOC_FREE(netlogon_pipe);
3262 /****************************************************************************
3263 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3264 Fetch the session key ourselves using a temporary netlogon pipe.
3265 ****************************************************************************/
3267 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
3269 enum pipe_auth_level auth_level,
3273 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3274 struct rpc_pipe_client *netlogon_pipe = NULL;
3275 struct rpc_pipe_client *result = NULL;
3277 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
3278 if (!netlogon_pipe) {
3279 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3280 "key from server %s for domain %s.\n",
3281 cli->desthost, domain ));
3285 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
3287 domain, netlogon_pipe->dc, perr);
3289 /* Now we've bound using the session key we can close the netlog pipe. */
3290 TALLOC_FREE(netlogon_pipe);
3295 /****************************************************************************
3296 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3297 The idea is this can be called with service_princ, username and password all
3298 NULL so long as the caller has a TGT.
3299 ****************************************************************************/
3301 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
3303 enum pipe_auth_level auth_level,
3304 const char *service_princ,
3305 const char *username,
3306 const char *password,
3310 struct rpc_pipe_client *result;
3311 struct cli_pipe_auth_data *auth;
3313 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3314 if (result == NULL) {
3318 *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3319 username, password, &auth);
3320 if (!NT_STATUS_IS_OK(*perr)) {
3321 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3323 TALLOC_FREE(result);
3327 *perr = rpc_pipe_bind(result, auth);
3328 if (!NT_STATUS_IS_OK(*perr)) {
3329 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
3330 nt_errstr(*perr) ));
3331 TALLOC_FREE(result);
3337 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));