Rename rpc_pipe_client.tcp.sock to rpc_pipe_client.sock.fd
[Samba/gbeck.git] / source / rpc_client / cli_pipe.c
blobb415a39a51bb3000d8231a6b294cd8fd84dbfc1f
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 = 0;
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.sock.fd, 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.sock.fd, 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 return NT_STATUS_NO_MEMORY;
845 nread = sys_read(cli->trans.sock.fd, prdata, 1);
846 if (nread == 0) {
847 SAFE_FREE(prdata);
849 if (nread == -1) {
850 ret = NT_STATUS_END_OF_FILE;
851 goto err;
853 rdata_len = nread;
854 break;
856 default:
857 DEBUG(0, ("unknown transport type %d\n",
858 cli->transport_type));
859 return NT_STATUS_INTERNAL_ERROR;
862 /* Throw away returned params - we know we won't use them. */
864 SAFE_FREE(rparam);
866 if (prdata == NULL) {
867 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
868 rpccli_pipe_txt(debug_ctx(), cli)));
869 /* Yes - some calls can truely return no data... */
870 prs_mem_free(&current_pdu);
871 return NT_STATUS_OK;
875 * Give this memory as dynamic to the current pdu.
878 prs_give_memory(&current_pdu, prdata, rdata_len, True);
880 /* Ensure we can mess with the return prs_struct. */
881 SMB_ASSERT(UNMARSHALLING(rbuf));
882 SMB_ASSERT(prs_data_size(rbuf) == 0);
884 /* Make rbuf dynamic with no memory. */
885 prs_give_memory(rbuf, 0, 0, True);
887 while(1) {
888 RPC_HDR rhdr;
889 char *ret_data;
890 uint32 ret_data_len;
892 /* Ensure we have enough data for a pdu. */
893 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
894 if (!NT_STATUS_IS_OK(ret)) {
895 goto err;
898 /* We pass in rbuf here so if the alloc hint is set correctly
899 we can set the output size and avoid reallocs. */
901 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
902 &ret_data, &ret_data_len, rbuf);
904 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
905 prs_data_size(&current_pdu), current_rbuf_offset ));
907 if (!NT_STATUS_IS_OK(ret)) {
908 goto err;
911 if ((rhdr.flags & RPC_FLG_FIRST)) {
912 if (rhdr.pack_type[0] == 0) {
913 /* Set the data type correctly for big-endian data on the first packet. */
914 DEBUG(10,("rpc_api_pipe: On %s "
915 "PDU data format is big-endian.\n",
916 rpccli_pipe_txt(debug_ctx(), cli)));
918 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
919 } else {
920 /* Check endianness on subsequent packets. */
921 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
922 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
923 rbuf->bigendian_data ? "big" : "little",
924 current_pdu.bigendian_data ? "big" : "little" ));
925 ret = NT_STATUS_INVALID_PARAMETER;
926 goto err;
931 /* Now copy the data portion out of the pdu into rbuf. */
932 if (!prs_force_grow(rbuf, ret_data_len)) {
933 ret = NT_STATUS_NO_MEMORY;
934 goto err;
936 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
937 current_rbuf_offset += ret_data_len;
939 /* See if we've finished with all the data in current_pdu yet ? */
940 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
941 if (!NT_STATUS_IS_OK(ret)) {
942 goto err;
945 if (rhdr.flags & RPC_FLG_LAST) {
946 break; /* We're done. */
950 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
951 rpccli_pipe_txt(debug_ctx(), cli),
952 (unsigned int)prs_data_size(rbuf) ));
954 prs_mem_free(&current_pdu);
955 return NT_STATUS_OK;
957 err:
959 prs_mem_free(&current_pdu);
960 prs_mem_free(rbuf);
961 return ret;
964 /*******************************************************************
965 Creates krb5 auth bind.
966 ********************************************************************/
968 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
969 enum pipe_auth_level auth_level,
970 RPC_HDR_AUTH *pauth_out,
971 prs_struct *auth_data)
973 #ifdef HAVE_KRB5
974 int ret;
975 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
976 DATA_BLOB tkt = data_blob_null;
977 DATA_BLOB tkt_wrapped = data_blob_null;
979 /* We may change the pad length before marshalling. */
980 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
982 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
983 a->service_principal ));
985 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
987 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
988 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
990 if (ret) {
991 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
992 "failed with %s\n",
993 a->service_principal,
994 error_message(ret) ));
996 data_blob_free(&tkt);
997 prs_mem_free(auth_data);
998 return NT_STATUS_INVALID_PARAMETER;
1001 /* wrap that up in a nice GSS-API wrapping */
1002 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1004 data_blob_free(&tkt);
1006 /* Auth len in the rpc header doesn't include auth_header. */
1007 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1008 data_blob_free(&tkt_wrapped);
1009 prs_mem_free(auth_data);
1010 return NT_STATUS_NO_MEMORY;
1013 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1014 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1016 data_blob_free(&tkt_wrapped);
1017 return NT_STATUS_OK;
1018 #else
1019 return NT_STATUS_INVALID_PARAMETER;
1020 #endif
1023 /*******************************************************************
1024 Creates SPNEGO NTLMSSP auth bind.
1025 ********************************************************************/
1027 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1028 enum pipe_auth_level auth_level,
1029 RPC_HDR_AUTH *pauth_out,
1030 prs_struct *auth_data)
1032 NTSTATUS nt_status;
1033 DATA_BLOB null_blob = data_blob_null;
1034 DATA_BLOB request = data_blob_null;
1035 DATA_BLOB spnego_msg = data_blob_null;
1037 /* We may change the pad length before marshalling. */
1038 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1040 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1041 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1042 null_blob,
1043 &request);
1045 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1046 data_blob_free(&request);
1047 prs_mem_free(auth_data);
1048 return nt_status;
1051 /* Wrap this in SPNEGO. */
1052 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1054 data_blob_free(&request);
1056 /* Auth len in the rpc header doesn't include auth_header. */
1057 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1058 data_blob_free(&spnego_msg);
1059 prs_mem_free(auth_data);
1060 return NT_STATUS_NO_MEMORY;
1063 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1064 dump_data(5, spnego_msg.data, spnego_msg.length);
1066 data_blob_free(&spnego_msg);
1067 return NT_STATUS_OK;
1070 /*******************************************************************
1071 Creates NTLMSSP auth bind.
1072 ********************************************************************/
1074 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1075 enum pipe_auth_level auth_level,
1076 RPC_HDR_AUTH *pauth_out,
1077 prs_struct *auth_data)
1079 NTSTATUS nt_status;
1080 DATA_BLOB null_blob = data_blob_null;
1081 DATA_BLOB request = data_blob_null;
1083 /* We may change the pad length before marshalling. */
1084 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1086 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1087 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1088 null_blob,
1089 &request);
1091 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1092 data_blob_free(&request);
1093 prs_mem_free(auth_data);
1094 return nt_status;
1097 /* Auth len in the rpc header doesn't include auth_header. */
1098 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1099 data_blob_free(&request);
1100 prs_mem_free(auth_data);
1101 return NT_STATUS_NO_MEMORY;
1104 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1105 dump_data(5, request.data, request.length);
1107 data_blob_free(&request);
1108 return NT_STATUS_OK;
1111 /*******************************************************************
1112 Creates schannel auth bind.
1113 ********************************************************************/
1115 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1116 enum pipe_auth_level auth_level,
1117 RPC_HDR_AUTH *pauth_out,
1118 prs_struct *auth_data)
1120 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1122 /* We may change the pad length before marshalling. */
1123 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1125 /* Use lp_workgroup() if domain not specified */
1127 if (!cli->auth->domain || !cli->auth->domain[0]) {
1128 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1129 if (cli->auth->domain == NULL) {
1130 return NT_STATUS_NO_MEMORY;
1134 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1135 global_myname());
1138 * Now marshall the data into the auth parse_struct.
1141 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1142 &schannel_neg, auth_data, 0)) {
1143 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1144 prs_mem_free(auth_data);
1145 return NT_STATUS_NO_MEMORY;
1148 return NT_STATUS_OK;
1151 /*******************************************************************
1152 Creates the internals of a DCE/RPC bind request or alter context PDU.
1153 ********************************************************************/
1155 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1156 prs_struct *rpc_out,
1157 uint32 rpc_call_id,
1158 const RPC_IFACE *abstract,
1159 const RPC_IFACE *transfer,
1160 RPC_HDR_AUTH *phdr_auth,
1161 prs_struct *pauth_info)
1163 RPC_HDR hdr;
1164 RPC_HDR_RB hdr_rb;
1165 RPC_CONTEXT rpc_ctx;
1166 uint16 auth_len = prs_offset(pauth_info);
1167 uint8 ss_padding_len = 0;
1168 uint16 frag_len = 0;
1170 /* create the RPC context. */
1171 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1173 /* create the bind request RPC_HDR_RB */
1174 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1176 /* Start building the frag length. */
1177 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1179 /* Do we need to pad ? */
1180 if (auth_len) {
1181 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1182 if (data_len % 8) {
1183 ss_padding_len = 8 - (data_len % 8);
1184 phdr_auth->auth_pad_len = ss_padding_len;
1186 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1189 /* Create the request RPC_HDR */
1190 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1192 /* Marshall the RPC header */
1193 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1194 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1195 return NT_STATUS_NO_MEMORY;
1198 /* Marshall the bind request data */
1199 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1200 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1201 return NT_STATUS_NO_MEMORY;
1205 * Grow the outgoing buffer to store any auth info.
1208 if(auth_len != 0) {
1209 if (ss_padding_len) {
1210 char pad[8];
1211 memset(pad, '\0', 8);
1212 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1213 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1214 return NT_STATUS_NO_MEMORY;
1218 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1219 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1220 return NT_STATUS_NO_MEMORY;
1224 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1225 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1226 return NT_STATUS_NO_MEMORY;
1230 return NT_STATUS_OK;
1233 /*******************************************************************
1234 Creates a DCE/RPC bind request.
1235 ********************************************************************/
1237 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1238 prs_struct *rpc_out,
1239 uint32 rpc_call_id,
1240 const RPC_IFACE *abstract,
1241 const RPC_IFACE *transfer,
1242 enum pipe_auth_type auth_type,
1243 enum pipe_auth_level auth_level)
1245 RPC_HDR_AUTH hdr_auth;
1246 prs_struct auth_info;
1247 NTSTATUS ret = NT_STATUS_OK;
1249 ZERO_STRUCT(hdr_auth);
1250 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1251 return NT_STATUS_NO_MEMORY;
1253 switch (auth_type) {
1254 case PIPE_AUTH_TYPE_SCHANNEL:
1255 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1256 if (!NT_STATUS_IS_OK(ret)) {
1257 prs_mem_free(&auth_info);
1258 return ret;
1260 break;
1262 case PIPE_AUTH_TYPE_NTLMSSP:
1263 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1264 if (!NT_STATUS_IS_OK(ret)) {
1265 prs_mem_free(&auth_info);
1266 return ret;
1268 break;
1270 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1271 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1272 if (!NT_STATUS_IS_OK(ret)) {
1273 prs_mem_free(&auth_info);
1274 return ret;
1276 break;
1278 case PIPE_AUTH_TYPE_KRB5:
1279 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1280 if (!NT_STATUS_IS_OK(ret)) {
1281 prs_mem_free(&auth_info);
1282 return ret;
1284 break;
1286 case PIPE_AUTH_TYPE_NONE:
1287 break;
1289 default:
1290 /* "Can't" happen. */
1291 return NT_STATUS_INVALID_INFO_CLASS;
1294 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1295 rpc_out,
1296 rpc_call_id,
1297 abstract,
1298 transfer,
1299 &hdr_auth,
1300 &auth_info);
1302 prs_mem_free(&auth_info);
1303 return ret;
1306 /*******************************************************************
1307 Create and add the NTLMSSP sign/seal auth header and data.
1308 ********************************************************************/
1310 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1311 RPC_HDR *phdr,
1312 uint32 ss_padding_len,
1313 prs_struct *outgoing_pdu)
1315 RPC_HDR_AUTH auth_info;
1316 NTSTATUS status;
1317 DATA_BLOB auth_blob = data_blob_null;
1318 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1320 if (!cli->auth->a_u.ntlmssp_state) {
1321 return NT_STATUS_INVALID_PARAMETER;
1324 /* Init and marshall the auth header. */
1325 init_rpc_hdr_auth(&auth_info,
1326 map_pipe_auth_type_to_rpc_auth_type(
1327 cli->auth->auth_type),
1328 cli->auth->auth_level,
1329 ss_padding_len,
1330 1 /* context id. */);
1332 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1333 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1334 data_blob_free(&auth_blob);
1335 return NT_STATUS_NO_MEMORY;
1338 switch (cli->auth->auth_level) {
1339 case PIPE_AUTH_LEVEL_PRIVACY:
1340 /* Data portion is encrypted. */
1341 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1342 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1343 data_and_pad_len,
1344 (unsigned char *)prs_data_p(outgoing_pdu),
1345 (size_t)prs_offset(outgoing_pdu),
1346 &auth_blob);
1347 if (!NT_STATUS_IS_OK(status)) {
1348 data_blob_free(&auth_blob);
1349 return status;
1351 break;
1353 case PIPE_AUTH_LEVEL_INTEGRITY:
1354 /* Data is signed. */
1355 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1356 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1357 data_and_pad_len,
1358 (unsigned char *)prs_data_p(outgoing_pdu),
1359 (size_t)prs_offset(outgoing_pdu),
1360 &auth_blob);
1361 if (!NT_STATUS_IS_OK(status)) {
1362 data_blob_free(&auth_blob);
1363 return status;
1365 break;
1367 default:
1368 /* Can't happen. */
1369 smb_panic("bad auth level");
1370 /* Notreached. */
1371 return NT_STATUS_INVALID_PARAMETER;
1374 /* Finally marshall the blob. */
1376 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1377 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1378 (unsigned int)NTLMSSP_SIG_SIZE));
1379 data_blob_free(&auth_blob);
1380 return NT_STATUS_NO_MEMORY;
1383 data_blob_free(&auth_blob);
1384 return NT_STATUS_OK;
1387 /*******************************************************************
1388 Create and add the schannel sign/seal auth header and data.
1389 ********************************************************************/
1391 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1392 RPC_HDR *phdr,
1393 uint32 ss_padding_len,
1394 prs_struct *outgoing_pdu)
1396 RPC_HDR_AUTH auth_info;
1397 RPC_AUTH_SCHANNEL_CHK verf;
1398 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1399 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1400 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1402 if (!sas) {
1403 return NT_STATUS_INVALID_PARAMETER;
1406 /* Init and marshall the auth header. */
1407 init_rpc_hdr_auth(&auth_info,
1408 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1409 cli->auth->auth_level,
1410 ss_padding_len,
1411 1 /* context id. */);
1413 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1414 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1415 return NT_STATUS_NO_MEMORY;
1418 switch (cli->auth->auth_level) {
1419 case PIPE_AUTH_LEVEL_PRIVACY:
1420 case PIPE_AUTH_LEVEL_INTEGRITY:
1421 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1422 sas->seq_num));
1424 schannel_encode(sas,
1425 cli->auth->auth_level,
1426 SENDER_IS_INITIATOR,
1427 &verf,
1428 data_p,
1429 data_and_pad_len);
1431 sas->seq_num++;
1432 break;
1434 default:
1435 /* Can't happen. */
1436 smb_panic("bad auth level");
1437 /* Notreached. */
1438 return NT_STATUS_INVALID_PARAMETER;
1441 /* Finally marshall the blob. */
1442 smb_io_rpc_auth_schannel_chk("",
1443 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1444 &verf,
1445 outgoing_pdu,
1448 return NT_STATUS_OK;
1451 /*******************************************************************
1452 Calculate how much data we're going to send in this packet, also
1453 work out any sign/seal padding length.
1454 ********************************************************************/
1456 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1457 uint32 data_left,
1458 uint16 *p_frag_len,
1459 uint16 *p_auth_len,
1460 uint32 *p_ss_padding)
1462 uint32 data_space, data_len;
1464 switch (cli->auth->auth_level) {
1465 case PIPE_AUTH_LEVEL_NONE:
1466 case PIPE_AUTH_LEVEL_CONNECT:
1467 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1468 data_len = MIN(data_space, data_left);
1469 *p_ss_padding = 0;
1470 *p_auth_len = 0;
1471 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1472 return data_len;
1474 case PIPE_AUTH_LEVEL_INTEGRITY:
1475 case PIPE_AUTH_LEVEL_PRIVACY:
1476 /* Treat the same for all authenticated rpc requests. */
1477 switch(cli->auth->auth_type) {
1478 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1479 case PIPE_AUTH_TYPE_NTLMSSP:
1480 *p_auth_len = NTLMSSP_SIG_SIZE;
1481 break;
1482 case PIPE_AUTH_TYPE_SCHANNEL:
1483 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1484 break;
1485 default:
1486 smb_panic("bad auth type");
1487 break;
1490 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1491 RPC_HDR_AUTH_LEN - *p_auth_len;
1493 data_len = MIN(data_space, data_left);
1494 if (data_len % 8) {
1495 *p_ss_padding = 8 - (data_len % 8);
1497 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1498 data_len + *p_ss_padding + /* data plus padding. */
1499 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1500 return data_len;
1502 default:
1503 smb_panic("bad auth level");
1504 /* Notreached. */
1505 return 0;
1509 /*******************************************************************
1510 External interface.
1511 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1512 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1513 and deals with signing/sealing details.
1514 ********************************************************************/
1516 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1517 uint8 op_num,
1518 prs_struct *in_data,
1519 prs_struct *out_data)
1521 NTSTATUS ret;
1522 uint32 data_left = prs_offset(in_data);
1523 uint32 alloc_hint = prs_offset(in_data);
1524 uint32 data_sent_thistime = 0;
1525 uint32 current_data_offset = 0;
1526 uint32 call_id = get_rpc_call_id();
1527 char pad[8];
1528 prs_struct outgoing_pdu;
1530 memset(pad, '\0', 8);
1532 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1533 /* Server is screwed up ! */
1534 return NT_STATUS_INVALID_PARAMETER;
1537 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1538 return NT_STATUS_NO_MEMORY;
1540 while (1) {
1541 RPC_HDR hdr;
1542 RPC_HDR_REQ hdr_req;
1543 uint16 auth_len = 0;
1544 uint16 frag_len = 0;
1545 uint8 flags = 0;
1546 uint32 ss_padding = 0;
1548 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1549 &frag_len, &auth_len, &ss_padding);
1551 if (current_data_offset == 0) {
1552 flags = RPC_FLG_FIRST;
1555 if (data_sent_thistime == data_left) {
1556 flags |= RPC_FLG_LAST;
1559 /* Create and marshall the header and request header. */
1560 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1562 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1563 prs_mem_free(&outgoing_pdu);
1564 return NT_STATUS_NO_MEMORY;
1567 /* Create the rpc request RPC_HDR_REQ */
1568 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1570 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1571 prs_mem_free(&outgoing_pdu);
1572 return NT_STATUS_NO_MEMORY;
1575 /* Copy in the data, plus any ss padding. */
1576 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1577 prs_mem_free(&outgoing_pdu);
1578 return NT_STATUS_NO_MEMORY;
1581 /* Copy the sign/seal padding data. */
1582 if (ss_padding) {
1583 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1584 prs_mem_free(&outgoing_pdu);
1585 return NT_STATUS_NO_MEMORY;
1589 /* Generate any auth sign/seal and add the auth footer. */
1590 if (auth_len) {
1591 switch (cli->auth->auth_type) {
1592 case PIPE_AUTH_TYPE_NONE:
1593 break;
1594 case PIPE_AUTH_TYPE_NTLMSSP:
1595 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1596 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1597 if (!NT_STATUS_IS_OK(ret)) {
1598 prs_mem_free(&outgoing_pdu);
1599 return ret;
1601 break;
1602 case PIPE_AUTH_TYPE_SCHANNEL:
1603 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1604 if (!NT_STATUS_IS_OK(ret)) {
1605 prs_mem_free(&outgoing_pdu);
1606 return ret;
1608 break;
1609 default:
1610 smb_panic("bad auth type");
1611 break; /* notreached */
1615 /* Actually send the packet. */
1616 if (flags & RPC_FLG_LAST) {
1617 /* Last packet - send the data, get the reply and return. */
1618 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1619 prs_mem_free(&outgoing_pdu);
1621 if ((DEBUGLEVEL >= 50)
1622 && (cli->transport_type == NCACN_NP)) {
1623 char *dump_name = NULL;
1624 /* Also capture received data */
1625 if (asprintf(&dump_name, "%s/reply_%s_%d",
1626 get_dyn_LOGFILEBASE(),
1627 cli->trans.np.pipe_name, op_num) > 0) {
1628 prs_dump(dump_name, op_num, out_data);
1629 SAFE_FREE(dump_name);
1633 return ret;
1634 } else {
1635 /* More packets to come - write and continue. */
1636 ssize_t num_written;
1638 switch (cli->transport_type) {
1639 case NCACN_NP:
1640 num_written = cli_write(cli->trans.np.cli,
1641 cli->trans.np.fnum,
1642 8, /* 8 means message mode. */
1643 prs_data_p(&outgoing_pdu),
1644 (off_t)0,
1645 (size_t)hdr.frag_len);
1647 if (num_written != hdr.frag_len) {
1648 prs_mem_free(&outgoing_pdu);
1649 return cli_get_nt_error(
1650 cli->trans.np.cli);
1652 break;
1653 case NCACN_IP_TCP:
1654 num_written = write_data(
1655 cli->trans.sock.fd,
1656 prs_data_p(&outgoing_pdu),
1657 (size_t)hdr.frag_len);
1658 if (num_written != hdr.frag_len) {
1659 NTSTATUS status;
1660 status = map_nt_error_from_unix(errno);
1661 prs_mem_free(&outgoing_pdu);
1662 return status;
1664 break;
1665 default:
1666 DEBUG(0, ("unknown transport type %d\n",
1667 cli->transport_type));
1668 return NT_STATUS_INTERNAL_ERROR;
1672 current_data_offset += data_sent_thistime;
1673 data_left -= data_sent_thistime;
1675 /* Reset the marshalling position back to zero. */
1676 if (!prs_set_offset(&outgoing_pdu, 0)) {
1677 prs_mem_free(&outgoing_pdu);
1678 return NT_STATUS_NO_MEMORY;
1682 #if 0
1683 /****************************************************************************
1684 Set the handle state.
1685 ****************************************************************************/
1687 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1688 const char *pipe_name, uint16 device_state)
1690 bool state_set = False;
1691 char param[2];
1692 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1693 char *rparam = NULL;
1694 char *rdata = NULL;
1695 uint32 rparam_len, rdata_len;
1697 if (pipe_name == NULL)
1698 return False;
1700 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1701 cli->fnum, pipe_name, device_state));
1703 /* create parameters: device state */
1704 SSVAL(param, 0, device_state);
1706 /* create setup parameters. */
1707 setup[0] = 0x0001;
1708 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1710 /* send the data on \PIPE\ */
1711 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1712 setup, 2, 0, /* setup, length, max */
1713 param, 2, 0, /* param, length, max */
1714 NULL, 0, 1024, /* data, length, max */
1715 &rparam, &rparam_len, /* return param, length */
1716 &rdata, &rdata_len)) /* return data, length */
1718 DEBUG(5, ("Set Handle state: return OK\n"));
1719 state_set = True;
1722 SAFE_FREE(rparam);
1723 SAFE_FREE(rdata);
1725 return state_set;
1727 #endif
1729 /****************************************************************************
1730 Check the rpc bind acknowledge response.
1731 ****************************************************************************/
1733 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1735 if ( hdr_ba->addr.len == 0) {
1736 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1739 /* check the transfer syntax */
1740 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1741 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1742 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1743 return False;
1746 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1747 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1748 hdr_ba->res.num_results, hdr_ba->res.reason));
1751 DEBUG(5,("check_bind_response: accepted!\n"));
1752 return True;
1755 /*******************************************************************
1756 Creates a DCE/RPC bind authentication response.
1757 This is the packet that is sent back to the server once we
1758 have received a BIND-ACK, to finish the third leg of
1759 the authentication handshake.
1760 ********************************************************************/
1762 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1763 uint32 rpc_call_id,
1764 enum pipe_auth_type auth_type,
1765 enum pipe_auth_level auth_level,
1766 DATA_BLOB *pauth_blob,
1767 prs_struct *rpc_out)
1769 RPC_HDR hdr;
1770 RPC_HDR_AUTH hdr_auth;
1771 uint32 pad = 0;
1773 /* Create the request RPC_HDR */
1774 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1775 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1776 pauth_blob->length );
1778 /* Marshall it. */
1779 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1780 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1781 return NT_STATUS_NO_MEMORY;
1785 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1786 about padding - shouldn't this pad to length 8 ? JRA.
1789 /* 4 bytes padding. */
1790 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1791 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1792 return NT_STATUS_NO_MEMORY;
1795 /* Create the request RPC_HDR_AUTHA */
1796 init_rpc_hdr_auth(&hdr_auth,
1797 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1798 auth_level, 0, 1);
1800 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1801 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1802 return NT_STATUS_NO_MEMORY;
1806 * Append the auth data to the outgoing buffer.
1809 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1810 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1811 return NT_STATUS_NO_MEMORY;
1814 return NT_STATUS_OK;
1817 /****************************************************************************
1818 Create and send the third packet in an RPC auth.
1819 ****************************************************************************/
1821 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1822 RPC_HDR *phdr,
1823 prs_struct *rbuf,
1824 uint32 rpc_call_id,
1825 enum pipe_auth_type auth_type,
1826 enum pipe_auth_level auth_level)
1828 DATA_BLOB server_response = data_blob_null;
1829 DATA_BLOB client_reply = data_blob_null;
1830 RPC_HDR_AUTH hdr_auth;
1831 NTSTATUS nt_status;
1832 prs_struct rpc_out;
1833 ssize_t ret;
1835 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1836 return NT_STATUS_INVALID_PARAMETER;
1839 /* Process the returned NTLMSSP blob first. */
1840 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1841 return NT_STATUS_INVALID_PARAMETER;
1844 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1845 return NT_STATUS_INVALID_PARAMETER;
1848 /* TODO - check auth_type/auth_level match. */
1850 server_response = data_blob(NULL, phdr->auth_len);
1851 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1853 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1854 server_response,
1855 &client_reply);
1857 if (!NT_STATUS_IS_OK(nt_status)) {
1858 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1859 data_blob_free(&server_response);
1860 return nt_status;
1863 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1865 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1866 auth_type, auth_level,
1867 &client_reply, &rpc_out);
1869 if (!NT_STATUS_IS_OK(nt_status)) {
1870 prs_mem_free(&rpc_out);
1871 data_blob_free(&client_reply);
1872 data_blob_free(&server_response);
1873 return nt_status;
1876 switch (cli->transport_type) {
1877 case NCACN_NP:
1878 /* 8 here is named pipe message mode. */
1879 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
1880 0x8, prs_data_p(&rpc_out), 0,
1881 (size_t)prs_offset(&rpc_out));
1882 break;
1884 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1885 nt_status = cli_get_nt_error(cli->trans.np.cli);
1887 case NCACN_IP_TCP:
1888 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
1889 (size_t)prs_offset(&rpc_out));
1890 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1891 nt_status = map_nt_error_from_unix(errno);
1893 break;
1894 default:
1895 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
1896 return NT_STATUS_INTERNAL_ERROR;
1899 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1900 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
1901 nt_errstr(nt_status)));
1902 prs_mem_free(&rpc_out);
1903 data_blob_free(&client_reply);
1904 data_blob_free(&server_response);
1905 return nt_status;
1908 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
1909 rpccli_pipe_txt(debug_ctx(), cli)));
1911 prs_mem_free(&rpc_out);
1912 data_blob_free(&client_reply);
1913 data_blob_free(&server_response);
1914 return NT_STATUS_OK;
1917 /*******************************************************************
1918 Creates a DCE/RPC bind alter context authentication request which
1919 may contain a spnego auth blobl
1920 ********************************************************************/
1922 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1923 const RPC_IFACE *abstract,
1924 const RPC_IFACE *transfer,
1925 enum pipe_auth_level auth_level,
1926 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1927 prs_struct *rpc_out)
1929 RPC_HDR_AUTH hdr_auth;
1930 prs_struct auth_info;
1931 NTSTATUS ret = NT_STATUS_OK;
1933 ZERO_STRUCT(hdr_auth);
1934 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1935 return NT_STATUS_NO_MEMORY;
1937 /* We may change the pad length before marshalling. */
1938 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1940 if (pauth_blob->length) {
1941 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1942 prs_mem_free(&auth_info);
1943 return NT_STATUS_NO_MEMORY;
1947 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1948 rpc_out,
1949 rpc_call_id,
1950 abstract,
1951 transfer,
1952 &hdr_auth,
1953 &auth_info);
1954 prs_mem_free(&auth_info);
1955 return ret;
1958 /*******************************************************************
1959 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1960 and gets a response.
1961 ********************************************************************/
1963 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1964 RPC_HDR *phdr,
1965 prs_struct *rbuf,
1966 uint32 rpc_call_id,
1967 const RPC_IFACE *abstract,
1968 const RPC_IFACE *transfer,
1969 enum pipe_auth_type auth_type,
1970 enum pipe_auth_level auth_level)
1972 DATA_BLOB server_spnego_response = data_blob_null;
1973 DATA_BLOB server_ntlm_response = data_blob_null;
1974 DATA_BLOB client_reply = data_blob_null;
1975 DATA_BLOB tmp_blob = data_blob_null;
1976 RPC_HDR_AUTH hdr_auth;
1977 NTSTATUS nt_status;
1978 prs_struct rpc_out;
1980 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1981 return NT_STATUS_INVALID_PARAMETER;
1984 /* Process the returned NTLMSSP blob first. */
1985 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1986 return NT_STATUS_INVALID_PARAMETER;
1989 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1990 return NT_STATUS_INVALID_PARAMETER;
1993 server_spnego_response = data_blob(NULL, phdr->auth_len);
1994 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1996 /* The server might give us back two challenges - tmp_blob is for the second. */
1997 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
1998 data_blob_free(&server_spnego_response);
1999 data_blob_free(&server_ntlm_response);
2000 data_blob_free(&tmp_blob);
2001 return NT_STATUS_INVALID_PARAMETER;
2004 /* We're finished with the server spnego response and the tmp_blob. */
2005 data_blob_free(&server_spnego_response);
2006 data_blob_free(&tmp_blob);
2008 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2009 server_ntlm_response,
2010 &client_reply);
2012 /* Finished with the server_ntlm response */
2013 data_blob_free(&server_ntlm_response);
2015 if (!NT_STATUS_IS_OK(nt_status)) {
2016 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2017 data_blob_free(&client_reply);
2018 return nt_status;
2021 /* SPNEGO wrap the client reply. */
2022 tmp_blob = spnego_gen_auth(client_reply);
2023 data_blob_free(&client_reply);
2024 client_reply = tmp_blob;
2025 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2027 /* Now prepare the alter context pdu. */
2028 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2030 nt_status = create_rpc_alter_context(rpc_call_id,
2031 abstract,
2032 transfer,
2033 auth_level,
2034 &client_reply,
2035 &rpc_out);
2037 data_blob_free(&client_reply);
2039 if (!NT_STATUS_IS_OK(nt_status)) {
2040 prs_mem_free(&rpc_out);
2041 return nt_status;
2044 /* Initialize the returning data struct. */
2045 prs_mem_free(rbuf);
2046 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2048 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2049 if (!NT_STATUS_IS_OK(nt_status)) {
2050 prs_mem_free(&rpc_out);
2051 return nt_status;
2054 prs_mem_free(&rpc_out);
2056 /* Get the auth blob from the reply. */
2057 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2058 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2059 return NT_STATUS_BUFFER_TOO_SMALL;
2062 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2063 return NT_STATUS_INVALID_PARAMETER;
2066 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2067 return NT_STATUS_INVALID_PARAMETER;
2070 server_spnego_response = data_blob(NULL, phdr->auth_len);
2071 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2073 /* Check we got a valid auth response. */
2074 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2075 data_blob_free(&server_spnego_response);
2076 data_blob_free(&tmp_blob);
2077 return NT_STATUS_INVALID_PARAMETER;
2080 data_blob_free(&server_spnego_response);
2081 data_blob_free(&tmp_blob);
2083 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2084 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2086 return NT_STATUS_OK;
2089 /****************************************************************************
2090 Do an rpc bind.
2091 ****************************************************************************/
2093 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2094 struct cli_pipe_auth_data *auth)
2096 RPC_HDR hdr;
2097 RPC_HDR_BA hdr_ba;
2098 prs_struct rpc_out;
2099 prs_struct rbuf;
2100 uint32 rpc_call_id;
2101 NTSTATUS status;
2103 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2104 rpccli_pipe_txt(debug_ctx(), cli),
2105 (unsigned int)auth->auth_type,
2106 (unsigned int)auth->auth_level ));
2108 cli->auth = talloc_move(cli, &auth);
2110 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2112 rpc_call_id = get_rpc_call_id();
2114 /* Marshall the outgoing data. */
2115 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2116 cli->abstract_syntax,
2117 cli->transfer_syntax,
2118 cli->auth->auth_type,
2119 cli->auth->auth_level);
2121 if (!NT_STATUS_IS_OK(status)) {
2122 prs_mem_free(&rpc_out);
2123 return status;
2126 /* Initialize the incoming data struct. */
2127 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2129 /* send data on \PIPE\. receive a response */
2130 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2131 if (!NT_STATUS_IS_OK(status)) {
2132 prs_mem_free(&rpc_out);
2133 return status;
2136 prs_mem_free(&rpc_out);
2138 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2139 rpccli_pipe_txt(debug_ctx(), cli)));
2141 /* Unmarshall the RPC header */
2142 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2143 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2144 prs_mem_free(&rbuf);
2145 return NT_STATUS_BUFFER_TOO_SMALL;
2148 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2149 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2150 prs_mem_free(&rbuf);
2151 return NT_STATUS_BUFFER_TOO_SMALL;
2154 if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2155 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2156 prs_mem_free(&rbuf);
2157 return NT_STATUS_BUFFER_TOO_SMALL;
2160 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2161 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2163 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2164 switch(cli->auth->auth_type) {
2166 case PIPE_AUTH_TYPE_NONE:
2167 case PIPE_AUTH_TYPE_SCHANNEL:
2168 /* Bind complete. */
2169 break;
2171 case PIPE_AUTH_TYPE_NTLMSSP:
2172 /* Need to send AUTH3 packet - no reply. */
2173 status = rpc_finish_auth3_bind(
2174 cli, &hdr, &rbuf, rpc_call_id,
2175 cli->auth->auth_type,
2176 cli->auth->auth_level);
2177 if (!NT_STATUS_IS_OK(status)) {
2178 prs_mem_free(&rbuf);
2179 return status;
2181 break;
2183 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2184 /* Need to send alter context request and reply. */
2185 status = rpc_finish_spnego_ntlmssp_bind(
2186 cli, &hdr, &rbuf, rpc_call_id,
2187 cli->abstract_syntax, cli->transfer_syntax,
2188 cli->auth->auth_type, cli->auth->auth_level);
2189 if (!NT_STATUS_IS_OK(status)) {
2190 prs_mem_free(&rbuf);
2191 return status;
2193 break;
2195 case PIPE_AUTH_TYPE_KRB5:
2196 /* */
2198 default:
2199 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2200 "%u\n", (unsigned int)cli->auth->auth_type));
2201 prs_mem_free(&rbuf);
2202 return NT_STATUS_INVALID_INFO_CLASS;
2205 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2206 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2207 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2208 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2209 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2210 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2211 prs_mem_free(&rbuf);
2212 return NT_STATUS_INVALID_PARAMETER;
2215 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2216 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2217 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2218 prs_mem_free(&rbuf);
2219 return NT_STATUS_INVALID_PARAMETER;
2224 prs_mem_free(&rbuf);
2225 return NT_STATUS_OK;
2228 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2229 unsigned int timeout)
2231 return cli_set_timeout(cli->trans.np.cli, timeout);
2234 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2236 return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
2239 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2241 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2242 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2243 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2244 return true;
2247 if (cli->transport_type == NCACN_NP) {
2248 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2249 return true;
2252 return false;
2255 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2257 if (p->transport_type == NCACN_NP) {
2258 return p->trans.np.cli;
2260 return NULL;
2263 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2265 if (p->transport_type == NCACN_NP) {
2266 bool ret;
2267 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2268 if (!ret) {
2269 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2270 "pipe %s. Error was %s\n",
2271 rpccli_pipe_txt(debug_ctx(), p),
2272 cli_errstr(p->trans.np.cli)));
2275 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2276 rpccli_pipe_txt(debug_ctx(), p)));
2278 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2279 return ret ? -1 : 0;
2282 return -1;
2285 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2286 struct cli_pipe_auth_data **presult)
2288 struct cli_pipe_auth_data *result;
2290 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2291 if (result == NULL) {
2292 return NT_STATUS_NO_MEMORY;
2295 result->auth_type = PIPE_AUTH_TYPE_NONE;
2296 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2298 result->user_name = talloc_strdup(result, "");
2299 result->domain = talloc_strdup(result, "");
2300 if ((result->user_name == NULL) || (result->domain == NULL)) {
2301 TALLOC_FREE(result);
2302 return NT_STATUS_NO_MEMORY;
2305 *presult = result;
2306 return NT_STATUS_OK;
2309 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2311 ntlmssp_end(&auth->a_u.ntlmssp_state);
2312 return 0;
2315 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2316 enum pipe_auth_type auth_type,
2317 enum pipe_auth_level auth_level,
2318 const char *domain,
2319 const char *username,
2320 const char *password,
2321 struct cli_pipe_auth_data **presult)
2323 struct cli_pipe_auth_data *result;
2324 NTSTATUS status;
2326 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2327 if (result == NULL) {
2328 return NT_STATUS_NO_MEMORY;
2331 result->auth_type = auth_type;
2332 result->auth_level = auth_level;
2334 result->user_name = talloc_strdup(result, username);
2335 result->domain = talloc_strdup(result, domain);
2336 if ((result->user_name == NULL) || (result->domain == NULL)) {
2337 status = NT_STATUS_NO_MEMORY;
2338 goto fail;
2341 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2342 if (!NT_STATUS_IS_OK(status)) {
2343 goto fail;
2346 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2348 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2349 if (!NT_STATUS_IS_OK(status)) {
2350 goto fail;
2353 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2354 if (!NT_STATUS_IS_OK(status)) {
2355 goto fail;
2358 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2359 if (!NT_STATUS_IS_OK(status)) {
2360 goto fail;
2364 * Turn off sign+seal to allow selected auth level to turn it back on.
2366 result->a_u.ntlmssp_state->neg_flags &=
2367 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2369 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2370 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2371 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2372 result->a_u.ntlmssp_state->neg_flags
2373 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2376 *presult = result;
2377 return NT_STATUS_OK;
2379 fail:
2380 TALLOC_FREE(result);
2381 return status;
2384 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2385 enum pipe_auth_level auth_level,
2386 const struct dcinfo *pdc,
2387 struct cli_pipe_auth_data **presult)
2389 struct cli_pipe_auth_data *result;
2391 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2392 if (result == NULL) {
2393 return NT_STATUS_NO_MEMORY;
2396 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2397 result->auth_level = auth_level;
2399 result->user_name = talloc_strdup(result, "");
2400 result->domain = talloc_strdup(result, domain);
2401 if ((result->user_name == NULL) || (result->domain == NULL)) {
2402 goto fail;
2405 result->a_u.schannel_auth = talloc(result,
2406 struct schannel_auth_struct);
2407 if (result->a_u.schannel_auth == NULL) {
2408 goto fail;
2411 memcpy(result->a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2412 result->a_u.schannel_auth->seq_num = 0;
2414 *presult = result;
2415 return NT_STATUS_OK;
2417 fail:
2418 TALLOC_FREE(result);
2419 return NT_STATUS_NO_MEMORY;
2422 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2424 data_blob_free(&auth->session_key);
2425 return 0;
2428 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2429 enum pipe_auth_level auth_level,
2430 const char *service_princ,
2431 const char *username,
2432 const char *password,
2433 struct cli_pipe_auth_data **presult)
2435 #ifdef HAVE_KRB5
2436 struct cli_pipe_auth_data *result;
2438 if ((username != NULL) && (password != NULL)) {
2439 int ret = kerberos_kinit_password(username, password, 0, NULL);
2440 if (ret != 0) {
2441 return NT_STATUS_ACCESS_DENIED;
2445 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2446 if (result == NULL) {
2447 return NT_STATUS_NO_MEMORY;
2450 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2451 result->auth_level = auth_level;
2454 * Username / domain need fixing!
2456 result->user_name = talloc_strdup(result, "");
2457 result->domain = talloc_strdup(result, "");
2458 if ((result->user_name == NULL) || (result->domain == NULL)) {
2459 goto fail;
2462 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2463 result, struct kerberos_auth_struct);
2464 if (result->a_u.kerberos_auth == NULL) {
2465 goto fail;
2467 talloc_set_destructor(result->a_u.kerberos_auth,
2468 cli_auth_kerberos_data_destructor);
2470 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2471 result, service_princ);
2472 if (result->a_u.kerberos_auth->service_principal == NULL) {
2473 goto fail;
2476 *presult = result;
2477 return NT_STATUS_OK;
2479 fail:
2480 TALLOC_FREE(result);
2481 return NT_STATUS_NO_MEMORY;
2482 #else
2483 return NT_STATUS_NOT_SUPPORTED;
2484 #endif
2487 /********************************************************************
2488 Create a rpc pipe client struct, connecting to a tcp port
2489 ********************************************************************/
2490 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2491 uint16_t port,
2492 const struct ndr_syntax_id *abstract_syntax,
2493 struct rpc_pipe_client **presult)
2495 struct rpc_pipe_client *result;
2496 struct sockaddr_storage addr;
2497 NTSTATUS status;
2499 result = talloc(mem_ctx, struct rpc_pipe_client);
2500 if (result == NULL) {
2501 return NT_STATUS_NO_MEMORY;
2504 result->transport_type = NCACN_IP_TCP;
2506 result->abstract_syntax = abstract_syntax;
2507 result->transfer_syntax = &ndr_transfer_syntax;
2509 result->desthost = talloc_strdup(result, host);
2510 result->srv_name_slash = talloc_asprintf_strupper_m(
2511 result, "\\\\%s", result->desthost);
2512 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2513 status = NT_STATUS_NO_MEMORY;
2514 goto fail;
2517 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2518 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2520 if (!resolve_name(host, &addr, 0)) {
2521 status = NT_STATUS_NOT_FOUND;
2522 goto fail;
2525 result->trans.sock.fd = open_socket_out(SOCK_STREAM, &addr, port, 60);
2526 if (result->trans.sock.fd == -1) {
2527 status = map_nt_error_from_unix(errno);
2528 goto fail;
2531 *presult = result;
2532 return NT_STATUS_OK;
2534 fail:
2535 TALLOC_FREE(result);
2536 return status;
2540 /****************************************************************************
2541 Open a named pipe over SMB to a remote server.
2543 * CAVEAT CALLER OF THIS FUNCTION:
2544 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2545 * so be sure that this function is called AFTER any structure (vs pointer)
2546 * assignment of the cli. In particular, libsmbclient does structure
2547 * assignments of cli, which invalidates the data in the returned
2548 * rpc_pipe_client if this function is called before the structure assignment
2549 * of cli.
2551 ****************************************************************************/
2553 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2555 struct rpc_pipe_client *result;
2556 int fnum;
2558 *perr = NT_STATUS_NO_MEMORY;
2560 /* sanity check to protect against crashes */
2562 if ( !cli ) {
2563 *perr = NT_STATUS_INVALID_HANDLE;
2564 return NULL;
2567 /* The pipe name index must fall within our array */
2568 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2570 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2571 if (result == NULL) {
2572 *perr = NT_STATUS_NO_MEMORY;
2573 return NULL;
2576 result->transport_type = NCACN_NP;
2578 result->trans.np.pipe_name = cli_get_pipe_name(pipe_idx);
2580 result->trans.np.cli = cli;
2581 result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2582 result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2583 result->desthost = talloc_strdup(result, cli->desthost);
2584 result->srv_name_slash = talloc_asprintf_strupper_m(
2585 result, "\\\\%s", result->desthost);
2587 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2588 *perr = NT_STATUS_NO_MEMORY;
2589 TALLOC_FREE(result);
2590 return NULL;
2593 if (pipe_idx == PI_NETLOGON) {
2594 /* Set up a netlogon credential chain for a netlogon pipe. */
2595 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2596 if (result->dc == NULL) {
2597 *perr = NT_STATUS_NO_MEMORY;
2598 TALLOC_FREE(result);
2599 return NULL;
2603 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2604 DESIRED_ACCESS_PIPE);
2605 if (fnum == -1) {
2606 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2607 "to machine %s. Error was %s\n",
2608 result->trans.np.pipe_name, cli->desthost,
2609 cli_errstr(cli)));
2610 *perr = cli_get_nt_error(cli);
2611 talloc_destroy(result);
2612 return NULL;
2615 result->trans.np.fnum = fnum;
2617 DLIST_ADD(cli->pipe_list, result);
2618 talloc_set_destructor(result, rpc_pipe_destructor);
2620 *perr = NT_STATUS_OK;
2622 return result;
2625 /****************************************************************************
2626 Open a named pipe to an SMB server and bind anonymously.
2627 ****************************************************************************/
2629 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2631 struct rpc_pipe_client *result;
2632 struct cli_pipe_auth_data *auth;
2634 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2635 if (result == NULL) {
2636 return NULL;
2639 *perr = rpccli_anon_bind_data(result, &auth);
2640 if (!NT_STATUS_IS_OK(*perr)) {
2641 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2642 nt_errstr(*perr)));
2643 TALLOC_FREE(result);
2644 return NULL;
2648 * This is a bit of an abstraction violation due to the fact that an
2649 * anonymous bind on an authenticated SMB inherits the user/domain
2650 * from the enclosing SMB creds
2653 TALLOC_FREE(auth->user_name);
2654 TALLOC_FREE(auth->domain);
2656 auth->user_name = talloc_strdup(auth, cli->user_name);
2657 auth->domain = talloc_strdup(auth, cli->domain);
2659 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2660 *perr = NT_STATUS_NO_MEMORY;
2661 TALLOC_FREE(result);
2662 return NULL;
2665 *perr = rpc_pipe_bind(result, auth);
2666 if (!NT_STATUS_IS_OK(*perr)) {
2667 int lvl = 0;
2668 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2669 /* non AD domains just don't have this pipe, avoid
2670 * level 0 statement in that case - gd */
2671 lvl = 3;
2673 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2674 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2675 TALLOC_FREE(result);
2676 return NULL;
2679 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2680 "%s and bound anonymously.\n", result->trans.np.pipe_name,
2681 cli->desthost ));
2683 return result;
2686 /****************************************************************************
2687 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2688 ****************************************************************************/
2690 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2691 int pipe_idx,
2692 enum pipe_auth_type auth_type,
2693 enum pipe_auth_level auth_level,
2694 const char *domain,
2695 const char *username,
2696 const char *password,
2697 NTSTATUS *perr)
2699 struct rpc_pipe_client *result;
2700 struct cli_pipe_auth_data *auth;
2702 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2703 if (result == NULL) {
2704 return NULL;
2707 *perr = rpccli_ntlmssp_bind_data(
2708 result, auth_type, auth_level, domain, username,
2709 cli->pwd.null_pwd ? NULL : password, &auth);
2710 if (!NT_STATUS_IS_OK(*perr)) {
2711 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2712 nt_errstr(*perr)));
2713 TALLOC_FREE(result);
2714 return NULL;
2717 *perr = rpc_pipe_bind(result, auth);
2718 if (!NT_STATUS_IS_OK(*perr)) {
2719 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2720 nt_errstr(*perr) ));
2721 goto err;
2724 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2725 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2726 result->trans.np.pipe_name, cli->desthost,
2727 domain, username ));
2729 return result;
2731 err:
2733 TALLOC_FREE(result);
2734 return NULL;
2737 /****************************************************************************
2738 External interface.
2739 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2740 ****************************************************************************/
2742 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2743 int pipe_idx,
2744 enum pipe_auth_level auth_level,
2745 const char *domain,
2746 const char *username,
2747 const char *password,
2748 NTSTATUS *perr)
2750 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2751 pipe_idx,
2752 PIPE_AUTH_TYPE_NTLMSSP,
2753 auth_level,
2754 domain,
2755 username,
2756 password,
2757 perr);
2760 /****************************************************************************
2761 External interface.
2762 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2763 ****************************************************************************/
2765 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2766 int pipe_idx,
2767 enum pipe_auth_level auth_level,
2768 const char *domain,
2769 const char *username,
2770 const char *password,
2771 NTSTATUS *perr)
2773 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2774 pipe_idx,
2775 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2776 auth_level,
2777 domain,
2778 username,
2779 password,
2780 perr);
2783 /****************************************************************************
2784 Get a the schannel session key out of an already opened netlogon pipe.
2785 ****************************************************************************/
2786 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2787 struct cli_state *cli,
2788 const char *domain,
2789 uint32 *pneg_flags,
2790 NTSTATUS *perr)
2792 uint32 sec_chan_type = 0;
2793 unsigned char machine_pwd[16];
2794 const char *machine_account;
2796 /* Get the machine account credentials from secrets.tdb. */
2797 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2798 &sec_chan_type))
2800 DEBUG(0, ("get_schannel_session_key: could not fetch "
2801 "trust account password for domain '%s'\n",
2802 domain));
2803 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2804 return false;
2807 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2808 cli->desthost, /* server name */
2809 domain, /* domain */
2810 global_myname(), /* client name */
2811 machine_account, /* machine account name */
2812 machine_pwd,
2813 sec_chan_type,
2814 pneg_flags);
2816 if (!NT_STATUS_IS_OK(*perr)) {
2817 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2818 "failed with result %s to server %s, domain %s, machine account %s.\n",
2819 nt_errstr(*perr), cli->desthost, domain, machine_account ));
2820 return false;
2823 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2824 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2825 cli->desthost));
2826 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2827 return false;
2830 return true;
2833 /****************************************************************************
2834 Open a netlogon pipe and get the schannel session key.
2835 Now exposed to external callers.
2836 ****************************************************************************/
2839 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2840 const char *domain,
2841 uint32 *pneg_flags,
2842 NTSTATUS *perr)
2844 struct rpc_pipe_client *netlogon_pipe = NULL;
2846 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2847 if (!netlogon_pipe) {
2848 return NULL;
2851 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2852 pneg_flags, perr))
2854 TALLOC_FREE(netlogon_pipe);
2855 return NULL;
2858 return netlogon_pipe;
2861 /****************************************************************************
2862 External interface.
2863 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2864 using session_key. sign and seal.
2865 ****************************************************************************/
2867 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2868 int pipe_idx,
2869 enum pipe_auth_level auth_level,
2870 const char *domain,
2871 const struct dcinfo *pdc,
2872 NTSTATUS *perr)
2874 struct rpc_pipe_client *result;
2875 struct cli_pipe_auth_data *auth;
2877 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2878 if (result == NULL) {
2879 return NULL;
2882 *perr = rpccli_schannel_bind_data(result, domain, auth_level,
2883 pdc, &auth);
2884 if (!NT_STATUS_IS_OK(*perr)) {
2885 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2886 nt_errstr(*perr)));
2887 TALLOC_FREE(result);
2888 return NULL;
2891 *perr = rpc_pipe_bind(result, auth);
2892 if (!NT_STATUS_IS_OK(*perr)) {
2893 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2894 nt_errstr(*perr) ));
2895 TALLOC_FREE(result);
2896 return NULL;
2899 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2900 if (result->dc) {
2901 *result->dc = *pdc;
2904 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2905 "for domain %s "
2906 "and bound using schannel.\n",
2907 result->trans.np.pipe_name, cli->desthost, domain ));
2909 return result;
2912 /****************************************************************************
2913 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2914 Fetch the session key ourselves using a temporary netlogon pipe. This
2915 version uses an ntlmssp auth bound netlogon pipe to get the key.
2916 ****************************************************************************/
2918 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2919 const char *domain,
2920 const char *username,
2921 const char *password,
2922 uint32 *pneg_flags,
2923 NTSTATUS *perr)
2925 struct rpc_pipe_client *netlogon_pipe = NULL;
2927 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2928 if (!netlogon_pipe) {
2929 return NULL;
2932 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2933 pneg_flags, perr))
2935 TALLOC_FREE(netlogon_pipe);
2936 return NULL;
2939 return netlogon_pipe;
2942 /****************************************************************************
2943 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2944 Fetch the session key ourselves using a temporary netlogon pipe. This version
2945 uses an ntlmssp bind to get the session key.
2946 ****************************************************************************/
2948 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2949 int pipe_idx,
2950 enum pipe_auth_level auth_level,
2951 const char *domain,
2952 const char *username,
2953 const char *password,
2954 NTSTATUS *perr)
2956 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2957 struct rpc_pipe_client *netlogon_pipe = NULL;
2958 struct rpc_pipe_client *result = NULL;
2960 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2961 password, &neg_flags, perr);
2962 if (!netlogon_pipe) {
2963 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2964 "key from server %s for domain %s.\n",
2965 cli->desthost, domain ));
2966 return NULL;
2969 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2970 auth_level,
2971 domain, netlogon_pipe->dc, perr);
2973 /* Now we've bound using the session key we can close the netlog pipe. */
2974 TALLOC_FREE(netlogon_pipe);
2976 return result;
2979 /****************************************************************************
2980 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2981 Fetch the session key ourselves using a temporary netlogon pipe.
2982 ****************************************************************************/
2984 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2985 int pipe_idx,
2986 enum pipe_auth_level auth_level,
2987 const char *domain,
2988 NTSTATUS *perr)
2990 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2991 struct rpc_pipe_client *netlogon_pipe = NULL;
2992 struct rpc_pipe_client *result = NULL;
2994 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2995 if (!netlogon_pipe) {
2996 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2997 "key from server %s for domain %s.\n",
2998 cli->desthost, domain ));
2999 return NULL;
3002 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
3003 auth_level,
3004 domain, netlogon_pipe->dc, perr);
3006 /* Now we've bound using the session key we can close the netlog pipe. */
3007 TALLOC_FREE(netlogon_pipe);
3009 return result;
3012 /****************************************************************************
3013 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3014 The idea is this can be called with service_princ, username and password all
3015 NULL so long as the caller has a TGT.
3016 ****************************************************************************/
3018 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
3019 int pipe_idx,
3020 enum pipe_auth_level auth_level,
3021 const char *service_princ,
3022 const char *username,
3023 const char *password,
3024 NTSTATUS *perr)
3026 #ifdef HAVE_KRB5
3027 struct rpc_pipe_client *result;
3028 struct cli_pipe_auth_data *auth;
3030 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3031 if (result == NULL) {
3032 return NULL;
3035 *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3036 username, password, &auth);
3037 if (!NT_STATUS_IS_OK(*perr)) {
3038 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3039 nt_errstr(*perr)));
3040 TALLOC_FREE(result);
3041 return NULL;
3044 *perr = rpc_pipe_bind(result, auth);
3045 if (!NT_STATUS_IS_OK(*perr)) {
3046 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
3047 nt_errstr(*perr) ));
3048 TALLOC_FREE(result);
3049 return NULL;
3052 return result;
3053 #else
3054 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3055 return NULL;
3056 #endif