Revert "cli_rpc_pipe_open_noauth must take the user/domain from the smb session"
[Samba.git] / source / rpc_client / cli_pipe.c
blob1897cff18e8cac54e0b4106df112abbd0d90f75f
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
227 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
228 return NT_STATUS_OK;
231 if (!ntlmssp_state) {
232 return NT_STATUS_INVALID_PARAMETER;
235 /* Ensure there's enough data for an authenticated response. */
236 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
237 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
238 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
239 (unsigned int)auth_len ));
240 return NT_STATUS_BUFFER_TOO_SMALL;
244 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
245 * after the RPC header.
246 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
247 * functions as NTLMv2 checks the rpc headers also.
250 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
251 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
253 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
254 full_packet_data_len = prhdr->frag_len - auth_len;
256 /* Pull the auth header and the following data into a blob. */
257 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
258 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
259 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
260 return NT_STATUS_BUFFER_TOO_SMALL;
263 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
264 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
265 return NT_STATUS_BUFFER_TOO_SMALL;
268 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
269 auth_blob.length = auth_len;
271 switch (cli->auth->auth_level) {
272 case PIPE_AUTH_LEVEL_PRIVACY:
273 /* Data is encrypted. */
274 status = ntlmssp_unseal_packet(ntlmssp_state,
275 data, data_len,
276 full_packet_data,
277 full_packet_data_len,
278 &auth_blob);
279 if (!NT_STATUS_IS_OK(status)) {
280 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
281 "packet from remote machine %s on pipe %s "
282 "fnum 0x%x. Error was %s.\n",
283 cli->desthost,
284 cli->pipe_name,
285 (unsigned int)cli->fnum,
286 nt_errstr(status) ));
287 return status;
289 break;
290 case PIPE_AUTH_LEVEL_INTEGRITY:
291 /* Data is signed. */
292 status = ntlmssp_check_packet(ntlmssp_state,
293 data, data_len,
294 full_packet_data,
295 full_packet_data_len,
296 &auth_blob);
297 if (!NT_STATUS_IS_OK(status)) {
298 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
299 "packet from remote machine %s on pipe %s "
300 "fnum 0x%x. Error was %s.\n",
301 cli->desthost,
302 cli->pipe_name,
303 (unsigned int)cli->fnum,
304 nt_errstr(status) ));
305 return status;
307 break;
308 default:
309 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
310 "auth level %d\n", cli->auth->auth_level));
311 return NT_STATUS_INVALID_INFO_CLASS;
315 * Return the current pointer to the data offset.
318 if(!prs_set_offset(current_pdu, save_offset)) {
319 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
320 (unsigned int)save_offset ));
321 return NT_STATUS_BUFFER_TOO_SMALL;
325 * Remember the padding length. We must remove it from the real data
326 * stream once the sign/seal is done.
329 *p_ss_padding_len = auth_info.auth_pad_len;
331 return NT_STATUS_OK;
334 /****************************************************************************
335 schannel specific sign/seal.
336 ****************************************************************************/
338 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
339 prs_struct *current_pdu,
340 uint8 *p_ss_padding_len)
342 RPC_HDR_AUTH auth_info;
343 RPC_AUTH_SCHANNEL_CHK schannel_chk;
344 uint32 auth_len = prhdr->auth_len;
345 uint32 save_offset = prs_offset(current_pdu);
346 struct schannel_auth_struct *schannel_auth =
347 cli->auth->a_u.schannel_auth;
348 uint32 data_len;
350 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
351 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
352 return NT_STATUS_OK;
355 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
356 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
357 return NT_STATUS_INVALID_PARAMETER;
360 if (!schannel_auth) {
361 return NT_STATUS_INVALID_PARAMETER;
364 /* Ensure there's enough data for an authenticated response. */
365 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
366 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
367 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
368 (unsigned int)auth_len ));
369 return NT_STATUS_INVALID_PARAMETER;
372 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
374 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
375 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
376 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
377 return NT_STATUS_BUFFER_TOO_SMALL;
380 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
381 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
382 return NT_STATUS_BUFFER_TOO_SMALL;
385 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
386 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
387 auth_info.auth_type));
388 return NT_STATUS_BUFFER_TOO_SMALL;
391 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
392 &schannel_chk, current_pdu, 0)) {
393 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
394 return NT_STATUS_BUFFER_TOO_SMALL;
397 if (!schannel_decode(schannel_auth,
398 cli->auth->auth_level,
399 SENDER_IS_ACCEPTOR,
400 &schannel_chk,
401 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
402 data_len)) {
403 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
404 "Connection to remote machine %s "
405 "pipe %s fnum 0x%x.\n",
406 cli->desthost,
407 cli->pipe_name,
408 (unsigned int)cli->fnum ));
409 return NT_STATUS_INVALID_PARAMETER;
412 /* The sequence number gets incremented on both send and receive. */
413 schannel_auth->seq_num++;
416 * Return the current pointer to the data offset.
419 if(!prs_set_offset(current_pdu, save_offset)) {
420 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
421 (unsigned int)save_offset ));
422 return NT_STATUS_BUFFER_TOO_SMALL;
426 * Remember the padding length. We must remove it from the real data
427 * stream once the sign/seal is done.
430 *p_ss_padding_len = auth_info.auth_pad_len;
432 return NT_STATUS_OK;
435 /****************************************************************************
436 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
437 ****************************************************************************/
439 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
440 prs_struct *current_pdu,
441 uint8 *p_ss_padding_len)
443 NTSTATUS ret = NT_STATUS_OK;
445 /* Paranioa checks for auth_len. */
446 if (prhdr->auth_len) {
447 if (prhdr->auth_len > prhdr->frag_len) {
448 return NT_STATUS_INVALID_PARAMETER;
451 if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len ||
452 prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) {
453 /* Integer wrap attempt. */
454 return NT_STATUS_INVALID_PARAMETER;
459 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
462 switch(cli->auth->auth_type) {
463 case PIPE_AUTH_TYPE_NONE:
464 if (prhdr->auth_len) {
465 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
466 "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
467 cli->desthost,
468 cli->pipe_name,
469 (unsigned int)cli->fnum,
470 (unsigned int)prhdr->auth_len ));
471 return NT_STATUS_INVALID_PARAMETER;
473 break;
475 case PIPE_AUTH_TYPE_NTLMSSP:
476 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
477 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
478 if (!NT_STATUS_IS_OK(ret)) {
479 return ret;
481 break;
483 case PIPE_AUTH_TYPE_SCHANNEL:
484 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
485 if (!NT_STATUS_IS_OK(ret)) {
486 return ret;
488 break;
490 case PIPE_AUTH_TYPE_KRB5:
491 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
492 default:
493 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
494 "to remote machine %s pipe %s fnum %x - "
495 "unknown internal auth type %u.\n",
496 cli->desthost, cli->pipe_name,
497 (unsigned int)cli->fnum,
498 cli->auth->auth_type ));
499 return NT_STATUS_INVALID_INFO_CLASS;
502 return NT_STATUS_OK;
505 /****************************************************************************
506 Do basic authentication checks on an incoming pdu.
507 ****************************************************************************/
509 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
510 prs_struct *current_pdu,
511 uint8 expected_pkt_type,
512 char **ppdata,
513 uint32 *pdata_len,
514 prs_struct *return_data)
517 NTSTATUS ret = NT_STATUS_OK;
518 uint32 current_pdu_len = prs_data_size(current_pdu);
520 if (current_pdu_len != prhdr->frag_len) {
521 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
522 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
523 return NT_STATUS_INVALID_PARAMETER;
527 * Point the return values at the real data including the RPC
528 * header. Just in case the caller wants it.
530 *ppdata = prs_data_p(current_pdu);
531 *pdata_len = current_pdu_len;
533 /* Ensure we have the correct type. */
534 switch (prhdr->pkt_type) {
535 case RPC_ALTCONTRESP:
536 case RPC_BINDACK:
538 /* Alter context and bind ack share the same packet definitions. */
539 break;
542 case RPC_RESPONSE:
544 RPC_HDR_RESP rhdr_resp;
545 uint8 ss_padding_len = 0;
547 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
548 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
549 return NT_STATUS_BUFFER_TOO_SMALL;
552 /* Here's where we deal with incoming sign/seal. */
553 ret = cli_pipe_validate_rpc_response(cli, prhdr,
554 current_pdu, &ss_padding_len);
555 if (!NT_STATUS_IS_OK(ret)) {
556 return ret;
559 /* Point the return values at the NDR data. Remember to remove any ss padding. */
560 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
562 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
563 return NT_STATUS_BUFFER_TOO_SMALL;
566 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
568 /* Remember to remove the auth footer. */
569 if (prhdr->auth_len) {
570 /* We've already done integer wrap tests on auth_len in
571 cli_pipe_validate_rpc_response(). */
572 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
573 return NT_STATUS_BUFFER_TOO_SMALL;
575 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
578 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
579 current_pdu_len, *pdata_len, ss_padding_len ));
582 * If this is the first reply, and the allocation hint is reasonably, try and
583 * set up the return_data parse_struct to the correct size.
586 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
587 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
588 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
589 "too large to allocate\n",
590 (unsigned int)rhdr_resp.alloc_hint ));
591 return NT_STATUS_NO_MEMORY;
595 break;
598 case RPC_BINDNACK:
599 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
600 "pipe %s fnum 0x%x!\n",
601 cli->desthost,
602 cli->pipe_name,
603 (unsigned int)cli->fnum));
604 /* Use this for now... */
605 return NT_STATUS_NETWORK_ACCESS_DENIED;
607 case RPC_FAULT:
609 RPC_HDR_RESP rhdr_resp;
610 RPC_HDR_FAULT fault_resp;
612 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
613 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
614 return NT_STATUS_BUFFER_TOO_SMALL;
617 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
618 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
619 return NT_STATUS_BUFFER_TOO_SMALL;
622 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
623 "pipe %s fnum 0x%x!\n",
624 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
625 cli->desthost,
626 cli->pipe_name,
627 (unsigned int)cli->fnum));
628 if (NT_STATUS_IS_OK(fault_resp.status)) {
629 return NT_STATUS_UNSUCCESSFUL;
630 } else {
631 return fault_resp.status;
635 default:
636 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
637 "from remote machine %s pipe %s fnum 0x%x!\n",
638 (unsigned int)prhdr->pkt_type,
639 cli->desthost,
640 cli->pipe_name,
641 (unsigned int)cli->fnum));
642 return NT_STATUS_INVALID_INFO_CLASS;
645 if (prhdr->pkt_type != expected_pkt_type) {
646 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
647 "pipe %s fnum %x got an unexpected RPC packet "
648 "type - %u, not %u\n",
649 cli->desthost,
650 cli->pipe_name,
651 (unsigned int)cli->fnum,
652 prhdr->pkt_type,
653 expected_pkt_type));
654 return NT_STATUS_INVALID_INFO_CLASS;
657 /* Do this just before return - we don't want to modify any rpc header
658 data before now as we may have needed to do cryptographic actions on
659 it before. */
661 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
662 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
663 "setting fragment first/last ON.\n"));
664 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
667 return NT_STATUS_OK;
670 /****************************************************************************
671 Ensure we eat the just processed pdu from the current_pdu prs_struct.
672 Normally the frag_len and buffer size will match, but on the first trans
673 reply there is a theoretical chance that buffer size > frag_len, so we must
674 deal with that.
675 ****************************************************************************/
677 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
679 uint32 current_pdu_len = prs_data_size(current_pdu);
681 if (current_pdu_len < prhdr->frag_len) {
682 return NT_STATUS_BUFFER_TOO_SMALL;
685 /* Common case. */
686 if (current_pdu_len == (uint32)prhdr->frag_len) {
687 prs_mem_free(current_pdu);
688 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
689 /* Make current_pdu dynamic with no memory. */
690 prs_give_memory(current_pdu, 0, 0, True);
691 return NT_STATUS_OK;
695 * Oh no ! More data in buffer than we processed in current pdu.
696 * Cheat. Move the data down and shrink the buffer.
699 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
700 current_pdu_len - prhdr->frag_len);
702 /* Remember to set the read offset back to zero. */
703 prs_set_offset(current_pdu, 0);
705 /* Shrink the buffer. */
706 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
707 return NT_STATUS_BUFFER_TOO_SMALL;
710 return NT_STATUS_OK;
713 /****************************************************************************
714 Send data on an rpc pipe via trans. The prs_struct data must be the last
715 pdu fragment of an NDR data stream.
717 Receive response data from an rpc pipe, which may be large...
719 Read the first fragment: unfortunately have to use SMBtrans for the first
720 bit, then SMBreadX for subsequent bits.
722 If first fragment received also wasn't the last fragment, continue
723 getting fragments until we _do_ receive the last fragment.
725 Request/Response PDU's look like the following...
727 |<------------------PDU len----------------------------------------------->|
728 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
730 +------------+-----------------+-------------+---------------+-------------+
731 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
732 +------------+-----------------+-------------+---------------+-------------+
734 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
735 signing & sealing being negotiated.
737 ****************************************************************************/
739 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
740 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
741 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
742 uint8 expected_pkt_type)
744 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
745 char *rparam = NULL;
746 uint32 rparam_len = 0;
747 uint16 setup[2];
748 char *pdata = prs_data_p(data);
749 uint32 data_len = prs_offset(data);
750 char *prdata = NULL;
751 uint32 rdata_len = 0;
752 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
753 uint32 current_rbuf_offset = 0;
754 prs_struct current_pdu;
756 #ifdef DEVELOPER
757 /* Ensure we're not sending too much. */
758 SMB_ASSERT(data_len <= max_data);
759 #endif
761 /* Set up the current pdu parse struct. */
762 prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
764 /* Create setup parameters - must be in native byte order. */
765 setup[0] = TRANSACT_DCERPCCMD;
766 setup[1] = cli->fnum; /* Pipe file handle. */
768 DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
769 cli->desthost,
770 cli->pipe_name,
771 (unsigned int)cli->fnum ));
774 * Send the last (or only) fragment of an RPC request. For small
775 * amounts of data (about 1024 bytes or so) the RPC request and response
776 * appears in a SMBtrans request and response.
779 if (!cli_api_pipe(cli->cli, "\\PIPE\\",
780 setup, 2, 0, /* Setup, length, max */
781 NULL, 0, 0, /* Params, length, max */
782 pdata, data_len, max_data, /* data, length, max */
783 &rparam, &rparam_len, /* return params, len */
784 &prdata, &rdata_len)) /* return data, len */
786 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x "
787 "returned critical error. Error was %s\n",
788 cli->desthost,
789 cli->pipe_name,
790 (unsigned int)cli->fnum,
791 cli_errstr(cli->cli)));
792 ret = cli_get_nt_error(cli->cli);
793 SAFE_FREE(rparam);
794 SAFE_FREE(prdata);
795 goto err;
798 /* Throw away returned params - we know we won't use them. */
800 SAFE_FREE(rparam);
802 if (prdata == NULL) {
803 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
804 "fnum 0x%x failed to return data.\n",
805 cli->desthost,
806 cli->pipe_name,
807 (unsigned int)cli->fnum));
808 /* Yes - some calls can truely return no data... */
809 prs_mem_free(&current_pdu);
810 return NT_STATUS_OK;
814 * Give this memory as dynamic to the current pdu.
817 prs_give_memory(&current_pdu, prdata, rdata_len, True);
819 /* Ensure we can mess with the return prs_struct. */
820 SMB_ASSERT(UNMARSHALLING(rbuf));
821 SMB_ASSERT(prs_data_size(rbuf) == 0);
823 /* Make rbuf dynamic with no memory. */
824 prs_give_memory(rbuf, 0, 0, True);
826 while(1) {
827 RPC_HDR rhdr;
828 char *ret_data;
829 uint32 ret_data_len;
831 /* Ensure we have enough data for a pdu. */
832 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
833 if (!NT_STATUS_IS_OK(ret)) {
834 goto err;
837 /* We pass in rbuf here so if the alloc hint is set correctly
838 we can set the output size and avoid reallocs. */
840 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
841 &ret_data, &ret_data_len, rbuf);
843 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
844 prs_data_size(&current_pdu), current_rbuf_offset ));
846 if (!NT_STATUS_IS_OK(ret)) {
847 goto err;
850 if ((rhdr.flags & RPC_FLG_FIRST)) {
851 if (rhdr.pack_type[0] == 0) {
852 /* Set the data type correctly for big-endian data on the first packet. */
853 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
854 "PDU data format is big-endian.\n",
855 cli->desthost,
856 cli->pipe_name,
857 (unsigned int)cli->fnum));
859 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
860 } else {
861 /* Check endianness on subsequent packets. */
862 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
863 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
864 rbuf->bigendian_data ? "big" : "little",
865 current_pdu.bigendian_data ? "big" : "little" ));
866 ret = NT_STATUS_INVALID_PARAMETER;
867 goto err;
872 /* Now copy the data portion out of the pdu into rbuf. */
873 if (!prs_force_grow(rbuf, ret_data_len)) {
874 ret = NT_STATUS_NO_MEMORY;
875 goto err;
877 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
878 current_rbuf_offset += ret_data_len;
880 /* See if we've finished with all the data in current_pdu yet ? */
881 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
882 if (!NT_STATUS_IS_OK(ret)) {
883 goto err;
886 if (rhdr.flags & RPC_FLG_LAST) {
887 break; /* We're done. */
891 DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
892 cli->desthost,
893 cli->pipe_name,
894 (unsigned int)cli->fnum,
895 (unsigned int)prs_data_size(rbuf) ));
897 prs_mem_free(&current_pdu);
898 return NT_STATUS_OK;
900 err:
902 prs_mem_free(&current_pdu);
903 prs_mem_free(rbuf);
904 return ret;
907 /*******************************************************************
908 Creates krb5 auth bind.
909 ********************************************************************/
911 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
912 enum pipe_auth_level auth_level,
913 RPC_HDR_AUTH *pauth_out,
914 prs_struct *auth_data)
916 #ifdef HAVE_KRB5
917 int ret;
918 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
919 DATA_BLOB tkt = data_blob_null;
920 DATA_BLOB tkt_wrapped = data_blob_null;
922 /* We may change the pad length before marshalling. */
923 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
925 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
926 a->service_principal ));
928 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
930 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
931 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
933 if (ret) {
934 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
935 "failed with %s\n",
936 a->service_principal,
937 error_message(ret) ));
939 data_blob_free(&tkt);
940 prs_mem_free(auth_data);
941 return NT_STATUS_INVALID_PARAMETER;
944 /* wrap that up in a nice GSS-API wrapping */
945 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
947 data_blob_free(&tkt);
949 /* Auth len in the rpc header doesn't include auth_header. */
950 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
951 data_blob_free(&tkt_wrapped);
952 prs_mem_free(auth_data);
953 return NT_STATUS_NO_MEMORY;
956 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
957 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
959 data_blob_free(&tkt_wrapped);
960 return NT_STATUS_OK;
961 #else
962 return NT_STATUS_INVALID_PARAMETER;
963 #endif
966 /*******************************************************************
967 Creates SPNEGO NTLMSSP auth bind.
968 ********************************************************************/
970 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
971 enum pipe_auth_level auth_level,
972 RPC_HDR_AUTH *pauth_out,
973 prs_struct *auth_data)
975 NTSTATUS nt_status;
976 DATA_BLOB null_blob = data_blob_null;
977 DATA_BLOB request = data_blob_null;
978 DATA_BLOB spnego_msg = data_blob_null;
980 /* We may change the pad length before marshalling. */
981 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
983 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
984 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
985 null_blob,
986 &request);
988 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
989 data_blob_free(&request);
990 prs_mem_free(auth_data);
991 return nt_status;
994 /* Wrap this in SPNEGO. */
995 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
997 data_blob_free(&request);
999 /* Auth len in the rpc header doesn't include auth_header. */
1000 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1001 data_blob_free(&spnego_msg);
1002 prs_mem_free(auth_data);
1003 return NT_STATUS_NO_MEMORY;
1006 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1007 dump_data(5, spnego_msg.data, spnego_msg.length);
1009 data_blob_free(&spnego_msg);
1010 return NT_STATUS_OK;
1013 /*******************************************************************
1014 Creates NTLMSSP auth bind.
1015 ********************************************************************/
1017 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1018 enum pipe_auth_level auth_level,
1019 RPC_HDR_AUTH *pauth_out,
1020 prs_struct *auth_data)
1022 NTSTATUS nt_status;
1023 DATA_BLOB null_blob = data_blob_null;
1024 DATA_BLOB request = data_blob_null;
1026 /* We may change the pad length before marshalling. */
1027 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1029 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1030 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1031 null_blob,
1032 &request);
1034 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1035 data_blob_free(&request);
1036 prs_mem_free(auth_data);
1037 return nt_status;
1040 /* Auth len in the rpc header doesn't include auth_header. */
1041 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1042 data_blob_free(&request);
1043 prs_mem_free(auth_data);
1044 return NT_STATUS_NO_MEMORY;
1047 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1048 dump_data(5, request.data, request.length);
1050 data_blob_free(&request);
1051 return NT_STATUS_OK;
1054 /*******************************************************************
1055 Creates schannel auth bind.
1056 ********************************************************************/
1058 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1059 enum pipe_auth_level auth_level,
1060 RPC_HDR_AUTH *pauth_out,
1061 prs_struct *auth_data)
1063 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1065 /* We may change the pad length before marshalling. */
1066 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1068 /* Use lp_workgroup() if domain not specified */
1070 if (!cli->auth->domain || !cli->auth->domain[0]) {
1071 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1072 if (cli->auth->domain == NULL) {
1073 return NT_STATUS_NO_MEMORY;
1077 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1078 global_myname());
1081 * Now marshall the data into the auth parse_struct.
1084 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1085 &schannel_neg, auth_data, 0)) {
1086 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1087 prs_mem_free(auth_data);
1088 return NT_STATUS_NO_MEMORY;
1091 return NT_STATUS_OK;
1094 /*******************************************************************
1095 Creates the internals of a DCE/RPC bind request or alter context PDU.
1096 ********************************************************************/
1098 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1099 prs_struct *rpc_out,
1100 uint32 rpc_call_id,
1101 const RPC_IFACE *abstract,
1102 const RPC_IFACE *transfer,
1103 RPC_HDR_AUTH *phdr_auth,
1104 prs_struct *pauth_info)
1106 RPC_HDR hdr;
1107 RPC_HDR_RB hdr_rb;
1108 RPC_CONTEXT rpc_ctx;
1109 uint16 auth_len = prs_offset(pauth_info);
1110 uint8 ss_padding_len = 0;
1111 uint16 frag_len = 0;
1113 /* create the RPC context. */
1114 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1116 /* create the bind request RPC_HDR_RB */
1117 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1119 /* Start building the frag length. */
1120 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1122 /* Do we need to pad ? */
1123 if (auth_len) {
1124 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1125 if (data_len % 8) {
1126 ss_padding_len = 8 - (data_len % 8);
1127 phdr_auth->auth_pad_len = ss_padding_len;
1129 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1132 /* Create the request RPC_HDR */
1133 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1135 /* Marshall the RPC header */
1136 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1137 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1138 return NT_STATUS_NO_MEMORY;
1141 /* Marshall the bind request data */
1142 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1143 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1144 return NT_STATUS_NO_MEMORY;
1148 * Grow the outgoing buffer to store any auth info.
1151 if(auth_len != 0) {
1152 if (ss_padding_len) {
1153 char pad[8];
1154 memset(pad, '\0', 8);
1155 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1156 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1157 return NT_STATUS_NO_MEMORY;
1161 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1162 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1163 return NT_STATUS_NO_MEMORY;
1167 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1168 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1169 return NT_STATUS_NO_MEMORY;
1173 return NT_STATUS_OK;
1176 /*******************************************************************
1177 Creates a DCE/RPC bind request.
1178 ********************************************************************/
1180 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1181 prs_struct *rpc_out,
1182 uint32 rpc_call_id,
1183 const RPC_IFACE *abstract,
1184 const RPC_IFACE *transfer,
1185 enum pipe_auth_type auth_type,
1186 enum pipe_auth_level auth_level)
1188 RPC_HDR_AUTH hdr_auth;
1189 prs_struct auth_info;
1190 NTSTATUS ret = NT_STATUS_OK;
1192 ZERO_STRUCT(hdr_auth);
1193 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1194 return NT_STATUS_NO_MEMORY;
1196 switch (auth_type) {
1197 case PIPE_AUTH_TYPE_SCHANNEL:
1198 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1199 if (!NT_STATUS_IS_OK(ret)) {
1200 prs_mem_free(&auth_info);
1201 return ret;
1203 break;
1205 case PIPE_AUTH_TYPE_NTLMSSP:
1206 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1207 if (!NT_STATUS_IS_OK(ret)) {
1208 prs_mem_free(&auth_info);
1209 return ret;
1211 break;
1213 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1214 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1215 if (!NT_STATUS_IS_OK(ret)) {
1216 prs_mem_free(&auth_info);
1217 return ret;
1219 break;
1221 case PIPE_AUTH_TYPE_KRB5:
1222 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1223 if (!NT_STATUS_IS_OK(ret)) {
1224 prs_mem_free(&auth_info);
1225 return ret;
1227 break;
1229 case PIPE_AUTH_TYPE_NONE:
1230 break;
1232 default:
1233 /* "Can't" happen. */
1234 return NT_STATUS_INVALID_INFO_CLASS;
1237 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1238 rpc_out,
1239 rpc_call_id,
1240 abstract,
1241 transfer,
1242 &hdr_auth,
1243 &auth_info);
1245 prs_mem_free(&auth_info);
1246 return ret;
1249 /*******************************************************************
1250 Create and add the NTLMSSP sign/seal auth header and data.
1251 ********************************************************************/
1253 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1254 RPC_HDR *phdr,
1255 uint32 ss_padding_len,
1256 prs_struct *outgoing_pdu)
1258 RPC_HDR_AUTH auth_info;
1259 NTSTATUS status;
1260 DATA_BLOB auth_blob = data_blob_null;
1261 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1263 if (!cli->auth->a_u.ntlmssp_state) {
1264 return NT_STATUS_INVALID_PARAMETER;
1267 /* Init and marshall the auth header. */
1268 init_rpc_hdr_auth(&auth_info,
1269 map_pipe_auth_type_to_rpc_auth_type(
1270 cli->auth->auth_type),
1271 cli->auth->auth_level,
1272 ss_padding_len,
1273 1 /* context id. */);
1275 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1276 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1277 data_blob_free(&auth_blob);
1278 return NT_STATUS_NO_MEMORY;
1281 switch (cli->auth->auth_level) {
1282 case PIPE_AUTH_LEVEL_PRIVACY:
1283 /* Data portion is encrypted. */
1284 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1285 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1286 data_and_pad_len,
1287 (unsigned char *)prs_data_p(outgoing_pdu),
1288 (size_t)prs_offset(outgoing_pdu),
1289 &auth_blob);
1290 if (!NT_STATUS_IS_OK(status)) {
1291 data_blob_free(&auth_blob);
1292 return status;
1294 break;
1296 case PIPE_AUTH_LEVEL_INTEGRITY:
1297 /* Data is signed. */
1298 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1299 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1300 data_and_pad_len,
1301 (unsigned char *)prs_data_p(outgoing_pdu),
1302 (size_t)prs_offset(outgoing_pdu),
1303 &auth_blob);
1304 if (!NT_STATUS_IS_OK(status)) {
1305 data_blob_free(&auth_blob);
1306 return status;
1308 break;
1310 default:
1311 /* Can't happen. */
1312 smb_panic("bad auth level");
1313 /* Notreached. */
1314 return NT_STATUS_INVALID_PARAMETER;
1317 /* Finally marshall the blob. */
1319 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1320 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1321 (unsigned int)NTLMSSP_SIG_SIZE));
1322 data_blob_free(&auth_blob);
1323 return NT_STATUS_NO_MEMORY;
1326 data_blob_free(&auth_blob);
1327 return NT_STATUS_OK;
1330 /*******************************************************************
1331 Create and add the schannel sign/seal auth header and data.
1332 ********************************************************************/
1334 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1335 RPC_HDR *phdr,
1336 uint32 ss_padding_len,
1337 prs_struct *outgoing_pdu)
1339 RPC_HDR_AUTH auth_info;
1340 RPC_AUTH_SCHANNEL_CHK verf;
1341 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1342 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1343 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1345 if (!sas) {
1346 return NT_STATUS_INVALID_PARAMETER;
1349 /* Init and marshall the auth header. */
1350 init_rpc_hdr_auth(&auth_info,
1351 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1352 cli->auth->auth_level,
1353 ss_padding_len,
1354 1 /* context id. */);
1356 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1357 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1358 return NT_STATUS_NO_MEMORY;
1361 switch (cli->auth->auth_level) {
1362 case PIPE_AUTH_LEVEL_PRIVACY:
1363 case PIPE_AUTH_LEVEL_INTEGRITY:
1364 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1365 sas->seq_num));
1367 schannel_encode(sas,
1368 cli->auth->auth_level,
1369 SENDER_IS_INITIATOR,
1370 &verf,
1371 data_p,
1372 data_and_pad_len);
1374 sas->seq_num++;
1375 break;
1377 default:
1378 /* Can't happen. */
1379 smb_panic("bad auth level");
1380 /* Notreached. */
1381 return NT_STATUS_INVALID_PARAMETER;
1384 /* Finally marshall the blob. */
1385 smb_io_rpc_auth_schannel_chk("",
1386 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1387 &verf,
1388 outgoing_pdu,
1391 return NT_STATUS_OK;
1394 /*******************************************************************
1395 Calculate how much data we're going to send in this packet, also
1396 work out any sign/seal padding length.
1397 ********************************************************************/
1399 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1400 uint32 data_left,
1401 uint16 *p_frag_len,
1402 uint16 *p_auth_len,
1403 uint32 *p_ss_padding)
1405 uint32 data_space, data_len;
1407 switch (cli->auth->auth_level) {
1408 case PIPE_AUTH_LEVEL_NONE:
1409 case PIPE_AUTH_LEVEL_CONNECT:
1410 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1411 data_len = MIN(data_space, data_left);
1412 *p_ss_padding = 0;
1413 *p_auth_len = 0;
1414 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1415 return data_len;
1417 case PIPE_AUTH_LEVEL_INTEGRITY:
1418 case PIPE_AUTH_LEVEL_PRIVACY:
1419 /* Treat the same for all authenticated rpc requests. */
1420 switch(cli->auth->auth_type) {
1421 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1422 case PIPE_AUTH_TYPE_NTLMSSP:
1423 *p_auth_len = NTLMSSP_SIG_SIZE;
1424 break;
1425 case PIPE_AUTH_TYPE_SCHANNEL:
1426 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1427 break;
1428 default:
1429 smb_panic("bad auth type");
1430 break;
1433 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1434 RPC_HDR_AUTH_LEN - *p_auth_len;
1436 data_len = MIN(data_space, data_left);
1437 if (data_len % 8) {
1438 *p_ss_padding = 8 - (data_len % 8);
1440 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1441 data_len + *p_ss_padding + /* data plus padding. */
1442 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1443 return data_len;
1445 default:
1446 smb_panic("bad auth level");
1447 /* Notreached. */
1448 return 0;
1452 /*******************************************************************
1453 External interface.
1454 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1455 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1456 and deals with signing/sealing details.
1457 ********************************************************************/
1459 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1460 uint8 op_num,
1461 prs_struct *in_data,
1462 prs_struct *out_data)
1464 NTSTATUS ret;
1465 uint32 data_left = prs_offset(in_data);
1466 uint32 alloc_hint = prs_offset(in_data);
1467 uint32 data_sent_thistime = 0;
1468 uint32 current_data_offset = 0;
1469 uint32 call_id = get_rpc_call_id();
1470 char pad[8];
1471 prs_struct outgoing_pdu;
1473 memset(pad, '\0', 8);
1475 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1476 /* Server is screwed up ! */
1477 return NT_STATUS_INVALID_PARAMETER;
1480 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1481 return NT_STATUS_NO_MEMORY;
1483 while (1) {
1484 RPC_HDR hdr;
1485 RPC_HDR_REQ hdr_req;
1486 uint16 auth_len = 0;
1487 uint16 frag_len = 0;
1488 uint8 flags = 0;
1489 uint32 ss_padding = 0;
1491 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1492 &frag_len, &auth_len, &ss_padding);
1494 if (current_data_offset == 0) {
1495 flags = RPC_FLG_FIRST;
1498 if (data_sent_thistime == data_left) {
1499 flags |= RPC_FLG_LAST;
1502 /* Create and marshall the header and request header. */
1503 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1505 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1506 prs_mem_free(&outgoing_pdu);
1507 return NT_STATUS_NO_MEMORY;
1510 /* Create the rpc request RPC_HDR_REQ */
1511 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1513 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1514 prs_mem_free(&outgoing_pdu);
1515 return NT_STATUS_NO_MEMORY;
1518 /* Copy in the data, plus any ss padding. */
1519 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1520 prs_mem_free(&outgoing_pdu);
1521 return NT_STATUS_NO_MEMORY;
1524 /* Copy the sign/seal padding data. */
1525 if (ss_padding) {
1526 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1527 prs_mem_free(&outgoing_pdu);
1528 return NT_STATUS_NO_MEMORY;
1532 /* Generate any auth sign/seal and add the auth footer. */
1533 if (auth_len) {
1534 switch (cli->auth->auth_type) {
1535 case PIPE_AUTH_TYPE_NONE:
1536 break;
1537 case PIPE_AUTH_TYPE_NTLMSSP:
1538 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1539 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1540 if (!NT_STATUS_IS_OK(ret)) {
1541 prs_mem_free(&outgoing_pdu);
1542 return ret;
1544 break;
1545 case PIPE_AUTH_TYPE_SCHANNEL:
1546 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1547 if (!NT_STATUS_IS_OK(ret)) {
1548 prs_mem_free(&outgoing_pdu);
1549 return ret;
1551 break;
1552 default:
1553 smb_panic("bad auth type");
1554 break; /* notreached */
1558 /* Actually send the packet. */
1559 if (flags & RPC_FLG_LAST) {
1560 /* Last packet - send the data, get the reply and return. */
1561 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1562 prs_mem_free(&outgoing_pdu);
1564 if (DEBUGLEVEL >= 50) {
1565 char *dump_name = NULL;
1566 /* Also capture received data */
1567 if (asprintf(&dump_name, "%s/reply_%s_%d",
1568 get_dyn_LOGFILEBASE(), cli->pipe_name,
1569 op_num) > 0) {
1570 prs_dump(dump_name, op_num, out_data);
1571 SAFE_FREE(dump_name);
1575 return ret;
1576 } else {
1577 /* More packets to come - write and continue. */
1578 ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */
1579 prs_data_p(&outgoing_pdu),
1580 (off_t)0,
1581 (size_t)hdr.frag_len);
1583 if (num_written != hdr.frag_len) {
1584 prs_mem_free(&outgoing_pdu);
1585 return cli_get_nt_error(cli->cli);
1589 current_data_offset += data_sent_thistime;
1590 data_left -= data_sent_thistime;
1592 /* Reset the marshalling position back to zero. */
1593 if (!prs_set_offset(&outgoing_pdu, 0)) {
1594 prs_mem_free(&outgoing_pdu);
1595 return NT_STATUS_NO_MEMORY;
1599 #if 0
1600 /****************************************************************************
1601 Set the handle state.
1602 ****************************************************************************/
1604 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1605 const char *pipe_name, uint16 device_state)
1607 bool state_set = False;
1608 char param[2];
1609 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1610 char *rparam = NULL;
1611 char *rdata = NULL;
1612 uint32 rparam_len, rdata_len;
1614 if (pipe_name == NULL)
1615 return False;
1617 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1618 cli->fnum, pipe_name, device_state));
1620 /* create parameters: device state */
1621 SSVAL(param, 0, device_state);
1623 /* create setup parameters. */
1624 setup[0] = 0x0001;
1625 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1627 /* send the data on \PIPE\ */
1628 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1629 setup, 2, 0, /* setup, length, max */
1630 param, 2, 0, /* param, length, max */
1631 NULL, 0, 1024, /* data, length, max */
1632 &rparam, &rparam_len, /* return param, length */
1633 &rdata, &rdata_len)) /* return data, length */
1635 DEBUG(5, ("Set Handle state: return OK\n"));
1636 state_set = True;
1639 SAFE_FREE(rparam);
1640 SAFE_FREE(rdata);
1642 return state_set;
1644 #endif
1646 /****************************************************************************
1647 Check the rpc bind acknowledge response.
1648 ****************************************************************************/
1650 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1652 if ( hdr_ba->addr.len == 0) {
1653 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1656 /* check the transfer syntax */
1657 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1658 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1659 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1660 return False;
1663 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1664 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1665 hdr_ba->res.num_results, hdr_ba->res.reason));
1668 DEBUG(5,("check_bind_response: accepted!\n"));
1669 return True;
1672 /*******************************************************************
1673 Creates a DCE/RPC bind authentication response.
1674 This is the packet that is sent back to the server once we
1675 have received a BIND-ACK, to finish the third leg of
1676 the authentication handshake.
1677 ********************************************************************/
1679 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1680 uint32 rpc_call_id,
1681 enum pipe_auth_type auth_type,
1682 enum pipe_auth_level auth_level,
1683 DATA_BLOB *pauth_blob,
1684 prs_struct *rpc_out)
1686 RPC_HDR hdr;
1687 RPC_HDR_AUTH hdr_auth;
1688 uint32 pad = 0;
1690 /* Create the request RPC_HDR */
1691 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1692 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1693 pauth_blob->length );
1695 /* Marshall it. */
1696 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1697 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1698 return NT_STATUS_NO_MEMORY;
1702 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1703 about padding - shouldn't this pad to length 8 ? JRA.
1706 /* 4 bytes padding. */
1707 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1708 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1709 return NT_STATUS_NO_MEMORY;
1712 /* Create the request RPC_HDR_AUTHA */
1713 init_rpc_hdr_auth(&hdr_auth,
1714 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1715 auth_level, 0, 1);
1717 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1718 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1719 return NT_STATUS_NO_MEMORY;
1723 * Append the auth data to the outgoing buffer.
1726 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1727 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1728 return NT_STATUS_NO_MEMORY;
1731 return NT_STATUS_OK;
1734 /****************************************************************************
1735 Create and send the third packet in an RPC auth.
1736 ****************************************************************************/
1738 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1739 RPC_HDR *phdr,
1740 prs_struct *rbuf,
1741 uint32 rpc_call_id,
1742 enum pipe_auth_type auth_type,
1743 enum pipe_auth_level auth_level)
1745 DATA_BLOB server_response = data_blob_null;
1746 DATA_BLOB client_reply = data_blob_null;
1747 RPC_HDR_AUTH hdr_auth;
1748 NTSTATUS nt_status;
1749 prs_struct rpc_out;
1750 ssize_t ret;
1752 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1753 return NT_STATUS_INVALID_PARAMETER;
1756 /* Process the returned NTLMSSP blob first. */
1757 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1758 return NT_STATUS_INVALID_PARAMETER;
1761 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1762 return NT_STATUS_INVALID_PARAMETER;
1765 /* TODO - check auth_type/auth_level match. */
1767 server_response = data_blob(NULL, phdr->auth_len);
1768 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1770 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1771 server_response,
1772 &client_reply);
1774 if (!NT_STATUS_IS_OK(nt_status)) {
1775 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1776 data_blob_free(&server_response);
1777 return nt_status;
1780 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1782 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1783 auth_type, auth_level,
1784 &client_reply, &rpc_out);
1786 if (!NT_STATUS_IS_OK(nt_status)) {
1787 prs_mem_free(&rpc_out);
1788 data_blob_free(&client_reply);
1789 data_blob_free(&server_response);
1790 return nt_status;
1793 /* 8 here is named pipe message mode. */
1794 ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
1795 (size_t)prs_offset(&rpc_out));
1797 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1798 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
1799 prs_mem_free(&rpc_out);
1800 data_blob_free(&client_reply);
1801 data_blob_free(&server_response);
1802 return cli_get_nt_error(cli->cli);
1805 DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
1806 "fnum 0x%x sent auth3 response ok.\n",
1807 cli->desthost,
1808 cli->pipe_name,
1809 (unsigned int)cli->fnum));
1811 prs_mem_free(&rpc_out);
1812 data_blob_free(&client_reply);
1813 data_blob_free(&server_response);
1814 return NT_STATUS_OK;
1817 /*******************************************************************
1818 Creates a DCE/RPC bind alter context authentication request which
1819 may contain a spnego auth blobl
1820 ********************************************************************/
1822 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1823 const RPC_IFACE *abstract,
1824 const RPC_IFACE *transfer,
1825 enum pipe_auth_level auth_level,
1826 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1827 prs_struct *rpc_out)
1829 RPC_HDR_AUTH hdr_auth;
1830 prs_struct auth_info;
1831 NTSTATUS ret = NT_STATUS_OK;
1833 ZERO_STRUCT(hdr_auth);
1834 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1835 return NT_STATUS_NO_MEMORY;
1837 /* We may change the pad length before marshalling. */
1838 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1840 if (pauth_blob->length) {
1841 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1842 prs_mem_free(&auth_info);
1843 return NT_STATUS_NO_MEMORY;
1847 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1848 rpc_out,
1849 rpc_call_id,
1850 abstract,
1851 transfer,
1852 &hdr_auth,
1853 &auth_info);
1854 prs_mem_free(&auth_info);
1855 return ret;
1858 /*******************************************************************
1859 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1860 and gets a response.
1861 ********************************************************************/
1863 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1864 RPC_HDR *phdr,
1865 prs_struct *rbuf,
1866 uint32 rpc_call_id,
1867 const RPC_IFACE *abstract,
1868 const RPC_IFACE *transfer,
1869 enum pipe_auth_type auth_type,
1870 enum pipe_auth_level auth_level)
1872 DATA_BLOB server_spnego_response = data_blob_null;
1873 DATA_BLOB server_ntlm_response = data_blob_null;
1874 DATA_BLOB client_reply = data_blob_null;
1875 DATA_BLOB tmp_blob = data_blob_null;
1876 RPC_HDR_AUTH hdr_auth;
1877 NTSTATUS nt_status;
1878 prs_struct rpc_out;
1880 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1881 return NT_STATUS_INVALID_PARAMETER;
1884 /* Process the returned NTLMSSP blob first. */
1885 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1886 return NT_STATUS_INVALID_PARAMETER;
1889 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1890 return NT_STATUS_INVALID_PARAMETER;
1893 server_spnego_response = data_blob(NULL, phdr->auth_len);
1894 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1896 /* The server might give us back two challenges - tmp_blob is for the second. */
1897 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
1898 data_blob_free(&server_spnego_response);
1899 data_blob_free(&server_ntlm_response);
1900 data_blob_free(&tmp_blob);
1901 return NT_STATUS_INVALID_PARAMETER;
1904 /* We're finished with the server spnego response and the tmp_blob. */
1905 data_blob_free(&server_spnego_response);
1906 data_blob_free(&tmp_blob);
1908 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1909 server_ntlm_response,
1910 &client_reply);
1912 /* Finished with the server_ntlm response */
1913 data_blob_free(&server_ntlm_response);
1915 if (!NT_STATUS_IS_OK(nt_status)) {
1916 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
1917 data_blob_free(&client_reply);
1918 return nt_status;
1921 /* SPNEGO wrap the client reply. */
1922 tmp_blob = spnego_gen_auth(client_reply);
1923 data_blob_free(&client_reply);
1924 client_reply = tmp_blob;
1925 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
1927 /* Now prepare the alter context pdu. */
1928 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1930 nt_status = create_rpc_alter_context(rpc_call_id,
1931 abstract,
1932 transfer,
1933 auth_level,
1934 &client_reply,
1935 &rpc_out);
1937 data_blob_free(&client_reply);
1939 if (!NT_STATUS_IS_OK(nt_status)) {
1940 prs_mem_free(&rpc_out);
1941 return nt_status;
1944 /* Initialize the returning data struct. */
1945 prs_mem_free(rbuf);
1946 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
1948 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
1949 if (!NT_STATUS_IS_OK(nt_status)) {
1950 prs_mem_free(&rpc_out);
1951 return nt_status;
1954 prs_mem_free(&rpc_out);
1956 /* Get the auth blob from the reply. */
1957 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
1958 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
1959 return NT_STATUS_BUFFER_TOO_SMALL;
1962 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1963 return NT_STATUS_INVALID_PARAMETER;
1966 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1967 return NT_STATUS_INVALID_PARAMETER;
1970 server_spnego_response = data_blob(NULL, phdr->auth_len);
1971 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1973 /* Check we got a valid auth response. */
1974 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
1975 data_blob_free(&server_spnego_response);
1976 data_blob_free(&tmp_blob);
1977 return NT_STATUS_INVALID_PARAMETER;
1980 data_blob_free(&server_spnego_response);
1981 data_blob_free(&tmp_blob);
1983 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
1984 "remote machine %s pipe %s fnum 0x%x.\n",
1985 cli->desthost,
1986 cli->pipe_name,
1987 (unsigned int)cli->fnum));
1989 return NT_STATUS_OK;
1992 /****************************************************************************
1993 Do an rpc bind.
1994 ****************************************************************************/
1996 static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1997 struct cli_pipe_auth_data *auth)
1999 RPC_HDR hdr;
2000 RPC_HDR_BA hdr_ba;
2001 prs_struct rpc_out;
2002 prs_struct rbuf;
2003 uint32 rpc_call_id;
2004 NTSTATUS status;
2006 DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2007 (unsigned int)cli->fnum,
2008 cli->pipe_name,
2009 (unsigned int)auth->auth_type,
2010 (unsigned int)auth->auth_level ));
2012 cli->auth = talloc_move(cli, &auth);
2014 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2016 rpc_call_id = get_rpc_call_id();
2018 /* Marshall the outgoing data. */
2019 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2020 cli->abstract_syntax,
2021 cli->transfer_syntax,
2022 cli->auth->auth_type,
2023 cli->auth->auth_level);
2025 if (!NT_STATUS_IS_OK(status)) {
2026 prs_mem_free(&rpc_out);
2027 return status;
2030 /* Initialize the incoming data struct. */
2031 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2033 /* send data on \PIPE\. receive a response */
2034 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2035 if (!NT_STATUS_IS_OK(status)) {
2036 prs_mem_free(&rpc_out);
2037 return status;
2040 prs_mem_free(&rpc_out);
2042 DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2043 "fnum 0x%x bind request returned ok.\n",
2044 cli->desthost,
2045 cli->pipe_name,
2046 (unsigned int)cli->fnum));
2048 /* Unmarshall the RPC header */
2049 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2050 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2051 prs_mem_free(&rbuf);
2052 return NT_STATUS_BUFFER_TOO_SMALL;
2055 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2056 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2057 prs_mem_free(&rbuf);
2058 return NT_STATUS_BUFFER_TOO_SMALL;
2061 if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2062 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2063 prs_mem_free(&rbuf);
2064 return NT_STATUS_BUFFER_TOO_SMALL;
2067 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2068 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2070 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2071 switch(cli->auth->auth_type) {
2073 case PIPE_AUTH_TYPE_NONE:
2074 case PIPE_AUTH_TYPE_SCHANNEL:
2075 /* Bind complete. */
2076 break;
2078 case PIPE_AUTH_TYPE_NTLMSSP:
2079 /* Need to send AUTH3 packet - no reply. */
2080 status = rpc_finish_auth3_bind(
2081 cli, &hdr, &rbuf, rpc_call_id,
2082 cli->auth->auth_type,
2083 cli->auth->auth_level);
2084 if (!NT_STATUS_IS_OK(status)) {
2085 prs_mem_free(&rbuf);
2086 return status;
2088 break;
2090 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2091 /* Need to send alter context request and reply. */
2092 status = rpc_finish_spnego_ntlmssp_bind(
2093 cli, &hdr, &rbuf, rpc_call_id,
2094 cli->abstract_syntax, cli->transfer_syntax,
2095 cli->auth->auth_type, cli->auth->auth_level);
2096 if (!NT_STATUS_IS_OK(status)) {
2097 prs_mem_free(&rbuf);
2098 return status;
2100 break;
2102 case PIPE_AUTH_TYPE_KRB5:
2103 /* */
2105 default:
2106 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2107 "%u\n", (unsigned int)cli->auth->auth_type));
2108 prs_mem_free(&rbuf);
2109 return NT_STATUS_INVALID_INFO_CLASS;
2112 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2113 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2114 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2115 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2116 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2117 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2118 prs_mem_free(&rbuf);
2119 return NT_STATUS_INVALID_PARAMETER;
2122 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2123 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2124 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2125 prs_mem_free(&rbuf);
2126 return NT_STATUS_INVALID_PARAMETER;
2131 prs_mem_free(&rbuf);
2132 return NT_STATUS_OK;
2135 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2136 unsigned int timeout)
2138 return cli_set_timeout(cli->cli, timeout);
2141 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2143 return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
2146 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2148 if (!((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2149 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2150 E_md4hash(cli->cli->pwd.password, nt_hash);
2151 return true;
2154 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2155 return true;
2158 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2160 return p->cli;
2163 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2165 bool ret;
2167 ret = cli_close(p->cli, p->fnum);
2168 if (!ret) {
2169 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s, "
2170 "fnum 0x%x to machine %s. Error was %s\n",
2171 p->pipe_name, (int) p->fnum,
2172 p->desthost, cli_errstr(p->cli)));
2175 DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n",
2176 p->pipe_name, p->desthost ));
2178 DLIST_REMOVE(p->cli->pipe_list, p);
2180 return ret ? -1 : 0;
2183 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2184 struct cli_pipe_auth_data **presult)
2186 struct cli_pipe_auth_data *result;
2188 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2189 if (result == NULL) {
2190 return NT_STATUS_NO_MEMORY;
2193 result->auth_type = PIPE_AUTH_TYPE_NONE;
2194 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2196 result->user_name = talloc_strdup(result, "");
2197 result->domain = talloc_strdup(result, "");
2198 if ((result->user_name == NULL) || (result->domain == NULL)) {
2199 TALLOC_FREE(result);
2200 return NT_STATUS_NO_MEMORY;
2203 *presult = result;
2204 return NT_STATUS_OK;
2207 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2209 ntlmssp_end(&auth->a_u.ntlmssp_state);
2210 return 0;
2213 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2214 enum pipe_auth_type auth_type,
2215 enum pipe_auth_level auth_level,
2216 const char *domain,
2217 const char *username,
2218 const char *password,
2219 struct cli_pipe_auth_data **presult)
2221 struct cli_pipe_auth_data *result;
2222 NTSTATUS status;
2224 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2225 if (result == NULL) {
2226 return NT_STATUS_NO_MEMORY;
2229 result->auth_type = auth_type;
2230 result->auth_level = auth_level;
2232 result->user_name = talloc_strdup(result, username);
2233 result->domain = talloc_strdup(result, domain);
2234 if ((result->user_name == NULL) || (result->domain == NULL)) {
2235 status = NT_STATUS_NO_MEMORY;
2236 goto fail;
2239 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2240 if (!NT_STATUS_IS_OK(status)) {
2241 goto fail;
2244 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2246 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2247 if (!NT_STATUS_IS_OK(status)) {
2248 goto fail;
2251 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2252 if (!NT_STATUS_IS_OK(status)) {
2253 goto fail;
2256 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2257 if (!NT_STATUS_IS_OK(status)) {
2258 goto fail;
2262 * Turn off sign+seal to allow selected auth level to turn it back on.
2264 result->a_u.ntlmssp_state->neg_flags &=
2265 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2267 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2268 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2269 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2270 result->a_u.ntlmssp_state->neg_flags
2271 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2274 *presult = result;
2275 return NT_STATUS_OK;
2277 fail:
2278 TALLOC_FREE(result);
2279 return status;
2282 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2283 enum pipe_auth_level auth_level,
2284 const struct dcinfo *pdc,
2285 struct cli_pipe_auth_data **presult)
2287 struct cli_pipe_auth_data *result;
2289 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2290 if (result == NULL) {
2291 return NT_STATUS_NO_MEMORY;
2294 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2295 result->auth_level = auth_level;
2297 result->user_name = talloc_strdup(result, "");
2298 result->domain = talloc_strdup(result, domain);
2299 if ((result->user_name == NULL) || (result->domain == NULL)) {
2300 goto fail;
2303 result->a_u.schannel_auth = talloc(result,
2304 struct schannel_auth_struct);
2305 if (result->a_u.schannel_auth == NULL) {
2306 goto fail;
2309 memcpy(result->a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2310 result->a_u.schannel_auth->seq_num = 0;
2312 *presult = result;
2313 return NT_STATUS_OK;
2315 fail:
2316 TALLOC_FREE(result);
2317 return NT_STATUS_NO_MEMORY;
2320 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2322 data_blob_free(&auth->session_key);
2323 return 0;
2326 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2327 enum pipe_auth_level auth_level,
2328 const char *service_princ,
2329 const char *username,
2330 const char *password,
2331 struct cli_pipe_auth_data **presult)
2333 struct cli_pipe_auth_data *result;
2335 if ((username != NULL) && (password != NULL)) {
2336 int ret = kerberos_kinit_password(username, password, 0, NULL);
2337 if (ret != 0) {
2338 return NT_STATUS_ACCESS_DENIED;
2342 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2343 if (result == NULL) {
2344 return NT_STATUS_NO_MEMORY;
2347 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2348 result->auth_level = auth_level;
2351 * Username / domain need fixing!
2353 result->user_name = talloc_strdup(result, "");
2354 result->domain = talloc_strdup(result, "");
2355 if ((result->user_name == NULL) || (result->domain == NULL)) {
2356 goto fail;
2359 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2360 result, struct kerberos_auth_struct);
2361 if (result->a_u.kerberos_auth == NULL) {
2362 goto fail;
2364 talloc_set_destructor(result->a_u.kerberos_auth,
2365 cli_auth_kerberos_data_destructor);
2367 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2368 result, service_princ);
2369 if (result->a_u.kerberos_auth->service_principal == NULL) {
2370 goto fail;
2373 *presult = result;
2374 return NT_STATUS_OK;
2376 fail:
2377 TALLOC_FREE(result);
2378 return NT_STATUS_NO_MEMORY;
2381 /****************************************************************************
2382 Open a named pipe over SMB to a remote server.
2384 * CAVEAT CALLER OF THIS FUNCTION:
2385 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2386 * so be sure that this function is called AFTER any structure (vs pointer)
2387 * assignment of the cli. In particular, libsmbclient does structure
2388 * assignments of cli, which invalidates the data in the returned
2389 * rpc_pipe_client if this function is called before the structure assignment
2390 * of cli.
2392 ****************************************************************************/
2394 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2396 struct rpc_pipe_client *result;
2397 int fnum;
2399 *perr = NT_STATUS_NO_MEMORY;
2401 /* sanity check to protect against crashes */
2403 if ( !cli ) {
2404 *perr = NT_STATUS_INVALID_HANDLE;
2405 return NULL;
2408 /* The pipe name index must fall within our array */
2409 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2411 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2412 if (result == NULL) {
2413 *perr = NT_STATUS_NO_MEMORY;
2414 return NULL;
2417 result->pipe_name = cli_get_pipe_name(pipe_idx);
2419 result->cli = cli;
2420 result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2421 result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2422 result->desthost = talloc_strdup(result, cli->desthost);
2423 result->srv_name_slash = talloc_asprintf_strupper_m(
2424 result, "\\\\%s", result->desthost);
2426 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2427 *perr = NT_STATUS_NO_MEMORY;
2428 TALLOC_FREE(result);
2429 return NULL;
2432 if (pipe_idx == PI_NETLOGON) {
2433 /* Set up a netlogon credential chain for a netlogon pipe. */
2434 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2435 if (result->dc == NULL) {
2436 *perr = NT_STATUS_NO_MEMORY;
2437 TALLOC_FREE(result);
2438 return NULL;
2442 fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2443 if (fnum == -1) {
2444 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2445 "to machine %s. Error was %s\n",
2446 result->pipe_name, cli->desthost,
2447 cli_errstr(cli)));
2448 *perr = cli_get_nt_error(cli);
2449 talloc_destroy(result);
2450 return NULL;
2453 result->fnum = fnum;
2455 DLIST_ADD(cli->pipe_list, result);
2456 talloc_set_destructor(result, rpc_pipe_destructor);
2458 *perr = NT_STATUS_OK;
2460 return result;
2463 /****************************************************************************
2464 Open a named pipe to an SMB server and bind anonymously.
2465 ****************************************************************************/
2467 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2469 struct rpc_pipe_client *result;
2470 struct cli_pipe_auth_data *auth;
2472 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2473 if (result == NULL) {
2474 return NULL;
2477 *perr = rpccli_anon_bind_data(result, &auth);
2478 if (!NT_STATUS_IS_OK(*perr)) {
2479 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2480 nt_errstr(*perr)));
2481 TALLOC_FREE(result);
2482 return NULL;
2485 *perr = rpc_pipe_bind(result, auth);
2486 if (!NT_STATUS_IS_OK(*perr)) {
2487 int lvl = 0;
2488 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2489 /* non AD domains just don't have this pipe, avoid
2490 * level 0 statement in that case - gd */
2491 lvl = 3;
2493 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2494 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2495 TALLOC_FREE(result);
2496 return NULL;
2499 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2500 result->pipe_name, cli->desthost ));
2502 return result;
2505 /****************************************************************************
2506 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2507 ****************************************************************************/
2509 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2510 int pipe_idx,
2511 enum pipe_auth_type auth_type,
2512 enum pipe_auth_level auth_level,
2513 const char *domain,
2514 const char *username,
2515 const char *password,
2516 NTSTATUS *perr)
2518 struct rpc_pipe_client *result;
2519 struct cli_pipe_auth_data *auth;
2521 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2522 if (result == NULL) {
2523 return NULL;
2526 *perr = rpccli_ntlmssp_bind_data(
2527 result, auth_type, auth_level, domain, username,
2528 cli->pwd.null_pwd ? NULL : password, &auth);
2529 if (!NT_STATUS_IS_OK(*perr)) {
2530 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2531 nt_errstr(*perr)));
2532 TALLOC_FREE(result);
2533 return NULL;
2536 *perr = rpc_pipe_bind(result, auth);
2537 if (!NT_STATUS_IS_OK(*perr)) {
2538 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2539 nt_errstr(*perr) ));
2540 goto err;
2543 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2544 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2545 result->pipe_name, cli->desthost,
2546 domain, username ));
2548 return result;
2550 err:
2552 TALLOC_FREE(result);
2553 return NULL;
2556 /****************************************************************************
2557 External interface.
2558 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2559 ****************************************************************************/
2561 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2562 int pipe_idx,
2563 enum pipe_auth_level auth_level,
2564 const char *domain,
2565 const char *username,
2566 const char *password,
2567 NTSTATUS *perr)
2569 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2570 pipe_idx,
2571 PIPE_AUTH_TYPE_NTLMSSP,
2572 auth_level,
2573 domain,
2574 username,
2575 password,
2576 perr);
2579 /****************************************************************************
2580 External interface.
2581 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2582 ****************************************************************************/
2584 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2585 int pipe_idx,
2586 enum pipe_auth_level auth_level,
2587 const char *domain,
2588 const char *username,
2589 const char *password,
2590 NTSTATUS *perr)
2592 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2593 pipe_idx,
2594 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2595 auth_level,
2596 domain,
2597 username,
2598 password,
2599 perr);
2602 /****************************************************************************
2603 Get a the schannel session key out of an already opened netlogon pipe.
2604 ****************************************************************************/
2605 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2606 struct cli_state *cli,
2607 const char *domain,
2608 uint32 *pneg_flags,
2609 NTSTATUS *perr)
2611 uint32 sec_chan_type = 0;
2612 unsigned char machine_pwd[16];
2613 const char *machine_account;
2615 /* Get the machine account credentials from secrets.tdb. */
2616 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2617 &sec_chan_type))
2619 DEBUG(0, ("get_schannel_session_key: could not fetch "
2620 "trust account password for domain '%s'\n",
2621 domain));
2622 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2623 return false;
2626 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2627 cli->desthost, /* server name */
2628 domain, /* domain */
2629 global_myname(), /* client name */
2630 machine_account, /* machine account name */
2631 machine_pwd,
2632 sec_chan_type,
2633 pneg_flags);
2635 if (!NT_STATUS_IS_OK(*perr)) {
2636 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2637 "failed with result %s to server %s, domain %s, machine account %s.\n",
2638 nt_errstr(*perr), cli->desthost, domain, machine_account ));
2639 return false;
2642 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2643 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2644 cli->desthost));
2645 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2646 return false;
2649 return true;
2652 /****************************************************************************
2653 Open a netlogon pipe and get the schannel session key.
2654 Now exposed to external callers.
2655 ****************************************************************************/
2658 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2659 const char *domain,
2660 uint32 *pneg_flags,
2661 NTSTATUS *perr)
2663 struct rpc_pipe_client *netlogon_pipe = NULL;
2665 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2666 if (!netlogon_pipe) {
2667 return NULL;
2670 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2671 pneg_flags, perr))
2673 TALLOC_FREE(netlogon_pipe);
2674 return NULL;
2677 return netlogon_pipe;
2680 /****************************************************************************
2681 External interface.
2682 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2683 using session_key. sign and seal.
2684 ****************************************************************************/
2686 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2687 int pipe_idx,
2688 enum pipe_auth_level auth_level,
2689 const char *domain,
2690 const struct dcinfo *pdc,
2691 NTSTATUS *perr)
2693 struct rpc_pipe_client *result;
2694 struct cli_pipe_auth_data *auth;
2696 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2697 if (result == NULL) {
2698 return NULL;
2701 *perr = rpccli_schannel_bind_data(result, domain, auth_level,
2702 pdc, &auth);
2703 if (!NT_STATUS_IS_OK(*perr)) {
2704 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2705 nt_errstr(*perr)));
2706 TALLOC_FREE(result);
2707 return NULL;
2710 *perr = rpc_pipe_bind(result, auth);
2711 if (!NT_STATUS_IS_OK(*perr)) {
2712 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2713 nt_errstr(*perr) ));
2714 TALLOC_FREE(result);
2715 return NULL;
2718 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2719 if (result->dc) {
2720 *result->dc = *pdc;
2723 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2724 "for domain %s "
2725 "and bound using schannel.\n",
2726 result->pipe_name, cli->desthost, domain ));
2728 return result;
2731 /****************************************************************************
2732 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2733 Fetch the session key ourselves using a temporary netlogon pipe. This
2734 version uses an ntlmssp auth bound netlogon pipe to get the key.
2735 ****************************************************************************/
2737 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2738 const char *domain,
2739 const char *username,
2740 const char *password,
2741 uint32 *pneg_flags,
2742 NTSTATUS *perr)
2744 struct rpc_pipe_client *netlogon_pipe = NULL;
2746 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2747 if (!netlogon_pipe) {
2748 return NULL;
2751 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2752 pneg_flags, perr))
2754 TALLOC_FREE(netlogon_pipe);
2755 return NULL;
2758 return netlogon_pipe;
2761 /****************************************************************************
2762 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2763 Fetch the session key ourselves using a temporary netlogon pipe. This version
2764 uses an ntlmssp bind to get the session key.
2765 ****************************************************************************/
2767 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2768 int pipe_idx,
2769 enum pipe_auth_level auth_level,
2770 const char *domain,
2771 const char *username,
2772 const char *password,
2773 NTSTATUS *perr)
2775 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2776 struct rpc_pipe_client *netlogon_pipe = NULL;
2777 struct rpc_pipe_client *result = NULL;
2779 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2780 password, &neg_flags, perr);
2781 if (!netlogon_pipe) {
2782 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2783 "key from server %s for domain %s.\n",
2784 cli->desthost, domain ));
2785 return NULL;
2788 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2789 auth_level,
2790 domain, netlogon_pipe->dc, perr);
2792 /* Now we've bound using the session key we can close the netlog pipe. */
2793 TALLOC_FREE(netlogon_pipe);
2795 return result;
2798 /****************************************************************************
2799 Open a named pipe to an SMB server and bind using schannel (bind type 68).
2800 Fetch the session key ourselves using a temporary netlogon pipe.
2801 ****************************************************************************/
2803 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2804 int pipe_idx,
2805 enum pipe_auth_level auth_level,
2806 const char *domain,
2807 NTSTATUS *perr)
2809 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2810 struct rpc_pipe_client *netlogon_pipe = NULL;
2811 struct rpc_pipe_client *result = NULL;
2813 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2814 if (!netlogon_pipe) {
2815 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2816 "key from server %s for domain %s.\n",
2817 cli->desthost, domain ));
2818 return NULL;
2821 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2822 auth_level,
2823 domain, netlogon_pipe->dc, perr);
2825 /* Now we've bound using the session key we can close the netlog pipe. */
2826 TALLOC_FREE(netlogon_pipe);
2828 return result;
2831 /****************************************************************************
2832 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2833 The idea is this can be called with service_princ, username and password all
2834 NULL so long as the caller has a TGT.
2835 ****************************************************************************/
2837 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2838 int pipe_idx,
2839 enum pipe_auth_level auth_level,
2840 const char *service_princ,
2841 const char *username,
2842 const char *password,
2843 NTSTATUS *perr)
2845 #ifdef HAVE_KRB5
2846 struct rpc_pipe_client *result;
2847 struct cli_pipe_auth_data *auth;
2849 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2850 if (result == NULL) {
2851 return NULL;
2854 *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ,
2855 username, password, &auth);
2856 if (!NT_STATUS_IS_OK(*perr)) {
2857 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
2858 nt_errstr(*perr)));
2859 TALLOC_FREE(result);
2860 return NULL;
2863 *perr = rpc_pipe_bind(result, auth);
2864 if (!NT_STATUS_IS_OK(*perr)) {
2865 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2866 nt_errstr(*perr) ));
2867 TALLOC_FREE(result);
2868 return NULL;
2871 return result;
2872 #else
2873 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
2874 return NULL;
2875 #endif