Revert "Introduce rpc_pipe_np_smb_conn()"
[Samba.git] / source / rpc_client / cli_pipe.c
blobb0d6f8eafd6c5f6fe05bd9db264b29d1be440c39
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 Rpc pipe call id.
62 ********************************************************************/
64 static uint32 get_rpc_call_id(void)
66 static uint32 call_id = 0;
67 return ++call_id;
70 /*******************************************************************
71 Use SMBreadX to get rest of one fragment's worth of rpc data.
72 Will expand the current_pdu struct to the correct size.
73 ********************************************************************/
75 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
76 prs_struct *current_pdu,
77 uint32 data_to_read,
78 uint32 *current_pdu_offset)
80 size_t size = (size_t)cli->max_recv_frag;
81 uint32 stream_offset = 0;
82 ssize_t num_read;
83 char *pdata;
84 ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
86 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
87 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
90 * Grow the buffer if needed to accommodate the data to be read.
93 if (extra_data_size > 0) {
94 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
95 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
96 return NT_STATUS_NO_MEMORY;
98 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
101 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
103 do {
104 /* read data using SMBreadX */
105 if (size > (size_t)data_to_read) {
106 size = (size_t)data_to_read;
109 num_read = cli_read(cli->cli, cli->fnum, pdata,
110 (off_t)stream_offset, size);
112 DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
113 (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read));
116 * A dos error of ERRDOS/ERRmoredata is not an error.
118 if (cli_is_dos_error(cli->cli)) {
119 uint32 ecode;
120 uint8 eclass;
121 cli_dos_error(cli->cli, &eclass, &ecode);
122 if (eclass != ERRDOS && ecode != ERRmoredata) {
123 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
124 eclass, (unsigned int)ecode,
125 cli_errstr(cli->cli),
126 cli->pipe_name ));
127 return dos_to_ntstatus(eclass, ecode);
132 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
134 if (cli_is_nt_error(cli->cli)) {
135 if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) {
136 DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
137 nt_errstr(cli_nt_error(cli->cli)),
138 cli->pipe_name ));
139 return cli_nt_error(cli->cli);
143 if (num_read == -1) {
144 DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
145 cli->pipe_name ));
146 return cli_get_nt_error(cli->cli);
149 data_to_read -= num_read;
150 stream_offset += num_read;
151 pdata += num_read;
153 } while (num_read > 0 && data_to_read > 0);
154 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
157 * Update the current offset into current_pdu by the amount read.
159 *current_pdu_offset += stream_offset;
160 return NT_STATUS_OK;
163 /****************************************************************************
164 Try and get a PDU's worth of data from current_pdu. If not, then read more
165 from the wire.
166 ****************************************************************************/
168 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
170 NTSTATUS ret = NT_STATUS_OK;
171 uint32 current_pdu_len = prs_data_size(current_pdu);
173 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
174 if (current_pdu_len < RPC_HEADER_LEN) {
175 /* rpc_read expands the current_pdu struct as neccessary. */
176 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
177 if (!NT_STATUS_IS_OK(ret)) {
178 return ret;
182 /* This next call sets the endian bit correctly in current_pdu. */
183 /* We will propagate this to rbuf later. */
184 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
185 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
186 return NT_STATUS_BUFFER_TOO_SMALL;
189 /* Ensure we have frag_len bytes of data. */
190 if (current_pdu_len < prhdr->frag_len) {
191 /* rpc_read expands the current_pdu struct as neccessary. */
192 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
193 if (!NT_STATUS_IS_OK(ret)) {
194 return ret;
198 if (current_pdu_len < prhdr->frag_len) {
199 return NT_STATUS_BUFFER_TOO_SMALL;
202 return NT_STATUS_OK;
205 /****************************************************************************
206 NTLMSSP specific sign/seal.
207 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
208 In fact I should probably abstract these into identical pieces of code... JRA.
209 ****************************************************************************/
211 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
212 prs_struct *current_pdu,
213 uint8 *p_ss_padding_len)
215 RPC_HDR_AUTH auth_info;
216 uint32 save_offset = prs_offset(current_pdu);
217 uint32 auth_len = prhdr->auth_len;
218 NTLMSSP_STATE *ntlmssp_state = cli->auth.a_u.ntlmssp_state;
219 unsigned char *data = NULL;
220 size_t data_len;
221 unsigned char *full_packet_data = NULL;
222 size_t full_packet_data_len;
223 DATA_BLOB auth_blob;
224 NTSTATUS status;
226 if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
227 return NT_STATUS_OK;
230 if (!ntlmssp_state) {
231 return NT_STATUS_INVALID_PARAMETER;
234 /* Ensure there's enough data for an authenticated response. */
235 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
236 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
237 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
238 (unsigned int)auth_len ));
239 return NT_STATUS_BUFFER_TOO_SMALL;
243 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
244 * after the RPC header.
245 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
246 * functions as NTLMv2 checks the rpc headers also.
249 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
250 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
252 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
253 full_packet_data_len = prhdr->frag_len - auth_len;
255 /* Pull the auth header and the following data into a blob. */
256 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
257 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
258 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
259 return NT_STATUS_BUFFER_TOO_SMALL;
262 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
263 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
264 return NT_STATUS_BUFFER_TOO_SMALL;
267 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
268 auth_blob.length = auth_len;
270 switch (cli->auth.auth_level) {
271 case PIPE_AUTH_LEVEL_PRIVACY:
272 /* Data is encrypted. */
273 status = ntlmssp_unseal_packet(ntlmssp_state,
274 data, data_len,
275 full_packet_data,
276 full_packet_data_len,
277 &auth_blob);
278 if (!NT_STATUS_IS_OK(status)) {
279 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
280 "packet from remote machine %s on pipe %s "
281 "fnum 0x%x. Error was %s.\n",
282 cli->desthost,
283 cli->pipe_name,
284 (unsigned int)cli->fnum,
285 nt_errstr(status) ));
286 return status;
288 break;
289 case PIPE_AUTH_LEVEL_INTEGRITY:
290 /* Data is signed. */
291 status = ntlmssp_check_packet(ntlmssp_state,
292 data, data_len,
293 full_packet_data,
294 full_packet_data_len,
295 &auth_blob);
296 if (!NT_STATUS_IS_OK(status)) {
297 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
298 "packet from remote machine %s on pipe %s "
299 "fnum 0x%x. Error was %s.\n",
300 cli->desthost,
301 cli->pipe_name,
302 (unsigned int)cli->fnum,
303 nt_errstr(status) ));
304 return status;
306 break;
307 default:
308 DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n",
309 cli->auth.auth_level ));
310 return NT_STATUS_INVALID_INFO_CLASS;
314 * Return the current pointer to the data offset.
317 if(!prs_set_offset(current_pdu, save_offset)) {
318 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
319 (unsigned int)save_offset ));
320 return NT_STATUS_BUFFER_TOO_SMALL;
324 * Remember the padding length. We must remove it from the real data
325 * stream once the sign/seal is done.
328 *p_ss_padding_len = auth_info.auth_pad_len;
330 return NT_STATUS_OK;
333 /****************************************************************************
334 schannel specific sign/seal.
335 ****************************************************************************/
337 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
338 prs_struct *current_pdu,
339 uint8 *p_ss_padding_len)
341 RPC_HDR_AUTH auth_info;
342 RPC_AUTH_SCHANNEL_CHK schannel_chk;
343 uint32 auth_len = prhdr->auth_len;
344 uint32 save_offset = prs_offset(current_pdu);
345 struct schannel_auth_struct *schannel_auth = cli->auth.a_u.schannel_auth;
346 uint32 data_len;
348 if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
349 return NT_STATUS_OK;
352 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
353 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
354 return NT_STATUS_INVALID_PARAMETER;
357 if (!schannel_auth) {
358 return NT_STATUS_INVALID_PARAMETER;
361 /* Ensure there's enough data for an authenticated response. */
362 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
363 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
364 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
365 (unsigned int)auth_len ));
366 return NT_STATUS_INVALID_PARAMETER;
369 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
371 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
372 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
373 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
374 return NT_STATUS_BUFFER_TOO_SMALL;
377 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
378 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
379 return NT_STATUS_BUFFER_TOO_SMALL;
382 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
383 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
384 auth_info.auth_type));
385 return NT_STATUS_BUFFER_TOO_SMALL;
388 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
389 &schannel_chk, current_pdu, 0)) {
390 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
391 return NT_STATUS_BUFFER_TOO_SMALL;
394 if (!schannel_decode(schannel_auth,
395 cli->auth.auth_level,
396 SENDER_IS_ACCEPTOR,
397 &schannel_chk,
398 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
399 data_len)) {
400 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
401 "Connection to remote machine %s "
402 "pipe %s fnum 0x%x.\n",
403 cli->desthost,
404 cli->pipe_name,
405 (unsigned int)cli->fnum ));
406 return NT_STATUS_INVALID_PARAMETER;
409 /* The sequence number gets incremented on both send and receive. */
410 schannel_auth->seq_num++;
413 * Return the current pointer to the data offset.
416 if(!prs_set_offset(current_pdu, save_offset)) {
417 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
418 (unsigned int)save_offset ));
419 return NT_STATUS_BUFFER_TOO_SMALL;
423 * Remember the padding length. We must remove it from the real data
424 * stream once the sign/seal is done.
427 *p_ss_padding_len = auth_info.auth_pad_len;
429 return NT_STATUS_OK;
432 /****************************************************************************
433 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
434 ****************************************************************************/
436 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
437 prs_struct *current_pdu,
438 uint8 *p_ss_padding_len)
440 NTSTATUS ret = NT_STATUS_OK;
442 /* Paranioa checks for auth_len. */
443 if (prhdr->auth_len) {
444 if (prhdr->auth_len > prhdr->frag_len) {
445 return NT_STATUS_INVALID_PARAMETER;
448 if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len ||
449 prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) {
450 /* Integer wrap attempt. */
451 return NT_STATUS_INVALID_PARAMETER;
456 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
459 switch(cli->auth.auth_type) {
460 case PIPE_AUTH_TYPE_NONE:
461 if (prhdr->auth_len) {
462 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
463 "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
464 cli->desthost,
465 cli->pipe_name,
466 (unsigned int)cli->fnum,
467 (unsigned int)prhdr->auth_len ));
468 return NT_STATUS_INVALID_PARAMETER;
470 break;
472 case PIPE_AUTH_TYPE_NTLMSSP:
473 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
474 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
475 if (!NT_STATUS_IS_OK(ret)) {
476 return ret;
478 break;
480 case PIPE_AUTH_TYPE_SCHANNEL:
481 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
482 if (!NT_STATUS_IS_OK(ret)) {
483 return ret;
485 break;
487 case PIPE_AUTH_TYPE_KRB5:
488 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
489 default:
490 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
491 "pipe %s fnum %x - unknown internal auth type %u.\n",
492 cli->desthost,
493 cli->pipe_name,
494 (unsigned int)cli->fnum,
495 cli->auth.auth_type ));
496 return NT_STATUS_INVALID_INFO_CLASS;
499 return NT_STATUS_OK;
502 /****************************************************************************
503 Do basic authentication checks on an incoming pdu.
504 ****************************************************************************/
506 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
507 prs_struct *current_pdu,
508 uint8 expected_pkt_type,
509 char **ppdata,
510 uint32 *pdata_len,
511 prs_struct *return_data)
514 NTSTATUS ret = NT_STATUS_OK;
515 uint32 current_pdu_len = prs_data_size(current_pdu);
517 if (current_pdu_len != prhdr->frag_len) {
518 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
519 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
520 return NT_STATUS_INVALID_PARAMETER;
524 * Point the return values at the real data including the RPC
525 * header. Just in case the caller wants it.
527 *ppdata = prs_data_p(current_pdu);
528 *pdata_len = current_pdu_len;
530 /* Ensure we have the correct type. */
531 switch (prhdr->pkt_type) {
532 case RPC_ALTCONTRESP:
533 case RPC_BINDACK:
535 /* Alter context and bind ack share the same packet definitions. */
536 break;
539 case RPC_RESPONSE:
541 RPC_HDR_RESP rhdr_resp;
542 uint8 ss_padding_len = 0;
544 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
545 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
546 return NT_STATUS_BUFFER_TOO_SMALL;
549 /* Here's where we deal with incoming sign/seal. */
550 ret = cli_pipe_validate_rpc_response(cli, prhdr,
551 current_pdu, &ss_padding_len);
552 if (!NT_STATUS_IS_OK(ret)) {
553 return ret;
556 /* Point the return values at the NDR data. Remember to remove any ss padding. */
557 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
559 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
560 return NT_STATUS_BUFFER_TOO_SMALL;
563 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
565 /* Remember to remove the auth footer. */
566 if (prhdr->auth_len) {
567 /* We've already done integer wrap tests on auth_len in
568 cli_pipe_validate_rpc_response(). */
569 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
570 return NT_STATUS_BUFFER_TOO_SMALL;
572 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
575 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
576 current_pdu_len, *pdata_len, ss_padding_len ));
579 * If this is the first reply, and the allocation hint is reasonably, try and
580 * set up the return_data parse_struct to the correct size.
583 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
584 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
585 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
586 "too large to allocate\n",
587 (unsigned int)rhdr_resp.alloc_hint ));
588 return NT_STATUS_NO_MEMORY;
592 break;
595 case RPC_BINDNACK:
596 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
597 "pipe %s fnum 0x%x!\n",
598 cli->desthost,
599 cli->pipe_name,
600 (unsigned int)cli->fnum));
601 /* Use this for now... */
602 return NT_STATUS_NETWORK_ACCESS_DENIED;
604 case RPC_FAULT:
606 RPC_HDR_RESP rhdr_resp;
607 RPC_HDR_FAULT fault_resp;
609 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
610 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
611 return NT_STATUS_BUFFER_TOO_SMALL;
614 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
615 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
616 return NT_STATUS_BUFFER_TOO_SMALL;
619 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
620 "pipe %s fnum 0x%x!\n",
621 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
622 cli->desthost,
623 cli->pipe_name,
624 (unsigned int)cli->fnum));
625 if (NT_STATUS_IS_OK(fault_resp.status)) {
626 return NT_STATUS_UNSUCCESSFUL;
627 } else {
628 return fault_resp.status;
633 default:
634 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
635 "from remote machine %s pipe %s fnum 0x%x!\n",
636 (unsigned int)prhdr->pkt_type,
637 cli->desthost,
638 cli->pipe_name,
639 (unsigned int)cli->fnum));
640 return NT_STATUS_INVALID_INFO_CLASS;
643 if (prhdr->pkt_type != expected_pkt_type) {
644 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
645 "pipe %s fnum %x got an unexpected RPC packet "
646 "type - %u, not %u\n",
647 cli->desthost,
648 cli->pipe_name,
649 (unsigned int)cli->fnum,
650 prhdr->pkt_type,
651 expected_pkt_type));
652 return NT_STATUS_INVALID_INFO_CLASS;
655 /* Do this just before return - we don't want to modify any rpc header
656 data before now as we may have needed to do cryptographic actions on
657 it before. */
659 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
660 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
661 "setting fragment first/last ON.\n"));
662 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
665 return NT_STATUS_OK;
668 /****************************************************************************
669 Ensure we eat the just processed pdu from the current_pdu prs_struct.
670 Normally the frag_len and buffer size will match, but on the first trans
671 reply there is a theoretical chance that buffer size > frag_len, so we must
672 deal with that.
673 ****************************************************************************/
675 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
677 uint32 current_pdu_len = prs_data_size(current_pdu);
679 if (current_pdu_len < prhdr->frag_len) {
680 return NT_STATUS_BUFFER_TOO_SMALL;
683 /* Common case. */
684 if (current_pdu_len == (uint32)prhdr->frag_len) {
685 prs_mem_free(current_pdu);
686 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
687 /* Make current_pdu dynamic with no memory. */
688 prs_give_memory(current_pdu, 0, 0, True);
689 return NT_STATUS_OK;
693 * Oh no ! More data in buffer than we processed in current pdu.
694 * Cheat. Move the data down and shrink the buffer.
697 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
698 current_pdu_len - prhdr->frag_len);
700 /* Remember to set the read offset back to zero. */
701 prs_set_offset(current_pdu, 0);
703 /* Shrink the buffer. */
704 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
705 return NT_STATUS_BUFFER_TOO_SMALL;
708 return NT_STATUS_OK;
711 /****************************************************************************
712 Send data on an rpc pipe via trans. The prs_struct data must be the last
713 pdu fragment of an NDR data stream.
715 Receive response data from an rpc pipe, which may be large...
717 Read the first fragment: unfortunately have to use SMBtrans for the first
718 bit, then SMBreadX for subsequent bits.
720 If first fragment received also wasn't the last fragment, continue
721 getting fragments until we _do_ receive the last fragment.
723 Request/Response PDU's look like the following...
725 |<------------------PDU len----------------------------------------------->|
726 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
728 +------------+-----------------+-------------+---------------+-------------+
729 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
730 +------------+-----------------+-------------+---------------+-------------+
732 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
733 signing & sealing being negotiated.
735 ****************************************************************************/
737 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
738 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
739 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
740 uint8 expected_pkt_type)
742 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
743 char *rparam = NULL;
744 uint32 rparam_len = 0;
745 uint16 setup[2];
746 char *pdata = prs_data_p(data);
747 uint32 data_len = prs_offset(data);
748 char *prdata = NULL;
749 uint32 rdata_len = 0;
750 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
751 uint32 current_rbuf_offset = 0;
752 prs_struct current_pdu;
754 #ifdef DEVELOPER
755 /* Ensure we're not sending too much. */
756 SMB_ASSERT(data_len <= max_data);
757 #endif
759 /* Set up the current pdu parse struct. */
760 prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
762 /* Create setup parameters - must be in native byte order. */
763 setup[0] = TRANSACT_DCERPCCMD;
764 setup[1] = cli->fnum; /* Pipe file handle. */
766 DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
767 cli->desthost,
768 cli->pipe_name,
769 (unsigned int)cli->fnum ));
772 * Send the last (or only) fragment of an RPC request. For small
773 * amounts of data (about 1024 bytes or so) the RPC request and response
774 * appears in a SMBtrans request and response.
777 if (!cli_api_pipe(cli->cli, "\\PIPE\\",
778 setup, 2, 0, /* Setup, length, max */
779 NULL, 0, 0, /* Params, length, max */
780 pdata, data_len, max_data, /* data, length, max */
781 &rparam, &rparam_len, /* return params, len */
782 &prdata, &rdata_len)) /* return data, len */
784 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x "
785 "returned critical error. Error was %s\n",
786 cli->desthost,
787 cli->pipe_name,
788 (unsigned int)cli->fnum,
789 cli_errstr(cli->cli)));
790 ret = cli_get_nt_error(cli->cli);
791 SAFE_FREE(rparam);
792 SAFE_FREE(prdata);
793 goto err;
796 /* Throw away returned params - we know we won't use them. */
798 SAFE_FREE(rparam);
800 if (prdata == NULL) {
801 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
802 "fnum 0x%x failed to return data.\n",
803 cli->desthost,
804 cli->pipe_name,
805 (unsigned int)cli->fnum));
806 /* Yes - some calls can truely return no data... */
807 prs_mem_free(&current_pdu);
808 return NT_STATUS_OK;
812 * Give this memory as dynamic to the current pdu.
815 prs_give_memory(&current_pdu, prdata, rdata_len, True);
817 /* Ensure we can mess with the return prs_struct. */
818 SMB_ASSERT(UNMARSHALLING(rbuf));
819 SMB_ASSERT(prs_data_size(rbuf) == 0);
821 /* Make rbuf dynamic with no memory. */
822 prs_give_memory(rbuf, 0, 0, True);
824 while(1) {
825 RPC_HDR rhdr;
826 char *ret_data;
827 uint32 ret_data_len;
829 /* Ensure we have enough data for a pdu. */
830 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
831 if (!NT_STATUS_IS_OK(ret)) {
832 goto err;
835 /* We pass in rbuf here so if the alloc hint is set correctly
836 we can set the output size and avoid reallocs. */
838 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
839 &ret_data, &ret_data_len, rbuf);
841 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
842 prs_data_size(&current_pdu), current_rbuf_offset ));
844 if (!NT_STATUS_IS_OK(ret)) {
845 goto err;
848 if ((rhdr.flags & RPC_FLG_FIRST)) {
849 if (rhdr.pack_type[0] == 0) {
850 /* Set the data type correctly for big-endian data on the first packet. */
851 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
852 "PDU data format is big-endian.\n",
853 cli->desthost,
854 cli->pipe_name,
855 (unsigned int)cli->fnum));
857 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
858 } else {
859 /* Check endianness on subsequent packets. */
860 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
861 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
862 rbuf->bigendian_data ? "big" : "little",
863 current_pdu.bigendian_data ? "big" : "little" ));
864 ret = NT_STATUS_INVALID_PARAMETER;
865 goto err;
870 /* Now copy the data portion out of the pdu into rbuf. */
871 if (!prs_force_grow(rbuf, ret_data_len)) {
872 ret = NT_STATUS_NO_MEMORY;
873 goto err;
875 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
876 current_rbuf_offset += ret_data_len;
878 /* See if we've finished with all the data in current_pdu yet ? */
879 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
880 if (!NT_STATUS_IS_OK(ret)) {
881 goto err;
884 if (rhdr.flags & RPC_FLG_LAST) {
885 break; /* We're done. */
889 DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
890 cli->desthost,
891 cli->pipe_name,
892 (unsigned int)cli->fnum,
893 (unsigned int)prs_data_size(rbuf) ));
895 prs_mem_free(&current_pdu);
896 return NT_STATUS_OK;
898 err:
900 prs_mem_free(&current_pdu);
901 prs_mem_free(rbuf);
902 return ret;
905 /*******************************************************************
906 Creates krb5 auth bind.
907 ********************************************************************/
909 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
910 enum pipe_auth_level auth_level,
911 RPC_HDR_AUTH *pauth_out,
912 prs_struct *auth_data)
914 #ifdef HAVE_KRB5
915 int ret;
916 struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth;
917 DATA_BLOB tkt = data_blob_null;
918 DATA_BLOB tkt_wrapped = data_blob_null;
920 /* We may change the pad length before marshalling. */
921 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
923 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
924 a->service_principal ));
926 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
928 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
929 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
931 if (ret) {
932 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
933 "failed with %s\n",
934 a->service_principal,
935 error_message(ret) ));
937 data_blob_free(&tkt);
938 prs_mem_free(auth_data);
939 return NT_STATUS_INVALID_PARAMETER;
942 /* wrap that up in a nice GSS-API wrapping */
943 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
945 data_blob_free(&tkt);
947 /* Auth len in the rpc header doesn't include auth_header. */
948 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
949 data_blob_free(&tkt_wrapped);
950 prs_mem_free(auth_data);
951 return NT_STATUS_NO_MEMORY;
954 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
955 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
957 data_blob_free(&tkt_wrapped);
958 return NT_STATUS_OK;
959 #else
960 return NT_STATUS_INVALID_PARAMETER;
961 #endif
964 /*******************************************************************
965 Creates SPNEGO NTLMSSP auth bind.
966 ********************************************************************/
968 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
969 enum pipe_auth_level auth_level,
970 RPC_HDR_AUTH *pauth_out,
971 prs_struct *auth_data)
973 NTSTATUS nt_status;
974 DATA_BLOB null_blob = data_blob_null;
975 DATA_BLOB request = data_blob_null;
976 DATA_BLOB spnego_msg = data_blob_null;
978 /* We may change the pad length before marshalling. */
979 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
981 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
982 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
983 null_blob,
984 &request);
986 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
987 data_blob_free(&request);
988 prs_mem_free(auth_data);
989 return nt_status;
992 /* Wrap this in SPNEGO. */
993 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
995 data_blob_free(&request);
997 /* Auth len in the rpc header doesn't include auth_header. */
998 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
999 data_blob_free(&spnego_msg);
1000 prs_mem_free(auth_data);
1001 return NT_STATUS_NO_MEMORY;
1004 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1005 dump_data(5, spnego_msg.data, spnego_msg.length);
1007 data_blob_free(&spnego_msg);
1008 return NT_STATUS_OK;
1011 /*******************************************************************
1012 Creates NTLMSSP auth bind.
1013 ********************************************************************/
1015 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1016 enum pipe_auth_level auth_level,
1017 RPC_HDR_AUTH *pauth_out,
1018 prs_struct *auth_data)
1020 NTSTATUS nt_status;
1021 DATA_BLOB null_blob = data_blob_null;
1022 DATA_BLOB request = data_blob_null;
1024 /* We may change the pad length before marshalling. */
1025 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1027 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1028 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1029 null_blob,
1030 &request);
1032 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1033 data_blob_free(&request);
1034 prs_mem_free(auth_data);
1035 return nt_status;
1038 /* Auth len in the rpc header doesn't include auth_header. */
1039 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1040 data_blob_free(&request);
1041 prs_mem_free(auth_data);
1042 return NT_STATUS_NO_MEMORY;
1045 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1046 dump_data(5, request.data, request.length);
1048 data_blob_free(&request);
1049 return NT_STATUS_OK;
1052 /*******************************************************************
1053 Creates schannel auth bind.
1054 ********************************************************************/
1056 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1057 enum pipe_auth_level auth_level,
1058 RPC_HDR_AUTH *pauth_out,
1059 prs_struct *auth_data)
1061 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1063 /* We may change the pad length before marshalling. */
1064 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1066 /* Use lp_workgroup() if domain not specified */
1068 if (!cli->domain || !cli->domain[0]) {
1069 cli->domain = talloc_strdup(cli, lp_workgroup());
1070 if (cli->domain == NULL) {
1071 return NT_STATUS_NO_MEMORY;
1075 init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
1078 * Now marshall the data into the auth parse_struct.
1081 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1082 &schannel_neg, auth_data, 0)) {
1083 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1084 prs_mem_free(auth_data);
1085 return NT_STATUS_NO_MEMORY;
1088 return NT_STATUS_OK;
1091 /*******************************************************************
1092 Creates the internals of a DCE/RPC bind request or alter context PDU.
1093 ********************************************************************/
1095 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1096 prs_struct *rpc_out,
1097 uint32 rpc_call_id,
1098 const RPC_IFACE *abstract,
1099 const RPC_IFACE *transfer,
1100 RPC_HDR_AUTH *phdr_auth,
1101 prs_struct *pauth_info)
1103 RPC_HDR hdr;
1104 RPC_HDR_RB hdr_rb;
1105 RPC_CONTEXT rpc_ctx;
1106 uint16 auth_len = prs_offset(pauth_info);
1107 uint8 ss_padding_len = 0;
1108 uint16 frag_len = 0;
1110 /* create the RPC context. */
1111 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1113 /* create the bind request RPC_HDR_RB */
1114 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1116 /* Start building the frag length. */
1117 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1119 /* Do we need to pad ? */
1120 if (auth_len) {
1121 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1122 if (data_len % 8) {
1123 ss_padding_len = 8 - (data_len % 8);
1124 phdr_auth->auth_pad_len = ss_padding_len;
1126 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1129 /* Create the request RPC_HDR */
1130 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1132 /* Marshall the RPC header */
1133 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1134 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1135 return NT_STATUS_NO_MEMORY;
1138 /* Marshall the bind request data */
1139 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1140 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1141 return NT_STATUS_NO_MEMORY;
1145 * Grow the outgoing buffer to store any auth info.
1148 if(auth_len != 0) {
1149 if (ss_padding_len) {
1150 char pad[8];
1151 memset(pad, '\0', 8);
1152 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1153 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1154 return NT_STATUS_NO_MEMORY;
1158 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1159 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1160 return NT_STATUS_NO_MEMORY;
1164 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1165 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1166 return NT_STATUS_NO_MEMORY;
1170 return NT_STATUS_OK;
1173 /*******************************************************************
1174 Creates a DCE/RPC bind request.
1175 ********************************************************************/
1177 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1178 prs_struct *rpc_out,
1179 uint32 rpc_call_id,
1180 const RPC_IFACE *abstract,
1181 const RPC_IFACE *transfer,
1182 enum pipe_auth_type auth_type,
1183 enum pipe_auth_level auth_level)
1185 RPC_HDR_AUTH hdr_auth;
1186 prs_struct auth_info;
1187 NTSTATUS ret = NT_STATUS_OK;
1189 ZERO_STRUCT(hdr_auth);
1190 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1191 return NT_STATUS_NO_MEMORY;
1193 switch (auth_type) {
1194 case PIPE_AUTH_TYPE_SCHANNEL:
1195 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1196 if (!NT_STATUS_IS_OK(ret)) {
1197 prs_mem_free(&auth_info);
1198 return ret;
1200 break;
1202 case PIPE_AUTH_TYPE_NTLMSSP:
1203 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1204 if (!NT_STATUS_IS_OK(ret)) {
1205 prs_mem_free(&auth_info);
1206 return ret;
1208 break;
1210 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1211 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1212 if (!NT_STATUS_IS_OK(ret)) {
1213 prs_mem_free(&auth_info);
1214 return ret;
1216 break;
1218 case PIPE_AUTH_TYPE_KRB5:
1219 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1220 if (!NT_STATUS_IS_OK(ret)) {
1221 prs_mem_free(&auth_info);
1222 return ret;
1224 break;
1226 case PIPE_AUTH_TYPE_NONE:
1227 break;
1229 default:
1230 /* "Can't" happen. */
1231 return NT_STATUS_INVALID_INFO_CLASS;
1234 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1235 rpc_out,
1236 rpc_call_id,
1237 abstract,
1238 transfer,
1239 &hdr_auth,
1240 &auth_info);
1242 prs_mem_free(&auth_info);
1243 return ret;
1246 /*******************************************************************
1247 Create and add the NTLMSSP sign/seal auth header and data.
1248 ********************************************************************/
1250 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1251 RPC_HDR *phdr,
1252 uint32 ss_padding_len,
1253 prs_struct *outgoing_pdu)
1255 RPC_HDR_AUTH auth_info;
1256 NTSTATUS status;
1257 DATA_BLOB auth_blob = data_blob_null;
1258 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1260 if (!cli->auth.a_u.ntlmssp_state) {
1261 return NT_STATUS_INVALID_PARAMETER;
1264 /* Init and marshall the auth header. */
1265 init_rpc_hdr_auth(&auth_info,
1266 map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1267 cli->auth.auth_level,
1268 ss_padding_len,
1269 1 /* context id. */);
1271 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1272 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1273 data_blob_free(&auth_blob);
1274 return NT_STATUS_NO_MEMORY;
1277 switch (cli->auth.auth_level) {
1278 case PIPE_AUTH_LEVEL_PRIVACY:
1279 /* Data portion is encrypted. */
1280 status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state,
1281 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1282 data_and_pad_len,
1283 (unsigned char *)prs_data_p(outgoing_pdu),
1284 (size_t)prs_offset(outgoing_pdu),
1285 &auth_blob);
1286 if (!NT_STATUS_IS_OK(status)) {
1287 data_blob_free(&auth_blob);
1288 return status;
1290 break;
1292 case PIPE_AUTH_LEVEL_INTEGRITY:
1293 /* Data is signed. */
1294 status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state,
1295 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1296 data_and_pad_len,
1297 (unsigned char *)prs_data_p(outgoing_pdu),
1298 (size_t)prs_offset(outgoing_pdu),
1299 &auth_blob);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 data_blob_free(&auth_blob);
1302 return status;
1304 break;
1306 default:
1307 /* Can't happen. */
1308 smb_panic("bad auth level");
1309 /* Notreached. */
1310 return NT_STATUS_INVALID_PARAMETER;
1313 /* Finally marshall the blob. */
1315 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1316 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1317 (unsigned int)NTLMSSP_SIG_SIZE));
1318 data_blob_free(&auth_blob);
1319 return NT_STATUS_NO_MEMORY;
1322 data_blob_free(&auth_blob);
1323 return NT_STATUS_OK;
1326 /*******************************************************************
1327 Create and add the schannel sign/seal auth header and data.
1328 ********************************************************************/
1330 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1331 RPC_HDR *phdr,
1332 uint32 ss_padding_len,
1333 prs_struct *outgoing_pdu)
1335 RPC_HDR_AUTH auth_info;
1336 RPC_AUTH_SCHANNEL_CHK verf;
1337 struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth;
1338 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1339 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1341 if (!sas) {
1342 return NT_STATUS_INVALID_PARAMETER;
1345 /* Init and marshall the auth header. */
1346 init_rpc_hdr_auth(&auth_info,
1347 map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1348 cli->auth.auth_level,
1349 ss_padding_len,
1350 1 /* context id. */);
1352 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1353 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1354 return NT_STATUS_NO_MEMORY;
1357 switch (cli->auth.auth_level) {
1358 case PIPE_AUTH_LEVEL_PRIVACY:
1359 case PIPE_AUTH_LEVEL_INTEGRITY:
1360 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1361 sas->seq_num));
1363 schannel_encode(sas,
1364 cli->auth.auth_level,
1365 SENDER_IS_INITIATOR,
1366 &verf,
1367 data_p,
1368 data_and_pad_len);
1370 sas->seq_num++;
1371 break;
1373 default:
1374 /* Can't happen. */
1375 smb_panic("bad auth level");
1376 /* Notreached. */
1377 return NT_STATUS_INVALID_PARAMETER;
1380 /* Finally marshall the blob. */
1381 smb_io_rpc_auth_schannel_chk("",
1382 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1383 &verf,
1384 outgoing_pdu,
1387 return NT_STATUS_OK;
1390 /*******************************************************************
1391 Calculate how much data we're going to send in this packet, also
1392 work out any sign/seal padding length.
1393 ********************************************************************/
1395 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1396 uint32 data_left,
1397 uint16 *p_frag_len,
1398 uint16 *p_auth_len,
1399 uint32 *p_ss_padding)
1401 uint32 data_space, data_len;
1403 switch (cli->auth.auth_level) {
1404 case PIPE_AUTH_LEVEL_NONE:
1405 case PIPE_AUTH_LEVEL_CONNECT:
1406 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1407 data_len = MIN(data_space, data_left);
1408 *p_ss_padding = 0;
1409 *p_auth_len = 0;
1410 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1411 return data_len;
1413 case PIPE_AUTH_LEVEL_INTEGRITY:
1414 case PIPE_AUTH_LEVEL_PRIVACY:
1415 /* Treat the same for all authenticated rpc requests. */
1416 switch(cli->auth.auth_type) {
1417 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1418 case PIPE_AUTH_TYPE_NTLMSSP:
1419 *p_auth_len = NTLMSSP_SIG_SIZE;
1420 break;
1421 case PIPE_AUTH_TYPE_SCHANNEL:
1422 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1423 break;
1424 default:
1425 smb_panic("bad auth type");
1426 break;
1429 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1430 RPC_HDR_AUTH_LEN - *p_auth_len;
1432 data_len = MIN(data_space, data_left);
1433 if (data_len % 8) {
1434 *p_ss_padding = 8 - (data_len % 8);
1436 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1437 data_len + *p_ss_padding + /* data plus padding. */
1438 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1439 return data_len;
1441 default:
1442 smb_panic("bad auth level");
1443 /* Notreached. */
1444 return 0;
1448 /*******************************************************************
1449 External interface.
1450 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1451 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1452 and deals with signing/sealing details.
1453 ********************************************************************/
1455 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1456 uint8 op_num,
1457 prs_struct *in_data,
1458 prs_struct *out_data)
1460 NTSTATUS ret;
1461 uint32 data_left = prs_offset(in_data);
1462 uint32 alloc_hint = prs_offset(in_data);
1463 uint32 data_sent_thistime = 0;
1464 uint32 current_data_offset = 0;
1465 uint32 call_id = get_rpc_call_id();
1466 char pad[8];
1467 prs_struct outgoing_pdu;
1469 memset(pad, '\0', 8);
1471 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1472 /* Server is screwed up ! */
1473 return NT_STATUS_INVALID_PARAMETER;
1476 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1477 return NT_STATUS_NO_MEMORY;
1479 while (1) {
1480 RPC_HDR hdr;
1481 RPC_HDR_REQ hdr_req;
1482 uint16 auth_len = 0;
1483 uint16 frag_len = 0;
1484 uint8 flags = 0;
1485 uint32 ss_padding = 0;
1487 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1488 &frag_len, &auth_len, &ss_padding);
1490 if (current_data_offset == 0) {
1491 flags = RPC_FLG_FIRST;
1494 if (data_sent_thistime == data_left) {
1495 flags |= RPC_FLG_LAST;
1498 /* Create and marshall the header and request header. */
1499 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1501 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1502 prs_mem_free(&outgoing_pdu);
1503 return NT_STATUS_NO_MEMORY;
1506 /* Create the rpc request RPC_HDR_REQ */
1507 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1509 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1510 prs_mem_free(&outgoing_pdu);
1511 return NT_STATUS_NO_MEMORY;
1514 /* Copy in the data, plus any ss padding. */
1515 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1516 prs_mem_free(&outgoing_pdu);
1517 return NT_STATUS_NO_MEMORY;
1520 /* Copy the sign/seal padding data. */
1521 if (ss_padding) {
1522 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1523 prs_mem_free(&outgoing_pdu);
1524 return NT_STATUS_NO_MEMORY;
1528 /* Generate any auth sign/seal and add the auth footer. */
1529 if (auth_len) {
1530 switch (cli->auth.auth_type) {
1531 case PIPE_AUTH_TYPE_NONE:
1532 break;
1533 case PIPE_AUTH_TYPE_NTLMSSP:
1534 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1535 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1536 if (!NT_STATUS_IS_OK(ret)) {
1537 prs_mem_free(&outgoing_pdu);
1538 return ret;
1540 break;
1541 case PIPE_AUTH_TYPE_SCHANNEL:
1542 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1543 if (!NT_STATUS_IS_OK(ret)) {
1544 prs_mem_free(&outgoing_pdu);
1545 return ret;
1547 break;
1548 default:
1549 smb_panic("bad auth type");
1550 break; /* notreached */
1554 /* Actually send the packet. */
1555 if (flags & RPC_FLG_LAST) {
1556 /* Last packet - send the data, get the reply and return. */
1557 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1558 prs_mem_free(&outgoing_pdu);
1560 if (DEBUGLEVEL >= 50) {
1561 char *dump_name = NULL;
1562 /* Also capture received data */
1563 if (asprintf(&dump_name, "%s/reply_%s_%d",
1564 get_dyn_LOGFILEBASE(), cli->pipe_name,
1565 op_num) > 0) {
1566 prs_dump(dump_name, op_num, out_data);
1567 SAFE_FREE(dump_name);
1571 return ret;
1572 } else {
1573 /* More packets to come - write and continue. */
1574 ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */
1575 prs_data_p(&outgoing_pdu),
1576 (off_t)0,
1577 (size_t)hdr.frag_len);
1579 if (num_written != hdr.frag_len) {
1580 prs_mem_free(&outgoing_pdu);
1581 return cli_get_nt_error(cli->cli);
1585 current_data_offset += data_sent_thistime;
1586 data_left -= data_sent_thistime;
1588 /* Reset the marshalling position back to zero. */
1589 if (!prs_set_offset(&outgoing_pdu, 0)) {
1590 prs_mem_free(&outgoing_pdu);
1591 return NT_STATUS_NO_MEMORY;
1595 #if 0
1596 /****************************************************************************
1597 Set the handle state.
1598 ****************************************************************************/
1600 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1601 const char *pipe_name, uint16 device_state)
1603 bool state_set = False;
1604 char param[2];
1605 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1606 char *rparam = NULL;
1607 char *rdata = NULL;
1608 uint32 rparam_len, rdata_len;
1610 if (pipe_name == NULL)
1611 return False;
1613 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1614 cli->fnum, pipe_name, device_state));
1616 /* create parameters: device state */
1617 SSVAL(param, 0, device_state);
1619 /* create setup parameters. */
1620 setup[0] = 0x0001;
1621 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1623 /* send the data on \PIPE\ */
1624 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1625 setup, 2, 0, /* setup, length, max */
1626 param, 2, 0, /* param, length, max */
1627 NULL, 0, 1024, /* data, length, max */
1628 &rparam, &rparam_len, /* return param, length */
1629 &rdata, &rdata_len)) /* return data, length */
1631 DEBUG(5, ("Set Handle state: return OK\n"));
1632 state_set = True;
1635 SAFE_FREE(rparam);
1636 SAFE_FREE(rdata);
1638 return state_set;
1640 #endif
1642 /****************************************************************************
1643 Check the rpc bind acknowledge response.
1644 ****************************************************************************/
1646 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1648 if ( hdr_ba->addr.len == 0) {
1649 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1652 /* check the transfer syntax */
1653 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1654 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1655 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1656 return False;
1659 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1660 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1661 hdr_ba->res.num_results, hdr_ba->res.reason));
1664 DEBUG(5,("check_bind_response: accepted!\n"));
1665 return True;
1668 /*******************************************************************
1669 Creates a DCE/RPC bind authentication response.
1670 This is the packet that is sent back to the server once we
1671 have received a BIND-ACK, to finish the third leg of
1672 the authentication handshake.
1673 ********************************************************************/
1675 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1676 uint32 rpc_call_id,
1677 enum pipe_auth_type auth_type,
1678 enum pipe_auth_level auth_level,
1679 DATA_BLOB *pauth_blob,
1680 prs_struct *rpc_out)
1682 RPC_HDR hdr;
1683 RPC_HDR_AUTH hdr_auth;
1684 uint32 pad = 0;
1686 /* Create the request RPC_HDR */
1687 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1688 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1689 pauth_blob->length );
1691 /* Marshall it. */
1692 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1693 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1694 return NT_STATUS_NO_MEMORY;
1698 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1699 about padding - shouldn't this pad to length 8 ? JRA.
1702 /* 4 bytes padding. */
1703 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1704 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1705 return NT_STATUS_NO_MEMORY;
1708 /* Create the request RPC_HDR_AUTHA */
1709 init_rpc_hdr_auth(&hdr_auth,
1710 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1711 auth_level, 0, 1);
1713 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1714 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1715 return NT_STATUS_NO_MEMORY;
1719 * Append the auth data to the outgoing buffer.
1722 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1723 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1724 return NT_STATUS_NO_MEMORY;
1727 return NT_STATUS_OK;
1730 /****************************************************************************
1731 Create and send the third packet in an RPC auth.
1732 ****************************************************************************/
1734 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1735 RPC_HDR *phdr,
1736 prs_struct *rbuf,
1737 uint32 rpc_call_id,
1738 enum pipe_auth_type auth_type,
1739 enum pipe_auth_level auth_level)
1741 DATA_BLOB server_response = data_blob_null;
1742 DATA_BLOB client_reply = data_blob_null;
1743 RPC_HDR_AUTH hdr_auth;
1744 NTSTATUS nt_status;
1745 prs_struct rpc_out;
1746 ssize_t ret;
1748 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1749 return NT_STATUS_INVALID_PARAMETER;
1752 /* Process the returned NTLMSSP blob first. */
1753 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1754 return NT_STATUS_INVALID_PARAMETER;
1757 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1758 return NT_STATUS_INVALID_PARAMETER;
1761 /* TODO - check auth_type/auth_level match. */
1763 server_response = data_blob(NULL, phdr->auth_len);
1764 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1766 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1767 server_response,
1768 &client_reply);
1770 if (!NT_STATUS_IS_OK(nt_status)) {
1771 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1772 data_blob_free(&server_response);
1773 return nt_status;
1776 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1778 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1779 auth_type, auth_level,
1780 &client_reply, &rpc_out);
1782 if (!NT_STATUS_IS_OK(nt_status)) {
1783 prs_mem_free(&rpc_out);
1784 data_blob_free(&client_reply);
1785 data_blob_free(&server_response);
1786 return nt_status;
1789 /* 8 here is named pipe message mode. */
1790 ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
1791 (size_t)prs_offset(&rpc_out));
1793 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1794 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
1795 prs_mem_free(&rpc_out);
1796 data_blob_free(&client_reply);
1797 data_blob_free(&server_response);
1798 return cli_get_nt_error(cli->cli);
1801 DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
1802 "fnum 0x%x sent auth3 response ok.\n",
1803 cli->desthost,
1804 cli->pipe_name,
1805 (unsigned int)cli->fnum));
1807 prs_mem_free(&rpc_out);
1808 data_blob_free(&client_reply);
1809 data_blob_free(&server_response);
1810 return NT_STATUS_OK;
1813 /*******************************************************************
1814 Creates a DCE/RPC bind alter context authentication request which
1815 may contain a spnego auth blobl
1816 ********************************************************************/
1818 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1819 const RPC_IFACE *abstract,
1820 const RPC_IFACE *transfer,
1821 enum pipe_auth_level auth_level,
1822 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1823 prs_struct *rpc_out)
1825 RPC_HDR_AUTH hdr_auth;
1826 prs_struct auth_info;
1827 NTSTATUS ret = NT_STATUS_OK;
1829 ZERO_STRUCT(hdr_auth);
1830 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1831 return NT_STATUS_NO_MEMORY;
1833 /* We may change the pad length before marshalling. */
1834 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1836 if (pauth_blob->length) {
1837 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1838 prs_mem_free(&auth_info);
1839 return NT_STATUS_NO_MEMORY;
1843 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1844 rpc_out,
1845 rpc_call_id,
1846 abstract,
1847 transfer,
1848 &hdr_auth,
1849 &auth_info);
1850 prs_mem_free(&auth_info);
1851 return ret;
1854 /*******************************************************************
1855 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1856 and gets a response.
1857 ********************************************************************/
1859 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1860 RPC_HDR *phdr,
1861 prs_struct *rbuf,
1862 uint32 rpc_call_id,
1863 const RPC_IFACE *abstract,
1864 const RPC_IFACE *transfer,
1865 enum pipe_auth_type auth_type,
1866 enum pipe_auth_level auth_level)
1868 DATA_BLOB server_spnego_response = data_blob_null;
1869 DATA_BLOB server_ntlm_response = data_blob_null;
1870 DATA_BLOB client_reply = data_blob_null;
1871 DATA_BLOB tmp_blob = data_blob_null;
1872 RPC_HDR_AUTH hdr_auth;
1873 NTSTATUS nt_status;
1874 prs_struct rpc_out;
1876 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1877 return NT_STATUS_INVALID_PARAMETER;
1880 /* Process the returned NTLMSSP blob first. */
1881 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1882 return NT_STATUS_INVALID_PARAMETER;
1885 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1886 return NT_STATUS_INVALID_PARAMETER;
1889 server_spnego_response = data_blob(NULL, phdr->auth_len);
1890 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1892 /* The server might give us back two challenges - tmp_blob is for the second. */
1893 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
1894 data_blob_free(&server_spnego_response);
1895 data_blob_free(&server_ntlm_response);
1896 data_blob_free(&tmp_blob);
1897 return NT_STATUS_INVALID_PARAMETER;
1900 /* We're finished with the server spnego response and the tmp_blob. */
1901 data_blob_free(&server_spnego_response);
1902 data_blob_free(&tmp_blob);
1904 nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1905 server_ntlm_response,
1906 &client_reply);
1908 /* Finished with the server_ntlm response */
1909 data_blob_free(&server_ntlm_response);
1911 if (!NT_STATUS_IS_OK(nt_status)) {
1912 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
1913 data_blob_free(&client_reply);
1914 return nt_status;
1917 /* SPNEGO wrap the client reply. */
1918 tmp_blob = spnego_gen_auth(client_reply);
1919 data_blob_free(&client_reply);
1920 client_reply = tmp_blob;
1921 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
1923 /* Now prepare the alter context pdu. */
1924 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1926 nt_status = create_rpc_alter_context(rpc_call_id,
1927 abstract,
1928 transfer,
1929 auth_level,
1930 &client_reply,
1931 &rpc_out);
1933 data_blob_free(&client_reply);
1935 if (!NT_STATUS_IS_OK(nt_status)) {
1936 prs_mem_free(&rpc_out);
1937 return nt_status;
1940 /* Initialize the returning data struct. */
1941 prs_mem_free(rbuf);
1942 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
1944 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
1945 if (!NT_STATUS_IS_OK(nt_status)) {
1946 prs_mem_free(&rpc_out);
1947 return nt_status;
1950 prs_mem_free(&rpc_out);
1952 /* Get the auth blob from the reply. */
1953 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
1954 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
1955 return NT_STATUS_BUFFER_TOO_SMALL;
1958 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1959 return NT_STATUS_INVALID_PARAMETER;
1962 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1963 return NT_STATUS_INVALID_PARAMETER;
1966 server_spnego_response = data_blob(NULL, phdr->auth_len);
1967 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1969 /* Check we got a valid auth response. */
1970 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
1971 data_blob_free(&server_spnego_response);
1972 data_blob_free(&tmp_blob);
1973 return NT_STATUS_INVALID_PARAMETER;
1976 data_blob_free(&server_spnego_response);
1977 data_blob_free(&tmp_blob);
1979 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
1980 "remote machine %s pipe %s fnum 0x%x.\n",
1981 cli->desthost,
1982 cli->pipe_name,
1983 (unsigned int)cli->fnum));
1985 return NT_STATUS_OK;
1988 /****************************************************************************
1989 Do an rpc bind.
1990 ****************************************************************************/
1992 static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1993 enum pipe_auth_type auth_type,
1994 enum pipe_auth_level auth_level)
1996 RPC_HDR hdr;
1997 RPC_HDR_BA hdr_ba;
1998 prs_struct rpc_out;
1999 prs_struct rbuf;
2000 uint32 rpc_call_id;
2001 NTSTATUS status;
2003 DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2004 (unsigned int)cli->fnum,
2005 cli->pipe_name,
2006 (unsigned int)auth_type,
2007 (unsigned int)auth_level ));
2009 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2011 rpc_call_id = get_rpc_call_id();
2013 /* Marshall the outgoing data. */
2014 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2015 cli->abstract_syntax,
2016 cli->transfer_syntax,
2017 auth_type,
2018 auth_level);
2020 if (!NT_STATUS_IS_OK(status)) {
2021 prs_mem_free(&rpc_out);
2022 return status;
2025 /* Initialize the incoming data struct. */
2026 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2028 /* send data on \PIPE\. receive a response */
2029 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2030 if (!NT_STATUS_IS_OK(status)) {
2031 prs_mem_free(&rpc_out);
2032 return status;
2035 prs_mem_free(&rpc_out);
2037 DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2038 "fnum 0x%x bind request returned ok.\n",
2039 cli->desthost,
2040 cli->pipe_name,
2041 (unsigned int)cli->fnum));
2043 /* Unmarshall the RPC header */
2044 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2045 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2046 prs_mem_free(&rbuf);
2047 return NT_STATUS_BUFFER_TOO_SMALL;
2050 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2051 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2052 prs_mem_free(&rbuf);
2053 return NT_STATUS_BUFFER_TOO_SMALL;
2056 if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2057 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2058 prs_mem_free(&rbuf);
2059 return NT_STATUS_BUFFER_TOO_SMALL;
2062 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2063 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2065 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2066 switch(auth_type) {
2068 case PIPE_AUTH_TYPE_NONE:
2069 case PIPE_AUTH_TYPE_SCHANNEL:
2070 /* Bind complete. */
2071 break;
2073 case PIPE_AUTH_TYPE_NTLMSSP:
2074 /* Need to send AUTH3 packet - no reply. */
2075 status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
2076 auth_type, auth_level);
2077 if (!NT_STATUS_IS_OK(status)) {
2078 prs_mem_free(&rbuf);
2079 return status;
2081 break;
2083 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2084 /* Need to send alter context request and reply. */
2085 status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
2086 cli->abstract_syntax,
2087 cli->transfer_syntax,
2088 auth_type, auth_level);
2089 if (!NT_STATUS_IS_OK(status)) {
2090 prs_mem_free(&rbuf);
2091 return status;
2093 break;
2095 case PIPE_AUTH_TYPE_KRB5:
2096 /* */
2098 default:
2099 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2100 (unsigned int)auth_type ));
2101 prs_mem_free(&rbuf);
2102 return NT_STATUS_INVALID_INFO_CLASS;
2105 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2106 if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2107 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2108 if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2109 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2110 prs_mem_free(&rbuf);
2111 return NT_STATUS_INVALID_PARAMETER;
2114 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2115 if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2116 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2117 prs_mem_free(&rbuf);
2118 return NT_STATUS_INVALID_PARAMETER;
2123 /* Pipe is bound - set up auth_type and auth_level data. */
2125 cli->auth.auth_type = auth_type;
2126 cli->auth.auth_level = auth_level;
2128 prs_mem_free(&rbuf);
2129 return NT_STATUS_OK;
2132 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2133 unsigned int timeout)
2135 return cli_set_timeout(cli->cli, timeout);
2138 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2140 return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
2143 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2145 bool ret;
2147 ret = cli_close(p->cli, p->fnum);
2148 if (!ret) {
2149 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s, "
2150 "fnum 0x%x to machine %s. Error was %s\n",
2151 p->pipe_name, (int) p->fnum,
2152 p->desthost, cli_errstr(p->cli)));
2155 if (p->auth.cli_auth_data_free_func) {
2156 (*p->auth.cli_auth_data_free_func)(&p->auth);
2159 DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n",
2160 p->pipe_name, p->desthost ));
2162 DLIST_REMOVE(p->cli->pipe_list, p);
2164 return ret ? -1 : 0;
2167 /****************************************************************************
2168 Open a named pipe over SMB to a remote server.
2170 * CAVEAT CALLER OF THIS FUNCTION:
2171 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2172 * so be sure that this function is called AFTER any structure (vs pointer)
2173 * assignment of the cli. In particular, libsmbclient does structure
2174 * assignments of cli, which invalidates the data in the returned
2175 * rpc_pipe_client if this function is called before the structure assignment
2176 * of cli.
2178 ****************************************************************************/
2180 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2182 struct rpc_pipe_client *result;
2183 int fnum;
2185 *perr = NT_STATUS_NO_MEMORY;
2187 /* sanity check to protect against crashes */
2189 if ( !cli ) {
2190 *perr = NT_STATUS_INVALID_HANDLE;
2191 return NULL;
2194 /* The pipe name index must fall within our array */
2195 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2197 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2198 if (result == NULL) {
2199 *perr = NT_STATUS_NO_MEMORY;
2200 return NULL;
2203 result->pipe_name = cli_get_pipe_name(pipe_idx);
2205 result->cli = cli;
2206 result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2207 result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2208 result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
2209 result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
2211 result->domain = talloc_strdup(result, cli->domain);
2212 result->user_name = talloc_strdup(result, cli->user_name);
2213 result->desthost = talloc_strdup(result, cli->desthost);
2214 result->srv_name_slash = talloc_asprintf_strupper_m(
2215 result, "\\\\%s", result->desthost);
2217 if ((result->domain == NULL)
2218 || (result->user_name == NULL)
2219 || (result->desthost == NULL)
2220 || (result->srv_name_slash == NULL)) {
2221 *perr = NT_STATUS_NO_MEMORY;
2222 TALLOC_FREE(result);
2223 return NULL;
2226 if (pipe_idx == PI_NETLOGON) {
2227 /* Set up a netlogon credential chain for a netlogon pipe. */
2228 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2229 if (result->dc == NULL) {
2230 *perr = NT_STATUS_NO_MEMORY;
2231 TALLOC_FREE(result);
2232 return NULL;
2236 fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2237 if (fnum == -1) {
2238 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2239 "to machine %s. Error was %s\n",
2240 result->pipe_name, cli->desthost,
2241 cli_errstr(cli)));
2242 *perr = cli_get_nt_error(cli);
2243 talloc_destroy(result);
2244 return NULL;
2247 result->fnum = fnum;
2249 DLIST_ADD(cli->pipe_list, result);
2250 talloc_set_destructor(result, rpc_pipe_destructor);
2252 *perr = NT_STATUS_OK;
2254 return result;
2257 /****************************************************************************
2258 Open a named pipe to an SMB server and bind anonymously.
2259 ****************************************************************************/
2261 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2263 struct rpc_pipe_client *result;
2265 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2266 if (result == NULL) {
2267 return NULL;
2270 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
2271 if (!NT_STATUS_IS_OK(*perr)) {
2272 int lvl = 0;
2273 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2274 /* non AD domains just don't have this pipe, avoid
2275 * level 0 statement in that case - gd */
2276 lvl = 3;
2278 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2279 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2280 TALLOC_FREE(result);
2281 return NULL;
2284 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2285 result->pipe_name, cli->desthost ));
2287 return result;
2290 /****************************************************************************
2291 Free function for NTLMSSP auth.
2292 ****************************************************************************/
2294 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
2296 if (auth->a_u.ntlmssp_state) {
2297 ntlmssp_end(&auth->a_u.ntlmssp_state);
2298 auth->a_u.ntlmssp_state = NULL;
2302 /****************************************************************************
2303 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2304 ****************************************************************************/
2306 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2307 int pipe_idx,
2308 enum pipe_auth_type auth_type,
2309 enum pipe_auth_level auth_level,
2310 const char *domain,
2311 const char *username,
2312 const char *password,
2313 NTSTATUS *perr)
2315 struct rpc_pipe_client *result;
2316 NTLMSSP_STATE *ntlmssp_state = NULL;
2318 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2319 if (result == NULL) {
2320 return NULL;
2323 result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
2325 TALLOC_FREE(result->domain);
2326 TALLOC_FREE(result->user_name);
2328 result->domain = talloc_strdup(result, domain);
2329 result->user_name = talloc_strdup(result, username);
2331 if ((result->domain == NULL) || (result->user_name == NULL)) {
2332 *perr = NT_STATUS_NO_MEMORY;
2333 goto err;
2336 pwd_set_cleartext(&result->pwd, password);
2338 *perr = ntlmssp_client_start(&ntlmssp_state);
2339 if (!NT_STATUS_IS_OK(*perr)) {
2340 goto err;
2343 result->auth.a_u.ntlmssp_state = ntlmssp_state;
2345 *perr = ntlmssp_set_username(ntlmssp_state, username);
2346 if (!NT_STATUS_IS_OK(*perr)) {
2347 goto err;
2350 *perr = ntlmssp_set_domain(ntlmssp_state, domain);
2351 if (!NT_STATUS_IS_OK(*perr)) {
2352 goto err;
2355 if (cli->pwd.null_pwd) {
2356 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
2357 if (!NT_STATUS_IS_OK(*perr)) {
2358 goto err;
2360 } else {
2361 *perr = ntlmssp_set_password(ntlmssp_state, password);
2362 if (!NT_STATUS_IS_OK(*perr)) {
2363 goto err;
2367 /* Turn off sign+seal to allow selected auth level to turn it back on. */
2368 ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
2370 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2371 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2372 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2373 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2376 *perr = rpc_pipe_bind(result, auth_type, auth_level);
2377 if (!NT_STATUS_IS_OK(*perr)) {
2378 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2379 nt_errstr(*perr) ));
2380 goto err;
2383 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2384 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2385 result->pipe_name, cli->desthost,
2386 domain, username ));
2388 return result;
2390 err:
2392 TALLOC_FREE(result);
2393 return NULL;
2396 /****************************************************************************
2397 External interface.
2398 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2399 ****************************************************************************/
2401 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2402 int pipe_idx,
2403 enum pipe_auth_level auth_level,
2404 const char *domain,
2405 const char *username,
2406 const char *password,
2407 NTSTATUS *perr)
2409 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2410 pipe_idx,
2411 PIPE_AUTH_TYPE_NTLMSSP,
2412 auth_level,
2413 domain,
2414 username,
2415 password,
2416 perr);
2419 /****************************************************************************
2420 External interface.
2421 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2422 ****************************************************************************/
2424 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2425 int pipe_idx,
2426 enum pipe_auth_level auth_level,
2427 const char *domain,
2428 const char *username,
2429 const char *password,
2430 NTSTATUS *perr)
2432 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2433 pipe_idx,
2434 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2435 auth_level,
2436 domain,
2437 username,
2438 password,
2439 perr);
2442 /****************************************************************************
2443 Get a the schannel session key out of an already opened netlogon pipe.
2444 ****************************************************************************/
2445 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2446 struct cli_state *cli,
2447 const char *domain,
2448 uint32 *pneg_flags,
2449 NTSTATUS *perr)
2451 uint32 sec_chan_type = 0;
2452 unsigned char machine_pwd[16];
2453 const char *machine_account;
2455 /* Get the machine account credentials from secrets.tdb. */
2456 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2457 &sec_chan_type))
2459 DEBUG(0, ("get_schannel_session_key: could not fetch "
2460 "trust account password for domain '%s'\n",
2461 domain));
2462 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2463 return false;
2466 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2467 cli->desthost, /* server name */
2468 domain, /* domain */
2469 global_myname(), /* client name */
2470 machine_account, /* machine account name */
2471 machine_pwd,
2472 sec_chan_type,
2473 pneg_flags);
2475 if (!NT_STATUS_IS_OK(*perr)) {
2476 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2477 "failed with result %s to server %s, domain %s, machine account %s.\n",
2478 nt_errstr(*perr), cli->desthost, domain, machine_account ));
2479 return false;
2482 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2483 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2484 cli->desthost));
2485 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2486 return false;
2489 return true;
2492 /****************************************************************************
2493 Open a netlogon pipe and get the schannel session key.
2494 Now exposed to external callers.
2495 ****************************************************************************/
2498 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2499 const char *domain,
2500 uint32 *pneg_flags,
2501 NTSTATUS *perr)
2503 struct rpc_pipe_client *netlogon_pipe = NULL;
2505 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2506 if (!netlogon_pipe) {
2507 return NULL;
2510 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2511 pneg_flags, perr))
2513 TALLOC_FREE(netlogon_pipe);
2514 return NULL;
2517 return netlogon_pipe;
2520 /****************************************************************************
2521 External interface.
2522 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2523 using session_key. sign and seal.
2524 ****************************************************************************/
2526 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2527 int pipe_idx,
2528 enum pipe_auth_level auth_level,
2529 const char *domain,
2530 const struct dcinfo *pdc,
2531 NTSTATUS *perr)
2533 struct rpc_pipe_client *result;
2535 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2536 if (result == NULL) {
2537 return NULL;
2540 result->auth.a_u.schannel_auth = TALLOC_ZERO_P(
2541 result, struct schannel_auth_struct);
2542 if (!result->auth.a_u.schannel_auth) {
2543 TALLOC_FREE(result);
2544 *perr = NT_STATUS_NO_MEMORY;
2545 return NULL;
2548 TALLOC_FREE(result->domain);
2549 result->domain = talloc_strdup(result, domain);
2550 if (result->domain == NULL) {
2551 TALLOC_FREE(result);
2552 *perr = NT_STATUS_NO_MEMORY;
2553 return NULL;
2556 memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2558 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
2559 if (!NT_STATUS_IS_OK(*perr)) {
2560 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2561 nt_errstr(*perr) ));
2562 TALLOC_FREE(result);
2563 return NULL;
2566 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2567 if (result->dc) {
2568 *result->dc = *pdc;
2571 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2572 "for domain %s "
2573 "and bound using schannel.\n",
2574 result->pipe_name, cli->desthost, domain ));
2576 return result;
2579 /****************************************************************************
2580 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2581 Fetch the session key ourselves using a temporary netlogon pipe. This
2582 version uses an ntlmssp auth bound netlogon pipe to get the key.
2583 ****************************************************************************/
2585 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2586 const char *domain,
2587 const char *username,
2588 const char *password,
2589 uint32 *pneg_flags,
2590 NTSTATUS *perr)
2592 struct rpc_pipe_client *netlogon_pipe = NULL;
2594 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2595 if (!netlogon_pipe) {
2596 return NULL;
2599 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2600 pneg_flags, perr))
2602 TALLOC_FREE(netlogon_pipe);
2603 return NULL;
2606 return netlogon_pipe;
2609 /****************************************************************************
2610 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2611 Fetch the session key ourselves using a temporary netlogon pipe. This version
2612 uses an ntlmssp bind to get the session key.
2613 ****************************************************************************/
2615 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2616 int pipe_idx,
2617 enum pipe_auth_level auth_level,
2618 const char *domain,
2619 const char *username,
2620 const char *password,
2621 NTSTATUS *perr)
2623 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2624 struct rpc_pipe_client *netlogon_pipe = NULL;
2625 struct rpc_pipe_client *result = NULL;
2627 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2628 password, &neg_flags, perr);
2629 if (!netlogon_pipe) {
2630 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2631 "key from server %s for domain %s.\n",
2632 cli->desthost, domain ));
2633 return NULL;
2636 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2637 auth_level,
2638 domain, netlogon_pipe->dc, perr);
2640 /* Now we've bound using the session key we can close the netlog pipe. */
2641 TALLOC_FREE(netlogon_pipe);
2643 return result;
2646 /****************************************************************************
2647 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2648 Fetch the session key ourselves using a temporary netlogon pipe.
2649 ****************************************************************************/
2651 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2652 int pipe_idx,
2653 enum pipe_auth_level auth_level,
2654 const char *domain,
2655 NTSTATUS *perr)
2657 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2658 struct rpc_pipe_client *netlogon_pipe = NULL;
2659 struct rpc_pipe_client *result = NULL;
2661 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2662 if (!netlogon_pipe) {
2663 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2664 "key from server %s for domain %s.\n",
2665 cli->desthost, domain ));
2666 return NULL;
2669 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2670 auth_level,
2671 domain, netlogon_pipe->dc, perr);
2673 /* Now we've bound using the session key we can close the netlog pipe. */
2674 TALLOC_FREE(netlogon_pipe);
2676 return result;
2679 #ifdef HAVE_KRB5
2681 /****************************************************************************
2682 Free function for the kerberos spcific data.
2683 ****************************************************************************/
2685 static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
2687 data_blob_free(&a->a_u.kerberos_auth->session_key);
2690 #endif
2692 /****************************************************************************
2693 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2694 The idea is this can be called with service_princ, username and password all
2695 NULL so long as the caller has a TGT.
2696 ****************************************************************************/
2698 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2699 int pipe_idx,
2700 enum pipe_auth_level auth_level,
2701 const char *service_princ,
2702 const char *username,
2703 const char *password,
2704 NTSTATUS *perr)
2706 #ifdef HAVE_KRB5
2707 struct rpc_pipe_client *result;
2709 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2710 if (result == NULL) {
2711 return NULL;
2714 /* Default service principal is "desthost$@realm" */
2715 if (!service_princ) {
2716 service_princ = talloc_asprintf(result, "%s$@%s",
2717 cli->desthost, lp_realm() );
2718 if (!service_princ) {
2719 TALLOC_FREE(result);
2720 return NULL;
2724 /* Only get a new TGT if username/password are given. */
2725 if (username && password) {
2726 int ret = kerberos_kinit_password(username, password, 0, NULL);
2727 if (ret) {
2728 TALLOC_FREE(result);
2729 return NULL;
2733 result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(
2734 result, struct kerberos_auth_struct);
2735 if (!result->auth.a_u.kerberos_auth) {
2736 TALLOC_FREE(result);
2737 *perr = NT_STATUS_NO_MEMORY;
2738 return NULL;
2741 result->auth.a_u.kerberos_auth->service_principal = service_princ;
2742 result->auth.cli_auth_data_free_func = kerberos_auth_struct_free;
2744 *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
2745 if (!NT_STATUS_IS_OK(*perr)) {
2746 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2747 nt_errstr(*perr) ));
2748 TALLOC_FREE(result);
2749 return NULL;
2752 return result;
2753 #else
2754 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
2755 return NULL;
2756 #endif