Add basic ncacn_ip_tcp client infrastructure
[Samba.git] / source3 / rpc_client / cli_pipe.c
bloba3ad774ee3326bfbf2126ee068262a35e8bf839d
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
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/>.
20 #include "includes.h"
22 #undef DBGC_CLASS
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)
33 switch (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;
51 default:
52 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
53 "auth type %u\n",
54 (unsigned int)auth_type ));
55 break;
57 return -1;
60 /********************************************************************
61 Pipe description for a DEBUG
62 ********************************************************************/
63 static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli)
65 char *result;
66 result = talloc_asprintf(mem_ctx, "host %s, pipe %s, fnum 0x%x",
67 cli->desthost,
68 cli->trans.np.pipe_name,
69 (unsigned int)(cli->trans.np.fnum));
70 SMB_ASSERT(result != NULL);
71 return result;
74 /********************************************************************
75 Rpc pipe call id.
76 ********************************************************************/
78 static uint32 get_rpc_call_id(void)
80 static uint32 call_id = 0;
81 return ++call_id;
84 /*******************************************************************
85 Read from a RPC named pipe
86 ********************************************************************/
87 static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name,
88 int fnum, char *buf, off_t offset, size_t size,
89 ssize_t *pnum_read)
91 ssize_t num_read;
93 num_read = cli_read(cli, fnum, buf, offset, size);
95 DEBUG(5,("rpc_read_np: num_read = %d, read offset: %u, to read: %u\n",
96 (int)num_read, (unsigned int)offset, (unsigned int)size));
99 * A dos error of ERRDOS/ERRmoredata is not an error.
101 if (cli_is_dos_error(cli)) {
102 uint32 ecode;
103 uint8 eclass;
104 cli_dos_error(cli, &eclass, &ecode);
105 if (eclass != ERRDOS && ecode != ERRmoredata) {
106 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read "
107 "on fnum 0x%x\n", eclass, (unsigned int)ecode,
108 cli_errstr(cli), fnum));
109 return dos_to_ntstatus(eclass, ecode);
114 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
116 if (cli_is_nt_error(cli)) {
117 if (!NT_STATUS_EQUAL(cli_nt_error(cli),
118 NT_STATUS_BUFFER_TOO_SMALL)) {
119 DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum "
120 "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum));
121 return cli_nt_error(cli);
125 if (num_read == -1) {
126 DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned "
127 "-1\n", fnum));
128 return cli_get_nt_error(cli);
131 *pnum_read = num_read;
132 return NT_STATUS_OK;
136 /*******************************************************************
137 Use SMBreadX to get rest of one fragment's worth of rpc data.
138 Will expand the current_pdu struct to the correct size.
139 ********************************************************************/
141 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
142 prs_struct *current_pdu,
143 uint32 data_to_read,
144 uint32 *current_pdu_offset)
146 size_t size = (size_t)cli->max_recv_frag;
147 uint32 stream_offset = 0;
148 ssize_t num_read;
149 char *pdata;
150 ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
152 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
153 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
156 * Grow the buffer if needed to accommodate the data to be read.
159 if (extra_data_size > 0) {
160 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
161 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
162 return NT_STATUS_NO_MEMORY;
164 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
167 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
169 do {
170 NTSTATUS status;
172 /* read data using SMBreadX */
173 if (size > (size_t)data_to_read) {
174 size = (size_t)data_to_read;
177 switch (cli->transport_type) {
178 case NCACN_NP:
179 status = rpc_read_np(cli->trans.np.cli,
180 cli->trans.np.pipe_name,
181 cli->trans.np.fnum, pdata,
182 (off_t)stream_offset, size,
183 &num_read);
184 break;
185 case NCACN_IP_TCP:
186 status = NT_STATUS_OK;
187 num_read = sys_read(cli->trans.tcp.sock, pdata, size);
188 if (num_read == -1) {
189 status = map_nt_error_from_unix(errno);
191 if (num_read == 0) {
192 status = NT_STATUS_END_OF_FILE;
194 break;
195 default:
196 DEBUG(0, ("unknown transport type %d\n",
197 cli->transport_type));
198 return NT_STATUS_INTERNAL_ERROR;
201 data_to_read -= num_read;
202 stream_offset += num_read;
203 pdata += num_read;
205 } while (num_read > 0 && data_to_read > 0);
206 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
209 * Update the current offset into current_pdu by the amount read.
211 *current_pdu_offset += stream_offset;
212 return NT_STATUS_OK;
215 /****************************************************************************
216 Try and get a PDU's worth of data from current_pdu. If not, then read more
217 from the wire.
218 ****************************************************************************/
220 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
222 NTSTATUS ret = NT_STATUS_OK;
223 uint32 current_pdu_len = prs_data_size(current_pdu);
225 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
226 if (current_pdu_len < RPC_HEADER_LEN) {
227 /* rpc_read expands the current_pdu struct as neccessary. */
228 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
229 if (!NT_STATUS_IS_OK(ret)) {
230 return ret;
234 /* This next call sets the endian bit correctly in current_pdu. */
235 /* We will propagate this to rbuf later. */
236 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
237 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
238 return NT_STATUS_BUFFER_TOO_SMALL;
241 /* Ensure we have frag_len bytes of data. */
242 if (current_pdu_len < prhdr->frag_len) {
243 /* rpc_read expands the current_pdu struct as neccessary. */
244 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
245 if (!NT_STATUS_IS_OK(ret)) {
246 return ret;
250 if (current_pdu_len < prhdr->frag_len) {
251 return NT_STATUS_BUFFER_TOO_SMALL;
254 return NT_STATUS_OK;
257 /****************************************************************************
258 NTLMSSP specific sign/seal.
259 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
260 In fact I should probably abstract these into identical pieces of code... JRA.
261 ****************************************************************************/
263 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
264 prs_struct *current_pdu,
265 uint8 *p_ss_padding_len)
267 RPC_HDR_AUTH auth_info;
268 uint32 save_offset = prs_offset(current_pdu);
269 uint32 auth_len = prhdr->auth_len;
270 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
271 unsigned char *data = NULL;
272 size_t data_len;
273 unsigned char *full_packet_data = NULL;
274 size_t full_packet_data_len;
275 DATA_BLOB auth_blob;
276 NTSTATUS status;
278 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
279 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
280 return NT_STATUS_OK;
283 if (!ntlmssp_state) {
284 return NT_STATUS_INVALID_PARAMETER;
287 /* Ensure there's enough data for an authenticated response. */
288 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
289 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
290 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
291 (unsigned int)auth_len ));
292 return NT_STATUS_BUFFER_TOO_SMALL;
296 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
297 * after the RPC header.
298 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
299 * functions as NTLMv2 checks the rpc headers also.
302 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
303 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
305 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
306 full_packet_data_len = prhdr->frag_len - auth_len;
308 /* Pull the auth header and the following data into a blob. */
309 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
310 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
311 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
312 return NT_STATUS_BUFFER_TOO_SMALL;
315 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
316 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
317 return NT_STATUS_BUFFER_TOO_SMALL;
320 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
321 auth_blob.length = auth_len;
323 switch (cli->auth->auth_level) {
324 case PIPE_AUTH_LEVEL_PRIVACY:
325 /* Data is encrypted. */
326 status = ntlmssp_unseal_packet(ntlmssp_state,
327 data, data_len,
328 full_packet_data,
329 full_packet_data_len,
330 &auth_blob);
331 if (!NT_STATUS_IS_OK(status)) {
332 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
333 "packet from %s. Error was %s.\n",
334 rpccli_pipe_txt(debug_ctx(), cli),
335 nt_errstr(status) ));
336 return status;
338 break;
339 case PIPE_AUTH_LEVEL_INTEGRITY:
340 /* Data is signed. */
341 status = ntlmssp_check_packet(ntlmssp_state,
342 data, data_len,
343 full_packet_data,
344 full_packet_data_len,
345 &auth_blob);
346 if (!NT_STATUS_IS_OK(status)) {
347 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
348 "packet from %s. Error was %s.\n",
349 rpccli_pipe_txt(debug_ctx(), cli),
350 nt_errstr(status) ));
351 return status;
353 break;
354 default:
355 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
356 "auth level %d\n", cli->auth->auth_level));
357 return NT_STATUS_INVALID_INFO_CLASS;
361 * Return the current pointer to the data offset.
364 if(!prs_set_offset(current_pdu, save_offset)) {
365 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
366 (unsigned int)save_offset ));
367 return NT_STATUS_BUFFER_TOO_SMALL;
371 * Remember the padding length. We must remove it from the real data
372 * stream once the sign/seal is done.
375 *p_ss_padding_len = auth_info.auth_pad_len;
377 return NT_STATUS_OK;
380 /****************************************************************************
381 schannel specific sign/seal.
382 ****************************************************************************/
384 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
385 prs_struct *current_pdu,
386 uint8 *p_ss_padding_len)
388 RPC_HDR_AUTH auth_info;
389 RPC_AUTH_SCHANNEL_CHK schannel_chk;
390 uint32 auth_len = prhdr->auth_len;
391 uint32 save_offset = prs_offset(current_pdu);
392 struct schannel_auth_struct *schannel_auth =
393 cli->auth->a_u.schannel_auth;
394 uint32 data_len;
396 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
397 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
398 return NT_STATUS_OK;
401 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
402 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
403 return NT_STATUS_INVALID_PARAMETER;
406 if (!schannel_auth) {
407 return NT_STATUS_INVALID_PARAMETER;
410 /* Ensure there's enough data for an authenticated response. */
411 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
412 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
413 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
414 (unsigned int)auth_len ));
415 return NT_STATUS_INVALID_PARAMETER;
418 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
420 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
421 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
422 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
423 return NT_STATUS_BUFFER_TOO_SMALL;
426 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
427 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
428 return NT_STATUS_BUFFER_TOO_SMALL;
431 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
432 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
433 auth_info.auth_type));
434 return NT_STATUS_BUFFER_TOO_SMALL;
437 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
438 &schannel_chk, current_pdu, 0)) {
439 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
440 return NT_STATUS_BUFFER_TOO_SMALL;
443 if (!schannel_decode(schannel_auth,
444 cli->auth->auth_level,
445 SENDER_IS_ACCEPTOR,
446 &schannel_chk,
447 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
448 data_len)) {
449 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
450 "Connection to %s.\n",
451 rpccli_pipe_txt(debug_ctx(), cli)));
452 return NT_STATUS_INVALID_PARAMETER;
455 /* The sequence number gets incremented on both send and receive. */
456 schannel_auth->seq_num++;
459 * Return the current pointer to the data offset.
462 if(!prs_set_offset(current_pdu, save_offset)) {
463 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
464 (unsigned int)save_offset ));
465 return NT_STATUS_BUFFER_TOO_SMALL;
469 * Remember the padding length. We must remove it from the real data
470 * stream once the sign/seal is done.
473 *p_ss_padding_len = auth_info.auth_pad_len;
475 return NT_STATUS_OK;
478 /****************************************************************************
479 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
480 ****************************************************************************/
482 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
483 prs_struct *current_pdu,
484 uint8 *p_ss_padding_len)
486 NTSTATUS ret = NT_STATUS_OK;
488 /* Paranioa checks for auth_len. */
489 if (prhdr->auth_len) {
490 if (prhdr->auth_len > prhdr->frag_len) {
491 return NT_STATUS_INVALID_PARAMETER;
494 if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len ||
495 prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) {
496 /* Integer wrap attempt. */
497 return NT_STATUS_INVALID_PARAMETER;
502 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
505 switch(cli->auth->auth_type) {
506 case PIPE_AUTH_TYPE_NONE:
507 if (prhdr->auth_len) {
508 DEBUG(3, ("cli_pipe_validate_rpc_response: "
509 "Connection to %s - got non-zero "
510 "auth len %u.\n",
511 rpccli_pipe_txt(debug_ctx(), cli),
512 (unsigned int)prhdr->auth_len ));
513 return NT_STATUS_INVALID_PARAMETER;
515 break;
517 case PIPE_AUTH_TYPE_NTLMSSP:
518 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
519 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
520 if (!NT_STATUS_IS_OK(ret)) {
521 return ret;
523 break;
525 case PIPE_AUTH_TYPE_SCHANNEL:
526 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
527 if (!NT_STATUS_IS_OK(ret)) {
528 return ret;
530 break;
532 case PIPE_AUTH_TYPE_KRB5:
533 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
534 default:
535 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
536 "to %s - unknown internal auth type %u.\n",
537 rpccli_pipe_txt(debug_ctx(), cli),
538 cli->auth->auth_type ));
539 return NT_STATUS_INVALID_INFO_CLASS;
542 return NT_STATUS_OK;
545 /****************************************************************************
546 Do basic authentication checks on an incoming pdu.
547 ****************************************************************************/
549 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
550 prs_struct *current_pdu,
551 uint8 expected_pkt_type,
552 char **ppdata,
553 uint32 *pdata_len,
554 prs_struct *return_data)
557 NTSTATUS ret = NT_STATUS_OK;
558 uint32 current_pdu_len = prs_data_size(current_pdu);
560 if (current_pdu_len != prhdr->frag_len) {
561 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
562 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
563 return NT_STATUS_INVALID_PARAMETER;
567 * Point the return values at the real data including the RPC
568 * header. Just in case the caller wants it.
570 *ppdata = prs_data_p(current_pdu);
571 *pdata_len = current_pdu_len;
573 /* Ensure we have the correct type. */
574 switch (prhdr->pkt_type) {
575 case RPC_ALTCONTRESP:
576 case RPC_BINDACK:
578 /* Alter context and bind ack share the same packet definitions. */
579 break;
582 case RPC_RESPONSE:
584 RPC_HDR_RESP rhdr_resp;
585 uint8 ss_padding_len = 0;
587 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
588 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
589 return NT_STATUS_BUFFER_TOO_SMALL;
592 /* Here's where we deal with incoming sign/seal. */
593 ret = cli_pipe_validate_rpc_response(cli, prhdr,
594 current_pdu, &ss_padding_len);
595 if (!NT_STATUS_IS_OK(ret)) {
596 return ret;
599 /* Point the return values at the NDR data. Remember to remove any ss padding. */
600 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
602 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
603 return NT_STATUS_BUFFER_TOO_SMALL;
606 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
608 /* Remember to remove the auth footer. */
609 if (prhdr->auth_len) {
610 /* We've already done integer wrap tests on auth_len in
611 cli_pipe_validate_rpc_response(). */
612 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
613 return NT_STATUS_BUFFER_TOO_SMALL;
615 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
618 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
619 current_pdu_len, *pdata_len, ss_padding_len ));
622 * If this is the first reply, and the allocation hint is reasonably, try and
623 * set up the return_data parse_struct to the correct size.
626 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
627 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
628 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
629 "too large to allocate\n",
630 (unsigned int)rhdr_resp.alloc_hint ));
631 return NT_STATUS_NO_MEMORY;
635 break;
638 case RPC_BINDNACK:
639 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
640 "received from %s!\n",
641 rpccli_pipe_txt(debug_ctx(), cli)));
642 /* Use this for now... */
643 return NT_STATUS_NETWORK_ACCESS_DENIED;
645 case RPC_FAULT:
647 RPC_HDR_RESP rhdr_resp;
648 RPC_HDR_FAULT fault_resp;
650 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
651 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
652 return NT_STATUS_BUFFER_TOO_SMALL;
655 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
656 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
657 return NT_STATUS_BUFFER_TOO_SMALL;
660 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
661 "code %s received from %s!\n",
662 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
663 rpccli_pipe_txt(debug_ctx(), cli)));
664 if (NT_STATUS_IS_OK(fault_resp.status)) {
665 return NT_STATUS_UNSUCCESSFUL;
666 } else {
667 return fault_resp.status;
671 default:
672 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
673 "from %s!\n",
674 (unsigned int)prhdr->pkt_type,
675 rpccli_pipe_txt(debug_ctx(), cli)));
676 return NT_STATUS_INVALID_INFO_CLASS;
679 if (prhdr->pkt_type != expected_pkt_type) {
680 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
681 "got an unexpected RPC packet type - %u, not %u\n",
682 rpccli_pipe_txt(debug_ctx(), cli),
683 prhdr->pkt_type,
684 expected_pkt_type));
685 return NT_STATUS_INVALID_INFO_CLASS;
688 /* Do this just before return - we don't want to modify any rpc header
689 data before now as we may have needed to do cryptographic actions on
690 it before. */
692 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
693 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
694 "setting fragment first/last ON.\n"));
695 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
698 return NT_STATUS_OK;
701 /****************************************************************************
702 Ensure we eat the just processed pdu from the current_pdu prs_struct.
703 Normally the frag_len and buffer size will match, but on the first trans
704 reply there is a theoretical chance that buffer size > frag_len, so we must
705 deal with that.
706 ****************************************************************************/
708 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
710 uint32 current_pdu_len = prs_data_size(current_pdu);
712 if (current_pdu_len < prhdr->frag_len) {
713 return NT_STATUS_BUFFER_TOO_SMALL;
716 /* Common case. */
717 if (current_pdu_len == (uint32)prhdr->frag_len) {
718 prs_mem_free(current_pdu);
719 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
720 /* Make current_pdu dynamic with no memory. */
721 prs_give_memory(current_pdu, 0, 0, True);
722 return NT_STATUS_OK;
726 * Oh no ! More data in buffer than we processed in current pdu.
727 * Cheat. Move the data down and shrink the buffer.
730 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
731 current_pdu_len - prhdr->frag_len);
733 /* Remember to set the read offset back to zero. */
734 prs_set_offset(current_pdu, 0);
736 /* Shrink the buffer. */
737 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
738 return NT_STATUS_BUFFER_TOO_SMALL;
741 return NT_STATUS_OK;
744 /****************************************************************************
745 Send data on an rpc pipe via trans. The prs_struct data must be the last
746 pdu fragment of an NDR data stream.
748 Receive response data from an rpc pipe, which may be large...
750 Read the first fragment: unfortunately have to use SMBtrans for the first
751 bit, then SMBreadX for subsequent bits.
753 If first fragment received also wasn't the last fragment, continue
754 getting fragments until we _do_ receive the last fragment.
756 Request/Response PDU's look like the following...
758 |<------------------PDU len----------------------------------------------->|
759 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
761 +------------+-----------------+-------------+---------------+-------------+
762 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
763 +------------+-----------------+-------------+---------------+-------------+
765 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
766 signing & sealing being negotiated.
768 ****************************************************************************/
770 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
771 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
772 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
773 uint8 expected_pkt_type)
775 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
776 char *rparam = NULL;
777 uint32 rparam_len = 0;
778 char *pdata = prs_data_p(data);
779 uint32 data_len = prs_offset(data);
780 char *prdata = NULL;
781 uint32 rdata_len = 0;
782 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
783 uint32 current_rbuf_offset = 0;
784 prs_struct current_pdu;
786 #ifdef DEVELOPER
787 /* Ensure we're not sending too much. */
788 SMB_ASSERT(data_len <= max_data);
789 #endif
791 /* Set up the current pdu parse struct. */
792 prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
794 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
796 switch (cli->transport_type) {
797 case NCACN_NP: {
798 uint16 setup[2];
799 /* Create setup parameters - must be in native byte order. */
800 setup[0] = TRANSACT_DCERPCCMD;
801 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
804 * Send the last (or only) fragment of an RPC request. For
805 * small amounts of data (about 1024 bytes or so) the RPC
806 * request and response appears in a SMBtrans request and
807 * response.
810 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
811 setup, 2, 0, /* Setup, length, max */
812 NULL, 0, 0, /* Params, length, max */
813 pdata, data_len, max_data, /* data, length,
814 * max */
815 &rparam, &rparam_len, /* return params,
816 * len */
817 &prdata, &rdata_len)) /* return data, len */
819 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
820 "Error was %s\n",
821 rpccli_pipe_txt(debug_ctx(), cli),
822 cli_errstr(cli->trans.np.cli)));
823 ret = cli_get_nt_error(cli->trans.np.cli);
824 SAFE_FREE(rparam);
825 SAFE_FREE(prdata);
826 goto err;
828 break;
830 case NCACN_IP_TCP:
832 ssize_t nwritten, nread;
833 nwritten = write_data(cli->trans.tcp.sock, pdata, data_len);
834 if (nwritten == -1) {
835 ret = map_nt_error_from_unix(errno);
836 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
837 strerror(errno)));
838 goto err;
840 rparam = NULL;
841 prdata = SMB_MALLOC_ARRAY(char, 1);
842 if (prdata != NULL) {
843 nread = sys_read(cli->trans.tcp.sock, prdata, 1);
845 if (nread == 0) {
846 SAFE_FREE(prdata);
848 if (nread == -1) {
849 ret = NT_STATUS_END_OF_FILE;
850 goto err;
852 rdata_len = nread;
853 break;
855 default:
856 DEBUG(0, ("unknown transport type %d\n",
857 cli->transport_type));
858 return NT_STATUS_INTERNAL_ERROR;
861 /* Throw away returned params - we know we won't use them. */
863 SAFE_FREE(rparam);
865 if (prdata == NULL) {
866 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
867 rpccli_pipe_txt(debug_ctx(), cli)));
868 /* Yes - some calls can truely return no data... */
869 prs_mem_free(&current_pdu);
870 return NT_STATUS_OK;
874 * Give this memory as dynamic to the current pdu.
877 prs_give_memory(&current_pdu, prdata, rdata_len, True);
879 /* Ensure we can mess with the return prs_struct. */
880 SMB_ASSERT(UNMARSHALLING(rbuf));
881 SMB_ASSERT(prs_data_size(rbuf) == 0);
883 /* Make rbuf dynamic with no memory. */
884 prs_give_memory(rbuf, 0, 0, True);
886 while(1) {
887 RPC_HDR rhdr;
888 char *ret_data;
889 uint32 ret_data_len;
891 /* Ensure we have enough data for a pdu. */
892 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
893 if (!NT_STATUS_IS_OK(ret)) {
894 goto err;
897 /* We pass in rbuf here so if the alloc hint is set correctly
898 we can set the output size and avoid reallocs. */
900 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
901 &ret_data, &ret_data_len, rbuf);
903 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
904 prs_data_size(&current_pdu), current_rbuf_offset ));
906 if (!NT_STATUS_IS_OK(ret)) {
907 goto err;
910 if ((rhdr.flags & RPC_FLG_FIRST)) {
911 if (rhdr.pack_type[0] == 0) {
912 /* Set the data type correctly for big-endian data on the first packet. */
913 DEBUG(10,("rpc_api_pipe: On %s "
914 "PDU data format is big-endian.\n",
915 rpccli_pipe_txt(debug_ctx(), cli)));
917 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
918 } else {
919 /* Check endianness on subsequent packets. */
920 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
921 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
922 rbuf->bigendian_data ? "big" : "little",
923 current_pdu.bigendian_data ? "big" : "little" ));
924 ret = NT_STATUS_INVALID_PARAMETER;
925 goto err;
930 /* Now copy the data portion out of the pdu into rbuf. */
931 if (!prs_force_grow(rbuf, ret_data_len)) {
932 ret = NT_STATUS_NO_MEMORY;
933 goto err;
935 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
936 current_rbuf_offset += ret_data_len;
938 /* See if we've finished with all the data in current_pdu yet ? */
939 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
940 if (!NT_STATUS_IS_OK(ret)) {
941 goto err;
944 if (rhdr.flags & RPC_FLG_LAST) {
945 break; /* We're done. */
949 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
950 rpccli_pipe_txt(debug_ctx(), cli),
951 (unsigned int)prs_data_size(rbuf) ));
953 prs_mem_free(&current_pdu);
954 return NT_STATUS_OK;
956 err:
958 prs_mem_free(&current_pdu);
959 prs_mem_free(rbuf);
960 return ret;
963 /*******************************************************************
964 Creates krb5 auth bind.
965 ********************************************************************/
967 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
968 enum pipe_auth_level auth_level,
969 RPC_HDR_AUTH *pauth_out,
970 prs_struct *auth_data)
972 #ifdef HAVE_KRB5
973 int ret;
974 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
975 DATA_BLOB tkt = data_blob_null;
976 DATA_BLOB tkt_wrapped = data_blob_null;
978 /* We may change the pad length before marshalling. */
979 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
981 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
982 a->service_principal ));
984 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
986 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
987 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
989 if (ret) {
990 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
991 "failed with %s\n",
992 a->service_principal,
993 error_message(ret) ));
995 data_blob_free(&tkt);
996 prs_mem_free(auth_data);
997 return NT_STATUS_INVALID_PARAMETER;
1000 /* wrap that up in a nice GSS-API wrapping */
1001 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1003 data_blob_free(&tkt);
1005 /* Auth len in the rpc header doesn't include auth_header. */
1006 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1007 data_blob_free(&tkt_wrapped);
1008 prs_mem_free(auth_data);
1009 return NT_STATUS_NO_MEMORY;
1012 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1013 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1015 data_blob_free(&tkt_wrapped);
1016 return NT_STATUS_OK;
1017 #else
1018 return NT_STATUS_INVALID_PARAMETER;
1019 #endif
1022 /*******************************************************************
1023 Creates SPNEGO NTLMSSP auth bind.
1024 ********************************************************************/
1026 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1027 enum pipe_auth_level auth_level,
1028 RPC_HDR_AUTH *pauth_out,
1029 prs_struct *auth_data)
1031 NTSTATUS nt_status;
1032 DATA_BLOB null_blob = data_blob_null;
1033 DATA_BLOB request = data_blob_null;
1034 DATA_BLOB spnego_msg = data_blob_null;
1036 /* We may change the pad length before marshalling. */
1037 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1039 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1040 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1041 null_blob,
1042 &request);
1044 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1045 data_blob_free(&request);
1046 prs_mem_free(auth_data);
1047 return nt_status;
1050 /* Wrap this in SPNEGO. */
1051 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1053 data_blob_free(&request);
1055 /* Auth len in the rpc header doesn't include auth_header. */
1056 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1057 data_blob_free(&spnego_msg);
1058 prs_mem_free(auth_data);
1059 return NT_STATUS_NO_MEMORY;
1062 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1063 dump_data(5, spnego_msg.data, spnego_msg.length);
1065 data_blob_free(&spnego_msg);
1066 return NT_STATUS_OK;
1069 /*******************************************************************
1070 Creates NTLMSSP auth bind.
1071 ********************************************************************/
1073 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1074 enum pipe_auth_level auth_level,
1075 RPC_HDR_AUTH *pauth_out,
1076 prs_struct *auth_data)
1078 NTSTATUS nt_status;
1079 DATA_BLOB null_blob = data_blob_null;
1080 DATA_BLOB request = data_blob_null;
1082 /* We may change the pad length before marshalling. */
1083 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1085 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1086 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1087 null_blob,
1088 &request);
1090 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1091 data_blob_free(&request);
1092 prs_mem_free(auth_data);
1093 return nt_status;
1096 /* Auth len in the rpc header doesn't include auth_header. */
1097 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1098 data_blob_free(&request);
1099 prs_mem_free(auth_data);
1100 return NT_STATUS_NO_MEMORY;
1103 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1104 dump_data(5, request.data, request.length);
1106 data_blob_free(&request);
1107 return NT_STATUS_OK;
1110 /*******************************************************************
1111 Creates schannel auth bind.
1112 ********************************************************************/
1114 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1115 enum pipe_auth_level auth_level,
1116 RPC_HDR_AUTH *pauth_out,
1117 prs_struct *auth_data)
1119 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1121 /* We may change the pad length before marshalling. */
1122 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1124 /* Use lp_workgroup() if domain not specified */
1126 if (!cli->auth->domain || !cli->auth->domain[0]) {
1127 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1128 if (cli->auth->domain == NULL) {
1129 return NT_STATUS_NO_MEMORY;
1133 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1134 global_myname());
1137 * Now marshall the data into the auth parse_struct.
1140 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1141 &schannel_neg, auth_data, 0)) {
1142 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1143 prs_mem_free(auth_data);
1144 return NT_STATUS_NO_MEMORY;
1147 return NT_STATUS_OK;
1150 /*******************************************************************
1151 Creates the internals of a DCE/RPC bind request or alter context PDU.
1152 ********************************************************************/
1154 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1155 prs_struct *rpc_out,
1156 uint32 rpc_call_id,
1157 const RPC_IFACE *abstract,
1158 const RPC_IFACE *transfer,
1159 RPC_HDR_AUTH *phdr_auth,
1160 prs_struct *pauth_info)
1162 RPC_HDR hdr;
1163 RPC_HDR_RB hdr_rb;
1164 RPC_CONTEXT rpc_ctx;
1165 uint16 auth_len = prs_offset(pauth_info);
1166 uint8 ss_padding_len = 0;
1167 uint16 frag_len = 0;
1169 /* create the RPC context. */
1170 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1172 /* create the bind request RPC_HDR_RB */
1173 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1175 /* Start building the frag length. */
1176 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1178 /* Do we need to pad ? */
1179 if (auth_len) {
1180 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1181 if (data_len % 8) {
1182 ss_padding_len = 8 - (data_len % 8);
1183 phdr_auth->auth_pad_len = ss_padding_len;
1185 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1188 /* Create the request RPC_HDR */
1189 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1191 /* Marshall the RPC header */
1192 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1193 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1194 return NT_STATUS_NO_MEMORY;
1197 /* Marshall the bind request data */
1198 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1199 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1200 return NT_STATUS_NO_MEMORY;
1204 * Grow the outgoing buffer to store any auth info.
1207 if(auth_len != 0) {
1208 if (ss_padding_len) {
1209 char pad[8];
1210 memset(pad, '\0', 8);
1211 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1212 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1213 return NT_STATUS_NO_MEMORY;
1217 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1218 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1219 return NT_STATUS_NO_MEMORY;
1223 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1224 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1225 return NT_STATUS_NO_MEMORY;
1229 return NT_STATUS_OK;
1232 /*******************************************************************
1233 Creates a DCE/RPC bind request.
1234 ********************************************************************/
1236 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1237 prs_struct *rpc_out,
1238 uint32 rpc_call_id,
1239 const RPC_IFACE *abstract,
1240 const RPC_IFACE *transfer,
1241 enum pipe_auth_type auth_type,
1242 enum pipe_auth_level auth_level)
1244 RPC_HDR_AUTH hdr_auth;
1245 prs_struct auth_info;
1246 NTSTATUS ret = NT_STATUS_OK;
1248 ZERO_STRUCT(hdr_auth);
1249 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1250 return NT_STATUS_NO_MEMORY;
1252 switch (auth_type) {
1253 case PIPE_AUTH_TYPE_SCHANNEL:
1254 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1255 if (!NT_STATUS_IS_OK(ret)) {
1256 prs_mem_free(&auth_info);
1257 return ret;
1259 break;
1261 case PIPE_AUTH_TYPE_NTLMSSP:
1262 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1263 if (!NT_STATUS_IS_OK(ret)) {
1264 prs_mem_free(&auth_info);
1265 return ret;
1267 break;
1269 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1270 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1271 if (!NT_STATUS_IS_OK(ret)) {
1272 prs_mem_free(&auth_info);
1273 return ret;
1275 break;
1277 case PIPE_AUTH_TYPE_KRB5:
1278 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1279 if (!NT_STATUS_IS_OK(ret)) {
1280 prs_mem_free(&auth_info);
1281 return ret;
1283 break;
1285 case PIPE_AUTH_TYPE_NONE:
1286 break;
1288 default:
1289 /* "Can't" happen. */
1290 return NT_STATUS_INVALID_INFO_CLASS;
1293 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1294 rpc_out,
1295 rpc_call_id,
1296 abstract,
1297 transfer,
1298 &hdr_auth,
1299 &auth_info);
1301 prs_mem_free(&auth_info);
1302 return ret;
1305 /*******************************************************************
1306 Create and add the NTLMSSP sign/seal auth header and data.
1307 ********************************************************************/
1309 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1310 RPC_HDR *phdr,
1311 uint32 ss_padding_len,
1312 prs_struct *outgoing_pdu)
1314 RPC_HDR_AUTH auth_info;
1315 NTSTATUS status;
1316 DATA_BLOB auth_blob = data_blob_null;
1317 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1319 if (!cli->auth->a_u.ntlmssp_state) {
1320 return NT_STATUS_INVALID_PARAMETER;
1323 /* Init and marshall the auth header. */
1324 init_rpc_hdr_auth(&auth_info,
1325 map_pipe_auth_type_to_rpc_auth_type(
1326 cli->auth->auth_type),
1327 cli->auth->auth_level,
1328 ss_padding_len,
1329 1 /* context id. */);
1331 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1332 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1333 data_blob_free(&auth_blob);
1334 return NT_STATUS_NO_MEMORY;
1337 switch (cli->auth->auth_level) {
1338 case PIPE_AUTH_LEVEL_PRIVACY:
1339 /* Data portion is encrypted. */
1340 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1341 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1342 data_and_pad_len,
1343 (unsigned char *)prs_data_p(outgoing_pdu),
1344 (size_t)prs_offset(outgoing_pdu),
1345 &auth_blob);
1346 if (!NT_STATUS_IS_OK(status)) {
1347 data_blob_free(&auth_blob);
1348 return status;
1350 break;
1352 case PIPE_AUTH_LEVEL_INTEGRITY:
1353 /* Data is signed. */
1354 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1355 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1356 data_and_pad_len,
1357 (unsigned char *)prs_data_p(outgoing_pdu),
1358 (size_t)prs_offset(outgoing_pdu),
1359 &auth_blob);
1360 if (!NT_STATUS_IS_OK(status)) {
1361 data_blob_free(&auth_blob);
1362 return status;
1364 break;
1366 default:
1367 /* Can't happen. */
1368 smb_panic("bad auth level");
1369 /* Notreached. */
1370 return NT_STATUS_INVALID_PARAMETER;
1373 /* Finally marshall the blob. */
1375 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1376 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1377 (unsigned int)NTLMSSP_SIG_SIZE));
1378 data_blob_free(&auth_blob);
1379 return NT_STATUS_NO_MEMORY;
1382 data_blob_free(&auth_blob);
1383 return NT_STATUS_OK;
1386 /*******************************************************************
1387 Create and add the schannel sign/seal auth header and data.
1388 ********************************************************************/
1390 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1391 RPC_HDR *phdr,
1392 uint32 ss_padding_len,
1393 prs_struct *outgoing_pdu)
1395 RPC_HDR_AUTH auth_info;
1396 RPC_AUTH_SCHANNEL_CHK verf;
1397 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1398 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1399 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1401 if (!sas) {
1402 return NT_STATUS_INVALID_PARAMETER;
1405 /* Init and marshall the auth header. */
1406 init_rpc_hdr_auth(&auth_info,
1407 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1408 cli->auth->auth_level,
1409 ss_padding_len,
1410 1 /* context id. */);
1412 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1413 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1414 return NT_STATUS_NO_MEMORY;
1417 switch (cli->auth->auth_level) {
1418 case PIPE_AUTH_LEVEL_PRIVACY:
1419 case PIPE_AUTH_LEVEL_INTEGRITY:
1420 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1421 sas->seq_num));
1423 schannel_encode(sas,
1424 cli->auth->auth_level,
1425 SENDER_IS_INITIATOR,
1426 &verf,
1427 data_p,
1428 data_and_pad_len);
1430 sas->seq_num++;
1431 break;
1433 default:
1434 /* Can't happen. */
1435 smb_panic("bad auth level");
1436 /* Notreached. */
1437 return NT_STATUS_INVALID_PARAMETER;
1440 /* Finally marshall the blob. */
1441 smb_io_rpc_auth_schannel_chk("",
1442 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1443 &verf,
1444 outgoing_pdu,
1447 return NT_STATUS_OK;
1450 /*******************************************************************
1451 Calculate how much data we're going to send in this packet, also
1452 work out any sign/seal padding length.
1453 ********************************************************************/
1455 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1456 uint32 data_left,
1457 uint16 *p_frag_len,
1458 uint16 *p_auth_len,
1459 uint32 *p_ss_padding)
1461 uint32 data_space, data_len;
1463 switch (cli->auth->auth_level) {
1464 case PIPE_AUTH_LEVEL_NONE:
1465 case PIPE_AUTH_LEVEL_CONNECT:
1466 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1467 data_len = MIN(data_space, data_left);
1468 *p_ss_padding = 0;
1469 *p_auth_len = 0;
1470 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1471 return data_len;
1473 case PIPE_AUTH_LEVEL_INTEGRITY:
1474 case PIPE_AUTH_LEVEL_PRIVACY:
1475 /* Treat the same for all authenticated rpc requests. */
1476 switch(cli->auth->auth_type) {
1477 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1478 case PIPE_AUTH_TYPE_NTLMSSP:
1479 *p_auth_len = NTLMSSP_SIG_SIZE;
1480 break;
1481 case PIPE_AUTH_TYPE_SCHANNEL:
1482 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1483 break;
1484 default:
1485 smb_panic("bad auth type");
1486 break;
1489 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1490 RPC_HDR_AUTH_LEN - *p_auth_len;
1492 data_len = MIN(data_space, data_left);
1493 if (data_len % 8) {
1494 *p_ss_padding = 8 - (data_len % 8);
1496 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1497 data_len + *p_ss_padding + /* data plus padding. */
1498 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1499 return data_len;
1501 default:
1502 smb_panic("bad auth level");
1503 /* Notreached. */
1504 return 0;
1508 /*******************************************************************
1509 External interface.
1510 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1511 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1512 and deals with signing/sealing details.
1513 ********************************************************************/
1515 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1516 uint8 op_num,
1517 prs_struct *in_data,
1518 prs_struct *out_data)
1520 NTSTATUS ret;
1521 uint32 data_left = prs_offset(in_data);
1522 uint32 alloc_hint = prs_offset(in_data);
1523 uint32 data_sent_thistime = 0;
1524 uint32 current_data_offset = 0;
1525 uint32 call_id = get_rpc_call_id();
1526 char pad[8];
1527 prs_struct outgoing_pdu;
1529 memset(pad, '\0', 8);
1531 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1532 /* Server is screwed up ! */
1533 return NT_STATUS_INVALID_PARAMETER;
1536 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1537 return NT_STATUS_NO_MEMORY;
1539 while (1) {
1540 RPC_HDR hdr;
1541 RPC_HDR_REQ hdr_req;
1542 uint16 auth_len = 0;
1543 uint16 frag_len = 0;
1544 uint8 flags = 0;
1545 uint32 ss_padding = 0;
1547 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1548 &frag_len, &auth_len, &ss_padding);
1550 if (current_data_offset == 0) {
1551 flags = RPC_FLG_FIRST;
1554 if (data_sent_thistime == data_left) {
1555 flags |= RPC_FLG_LAST;
1558 /* Create and marshall the header and request header. */
1559 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1561 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1562 prs_mem_free(&outgoing_pdu);
1563 return NT_STATUS_NO_MEMORY;
1566 /* Create the rpc request RPC_HDR_REQ */
1567 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1569 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1570 prs_mem_free(&outgoing_pdu);
1571 return NT_STATUS_NO_MEMORY;
1574 /* Copy in the data, plus any ss padding. */
1575 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1576 prs_mem_free(&outgoing_pdu);
1577 return NT_STATUS_NO_MEMORY;
1580 /* Copy the sign/seal padding data. */
1581 if (ss_padding) {
1582 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1583 prs_mem_free(&outgoing_pdu);
1584 return NT_STATUS_NO_MEMORY;
1588 /* Generate any auth sign/seal and add the auth footer. */
1589 if (auth_len) {
1590 switch (cli->auth->auth_type) {
1591 case PIPE_AUTH_TYPE_NONE:
1592 break;
1593 case PIPE_AUTH_TYPE_NTLMSSP:
1594 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1595 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1596 if (!NT_STATUS_IS_OK(ret)) {
1597 prs_mem_free(&outgoing_pdu);
1598 return ret;
1600 break;
1601 case PIPE_AUTH_TYPE_SCHANNEL:
1602 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1603 if (!NT_STATUS_IS_OK(ret)) {
1604 prs_mem_free(&outgoing_pdu);
1605 return ret;
1607 break;
1608 default:
1609 smb_panic("bad auth type");
1610 break; /* notreached */
1614 /* Actually send the packet. */
1615 if (flags & RPC_FLG_LAST) {
1616 /* Last packet - send the data, get the reply and return. */
1617 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1618 prs_mem_free(&outgoing_pdu);
1620 if ((DEBUGLEVEL >= 50)
1621 && (cli->transport_type == NCACN_NP)) {
1622 char *dump_name = NULL;
1623 /* Also capture received data */
1624 if (asprintf(&dump_name, "%s/reply_%s_%d",
1625 get_dyn_LOGFILEBASE(),
1626 cli->trans.np.pipe_name, op_num) > 0) {
1627 prs_dump(dump_name, op_num, out_data);
1628 SAFE_FREE(dump_name);
1632 return ret;
1633 } else {
1634 /* More packets to come - write and continue. */
1635 ssize_t num_written;
1637 switch (cli->transport_type) {
1638 case NCACN_NP:
1639 num_written = cli_write(cli->trans.np.cli,
1640 cli->trans.np.fnum,
1641 8, /* 8 means message mode. */
1642 prs_data_p(&outgoing_pdu),
1643 (off_t)0,
1644 (size_t)hdr.frag_len);
1646 if (num_written != hdr.frag_len) {
1647 prs_mem_free(&outgoing_pdu);
1648 return cli_get_nt_error(
1649 cli->trans.np.cli);
1651 break;
1652 case NCACN_IP_TCP:
1653 num_written = write_data(
1654 cli->trans.tcp.sock,
1655 prs_data_p(&outgoing_pdu),
1656 (size_t)hdr.frag_len);
1657 if (num_written != hdr.frag_len) {
1658 NTSTATUS status;
1659 status = map_nt_error_from_unix(errno);
1660 prs_mem_free(&outgoing_pdu);
1661 return status;
1663 break;
1664 default:
1665 DEBUG(0, ("unknown transport type %d\n",
1666 cli->transport_type));
1667 return NT_STATUS_INTERNAL_ERROR;
1671 current_data_offset += data_sent_thistime;
1672 data_left -= data_sent_thistime;
1674 /* Reset the marshalling position back to zero. */
1675 if (!prs_set_offset(&outgoing_pdu, 0)) {
1676 prs_mem_free(&outgoing_pdu);
1677 return NT_STATUS_NO_MEMORY;
1681 #if 0
1682 /****************************************************************************
1683 Set the handle state.
1684 ****************************************************************************/
1686 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1687 const char *pipe_name, uint16 device_state)
1689 bool state_set = False;
1690 char param[2];
1691 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1692 char *rparam = NULL;
1693 char *rdata = NULL;
1694 uint32 rparam_len, rdata_len;
1696 if (pipe_name == NULL)
1697 return False;
1699 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1700 cli->fnum, pipe_name, device_state));
1702 /* create parameters: device state */
1703 SSVAL(param, 0, device_state);
1705 /* create setup parameters. */
1706 setup[0] = 0x0001;
1707 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1709 /* send the data on \PIPE\ */
1710 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1711 setup, 2, 0, /* setup, length, max */
1712 param, 2, 0, /* param, length, max */
1713 NULL, 0, 1024, /* data, length, max */
1714 &rparam, &rparam_len, /* return param, length */
1715 &rdata, &rdata_len)) /* return data, length */
1717 DEBUG(5, ("Set Handle state: return OK\n"));
1718 state_set = True;
1721 SAFE_FREE(rparam);
1722 SAFE_FREE(rdata);
1724 return state_set;
1726 #endif
1728 /****************************************************************************
1729 Check the rpc bind acknowledge response.
1730 ****************************************************************************/
1732 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1734 if ( hdr_ba->addr.len == 0) {
1735 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1738 /* check the transfer syntax */
1739 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1740 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1741 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1742 return False;
1745 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1746 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1747 hdr_ba->res.num_results, hdr_ba->res.reason));
1750 DEBUG(5,("check_bind_response: accepted!\n"));
1751 return True;
1754 /*******************************************************************
1755 Creates a DCE/RPC bind authentication response.
1756 This is the packet that is sent back to the server once we
1757 have received a BIND-ACK, to finish the third leg of
1758 the authentication handshake.
1759 ********************************************************************/
1761 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1762 uint32 rpc_call_id,
1763 enum pipe_auth_type auth_type,
1764 enum pipe_auth_level auth_level,
1765 DATA_BLOB *pauth_blob,
1766 prs_struct *rpc_out)
1768 RPC_HDR hdr;
1769 RPC_HDR_AUTH hdr_auth;
1770 uint32 pad = 0;
1772 /* Create the request RPC_HDR */
1773 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1774 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1775 pauth_blob->length );
1777 /* Marshall it. */
1778 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1779 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1780 return NT_STATUS_NO_MEMORY;
1784 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1785 about padding - shouldn't this pad to length 8 ? JRA.
1788 /* 4 bytes padding. */
1789 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1790 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1791 return NT_STATUS_NO_MEMORY;
1794 /* Create the request RPC_HDR_AUTHA */
1795 init_rpc_hdr_auth(&hdr_auth,
1796 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1797 auth_level, 0, 1);
1799 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1800 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1801 return NT_STATUS_NO_MEMORY;
1805 * Append the auth data to the outgoing buffer.
1808 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1809 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1810 return NT_STATUS_NO_MEMORY;
1813 return NT_STATUS_OK;
1816 /****************************************************************************
1817 Create and send the third packet in an RPC auth.
1818 ****************************************************************************/
1820 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1821 RPC_HDR *phdr,
1822 prs_struct *rbuf,
1823 uint32 rpc_call_id,
1824 enum pipe_auth_type auth_type,
1825 enum pipe_auth_level auth_level)
1827 DATA_BLOB server_response = data_blob_null;
1828 DATA_BLOB client_reply = data_blob_null;
1829 RPC_HDR_AUTH hdr_auth;
1830 NTSTATUS nt_status;
1831 prs_struct rpc_out;
1832 ssize_t ret;
1834 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1835 return NT_STATUS_INVALID_PARAMETER;
1838 /* Process the returned NTLMSSP blob first. */
1839 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1840 return NT_STATUS_INVALID_PARAMETER;
1843 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1844 return NT_STATUS_INVALID_PARAMETER;
1847 /* TODO - check auth_type/auth_level match. */
1849 server_response = data_blob(NULL, phdr->auth_len);
1850 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1852 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1853 server_response,
1854 &client_reply);
1856 if (!NT_STATUS_IS_OK(nt_status)) {
1857 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1858 data_blob_free(&server_response);
1859 return nt_status;
1862 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1864 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1865 auth_type, auth_level,
1866 &client_reply, &rpc_out);
1868 if (!NT_STATUS_IS_OK(nt_status)) {
1869 prs_mem_free(&rpc_out);
1870 data_blob_free(&client_reply);
1871 data_blob_free(&server_response);
1872 return nt_status;
1875 switch (cli->transport_type) {
1876 case NCACN_NP:
1877 /* 8 here is named pipe message mode. */
1878 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
1879 0x8, prs_data_p(&rpc_out), 0,
1880 (size_t)prs_offset(&rpc_out));
1881 break;
1883 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1884 nt_status = cli_get_nt_error(cli->trans.np.cli);
1886 case NCACN_IP_TCP:
1887 ret = write_data(cli->trans.tcp.sock, prs_data_p(&rpc_out),
1888 (size_t)prs_offset(&rpc_out));
1889 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1890 nt_status = map_nt_error_from_unix(errno);
1892 break;
1893 default:
1894 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
1895 return NT_STATUS_INTERNAL_ERROR;
1898 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1899 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
1900 nt_errstr(nt_status)));
1901 prs_mem_free(&rpc_out);
1902 data_blob_free(&client_reply);
1903 data_blob_free(&server_response);
1904 return nt_status;
1907 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
1908 rpccli_pipe_txt(debug_ctx(), cli)));
1910 prs_mem_free(&rpc_out);
1911 data_blob_free(&client_reply);
1912 data_blob_free(&server_response);
1913 return NT_STATUS_OK;
1916 /*******************************************************************
1917 Creates a DCE/RPC bind alter context authentication request which
1918 may contain a spnego auth blobl
1919 ********************************************************************/
1921 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1922 const RPC_IFACE *abstract,
1923 const RPC_IFACE *transfer,
1924 enum pipe_auth_level auth_level,
1925 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1926 prs_struct *rpc_out)
1928 RPC_HDR_AUTH hdr_auth;
1929 prs_struct auth_info;
1930 NTSTATUS ret = NT_STATUS_OK;
1932 ZERO_STRUCT(hdr_auth);
1933 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1934 return NT_STATUS_NO_MEMORY;
1936 /* We may change the pad length before marshalling. */
1937 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1939 if (pauth_blob->length) {
1940 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1941 prs_mem_free(&auth_info);
1942 return NT_STATUS_NO_MEMORY;
1946 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1947 rpc_out,
1948 rpc_call_id,
1949 abstract,
1950 transfer,
1951 &hdr_auth,
1952 &auth_info);
1953 prs_mem_free(&auth_info);
1954 return ret;
1957 /*******************************************************************
1958 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1959 and gets a response.
1960 ********************************************************************/
1962 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1963 RPC_HDR *phdr,
1964 prs_struct *rbuf,
1965 uint32 rpc_call_id,
1966 const RPC_IFACE *abstract,
1967 const RPC_IFACE *transfer,
1968 enum pipe_auth_type auth_type,
1969 enum pipe_auth_level auth_level)
1971 DATA_BLOB server_spnego_response = data_blob_null;
1972 DATA_BLOB server_ntlm_response = data_blob_null;
1973 DATA_BLOB client_reply = data_blob_null;
1974 DATA_BLOB tmp_blob = data_blob_null;
1975 RPC_HDR_AUTH hdr_auth;
1976 NTSTATUS nt_status;
1977 prs_struct rpc_out;
1979 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1980 return NT_STATUS_INVALID_PARAMETER;
1983 /* Process the returned NTLMSSP blob first. */
1984 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1985 return NT_STATUS_INVALID_PARAMETER;
1988 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1989 return NT_STATUS_INVALID_PARAMETER;
1992 server_spnego_response = data_blob(NULL, phdr->auth_len);
1993 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1995 /* The server might give us back two challenges - tmp_blob is for the second. */
1996 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
1997 data_blob_free(&server_spnego_response);
1998 data_blob_free(&server_ntlm_response);
1999 data_blob_free(&tmp_blob);
2000 return NT_STATUS_INVALID_PARAMETER;
2003 /* We're finished with the server spnego response and the tmp_blob. */
2004 data_blob_free(&server_spnego_response);
2005 data_blob_free(&tmp_blob);
2007 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2008 server_ntlm_response,
2009 &client_reply);
2011 /* Finished with the server_ntlm response */
2012 data_blob_free(&server_ntlm_response);
2014 if (!NT_STATUS_IS_OK(nt_status)) {
2015 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2016 data_blob_free(&client_reply);
2017 return nt_status;
2020 /* SPNEGO wrap the client reply. */
2021 tmp_blob = spnego_gen_auth(client_reply);
2022 data_blob_free(&client_reply);
2023 client_reply = tmp_blob;
2024 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2026 /* Now prepare the alter context pdu. */
2027 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2029 nt_status = create_rpc_alter_context(rpc_call_id,
2030 abstract,
2031 transfer,
2032 auth_level,
2033 &client_reply,
2034 &rpc_out);
2036 data_blob_free(&client_reply);
2038 if (!NT_STATUS_IS_OK(nt_status)) {
2039 prs_mem_free(&rpc_out);
2040 return nt_status;
2043 /* Initialize the returning data struct. */
2044 prs_mem_free(rbuf);
2045 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2047 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2048 if (!NT_STATUS_IS_OK(nt_status)) {
2049 prs_mem_free(&rpc_out);
2050 return nt_status;
2053 prs_mem_free(&rpc_out);
2055 /* Get the auth blob from the reply. */
2056 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2057 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2058 return NT_STATUS_BUFFER_TOO_SMALL;
2061 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2062 return NT_STATUS_INVALID_PARAMETER;
2065 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2066 return NT_STATUS_INVALID_PARAMETER;
2069 server_spnego_response = data_blob(NULL, phdr->auth_len);
2070 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2072 /* Check we got a valid auth response. */
2073 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2074 data_blob_free(&server_spnego_response);
2075 data_blob_free(&tmp_blob);
2076 return NT_STATUS_INVALID_PARAMETER;
2079 data_blob_free(&server_spnego_response);
2080 data_blob_free(&tmp_blob);
2082 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2083 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2085 return NT_STATUS_OK;
2088 /****************************************************************************
2089 Do an rpc bind.
2090 ****************************************************************************/
2092 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2093 struct cli_pipe_auth_data *auth)
2095 RPC_HDR hdr;
2096 RPC_HDR_BA hdr_ba;
2097 prs_struct rpc_out;
2098 prs_struct rbuf;
2099 uint32 rpc_call_id;
2100 NTSTATUS status;
2102 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2103 rpccli_pipe_txt(debug_ctx(), cli),
2104 (unsigned int)auth->auth_type,
2105 (unsigned int)auth->auth_level ));
2107 cli->auth = talloc_move(cli, &auth);
2109 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2111 rpc_call_id = get_rpc_call_id();
2113 /* Marshall the outgoing data. */
2114 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2115 cli->abstract_syntax,
2116 cli->transfer_syntax,
2117 cli->auth->auth_type,
2118 cli->auth->auth_level);
2120 if (!NT_STATUS_IS_OK(status)) {
2121 prs_mem_free(&rpc_out);
2122 return status;
2125 /* Initialize the incoming data struct. */
2126 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2128 /* send data on \PIPE\. receive a response */
2129 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2130 if (!NT_STATUS_IS_OK(status)) {
2131 prs_mem_free(&rpc_out);
2132 return status;
2135 prs_mem_free(&rpc_out);
2137 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2138 rpccli_pipe_txt(debug_ctx(), cli)));
2140 /* Unmarshall the RPC header */
2141 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2142 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2143 prs_mem_free(&rbuf);
2144 return NT_STATUS_BUFFER_TOO_SMALL;
2147 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2148 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2149 prs_mem_free(&rbuf);
2150 return NT_STATUS_BUFFER_TOO_SMALL;
2153 if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2154 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2155 prs_mem_free(&rbuf);
2156 return NT_STATUS_BUFFER_TOO_SMALL;
2159 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2160 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2162 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2163 switch(cli->auth->auth_type) {
2165 case PIPE_AUTH_TYPE_NONE:
2166 case PIPE_AUTH_TYPE_SCHANNEL:
2167 /* Bind complete. */
2168 break;
2170 case PIPE_AUTH_TYPE_NTLMSSP:
2171 /* Need to send AUTH3 packet - no reply. */
2172 status = rpc_finish_auth3_bind(
2173 cli, &hdr, &rbuf, rpc_call_id,
2174 cli->auth->auth_type,
2175 cli->auth->auth_level);
2176 if (!NT_STATUS_IS_OK(status)) {
2177 prs_mem_free(&rbuf);
2178 return status;
2180 break;
2182 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2183 /* Need to send alter context request and reply. */
2184 status = rpc_finish_spnego_ntlmssp_bind(
2185 cli, &hdr, &rbuf, rpc_call_id,
2186 cli->abstract_syntax, cli->transfer_syntax,
2187 cli->auth->auth_type, cli->auth->auth_level);
2188 if (!NT_STATUS_IS_OK(status)) {
2189 prs_mem_free(&rbuf);
2190 return status;
2192 break;
2194 case PIPE_AUTH_TYPE_KRB5:
2195 /* */
2197 default:
2198 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2199 "%u\n", (unsigned int)cli->auth->auth_type));
2200 prs_mem_free(&rbuf);
2201 return NT_STATUS_INVALID_INFO_CLASS;
2204 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2205 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2206 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2207 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2208 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2209 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2210 prs_mem_free(&rbuf);
2211 return NT_STATUS_INVALID_PARAMETER;
2214 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2215 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2216 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2217 prs_mem_free(&rbuf);
2218 return NT_STATUS_INVALID_PARAMETER;
2223 prs_mem_free(&rbuf);
2224 return NT_STATUS_OK;
2227 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2228 unsigned int timeout)
2230 return cli_set_timeout(cli->trans.np.cli, timeout);
2233 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2235 return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
2238 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2240 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2241 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2242 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2243 return true;
2246 if (cli->transport_type == NCACN_NP) {
2247 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2248 return true;
2251 return false;
2254 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2256 if (p->transport_type == NCACN_NP) {
2257 return p->trans.np.cli;
2259 return NULL;
2262 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2264 if (p->transport_type == NCACN_NP) {
2265 bool ret;
2266 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2267 if (!ret) {
2268 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2269 "pipe %s. Error was %s\n",
2270 rpccli_pipe_txt(debug_ctx(), p),
2271 cli_errstr(p->trans.np.cli)));
2274 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2275 rpccli_pipe_txt(debug_ctx(), p)));
2277 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2278 return ret ? -1 : 0;
2281 return -1;
2284 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2285 struct cli_pipe_auth_data **presult)
2287 struct cli_pipe_auth_data *result;
2289 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2290 if (result == NULL) {
2291 return NT_STATUS_NO_MEMORY;
2294 result->auth_type = PIPE_AUTH_TYPE_NONE;
2295 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2297 result->user_name = talloc_strdup(result, "");
2298 result->domain = talloc_strdup(result, "");
2299 if ((result->user_name == NULL) || (result->domain == NULL)) {
2300 TALLOC_FREE(result);
2301 return NT_STATUS_NO_MEMORY;
2304 *presult = result;
2305 return NT_STATUS_OK;
2308 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2310 ntlmssp_end(&auth->a_u.ntlmssp_state);
2311 return 0;
2314 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2315 enum pipe_auth_type auth_type,
2316 enum pipe_auth_level auth_level,
2317 const char *domain,
2318 const char *username,
2319 const char *password,
2320 struct cli_pipe_auth_data **presult)
2322 struct cli_pipe_auth_data *result;
2323 NTSTATUS status;
2325 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2326 if (result == NULL) {
2327 return NT_STATUS_NO_MEMORY;
2330 result->auth_type = auth_type;
2331 result->auth_level = auth_level;
2333 result->user_name = talloc_strdup(result, username);
2334 result->domain = talloc_strdup(result, domain);
2335 if ((result->user_name == NULL) || (result->domain == NULL)) {
2336 status = NT_STATUS_NO_MEMORY;
2337 goto fail;
2340 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2341 if (!NT_STATUS_IS_OK(status)) {
2342 goto fail;
2345 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2347 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2348 if (!NT_STATUS_IS_OK(status)) {
2349 goto fail;
2352 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2353 if (!NT_STATUS_IS_OK(status)) {
2354 goto fail;
2357 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2358 if (!NT_STATUS_IS_OK(status)) {
2359 goto fail;
2363 * Turn off sign+seal to allow selected auth level to turn it back on.
2365 result->a_u.ntlmssp_state->neg_flags &=
2366 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2368 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2369 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2370 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2371 result->a_u.ntlmssp_state->neg_flags
2372 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2375 *presult = result;
2376 return NT_STATUS_OK;
2378 fail:
2379 TALLOC_FREE(result);
2380 return status;
2383 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2384 enum pipe_auth_level auth_level,
2385 const struct dcinfo *pdc,
2386 struct cli_pipe_auth_data **presult)
2388 struct cli_pipe_auth_data *result;
2390 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2391 if (result == NULL) {
2392 return NT_STATUS_NO_MEMORY;
2395 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2396 result->auth_level = auth_level;
2398 result->user_name = talloc_strdup(result, "");
2399 result->domain = talloc_strdup(result, domain);
2400 if ((result->user_name == NULL) || (result->domain == NULL)) {
2401 goto fail;
2404 result->a_u.schannel_auth = talloc(result,
2405 struct schannel_auth_struct);
2406 if (result->a_u.schannel_auth == NULL) {
2407 goto fail;
2410 memcpy(result->a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2411 result->a_u.schannel_auth->seq_num = 0;
2413 *presult = result;
2414 return NT_STATUS_OK;
2416 fail:
2417 TALLOC_FREE(result);
2418 return NT_STATUS_NO_MEMORY;
2421 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2423 data_blob_free(&auth->session_key);
2424 return 0;
2427 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2428 enum pipe_auth_level auth_level,
2429 const char *service_princ,
2430 const char *username,
2431 const char *password,
2432 struct cli_pipe_auth_data **presult)
2434 struct cli_pipe_auth_data *result;
2436 if ((username != NULL) && (password != NULL)) {
2437 int ret = kerberos_kinit_password(username, password, 0, NULL);
2438 if (ret != 0) {
2439 return NT_STATUS_ACCESS_DENIED;
2443 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2444 if (result == NULL) {
2445 return NT_STATUS_NO_MEMORY;
2448 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2449 result->auth_level = auth_level;
2452 * Username / domain need fixing!
2454 result->user_name = talloc_strdup(result, "");
2455 result->domain = talloc_strdup(result, "");
2456 if ((result->user_name == NULL) || (result->domain == NULL)) {
2457 goto fail;
2460 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2461 result, struct kerberos_auth_struct);
2462 if (result->a_u.kerberos_auth == NULL) {
2463 goto fail;
2465 talloc_set_destructor(result->a_u.kerberos_auth,
2466 cli_auth_kerberos_data_destructor);
2468 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2469 result, service_princ);
2470 if (result->a_u.kerberos_auth->service_principal == NULL) {
2471 goto fail;
2474 *presult = result;
2475 return NT_STATUS_OK;
2477 fail:
2478 TALLOC_FREE(result);
2479 return NT_STATUS_NO_MEMORY;
2482 /********************************************************************
2483 Create a named pipe struct, connecting to a tcp port
2484 ********************************************************************/
2485 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2486 uint16_t port,
2487 const struct ndr_syntax_id *abstract_syntax,
2488 struct rpc_pipe_client **presult)
2490 struct rpc_pipe_client *result;
2491 struct sockaddr_storage addr;
2492 NTSTATUS status;
2494 result = talloc(mem_ctx, struct rpc_pipe_client);
2495 if (result == NULL) {
2496 return NT_STATUS_NO_MEMORY;
2499 result->transport_type = NCACN_IP_TCP;
2501 result->abstract_syntax = abstract_syntax;
2502 result->transfer_syntax = &ndr_transfer_syntax;
2504 result->desthost = talloc_strdup(result, host);
2505 result->srv_name_slash = talloc_asprintf_strupper_m(
2506 result, "\\\\%s", result->desthost);
2507 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2508 status = NT_STATUS_NO_MEMORY;
2509 goto fail;
2512 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2513 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2515 if (!resolve_name(host, &addr, 0)) {
2516 status = NT_STATUS_NOT_FOUND;
2517 goto fail;
2520 result->trans.tcp.sock = open_socket_out(SOCK_STREAM, &addr, port, 60);
2521 if (result->trans.tcp.sock == -1) {
2522 status = map_nt_error_from_unix(errno);
2523 goto fail;
2526 *presult = result;
2527 return NT_STATUS_OK;
2529 fail:
2530 TALLOC_FREE(result);
2531 return status;
2535 /****************************************************************************
2536 Open a named pipe over SMB to a remote server.
2538 * CAVEAT CALLER OF THIS FUNCTION:
2539 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2540 * so be sure that this function is called AFTER any structure (vs pointer)
2541 * assignment of the cli. In particular, libsmbclient does structure
2542 * assignments of cli, which invalidates the data in the returned
2543 * rpc_pipe_client if this function is called before the structure assignment
2544 * of cli.
2546 ****************************************************************************/
2548 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2550 struct rpc_pipe_client *result;
2551 int fnum;
2553 *perr = NT_STATUS_NO_MEMORY;
2555 /* sanity check to protect against crashes */
2557 if ( !cli ) {
2558 *perr = NT_STATUS_INVALID_HANDLE;
2559 return NULL;
2562 /* The pipe name index must fall within our array */
2563 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2565 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2566 if (result == NULL) {
2567 *perr = NT_STATUS_NO_MEMORY;
2568 return NULL;
2571 result->transport_type = NCACN_NP;
2573 result->trans.np.pipe_name = cli_get_pipe_name(pipe_idx);
2575 result->trans.np.cli = cli;
2576 result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2577 result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2578 result->desthost = talloc_strdup(result, cli->desthost);
2579 result->srv_name_slash = talloc_asprintf_strupper_m(
2580 result, "\\\\%s", result->desthost);
2582 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2583 *perr = NT_STATUS_NO_MEMORY;
2584 TALLOC_FREE(result);
2585 return NULL;
2588 if (pipe_idx == PI_NETLOGON) {
2589 /* Set up a netlogon credential chain for a netlogon pipe. */
2590 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2591 if (result->dc == NULL) {
2592 *perr = NT_STATUS_NO_MEMORY;
2593 TALLOC_FREE(result);
2594 return NULL;
2598 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2599 DESIRED_ACCESS_PIPE);
2600 if (fnum == -1) {
2601 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2602 "to machine %s. Error was %s\n",
2603 result->trans.np.pipe_name, cli->desthost,
2604 cli_errstr(cli)));
2605 *perr = cli_get_nt_error(cli);
2606 talloc_destroy(result);
2607 return NULL;
2610 result->trans.np.fnum = fnum;
2612 DLIST_ADD(cli->pipe_list, result);
2613 talloc_set_destructor(result, rpc_pipe_destructor);
2615 *perr = NT_STATUS_OK;
2617 return result;
2620 /****************************************************************************
2621 Open a named pipe to an SMB server and bind anonymously.
2622 ****************************************************************************/
2624 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2626 struct rpc_pipe_client *result;
2627 struct cli_pipe_auth_data *auth;
2629 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2630 if (result == NULL) {
2631 return NULL;
2634 *perr = rpccli_anon_bind_data(result, &auth);
2635 if (!NT_STATUS_IS_OK(*perr)) {
2636 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2637 nt_errstr(*perr)));
2638 TALLOC_FREE(result);
2639 return NULL;
2643 * This is a bit of an abstraction violation due to the fact that an
2644 * anonymous bind on an authenticated SMB inherits the user/domain
2645 * from the enclosing SMB creds
2648 TALLOC_FREE(auth->user_name);
2649 TALLOC_FREE(auth->domain);
2651 auth->user_name = talloc_strdup(auth, cli->user_name);
2652 auth->domain = talloc_strdup(auth, cli->domain);
2654 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2655 *perr = NT_STATUS_NO_MEMORY;
2656 TALLOC_FREE(result);
2657 return NULL;
2660 *perr = rpc_pipe_bind(result, auth);
2661 if (!NT_STATUS_IS_OK(*perr)) {
2662 int lvl = 0;
2663 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2664 /* non AD domains just don't have this pipe, avoid
2665 * level 0 statement in that case - gd */
2666 lvl = 3;
2668 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2669 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2670 TALLOC_FREE(result);
2671 return NULL;
2674 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2675 "%s and bound anonymously.\n", result->trans.np.pipe_name,
2676 cli->desthost ));
2678 return result;
2681 /****************************************************************************
2682 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2683 ****************************************************************************/
2685 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2686 int pipe_idx,
2687 enum pipe_auth_type auth_type,
2688 enum pipe_auth_level auth_level,
2689 const char *domain,
2690 const char *username,
2691 const char *password,
2692 NTSTATUS *perr)
2694 struct rpc_pipe_client *result;
2695 struct cli_pipe_auth_data *auth;
2697 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2698 if (result == NULL) {
2699 return NULL;
2702 *perr = rpccli_ntlmssp_bind_data(
2703 result, auth_type, auth_level, domain, username,
2704 cli->pwd.null_pwd ? NULL : password, &auth);
2705 if (!NT_STATUS_IS_OK(*perr)) {
2706 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2707 nt_errstr(*perr)));
2708 TALLOC_FREE(result);
2709 return NULL;
2712 *perr = rpc_pipe_bind(result, auth);
2713 if (!NT_STATUS_IS_OK(*perr)) {
2714 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2715 nt_errstr(*perr) ));
2716 goto err;
2719 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2720 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2721 result->trans.np.pipe_name, cli->desthost,
2722 domain, username ));
2724 return result;
2726 err:
2728 TALLOC_FREE(result);
2729 return NULL;
2732 /****************************************************************************
2733 External interface.
2734 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2735 ****************************************************************************/
2737 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2738 int pipe_idx,
2739 enum pipe_auth_level auth_level,
2740 const char *domain,
2741 const char *username,
2742 const char *password,
2743 NTSTATUS *perr)
2745 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2746 pipe_idx,
2747 PIPE_AUTH_TYPE_NTLMSSP,
2748 auth_level,
2749 domain,
2750 username,
2751 password,
2752 perr);
2755 /****************************************************************************
2756 External interface.
2757 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2758 ****************************************************************************/
2760 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2761 int pipe_idx,
2762 enum pipe_auth_level auth_level,
2763 const char *domain,
2764 const char *username,
2765 const char *password,
2766 NTSTATUS *perr)
2768 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2769 pipe_idx,
2770 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2771 auth_level,
2772 domain,
2773 username,
2774 password,
2775 perr);
2778 /****************************************************************************
2779 Get a the schannel session key out of an already opened netlogon pipe.
2780 ****************************************************************************/
2781 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2782 struct cli_state *cli,
2783 const char *domain,
2784 uint32 *pneg_flags,
2785 NTSTATUS *perr)
2787 uint32 sec_chan_type = 0;
2788 unsigned char machine_pwd[16];
2789 const char *machine_account;
2791 /* Get the machine account credentials from secrets.tdb. */
2792 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2793 &sec_chan_type))
2795 DEBUG(0, ("get_schannel_session_key: could not fetch "
2796 "trust account password for domain '%s'\n",
2797 domain));
2798 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2799 return false;
2802 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2803 cli->desthost, /* server name */
2804 domain, /* domain */
2805 global_myname(), /* client name */
2806 machine_account, /* machine account name */
2807 machine_pwd,
2808 sec_chan_type,
2809 pneg_flags);
2811 if (!NT_STATUS_IS_OK(*perr)) {
2812 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2813 "failed with result %s to server %s, domain %s, machine account %s.\n",
2814 nt_errstr(*perr), cli->desthost, domain, machine_account ));
2815 return false;
2818 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2819 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2820 cli->desthost));
2821 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2822 return false;
2825 return true;
2828 /****************************************************************************
2829 Open a netlogon pipe and get the schannel session key.
2830 Now exposed to external callers.
2831 ****************************************************************************/
2834 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2835 const char *domain,
2836 uint32 *pneg_flags,
2837 NTSTATUS *perr)
2839 struct rpc_pipe_client *netlogon_pipe = NULL;
2841 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2842 if (!netlogon_pipe) {
2843 return NULL;
2846 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2847 pneg_flags, perr))
2849 TALLOC_FREE(netlogon_pipe);
2850 return NULL;
2853 return netlogon_pipe;
2856 /****************************************************************************
2857 External interface.
2858 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2859 using session_key. sign and seal.
2860 ****************************************************************************/
2862 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2863 int pipe_idx,
2864 enum pipe_auth_level auth_level,
2865 const char *domain,
2866 const struct dcinfo *pdc,
2867 NTSTATUS *perr)
2869 struct rpc_pipe_client *result;
2870 struct cli_pipe_auth_data *auth;
2872 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2873 if (result == NULL) {
2874 return NULL;
2877 *perr = rpccli_schannel_bind_data(result, domain, auth_level,
2878 pdc, &auth);
2879 if (!NT_STATUS_IS_OK(*perr)) {
2880 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2881 nt_errstr(*perr)));
2882 TALLOC_FREE(result);
2883 return NULL;
2886 *perr = rpc_pipe_bind(result, auth);
2887 if (!NT_STATUS_IS_OK(*perr)) {
2888 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2889 nt_errstr(*perr) ));
2890 TALLOC_FREE(result);
2891 return NULL;
2894 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2895 if (result->dc) {
2896 *result->dc = *pdc;
2899 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2900 "for domain %s "
2901 "and bound using schannel.\n",
2902 result->trans.np.pipe_name, cli->desthost, domain ));
2904 return result;
2907 /****************************************************************************
2908 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2909 Fetch the session key ourselves using a temporary netlogon pipe. This
2910 version uses an ntlmssp auth bound netlogon pipe to get the key.
2911 ****************************************************************************/
2913 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2914 const char *domain,
2915 const char *username,
2916 const char *password,
2917 uint32 *pneg_flags,
2918 NTSTATUS *perr)
2920 struct rpc_pipe_client *netlogon_pipe = NULL;
2922 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2923 if (!netlogon_pipe) {
2924 return NULL;
2927 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2928 pneg_flags, perr))
2930 TALLOC_FREE(netlogon_pipe);
2931 return NULL;
2934 return netlogon_pipe;
2937 /****************************************************************************
2938 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2939 Fetch the session key ourselves using a temporary netlogon pipe. This version
2940 uses an ntlmssp bind to get the session key.
2941 ****************************************************************************/
2943 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2944 int pipe_idx,
2945 enum pipe_auth_level auth_level,
2946 const char *domain,
2947 const char *username,
2948 const char *password,
2949 NTSTATUS *perr)
2951 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2952 struct rpc_pipe_client *netlogon_pipe = NULL;
2953 struct rpc_pipe_client *result = NULL;
2955 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2956 password, &neg_flags, perr);
2957 if (!netlogon_pipe) {
2958 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2959 "key from server %s for domain %s.\n",
2960 cli->desthost, domain ));
2961 return NULL;
2964 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2965 auth_level,
2966 domain, netlogon_pipe->dc, perr);
2968 /* Now we've bound using the session key we can close the netlog pipe. */
2969 TALLOC_FREE(netlogon_pipe);
2971 return result;
2974 /****************************************************************************
2975 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2976 Fetch the session key ourselves using a temporary netlogon pipe.
2977 ****************************************************************************/
2979 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2980 int pipe_idx,
2981 enum pipe_auth_level auth_level,
2982 const char *domain,
2983 NTSTATUS *perr)
2985 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2986 struct rpc_pipe_client *netlogon_pipe = NULL;
2987 struct rpc_pipe_client *result = NULL;
2989 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2990 if (!netlogon_pipe) {
2991 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2992 "key from server %s for domain %s.\n",
2993 cli->desthost, domain ));
2994 return NULL;
2997 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2998 auth_level,
2999 domain, netlogon_pipe->dc, perr);
3001 /* Now we've bound using the session key we can close the netlog pipe. */
3002 TALLOC_FREE(netlogon_pipe);
3004 return result;
3007 /****************************************************************************
3008 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3009 The idea is this can be called with service_princ, username and password all
3010 NULL so long as the caller has a TGT.
3011 ****************************************************************************/
3013 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
3014 int pipe_idx,
3015 enum pipe_auth_level auth_level,
3016 const char *service_princ,
3017 const char *username,
3018 const char *password,
3019 NTSTATUS *perr)
3021 #ifdef HAVE_KRB5
3022 struct rpc_pipe_client *result;
3023 struct cli_pipe_auth_data *auth;
3025 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3026 if (result == NULL) {
3027 return NULL;
3030 *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3031 username, password, &auth);
3032 if (!NT_STATUS_IS_OK(*perr)) {
3033 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3034 nt_errstr(*perr)));
3035 TALLOC_FREE(result);
3036 return NULL;
3039 *perr = rpc_pipe_bind(result, auth);
3040 if (!NT_STATUS_IS_OK(*perr)) {
3041 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
3042 nt_errstr(*perr) ));
3043 TALLOC_FREE(result);
3044 return NULL;
3047 return result;
3048 #else
3049 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3050 return NULL;
3051 #endif