rpc_client: add a destructor to close the socket for pipes over tcp.
[Samba/gbeck.git] / source / rpc_client / cli_pipe.c
blob9908c69674e9c11c3f89a4fd5295ce4bd2f1da66
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
22 #undef DBGC_CLASS
23 #define DBGC_CLASS DBGC_RPC_CLI
25 extern struct pipe_id_info pipe_names[];
27 /********************************************************************
28 Map internal value to wire value.
29 ********************************************************************/
31 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
33 switch (auth_type) {
35 case PIPE_AUTH_TYPE_NONE:
36 return RPC_ANONYMOUS_AUTH_TYPE;
38 case PIPE_AUTH_TYPE_NTLMSSP:
39 return RPC_NTLMSSP_AUTH_TYPE;
41 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
42 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
43 return RPC_SPNEGO_AUTH_TYPE;
45 case PIPE_AUTH_TYPE_SCHANNEL:
46 return RPC_SCHANNEL_AUTH_TYPE;
48 case PIPE_AUTH_TYPE_KRB5:
49 return RPC_KRB5_AUTH_TYPE;
51 default:
52 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
53 "auth type %u\n",
54 (unsigned int)auth_type ));
55 break;
57 return -1;
60 /********************************************************************
61 Pipe description for a DEBUG
62 ********************************************************************/
63 static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli)
65 char *result;
67 switch (cli->transport_type) {
68 case NCACN_NP:
69 result = talloc_asprintf(mem_ctx, "host %s, pipe %s, "
70 "fnum 0x%x",
71 cli->desthost,
72 cli->trans.np.pipe_name,
73 (unsigned int)(cli->trans.np.fnum));
74 break;
75 case NCACN_IP_TCP:
76 case NCACN_UNIX_STREAM:
77 result = talloc_asprintf(mem_ctx, "host %s, fd %d",
78 cli->desthost, cli->trans.sock.fd);
79 break;
80 default:
81 result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
82 break;
84 SMB_ASSERT(result != NULL);
85 return result;
88 /********************************************************************
89 Rpc pipe call id.
90 ********************************************************************/
92 static uint32 get_rpc_call_id(void)
94 static uint32 call_id = 0;
95 return ++call_id;
98 /*******************************************************************
99 Read from a RPC named pipe
100 ********************************************************************/
101 static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name,
102 int fnum, char *buf, off_t offset, size_t size,
103 ssize_t *pnum_read)
105 ssize_t num_read;
107 num_read = cli_read(cli, fnum, buf, offset, size);
109 DEBUG(5,("rpc_read_np: num_read = %d, read offset: %u, to read: %u\n",
110 (int)num_read, (unsigned int)offset, (unsigned int)size));
113 * A dos error of ERRDOS/ERRmoredata is not an error.
115 if (cli_is_dos_error(cli)) {
116 uint32 ecode;
117 uint8 eclass;
118 cli_dos_error(cli, &eclass, &ecode);
119 if (eclass != ERRDOS && ecode != ERRmoredata) {
120 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read "
121 "on fnum 0x%x\n", eclass, (unsigned int)ecode,
122 cli_errstr(cli), fnum));
123 return dos_to_ntstatus(eclass, ecode);
128 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
130 if (cli_is_nt_error(cli)) {
131 if (!NT_STATUS_EQUAL(cli_nt_error(cli),
132 NT_STATUS_BUFFER_TOO_SMALL)) {
133 DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum "
134 "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum));
135 return cli_nt_error(cli);
139 if (num_read == -1) {
140 DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned "
141 "-1\n", fnum));
142 return cli_get_nt_error(cli);
145 *pnum_read = num_read;
146 return NT_STATUS_OK;
150 /*******************************************************************
151 Use SMBreadX to get rest of one fragment's worth of rpc data.
152 Will expand the current_pdu struct to the correct size.
153 ********************************************************************/
155 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
156 prs_struct *current_pdu,
157 uint32 data_to_read,
158 uint32 *current_pdu_offset)
160 size_t size = (size_t)cli->max_recv_frag;
161 uint32 stream_offset = 0;
162 ssize_t num_read = 0;
163 char *pdata;
164 ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
166 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
167 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
170 * Grow the buffer if needed to accommodate the data to be read.
173 if (extra_data_size > 0) {
174 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
175 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
176 return NT_STATUS_NO_MEMORY;
178 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
181 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
183 do {
184 NTSTATUS status;
186 /* read data using SMBreadX */
187 if (size > (size_t)data_to_read) {
188 size = (size_t)data_to_read;
191 switch (cli->transport_type) {
192 case NCACN_NP:
193 status = rpc_read_np(cli->trans.np.cli,
194 cli->trans.np.pipe_name,
195 cli->trans.np.fnum, pdata,
196 (off_t)stream_offset, size,
197 &num_read);
198 break;
199 case NCACN_IP_TCP:
200 case NCACN_UNIX_STREAM:
201 status = NT_STATUS_OK;
202 num_read = sys_read(cli->trans.sock.fd, pdata, size);
203 if (num_read == -1) {
204 status = map_nt_error_from_unix(errno);
206 if (num_read == 0) {
207 status = NT_STATUS_END_OF_FILE;
209 break;
210 default:
211 DEBUG(0, ("unknown transport type %d\n",
212 cli->transport_type));
213 return NT_STATUS_INTERNAL_ERROR;
216 data_to_read -= num_read;
217 stream_offset += num_read;
218 pdata += num_read;
220 } while (num_read > 0 && data_to_read > 0);
221 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
224 * Update the current offset into current_pdu by the amount read.
226 *current_pdu_offset += stream_offset;
227 return NT_STATUS_OK;
230 /****************************************************************************
231 Try and get a PDU's worth of data from current_pdu. If not, then read more
232 from the wire.
233 ****************************************************************************/
235 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
237 NTSTATUS ret = NT_STATUS_OK;
238 uint32 current_pdu_len = prs_data_size(current_pdu);
240 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
241 if (current_pdu_len < RPC_HEADER_LEN) {
242 /* rpc_read expands the current_pdu struct as neccessary. */
243 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
244 if (!NT_STATUS_IS_OK(ret)) {
245 return ret;
249 /* This next call sets the endian bit correctly in current_pdu. */
250 /* We will propagate this to rbuf later. */
251 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
252 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
253 return NT_STATUS_BUFFER_TOO_SMALL;
256 /* Ensure we have frag_len bytes of data. */
257 if (current_pdu_len < prhdr->frag_len) {
258 /* rpc_read expands the current_pdu struct as neccessary. */
259 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
260 if (!NT_STATUS_IS_OK(ret)) {
261 return ret;
265 if (current_pdu_len < prhdr->frag_len) {
266 return NT_STATUS_BUFFER_TOO_SMALL;
269 return NT_STATUS_OK;
272 /****************************************************************************
273 NTLMSSP specific sign/seal.
274 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
275 In fact I should probably abstract these into identical pieces of code... JRA.
276 ****************************************************************************/
278 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
279 prs_struct *current_pdu,
280 uint8 *p_ss_padding_len)
282 RPC_HDR_AUTH auth_info;
283 uint32 save_offset = prs_offset(current_pdu);
284 uint32 auth_len = prhdr->auth_len;
285 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
286 unsigned char *data = NULL;
287 size_t data_len;
288 unsigned char *full_packet_data = NULL;
289 size_t full_packet_data_len;
290 DATA_BLOB auth_blob;
291 NTSTATUS status;
293 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
294 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
295 return NT_STATUS_OK;
298 if (!ntlmssp_state) {
299 return NT_STATUS_INVALID_PARAMETER;
302 /* Ensure there's enough data for an authenticated response. */
303 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
304 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
305 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
306 (unsigned int)auth_len ));
307 return NT_STATUS_BUFFER_TOO_SMALL;
311 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
312 * after the RPC header.
313 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
314 * functions as NTLMv2 checks the rpc headers also.
317 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
318 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
320 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
321 full_packet_data_len = prhdr->frag_len - auth_len;
323 /* Pull the auth header and the following data into a blob. */
324 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
325 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
326 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
327 return NT_STATUS_BUFFER_TOO_SMALL;
330 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
331 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
332 return NT_STATUS_BUFFER_TOO_SMALL;
335 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
336 auth_blob.length = auth_len;
338 switch (cli->auth->auth_level) {
339 case PIPE_AUTH_LEVEL_PRIVACY:
340 /* Data is encrypted. */
341 status = ntlmssp_unseal_packet(ntlmssp_state,
342 data, data_len,
343 full_packet_data,
344 full_packet_data_len,
345 &auth_blob);
346 if (!NT_STATUS_IS_OK(status)) {
347 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
348 "packet from %s. Error was %s.\n",
349 rpccli_pipe_txt(debug_ctx(), cli),
350 nt_errstr(status) ));
351 return status;
353 break;
354 case PIPE_AUTH_LEVEL_INTEGRITY:
355 /* Data is signed. */
356 status = ntlmssp_check_packet(ntlmssp_state,
357 data, data_len,
358 full_packet_data,
359 full_packet_data_len,
360 &auth_blob);
361 if (!NT_STATUS_IS_OK(status)) {
362 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
363 "packet from %s. Error was %s.\n",
364 rpccli_pipe_txt(debug_ctx(), cli),
365 nt_errstr(status) ));
366 return status;
368 break;
369 default:
370 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
371 "auth level %d\n", cli->auth->auth_level));
372 return NT_STATUS_INVALID_INFO_CLASS;
376 * Return the current pointer to the data offset.
379 if(!prs_set_offset(current_pdu, save_offset)) {
380 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
381 (unsigned int)save_offset ));
382 return NT_STATUS_BUFFER_TOO_SMALL;
386 * Remember the padding length. We must remove it from the real data
387 * stream once the sign/seal is done.
390 *p_ss_padding_len = auth_info.auth_pad_len;
392 return NT_STATUS_OK;
395 /****************************************************************************
396 schannel specific sign/seal.
397 ****************************************************************************/
399 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
400 prs_struct *current_pdu,
401 uint8 *p_ss_padding_len)
403 RPC_HDR_AUTH auth_info;
404 RPC_AUTH_SCHANNEL_CHK schannel_chk;
405 uint32 auth_len = prhdr->auth_len;
406 uint32 save_offset = prs_offset(current_pdu);
407 struct schannel_auth_struct *schannel_auth =
408 cli->auth->a_u.schannel_auth;
409 uint32 data_len;
411 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
412 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
413 return NT_STATUS_OK;
416 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
417 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
418 return NT_STATUS_INVALID_PARAMETER;
421 if (!schannel_auth) {
422 return NT_STATUS_INVALID_PARAMETER;
425 /* Ensure there's enough data for an authenticated response. */
426 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
427 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
428 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
429 (unsigned int)auth_len ));
430 return NT_STATUS_INVALID_PARAMETER;
433 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
435 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
436 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
437 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
438 return NT_STATUS_BUFFER_TOO_SMALL;
441 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
442 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
443 return NT_STATUS_BUFFER_TOO_SMALL;
446 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
447 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
448 auth_info.auth_type));
449 return NT_STATUS_BUFFER_TOO_SMALL;
452 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
453 &schannel_chk, current_pdu, 0)) {
454 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
455 return NT_STATUS_BUFFER_TOO_SMALL;
458 if (!schannel_decode(schannel_auth,
459 cli->auth->auth_level,
460 SENDER_IS_ACCEPTOR,
461 &schannel_chk,
462 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
463 data_len)) {
464 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
465 "Connection to %s.\n",
466 rpccli_pipe_txt(debug_ctx(), cli)));
467 return NT_STATUS_INVALID_PARAMETER;
470 /* The sequence number gets incremented on both send and receive. */
471 schannel_auth->seq_num++;
474 * Return the current pointer to the data offset.
477 if(!prs_set_offset(current_pdu, save_offset)) {
478 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
479 (unsigned int)save_offset ));
480 return NT_STATUS_BUFFER_TOO_SMALL;
484 * Remember the padding length. We must remove it from the real data
485 * stream once the sign/seal is done.
488 *p_ss_padding_len = auth_info.auth_pad_len;
490 return NT_STATUS_OK;
493 /****************************************************************************
494 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
495 ****************************************************************************/
497 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
498 prs_struct *current_pdu,
499 uint8 *p_ss_padding_len)
501 NTSTATUS ret = NT_STATUS_OK;
503 /* Paranioa checks for auth_len. */
504 if (prhdr->auth_len) {
505 if (prhdr->auth_len > prhdr->frag_len) {
506 return NT_STATUS_INVALID_PARAMETER;
509 if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len ||
510 prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) {
511 /* Integer wrap attempt. */
512 return NT_STATUS_INVALID_PARAMETER;
517 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
520 switch(cli->auth->auth_type) {
521 case PIPE_AUTH_TYPE_NONE:
522 if (prhdr->auth_len) {
523 DEBUG(3, ("cli_pipe_validate_rpc_response: "
524 "Connection to %s - got non-zero "
525 "auth len %u.\n",
526 rpccli_pipe_txt(debug_ctx(), cli),
527 (unsigned int)prhdr->auth_len ));
528 return NT_STATUS_INVALID_PARAMETER;
530 break;
532 case PIPE_AUTH_TYPE_NTLMSSP:
533 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
534 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
535 if (!NT_STATUS_IS_OK(ret)) {
536 return ret;
538 break;
540 case PIPE_AUTH_TYPE_SCHANNEL:
541 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
542 if (!NT_STATUS_IS_OK(ret)) {
543 return ret;
545 break;
547 case PIPE_AUTH_TYPE_KRB5:
548 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
549 default:
550 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
551 "to %s - unknown internal auth type %u.\n",
552 rpccli_pipe_txt(debug_ctx(), cli),
553 cli->auth->auth_type ));
554 return NT_STATUS_INVALID_INFO_CLASS;
557 return NT_STATUS_OK;
560 /****************************************************************************
561 Do basic authentication checks on an incoming pdu.
562 ****************************************************************************/
564 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
565 prs_struct *current_pdu,
566 uint8 expected_pkt_type,
567 char **ppdata,
568 uint32 *pdata_len,
569 prs_struct *return_data)
572 NTSTATUS ret = NT_STATUS_OK;
573 uint32 current_pdu_len = prs_data_size(current_pdu);
575 if (current_pdu_len != prhdr->frag_len) {
576 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
577 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
578 return NT_STATUS_INVALID_PARAMETER;
582 * Point the return values at the real data including the RPC
583 * header. Just in case the caller wants it.
585 *ppdata = prs_data_p(current_pdu);
586 *pdata_len = current_pdu_len;
588 /* Ensure we have the correct type. */
589 switch (prhdr->pkt_type) {
590 case RPC_ALTCONTRESP:
591 case RPC_BINDACK:
593 /* Alter context and bind ack share the same packet definitions. */
594 break;
597 case RPC_RESPONSE:
599 RPC_HDR_RESP rhdr_resp;
600 uint8 ss_padding_len = 0;
602 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
603 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
604 return NT_STATUS_BUFFER_TOO_SMALL;
607 /* Here's where we deal with incoming sign/seal. */
608 ret = cli_pipe_validate_rpc_response(cli, prhdr,
609 current_pdu, &ss_padding_len);
610 if (!NT_STATUS_IS_OK(ret)) {
611 return ret;
614 /* Point the return values at the NDR data. Remember to remove any ss padding. */
615 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
617 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
618 return NT_STATUS_BUFFER_TOO_SMALL;
621 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
623 /* Remember to remove the auth footer. */
624 if (prhdr->auth_len) {
625 /* We've already done integer wrap tests on auth_len in
626 cli_pipe_validate_rpc_response(). */
627 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
628 return NT_STATUS_BUFFER_TOO_SMALL;
630 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
633 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
634 current_pdu_len, *pdata_len, ss_padding_len ));
637 * If this is the first reply, and the allocation hint is reasonably, try and
638 * set up the return_data parse_struct to the correct size.
641 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
642 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
643 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
644 "too large to allocate\n",
645 (unsigned int)rhdr_resp.alloc_hint ));
646 return NT_STATUS_NO_MEMORY;
650 break;
653 case RPC_BINDNACK:
654 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
655 "received from %s!\n",
656 rpccli_pipe_txt(debug_ctx(), cli)));
657 /* Use this for now... */
658 return NT_STATUS_NETWORK_ACCESS_DENIED;
660 case RPC_FAULT:
662 RPC_HDR_RESP rhdr_resp;
663 RPC_HDR_FAULT fault_resp;
665 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
666 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
667 return NT_STATUS_BUFFER_TOO_SMALL;
670 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
671 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
672 return NT_STATUS_BUFFER_TOO_SMALL;
675 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
676 "code %s received from %s!\n",
677 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
678 rpccli_pipe_txt(debug_ctx(), cli)));
679 if (NT_STATUS_IS_OK(fault_resp.status)) {
680 return NT_STATUS_UNSUCCESSFUL;
681 } else {
682 return fault_resp.status;
686 default:
687 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
688 "from %s!\n",
689 (unsigned int)prhdr->pkt_type,
690 rpccli_pipe_txt(debug_ctx(), cli)));
691 return NT_STATUS_INVALID_INFO_CLASS;
694 if (prhdr->pkt_type != expected_pkt_type) {
695 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
696 "got an unexpected RPC packet type - %u, not %u\n",
697 rpccli_pipe_txt(debug_ctx(), cli),
698 prhdr->pkt_type,
699 expected_pkt_type));
700 return NT_STATUS_INVALID_INFO_CLASS;
703 /* Do this just before return - we don't want to modify any rpc header
704 data before now as we may have needed to do cryptographic actions on
705 it before. */
707 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
708 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
709 "setting fragment first/last ON.\n"));
710 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
713 return NT_STATUS_OK;
716 /****************************************************************************
717 Ensure we eat the just processed pdu from the current_pdu prs_struct.
718 Normally the frag_len and buffer size will match, but on the first trans
719 reply there is a theoretical chance that buffer size > frag_len, so we must
720 deal with that.
721 ****************************************************************************/
723 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
725 uint32 current_pdu_len = prs_data_size(current_pdu);
727 if (current_pdu_len < prhdr->frag_len) {
728 return NT_STATUS_BUFFER_TOO_SMALL;
731 /* Common case. */
732 if (current_pdu_len == (uint32)prhdr->frag_len) {
733 prs_mem_free(current_pdu);
734 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
735 /* Make current_pdu dynamic with no memory. */
736 prs_give_memory(current_pdu, 0, 0, True);
737 return NT_STATUS_OK;
741 * Oh no ! More data in buffer than we processed in current pdu.
742 * Cheat. Move the data down and shrink the buffer.
745 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
746 current_pdu_len - prhdr->frag_len);
748 /* Remember to set the read offset back to zero. */
749 prs_set_offset(current_pdu, 0);
751 /* Shrink the buffer. */
752 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
753 return NT_STATUS_BUFFER_TOO_SMALL;
756 return NT_STATUS_OK;
759 /****************************************************************************
760 Send data on an rpc pipe via trans. The prs_struct data must be the last
761 pdu fragment of an NDR data stream.
763 Receive response data from an rpc pipe, which may be large...
765 Read the first fragment: unfortunately have to use SMBtrans for the first
766 bit, then SMBreadX for subsequent bits.
768 If first fragment received also wasn't the last fragment, continue
769 getting fragments until we _do_ receive the last fragment.
771 Request/Response PDU's look like the following...
773 |<------------------PDU len----------------------------------------------->|
774 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
776 +------------+-----------------+-------------+---------------+-------------+
777 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
778 +------------+-----------------+-------------+---------------+-------------+
780 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
781 signing & sealing being negotiated.
783 ****************************************************************************/
785 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
786 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
787 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
788 uint8 expected_pkt_type)
790 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
791 char *rparam = NULL;
792 uint32 rparam_len = 0;
793 char *pdata = prs_data_p(data);
794 uint32 data_len = prs_offset(data);
795 char *prdata = NULL;
796 uint32 rdata_len = 0;
797 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
798 uint32 current_rbuf_offset = 0;
799 prs_struct current_pdu;
801 #ifdef DEVELOPER
802 /* Ensure we're not sending too much. */
803 SMB_ASSERT(data_len <= max_data);
804 #endif
806 /* Set up the current pdu parse struct. */
807 prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
809 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
811 switch (cli->transport_type) {
812 case NCACN_NP: {
813 uint16 setup[2];
814 /* Create setup parameters - must be in native byte order. */
815 setup[0] = TRANSACT_DCERPCCMD;
816 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
819 * Send the last (or only) fragment of an RPC request. For
820 * small amounts of data (about 1024 bytes or so) the RPC
821 * request and response appears in a SMBtrans request and
822 * response.
825 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
826 setup, 2, 0, /* Setup, length, max */
827 NULL, 0, 0, /* Params, length, max */
828 pdata, data_len, max_data, /* data, length,
829 * max */
830 &rparam, &rparam_len, /* return params,
831 * len */
832 &prdata, &rdata_len)) /* return data, len */
834 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
835 "Error was %s\n",
836 rpccli_pipe_txt(debug_ctx(), cli),
837 cli_errstr(cli->trans.np.cli)));
838 ret = cli_get_nt_error(cli->trans.np.cli);
839 SAFE_FREE(rparam);
840 SAFE_FREE(prdata);
841 goto err;
843 break;
845 case NCACN_IP_TCP:
846 case NCACN_UNIX_STREAM:
848 ssize_t nwritten, nread;
849 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
850 if (nwritten == -1) {
851 ret = map_nt_error_from_unix(errno);
852 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
853 strerror(errno)));
854 goto err;
856 rparam = NULL;
857 prdata = SMB_MALLOC_ARRAY(char, 1);
858 if (prdata == NULL) {
859 return NT_STATUS_NO_MEMORY;
861 nread = sys_read(cli->trans.sock.fd, prdata, 1);
862 if (nread == 0) {
863 SAFE_FREE(prdata);
865 if (nread == -1) {
866 ret = NT_STATUS_END_OF_FILE;
867 goto err;
869 rdata_len = nread;
870 break;
872 default:
873 DEBUG(0, ("unknown transport type %d\n",
874 cli->transport_type));
875 return NT_STATUS_INTERNAL_ERROR;
878 /* Throw away returned params - we know we won't use them. */
880 SAFE_FREE(rparam);
882 if (prdata == NULL) {
883 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
884 rpccli_pipe_txt(debug_ctx(), cli)));
885 /* Yes - some calls can truely return no data... */
886 prs_mem_free(&current_pdu);
887 return NT_STATUS_OK;
891 * Give this memory as dynamic to the current pdu.
894 prs_give_memory(&current_pdu, prdata, rdata_len, True);
896 /* Ensure we can mess with the return prs_struct. */
897 SMB_ASSERT(UNMARSHALLING(rbuf));
898 SMB_ASSERT(prs_data_size(rbuf) == 0);
900 /* Make rbuf dynamic with no memory. */
901 prs_give_memory(rbuf, 0, 0, True);
903 while(1) {
904 RPC_HDR rhdr;
905 char *ret_data;
906 uint32 ret_data_len;
908 /* Ensure we have enough data for a pdu. */
909 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
910 if (!NT_STATUS_IS_OK(ret)) {
911 goto err;
914 /* We pass in rbuf here so if the alloc hint is set correctly
915 we can set the output size and avoid reallocs. */
917 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
918 &ret_data, &ret_data_len, rbuf);
920 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
921 prs_data_size(&current_pdu), current_rbuf_offset ));
923 if (!NT_STATUS_IS_OK(ret)) {
924 goto err;
927 if ((rhdr.flags & RPC_FLG_FIRST)) {
928 if (rhdr.pack_type[0] == 0) {
929 /* Set the data type correctly for big-endian data on the first packet. */
930 DEBUG(10,("rpc_api_pipe: On %s "
931 "PDU data format is big-endian.\n",
932 rpccli_pipe_txt(debug_ctx(), cli)));
934 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
935 } else {
936 /* Check endianness on subsequent packets. */
937 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
938 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
939 rbuf->bigendian_data ? "big" : "little",
940 current_pdu.bigendian_data ? "big" : "little" ));
941 ret = NT_STATUS_INVALID_PARAMETER;
942 goto err;
947 /* Now copy the data portion out of the pdu into rbuf. */
948 if (!prs_force_grow(rbuf, ret_data_len)) {
949 ret = NT_STATUS_NO_MEMORY;
950 goto err;
952 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
953 current_rbuf_offset += ret_data_len;
955 /* See if we've finished with all the data in current_pdu yet ? */
956 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
957 if (!NT_STATUS_IS_OK(ret)) {
958 goto err;
961 if (rhdr.flags & RPC_FLG_LAST) {
962 break; /* We're done. */
966 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
967 rpccli_pipe_txt(debug_ctx(), cli),
968 (unsigned int)prs_data_size(rbuf) ));
970 prs_mem_free(&current_pdu);
971 return NT_STATUS_OK;
973 err:
975 prs_mem_free(&current_pdu);
976 prs_mem_free(rbuf);
977 return ret;
980 /*******************************************************************
981 Creates krb5 auth bind.
982 ********************************************************************/
984 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
985 enum pipe_auth_level auth_level,
986 RPC_HDR_AUTH *pauth_out,
987 prs_struct *auth_data)
989 #ifdef HAVE_KRB5
990 int ret;
991 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
992 DATA_BLOB tkt = data_blob_null;
993 DATA_BLOB tkt_wrapped = data_blob_null;
995 /* We may change the pad length before marshalling. */
996 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
998 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
999 a->service_principal ));
1001 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1003 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1004 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1006 if (ret) {
1007 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1008 "failed with %s\n",
1009 a->service_principal,
1010 error_message(ret) ));
1012 data_blob_free(&tkt);
1013 prs_mem_free(auth_data);
1014 return NT_STATUS_INVALID_PARAMETER;
1017 /* wrap that up in a nice GSS-API wrapping */
1018 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1020 data_blob_free(&tkt);
1022 /* Auth len in the rpc header doesn't include auth_header. */
1023 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1024 data_blob_free(&tkt_wrapped);
1025 prs_mem_free(auth_data);
1026 return NT_STATUS_NO_MEMORY;
1029 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1030 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1032 data_blob_free(&tkt_wrapped);
1033 return NT_STATUS_OK;
1034 #else
1035 return NT_STATUS_INVALID_PARAMETER;
1036 #endif
1039 /*******************************************************************
1040 Creates SPNEGO NTLMSSP auth bind.
1041 ********************************************************************/
1043 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1044 enum pipe_auth_level auth_level,
1045 RPC_HDR_AUTH *pauth_out,
1046 prs_struct *auth_data)
1048 NTSTATUS nt_status;
1049 DATA_BLOB null_blob = data_blob_null;
1050 DATA_BLOB request = data_blob_null;
1051 DATA_BLOB spnego_msg = data_blob_null;
1053 /* We may change the pad length before marshalling. */
1054 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1056 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1057 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1058 null_blob,
1059 &request);
1061 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1062 data_blob_free(&request);
1063 prs_mem_free(auth_data);
1064 return nt_status;
1067 /* Wrap this in SPNEGO. */
1068 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1070 data_blob_free(&request);
1072 /* Auth len in the rpc header doesn't include auth_header. */
1073 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1074 data_blob_free(&spnego_msg);
1075 prs_mem_free(auth_data);
1076 return NT_STATUS_NO_MEMORY;
1079 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1080 dump_data(5, spnego_msg.data, spnego_msg.length);
1082 data_blob_free(&spnego_msg);
1083 return NT_STATUS_OK;
1086 /*******************************************************************
1087 Creates NTLMSSP auth bind.
1088 ********************************************************************/
1090 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1091 enum pipe_auth_level auth_level,
1092 RPC_HDR_AUTH *pauth_out,
1093 prs_struct *auth_data)
1095 NTSTATUS nt_status;
1096 DATA_BLOB null_blob = data_blob_null;
1097 DATA_BLOB request = data_blob_null;
1099 /* We may change the pad length before marshalling. */
1100 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1102 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1103 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1104 null_blob,
1105 &request);
1107 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1108 data_blob_free(&request);
1109 prs_mem_free(auth_data);
1110 return nt_status;
1113 /* Auth len in the rpc header doesn't include auth_header. */
1114 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1115 data_blob_free(&request);
1116 prs_mem_free(auth_data);
1117 return NT_STATUS_NO_MEMORY;
1120 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1121 dump_data(5, request.data, request.length);
1123 data_blob_free(&request);
1124 return NT_STATUS_OK;
1127 /*******************************************************************
1128 Creates schannel auth bind.
1129 ********************************************************************/
1131 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1132 enum pipe_auth_level auth_level,
1133 RPC_HDR_AUTH *pauth_out,
1134 prs_struct *auth_data)
1136 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1138 /* We may change the pad length before marshalling. */
1139 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1141 /* Use lp_workgroup() if domain not specified */
1143 if (!cli->auth->domain || !cli->auth->domain[0]) {
1144 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1145 if (cli->auth->domain == NULL) {
1146 return NT_STATUS_NO_MEMORY;
1150 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1151 global_myname());
1154 * Now marshall the data into the auth parse_struct.
1157 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1158 &schannel_neg, auth_data, 0)) {
1159 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1160 prs_mem_free(auth_data);
1161 return NT_STATUS_NO_MEMORY;
1164 return NT_STATUS_OK;
1167 /*******************************************************************
1168 Creates the internals of a DCE/RPC bind request or alter context PDU.
1169 ********************************************************************/
1171 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1172 prs_struct *rpc_out,
1173 uint32 rpc_call_id,
1174 const RPC_IFACE *abstract,
1175 const RPC_IFACE *transfer,
1176 RPC_HDR_AUTH *phdr_auth,
1177 prs_struct *pauth_info)
1179 RPC_HDR hdr;
1180 RPC_HDR_RB hdr_rb;
1181 RPC_CONTEXT rpc_ctx;
1182 uint16 auth_len = prs_offset(pauth_info);
1183 uint8 ss_padding_len = 0;
1184 uint16 frag_len = 0;
1186 /* create the RPC context. */
1187 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1189 /* create the bind request RPC_HDR_RB */
1190 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1192 /* Start building the frag length. */
1193 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1195 /* Do we need to pad ? */
1196 if (auth_len) {
1197 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1198 if (data_len % 8) {
1199 ss_padding_len = 8 - (data_len % 8);
1200 phdr_auth->auth_pad_len = ss_padding_len;
1202 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1205 /* Create the request RPC_HDR */
1206 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1208 /* Marshall the RPC header */
1209 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1210 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1211 return NT_STATUS_NO_MEMORY;
1214 /* Marshall the bind request data */
1215 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1216 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1217 return NT_STATUS_NO_MEMORY;
1221 * Grow the outgoing buffer to store any auth info.
1224 if(auth_len != 0) {
1225 if (ss_padding_len) {
1226 char pad[8];
1227 memset(pad, '\0', 8);
1228 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1229 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1230 return NT_STATUS_NO_MEMORY;
1234 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1235 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1236 return NT_STATUS_NO_MEMORY;
1240 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1241 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1242 return NT_STATUS_NO_MEMORY;
1246 return NT_STATUS_OK;
1249 /*******************************************************************
1250 Creates a DCE/RPC bind request.
1251 ********************************************************************/
1253 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1254 prs_struct *rpc_out,
1255 uint32 rpc_call_id,
1256 const RPC_IFACE *abstract,
1257 const RPC_IFACE *transfer,
1258 enum pipe_auth_type auth_type,
1259 enum pipe_auth_level auth_level)
1261 RPC_HDR_AUTH hdr_auth;
1262 prs_struct auth_info;
1263 NTSTATUS ret = NT_STATUS_OK;
1265 ZERO_STRUCT(hdr_auth);
1266 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1267 return NT_STATUS_NO_MEMORY;
1269 switch (auth_type) {
1270 case PIPE_AUTH_TYPE_SCHANNEL:
1271 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1272 if (!NT_STATUS_IS_OK(ret)) {
1273 prs_mem_free(&auth_info);
1274 return ret;
1276 break;
1278 case PIPE_AUTH_TYPE_NTLMSSP:
1279 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1280 if (!NT_STATUS_IS_OK(ret)) {
1281 prs_mem_free(&auth_info);
1282 return ret;
1284 break;
1286 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1287 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1288 if (!NT_STATUS_IS_OK(ret)) {
1289 prs_mem_free(&auth_info);
1290 return ret;
1292 break;
1294 case PIPE_AUTH_TYPE_KRB5:
1295 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1296 if (!NT_STATUS_IS_OK(ret)) {
1297 prs_mem_free(&auth_info);
1298 return ret;
1300 break;
1302 case PIPE_AUTH_TYPE_NONE:
1303 break;
1305 default:
1306 /* "Can't" happen. */
1307 return NT_STATUS_INVALID_INFO_CLASS;
1310 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1311 rpc_out,
1312 rpc_call_id,
1313 abstract,
1314 transfer,
1315 &hdr_auth,
1316 &auth_info);
1318 prs_mem_free(&auth_info);
1319 return ret;
1322 /*******************************************************************
1323 Create and add the NTLMSSP sign/seal auth header and data.
1324 ********************************************************************/
1326 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1327 RPC_HDR *phdr,
1328 uint32 ss_padding_len,
1329 prs_struct *outgoing_pdu)
1331 RPC_HDR_AUTH auth_info;
1332 NTSTATUS status;
1333 DATA_BLOB auth_blob = data_blob_null;
1334 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1336 if (!cli->auth->a_u.ntlmssp_state) {
1337 return NT_STATUS_INVALID_PARAMETER;
1340 /* Init and marshall the auth header. */
1341 init_rpc_hdr_auth(&auth_info,
1342 map_pipe_auth_type_to_rpc_auth_type(
1343 cli->auth->auth_type),
1344 cli->auth->auth_level,
1345 ss_padding_len,
1346 1 /* context id. */);
1348 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1349 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1350 data_blob_free(&auth_blob);
1351 return NT_STATUS_NO_MEMORY;
1354 switch (cli->auth->auth_level) {
1355 case PIPE_AUTH_LEVEL_PRIVACY:
1356 /* Data portion is encrypted. */
1357 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1358 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1359 data_and_pad_len,
1360 (unsigned char *)prs_data_p(outgoing_pdu),
1361 (size_t)prs_offset(outgoing_pdu),
1362 &auth_blob);
1363 if (!NT_STATUS_IS_OK(status)) {
1364 data_blob_free(&auth_blob);
1365 return status;
1367 break;
1369 case PIPE_AUTH_LEVEL_INTEGRITY:
1370 /* Data is signed. */
1371 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1372 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1373 data_and_pad_len,
1374 (unsigned char *)prs_data_p(outgoing_pdu),
1375 (size_t)prs_offset(outgoing_pdu),
1376 &auth_blob);
1377 if (!NT_STATUS_IS_OK(status)) {
1378 data_blob_free(&auth_blob);
1379 return status;
1381 break;
1383 default:
1384 /* Can't happen. */
1385 smb_panic("bad auth level");
1386 /* Notreached. */
1387 return NT_STATUS_INVALID_PARAMETER;
1390 /* Finally marshall the blob. */
1392 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1393 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1394 (unsigned int)NTLMSSP_SIG_SIZE));
1395 data_blob_free(&auth_blob);
1396 return NT_STATUS_NO_MEMORY;
1399 data_blob_free(&auth_blob);
1400 return NT_STATUS_OK;
1403 /*******************************************************************
1404 Create and add the schannel sign/seal auth header and data.
1405 ********************************************************************/
1407 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1408 RPC_HDR *phdr,
1409 uint32 ss_padding_len,
1410 prs_struct *outgoing_pdu)
1412 RPC_HDR_AUTH auth_info;
1413 RPC_AUTH_SCHANNEL_CHK verf;
1414 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1415 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1416 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1418 if (!sas) {
1419 return NT_STATUS_INVALID_PARAMETER;
1422 /* Init and marshall the auth header. */
1423 init_rpc_hdr_auth(&auth_info,
1424 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1425 cli->auth->auth_level,
1426 ss_padding_len,
1427 1 /* context id. */);
1429 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1430 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1431 return NT_STATUS_NO_MEMORY;
1434 switch (cli->auth->auth_level) {
1435 case PIPE_AUTH_LEVEL_PRIVACY:
1436 case PIPE_AUTH_LEVEL_INTEGRITY:
1437 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1438 sas->seq_num));
1440 schannel_encode(sas,
1441 cli->auth->auth_level,
1442 SENDER_IS_INITIATOR,
1443 &verf,
1444 data_p,
1445 data_and_pad_len);
1447 sas->seq_num++;
1448 break;
1450 default:
1451 /* Can't happen. */
1452 smb_panic("bad auth level");
1453 /* Notreached. */
1454 return NT_STATUS_INVALID_PARAMETER;
1457 /* Finally marshall the blob. */
1458 smb_io_rpc_auth_schannel_chk("",
1459 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1460 &verf,
1461 outgoing_pdu,
1464 return NT_STATUS_OK;
1467 /*******************************************************************
1468 Calculate how much data we're going to send in this packet, also
1469 work out any sign/seal padding length.
1470 ********************************************************************/
1472 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1473 uint32 data_left,
1474 uint16 *p_frag_len,
1475 uint16 *p_auth_len,
1476 uint32 *p_ss_padding)
1478 uint32 data_space, data_len;
1480 switch (cli->auth->auth_level) {
1481 case PIPE_AUTH_LEVEL_NONE:
1482 case PIPE_AUTH_LEVEL_CONNECT:
1483 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1484 data_len = MIN(data_space, data_left);
1485 *p_ss_padding = 0;
1486 *p_auth_len = 0;
1487 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1488 return data_len;
1490 case PIPE_AUTH_LEVEL_INTEGRITY:
1491 case PIPE_AUTH_LEVEL_PRIVACY:
1492 /* Treat the same for all authenticated rpc requests. */
1493 switch(cli->auth->auth_type) {
1494 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1495 case PIPE_AUTH_TYPE_NTLMSSP:
1496 *p_auth_len = NTLMSSP_SIG_SIZE;
1497 break;
1498 case PIPE_AUTH_TYPE_SCHANNEL:
1499 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1500 break;
1501 default:
1502 smb_panic("bad auth type");
1503 break;
1506 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1507 RPC_HDR_AUTH_LEN - *p_auth_len;
1509 data_len = MIN(data_space, data_left);
1510 if (data_len % 8) {
1511 *p_ss_padding = 8 - (data_len % 8);
1513 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1514 data_len + *p_ss_padding + /* data plus padding. */
1515 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1516 return data_len;
1518 default:
1519 smb_panic("bad auth level");
1520 /* Notreached. */
1521 return 0;
1525 /*******************************************************************
1526 External interface.
1527 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1528 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1529 and deals with signing/sealing details.
1530 ********************************************************************/
1532 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1533 uint8 op_num,
1534 prs_struct *in_data,
1535 prs_struct *out_data)
1537 NTSTATUS ret;
1538 uint32 data_left = prs_offset(in_data);
1539 uint32 alloc_hint = prs_offset(in_data);
1540 uint32 data_sent_thistime = 0;
1541 uint32 current_data_offset = 0;
1542 uint32 call_id = get_rpc_call_id();
1543 char pad[8];
1544 prs_struct outgoing_pdu;
1546 memset(pad, '\0', 8);
1548 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1549 /* Server is screwed up ! */
1550 return NT_STATUS_INVALID_PARAMETER;
1553 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1554 return NT_STATUS_NO_MEMORY;
1556 while (1) {
1557 RPC_HDR hdr;
1558 RPC_HDR_REQ hdr_req;
1559 uint16 auth_len = 0;
1560 uint16 frag_len = 0;
1561 uint8 flags = 0;
1562 uint32 ss_padding = 0;
1564 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1565 &frag_len, &auth_len, &ss_padding);
1567 if (current_data_offset == 0) {
1568 flags = RPC_FLG_FIRST;
1571 if (data_sent_thistime == data_left) {
1572 flags |= RPC_FLG_LAST;
1575 /* Create and marshall the header and request header. */
1576 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1578 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1579 prs_mem_free(&outgoing_pdu);
1580 return NT_STATUS_NO_MEMORY;
1583 /* Create the rpc request RPC_HDR_REQ */
1584 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1586 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1587 prs_mem_free(&outgoing_pdu);
1588 return NT_STATUS_NO_MEMORY;
1591 /* Copy in the data, plus any ss padding. */
1592 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1593 prs_mem_free(&outgoing_pdu);
1594 return NT_STATUS_NO_MEMORY;
1597 /* Copy the sign/seal padding data. */
1598 if (ss_padding) {
1599 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1600 prs_mem_free(&outgoing_pdu);
1601 return NT_STATUS_NO_MEMORY;
1605 /* Generate any auth sign/seal and add the auth footer. */
1606 if (auth_len) {
1607 switch (cli->auth->auth_type) {
1608 case PIPE_AUTH_TYPE_NONE:
1609 break;
1610 case PIPE_AUTH_TYPE_NTLMSSP:
1611 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1612 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1613 if (!NT_STATUS_IS_OK(ret)) {
1614 prs_mem_free(&outgoing_pdu);
1615 return ret;
1617 break;
1618 case PIPE_AUTH_TYPE_SCHANNEL:
1619 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1620 if (!NT_STATUS_IS_OK(ret)) {
1621 prs_mem_free(&outgoing_pdu);
1622 return ret;
1624 break;
1625 default:
1626 smb_panic("bad auth type");
1627 break; /* notreached */
1631 /* Actually send the packet. */
1632 if (flags & RPC_FLG_LAST) {
1633 /* Last packet - send the data, get the reply and return. */
1634 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1635 prs_mem_free(&outgoing_pdu);
1637 if ((DEBUGLEVEL >= 50)
1638 && (cli->transport_type == NCACN_NP)) {
1639 char *dump_name = NULL;
1640 /* Also capture received data */
1641 if (asprintf(&dump_name, "%s/reply_%s_%d",
1642 get_dyn_LOGFILEBASE(),
1643 cli->trans.np.pipe_name, op_num) > 0) {
1644 prs_dump(dump_name, op_num, out_data);
1645 SAFE_FREE(dump_name);
1649 return ret;
1650 } else {
1651 /* More packets to come - write and continue. */
1652 ssize_t num_written;
1654 switch (cli->transport_type) {
1655 case NCACN_NP:
1656 num_written = cli_write(cli->trans.np.cli,
1657 cli->trans.np.fnum,
1658 8, /* 8 means message mode. */
1659 prs_data_p(&outgoing_pdu),
1660 (off_t)0,
1661 (size_t)hdr.frag_len);
1663 if (num_written != hdr.frag_len) {
1664 prs_mem_free(&outgoing_pdu);
1665 return cli_get_nt_error(
1666 cli->trans.np.cli);
1668 break;
1669 case NCACN_IP_TCP:
1670 case NCACN_UNIX_STREAM:
1671 num_written = write_data(
1672 cli->trans.sock.fd,
1673 prs_data_p(&outgoing_pdu),
1674 (size_t)hdr.frag_len);
1675 if (num_written != hdr.frag_len) {
1676 NTSTATUS status;
1677 status = map_nt_error_from_unix(errno);
1678 prs_mem_free(&outgoing_pdu);
1679 return status;
1681 break;
1682 default:
1683 DEBUG(0, ("unknown transport type %d\n",
1684 cli->transport_type));
1685 return NT_STATUS_INTERNAL_ERROR;
1689 current_data_offset += data_sent_thistime;
1690 data_left -= data_sent_thistime;
1692 /* Reset the marshalling position back to zero. */
1693 if (!prs_set_offset(&outgoing_pdu, 0)) {
1694 prs_mem_free(&outgoing_pdu);
1695 return NT_STATUS_NO_MEMORY;
1699 #if 0
1700 /****************************************************************************
1701 Set the handle state.
1702 ****************************************************************************/
1704 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1705 const char *pipe_name, uint16 device_state)
1707 bool state_set = False;
1708 char param[2];
1709 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1710 char *rparam = NULL;
1711 char *rdata = NULL;
1712 uint32 rparam_len, rdata_len;
1714 if (pipe_name == NULL)
1715 return False;
1717 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1718 cli->fnum, pipe_name, device_state));
1720 /* create parameters: device state */
1721 SSVAL(param, 0, device_state);
1723 /* create setup parameters. */
1724 setup[0] = 0x0001;
1725 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1727 /* send the data on \PIPE\ */
1728 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1729 setup, 2, 0, /* setup, length, max */
1730 param, 2, 0, /* param, length, max */
1731 NULL, 0, 1024, /* data, length, max */
1732 &rparam, &rparam_len, /* return param, length */
1733 &rdata, &rdata_len)) /* return data, length */
1735 DEBUG(5, ("Set Handle state: return OK\n"));
1736 state_set = True;
1739 SAFE_FREE(rparam);
1740 SAFE_FREE(rdata);
1742 return state_set;
1744 #endif
1746 /****************************************************************************
1747 Check the rpc bind acknowledge response.
1748 ****************************************************************************/
1750 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1752 if ( hdr_ba->addr.len == 0) {
1753 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1756 /* check the transfer syntax */
1757 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1758 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1759 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1760 return False;
1763 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1764 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1765 hdr_ba->res.num_results, hdr_ba->res.reason));
1768 DEBUG(5,("check_bind_response: accepted!\n"));
1769 return True;
1772 /*******************************************************************
1773 Creates a DCE/RPC bind authentication response.
1774 This is the packet that is sent back to the server once we
1775 have received a BIND-ACK, to finish the third leg of
1776 the authentication handshake.
1777 ********************************************************************/
1779 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1780 uint32 rpc_call_id,
1781 enum pipe_auth_type auth_type,
1782 enum pipe_auth_level auth_level,
1783 DATA_BLOB *pauth_blob,
1784 prs_struct *rpc_out)
1786 RPC_HDR hdr;
1787 RPC_HDR_AUTH hdr_auth;
1788 uint32 pad = 0;
1790 /* Create the request RPC_HDR */
1791 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1792 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1793 pauth_blob->length );
1795 /* Marshall it. */
1796 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1797 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1798 return NT_STATUS_NO_MEMORY;
1802 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1803 about padding - shouldn't this pad to length 8 ? JRA.
1806 /* 4 bytes padding. */
1807 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1808 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1809 return NT_STATUS_NO_MEMORY;
1812 /* Create the request RPC_HDR_AUTHA */
1813 init_rpc_hdr_auth(&hdr_auth,
1814 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1815 auth_level, 0, 1);
1817 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1818 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1819 return NT_STATUS_NO_MEMORY;
1823 * Append the auth data to the outgoing buffer.
1826 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1827 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1828 return NT_STATUS_NO_MEMORY;
1831 return NT_STATUS_OK;
1834 /****************************************************************************
1835 Create and send the third packet in an RPC auth.
1836 ****************************************************************************/
1838 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1839 RPC_HDR *phdr,
1840 prs_struct *rbuf,
1841 uint32 rpc_call_id,
1842 enum pipe_auth_type auth_type,
1843 enum pipe_auth_level auth_level)
1845 DATA_BLOB server_response = data_blob_null;
1846 DATA_BLOB client_reply = data_blob_null;
1847 RPC_HDR_AUTH hdr_auth;
1848 NTSTATUS nt_status;
1849 prs_struct rpc_out;
1850 ssize_t ret;
1852 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1853 return NT_STATUS_INVALID_PARAMETER;
1856 /* Process the returned NTLMSSP blob first. */
1857 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1858 return NT_STATUS_INVALID_PARAMETER;
1861 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1862 return NT_STATUS_INVALID_PARAMETER;
1865 /* TODO - check auth_type/auth_level match. */
1867 server_response = data_blob(NULL, phdr->auth_len);
1868 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1870 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1871 server_response,
1872 &client_reply);
1874 if (!NT_STATUS_IS_OK(nt_status)) {
1875 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1876 data_blob_free(&server_response);
1877 return nt_status;
1880 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1882 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1883 auth_type, auth_level,
1884 &client_reply, &rpc_out);
1886 if (!NT_STATUS_IS_OK(nt_status)) {
1887 prs_mem_free(&rpc_out);
1888 data_blob_free(&client_reply);
1889 data_blob_free(&server_response);
1890 return nt_status;
1893 switch (cli->transport_type) {
1894 case NCACN_NP:
1895 /* 8 here is named pipe message mode. */
1896 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
1897 0x8, prs_data_p(&rpc_out), 0,
1898 (size_t)prs_offset(&rpc_out));
1899 break;
1901 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1902 nt_status = cli_get_nt_error(cli->trans.np.cli);
1904 case NCACN_IP_TCP:
1905 case NCACN_UNIX_STREAM:
1906 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
1907 (size_t)prs_offset(&rpc_out));
1908 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1909 nt_status = map_nt_error_from_unix(errno);
1911 break;
1912 default:
1913 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
1914 return NT_STATUS_INTERNAL_ERROR;
1917 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1918 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
1919 nt_errstr(nt_status)));
1920 prs_mem_free(&rpc_out);
1921 data_blob_free(&client_reply);
1922 data_blob_free(&server_response);
1923 return nt_status;
1926 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
1927 rpccli_pipe_txt(debug_ctx(), cli)));
1929 prs_mem_free(&rpc_out);
1930 data_blob_free(&client_reply);
1931 data_blob_free(&server_response);
1932 return NT_STATUS_OK;
1935 /*******************************************************************
1936 Creates a DCE/RPC bind alter context authentication request which
1937 may contain a spnego auth blobl
1938 ********************************************************************/
1940 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1941 const RPC_IFACE *abstract,
1942 const RPC_IFACE *transfer,
1943 enum pipe_auth_level auth_level,
1944 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1945 prs_struct *rpc_out)
1947 RPC_HDR_AUTH hdr_auth;
1948 prs_struct auth_info;
1949 NTSTATUS ret = NT_STATUS_OK;
1951 ZERO_STRUCT(hdr_auth);
1952 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1953 return NT_STATUS_NO_MEMORY;
1955 /* We may change the pad length before marshalling. */
1956 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1958 if (pauth_blob->length) {
1959 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1960 prs_mem_free(&auth_info);
1961 return NT_STATUS_NO_MEMORY;
1965 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1966 rpc_out,
1967 rpc_call_id,
1968 abstract,
1969 transfer,
1970 &hdr_auth,
1971 &auth_info);
1972 prs_mem_free(&auth_info);
1973 return ret;
1976 /*******************************************************************
1977 Third leg of the SPNEGO bind mechanism - sends alter context PDU
1978 and gets a response.
1979 ********************************************************************/
1981 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1982 RPC_HDR *phdr,
1983 prs_struct *rbuf,
1984 uint32 rpc_call_id,
1985 const RPC_IFACE *abstract,
1986 const RPC_IFACE *transfer,
1987 enum pipe_auth_type auth_type,
1988 enum pipe_auth_level auth_level)
1990 DATA_BLOB server_spnego_response = data_blob_null;
1991 DATA_BLOB server_ntlm_response = data_blob_null;
1992 DATA_BLOB client_reply = data_blob_null;
1993 DATA_BLOB tmp_blob = data_blob_null;
1994 RPC_HDR_AUTH hdr_auth;
1995 NTSTATUS nt_status;
1996 prs_struct rpc_out;
1998 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1999 return NT_STATUS_INVALID_PARAMETER;
2002 /* Process the returned NTLMSSP blob first. */
2003 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2004 return NT_STATUS_INVALID_PARAMETER;
2007 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2008 return NT_STATUS_INVALID_PARAMETER;
2011 server_spnego_response = data_blob(NULL, phdr->auth_len);
2012 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2014 /* The server might give us back two challenges - tmp_blob is for the second. */
2015 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2016 data_blob_free(&server_spnego_response);
2017 data_blob_free(&server_ntlm_response);
2018 data_blob_free(&tmp_blob);
2019 return NT_STATUS_INVALID_PARAMETER;
2022 /* We're finished with the server spnego response and the tmp_blob. */
2023 data_blob_free(&server_spnego_response);
2024 data_blob_free(&tmp_blob);
2026 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2027 server_ntlm_response,
2028 &client_reply);
2030 /* Finished with the server_ntlm response */
2031 data_blob_free(&server_ntlm_response);
2033 if (!NT_STATUS_IS_OK(nt_status)) {
2034 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2035 data_blob_free(&client_reply);
2036 return nt_status;
2039 /* SPNEGO wrap the client reply. */
2040 tmp_blob = spnego_gen_auth(client_reply);
2041 data_blob_free(&client_reply);
2042 client_reply = tmp_blob;
2043 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2045 /* Now prepare the alter context pdu. */
2046 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2048 nt_status = create_rpc_alter_context(rpc_call_id,
2049 abstract,
2050 transfer,
2051 auth_level,
2052 &client_reply,
2053 &rpc_out);
2055 data_blob_free(&client_reply);
2057 if (!NT_STATUS_IS_OK(nt_status)) {
2058 prs_mem_free(&rpc_out);
2059 return nt_status;
2062 /* Initialize the returning data struct. */
2063 prs_mem_free(rbuf);
2064 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2066 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2067 if (!NT_STATUS_IS_OK(nt_status)) {
2068 prs_mem_free(&rpc_out);
2069 return nt_status;
2072 prs_mem_free(&rpc_out);
2074 /* Get the auth blob from the reply. */
2075 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2076 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2077 return NT_STATUS_BUFFER_TOO_SMALL;
2080 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2081 return NT_STATUS_INVALID_PARAMETER;
2084 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2085 return NT_STATUS_INVALID_PARAMETER;
2088 server_spnego_response = data_blob(NULL, phdr->auth_len);
2089 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2091 /* Check we got a valid auth response. */
2092 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2093 data_blob_free(&server_spnego_response);
2094 data_blob_free(&tmp_blob);
2095 return NT_STATUS_INVALID_PARAMETER;
2098 data_blob_free(&server_spnego_response);
2099 data_blob_free(&tmp_blob);
2101 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2102 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2104 return NT_STATUS_OK;
2107 /****************************************************************************
2108 Do an rpc bind.
2109 ****************************************************************************/
2111 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2112 struct cli_pipe_auth_data *auth)
2114 RPC_HDR hdr;
2115 RPC_HDR_BA hdr_ba;
2116 prs_struct rpc_out;
2117 prs_struct rbuf;
2118 uint32 rpc_call_id;
2119 NTSTATUS status;
2121 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2122 rpccli_pipe_txt(debug_ctx(), cli),
2123 (unsigned int)auth->auth_type,
2124 (unsigned int)auth->auth_level ));
2126 cli->auth = talloc_move(cli, &auth);
2128 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2130 rpc_call_id = get_rpc_call_id();
2132 /* Marshall the outgoing data. */
2133 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2134 cli->abstract_syntax,
2135 cli->transfer_syntax,
2136 cli->auth->auth_type,
2137 cli->auth->auth_level);
2139 if (!NT_STATUS_IS_OK(status)) {
2140 prs_mem_free(&rpc_out);
2141 return status;
2144 /* Initialize the incoming data struct. */
2145 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2147 /* send data on \PIPE\. receive a response */
2148 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2149 if (!NT_STATUS_IS_OK(status)) {
2150 prs_mem_free(&rpc_out);
2151 return status;
2154 prs_mem_free(&rpc_out);
2156 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2157 rpccli_pipe_txt(debug_ctx(), cli)));
2159 /* Unmarshall the RPC header */
2160 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2161 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2162 prs_mem_free(&rbuf);
2163 return NT_STATUS_BUFFER_TOO_SMALL;
2166 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2167 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2168 prs_mem_free(&rbuf);
2169 return NT_STATUS_BUFFER_TOO_SMALL;
2172 if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2173 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2174 prs_mem_free(&rbuf);
2175 return NT_STATUS_BUFFER_TOO_SMALL;
2178 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2179 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2181 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2182 switch(cli->auth->auth_type) {
2184 case PIPE_AUTH_TYPE_NONE:
2185 case PIPE_AUTH_TYPE_SCHANNEL:
2186 /* Bind complete. */
2187 break;
2189 case PIPE_AUTH_TYPE_NTLMSSP:
2190 /* Need to send AUTH3 packet - no reply. */
2191 status = rpc_finish_auth3_bind(
2192 cli, &hdr, &rbuf, rpc_call_id,
2193 cli->auth->auth_type,
2194 cli->auth->auth_level);
2195 if (!NT_STATUS_IS_OK(status)) {
2196 prs_mem_free(&rbuf);
2197 return status;
2199 break;
2201 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2202 /* Need to send alter context request and reply. */
2203 status = rpc_finish_spnego_ntlmssp_bind(
2204 cli, &hdr, &rbuf, rpc_call_id,
2205 cli->abstract_syntax, cli->transfer_syntax,
2206 cli->auth->auth_type, cli->auth->auth_level);
2207 if (!NT_STATUS_IS_OK(status)) {
2208 prs_mem_free(&rbuf);
2209 return status;
2211 break;
2213 case PIPE_AUTH_TYPE_KRB5:
2214 /* */
2216 default:
2217 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2218 "%u\n", (unsigned int)cli->auth->auth_type));
2219 prs_mem_free(&rbuf);
2220 return NT_STATUS_INVALID_INFO_CLASS;
2223 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2224 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2225 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2226 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2227 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2228 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2229 prs_mem_free(&rbuf);
2230 return NT_STATUS_INVALID_PARAMETER;
2233 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2234 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2235 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2236 prs_mem_free(&rbuf);
2237 return NT_STATUS_INVALID_PARAMETER;
2242 prs_mem_free(&rbuf);
2243 return NT_STATUS_OK;
2246 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2247 unsigned int timeout)
2249 return cli_set_timeout(cli->trans.np.cli, timeout);
2252 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2254 return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
2257 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2259 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2260 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2261 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2262 return true;
2265 if (cli->transport_type == NCACN_NP) {
2266 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2267 return true;
2270 return false;
2273 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2275 if (p->transport_type == NCACN_NP) {
2276 return p->trans.np.cli;
2278 return NULL;
2281 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2283 if (p->transport_type == NCACN_NP) {
2284 bool ret;
2285 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2286 if (!ret) {
2287 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2288 "pipe %s. Error was %s\n",
2289 rpccli_pipe_txt(debug_ctx(), p),
2290 cli_errstr(p->trans.np.cli)));
2293 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2294 rpccli_pipe_txt(debug_ctx(), p)));
2296 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2297 return ret ? -1 : 0;
2300 return -1;
2303 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2304 struct cli_pipe_auth_data **presult)
2306 struct cli_pipe_auth_data *result;
2308 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2309 if (result == NULL) {
2310 return NT_STATUS_NO_MEMORY;
2313 result->auth_type = PIPE_AUTH_TYPE_NONE;
2314 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2316 result->user_name = talloc_strdup(result, "");
2317 result->domain = talloc_strdup(result, "");
2318 if ((result->user_name == NULL) || (result->domain == NULL)) {
2319 TALLOC_FREE(result);
2320 return NT_STATUS_NO_MEMORY;
2323 *presult = result;
2324 return NT_STATUS_OK;
2327 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2329 ntlmssp_end(&auth->a_u.ntlmssp_state);
2330 return 0;
2333 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2334 enum pipe_auth_type auth_type,
2335 enum pipe_auth_level auth_level,
2336 const char *domain,
2337 const char *username,
2338 const char *password,
2339 struct cli_pipe_auth_data **presult)
2341 struct cli_pipe_auth_data *result;
2342 NTSTATUS status;
2344 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2345 if (result == NULL) {
2346 return NT_STATUS_NO_MEMORY;
2349 result->auth_type = auth_type;
2350 result->auth_level = auth_level;
2352 result->user_name = talloc_strdup(result, username);
2353 result->domain = talloc_strdup(result, domain);
2354 if ((result->user_name == NULL) || (result->domain == NULL)) {
2355 status = NT_STATUS_NO_MEMORY;
2356 goto fail;
2359 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2360 if (!NT_STATUS_IS_OK(status)) {
2361 goto fail;
2364 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2366 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2367 if (!NT_STATUS_IS_OK(status)) {
2368 goto fail;
2371 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2372 if (!NT_STATUS_IS_OK(status)) {
2373 goto fail;
2376 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 goto fail;
2382 * Turn off sign+seal to allow selected auth level to turn it back on.
2384 result->a_u.ntlmssp_state->neg_flags &=
2385 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2387 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2388 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2389 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2390 result->a_u.ntlmssp_state->neg_flags
2391 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2394 *presult = result;
2395 return NT_STATUS_OK;
2397 fail:
2398 TALLOC_FREE(result);
2399 return status;
2402 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2403 enum pipe_auth_level auth_level,
2404 const uint8_t sess_key[16],
2405 struct cli_pipe_auth_data **presult)
2407 struct cli_pipe_auth_data *result;
2409 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2410 if (result == NULL) {
2411 return NT_STATUS_NO_MEMORY;
2414 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2415 result->auth_level = auth_level;
2417 result->user_name = talloc_strdup(result, "");
2418 result->domain = talloc_strdup(result, domain);
2419 if ((result->user_name == NULL) || (result->domain == NULL)) {
2420 goto fail;
2423 result->a_u.schannel_auth = talloc(result,
2424 struct schannel_auth_struct);
2425 if (result->a_u.schannel_auth == NULL) {
2426 goto fail;
2429 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2430 sizeof(result->a_u.schannel_auth->sess_key));
2431 result->a_u.schannel_auth->seq_num = 0;
2433 *presult = result;
2434 return NT_STATUS_OK;
2436 fail:
2437 TALLOC_FREE(result);
2438 return NT_STATUS_NO_MEMORY;
2441 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2443 data_blob_free(&auth->session_key);
2444 return 0;
2447 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2448 enum pipe_auth_level auth_level,
2449 const char *service_princ,
2450 const char *username,
2451 const char *password,
2452 struct cli_pipe_auth_data **presult)
2454 #ifdef HAVE_KRB5
2455 struct cli_pipe_auth_data *result;
2457 if ((username != NULL) && (password != NULL)) {
2458 int ret = kerberos_kinit_password(username, password, 0, NULL);
2459 if (ret != 0) {
2460 return NT_STATUS_ACCESS_DENIED;
2464 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2465 if (result == NULL) {
2466 return NT_STATUS_NO_MEMORY;
2469 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2470 result->auth_level = auth_level;
2473 * Username / domain need fixing!
2475 result->user_name = talloc_strdup(result, "");
2476 result->domain = talloc_strdup(result, "");
2477 if ((result->user_name == NULL) || (result->domain == NULL)) {
2478 goto fail;
2481 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2482 result, struct kerberos_auth_struct);
2483 if (result->a_u.kerberos_auth == NULL) {
2484 goto fail;
2486 talloc_set_destructor(result->a_u.kerberos_auth,
2487 cli_auth_kerberos_data_destructor);
2489 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2490 result, service_princ);
2491 if (result->a_u.kerberos_auth->service_principal == NULL) {
2492 goto fail;
2495 *presult = result;
2496 return NT_STATUS_OK;
2498 fail:
2499 TALLOC_FREE(result);
2500 return NT_STATUS_NO_MEMORY;
2501 #else
2502 return NT_STATUS_NOT_SUPPORTED;
2503 #endif
2506 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2508 close(p->trans.sock.fd);
2509 return 0;
2512 /********************************************************************
2513 Create a rpc pipe client struct, connecting to a tcp port
2514 ********************************************************************/
2515 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2516 uint16_t port,
2517 const struct ndr_syntax_id *abstract_syntax,
2518 struct rpc_pipe_client **presult)
2520 struct rpc_pipe_client *result;
2521 struct sockaddr_storage addr;
2522 NTSTATUS status;
2524 result = talloc(mem_ctx, struct rpc_pipe_client);
2525 if (result == NULL) {
2526 return NT_STATUS_NO_MEMORY;
2529 result->transport_type = NCACN_IP_TCP;
2531 result->abstract_syntax = abstract_syntax;
2532 result->transfer_syntax = &ndr_transfer_syntax;
2534 result->desthost = talloc_strdup(result, host);
2535 result->srv_name_slash = talloc_asprintf_strupper_m(
2536 result, "\\\\%s", result->desthost);
2537 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2538 status = NT_STATUS_NO_MEMORY;
2539 goto fail;
2542 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2543 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2545 if (!resolve_name(host, &addr, 0)) {
2546 status = NT_STATUS_NOT_FOUND;
2547 goto fail;
2550 result->trans.sock.fd = open_socket_out(SOCK_STREAM, &addr, port, 60);
2551 if (result->trans.sock.fd == -1) {
2552 status = map_nt_error_from_unix(errno);
2553 goto fail;
2556 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2558 *presult = result;
2559 return NT_STATUS_OK;
2561 fail:
2562 TALLOC_FREE(result);
2563 return status;
2566 /********************************************************************
2567 Create a rpc pipe client struct, connecting to a unix domain socket
2568 ********************************************************************/
2569 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2570 const struct ndr_syntax_id *abstract_syntax,
2571 struct rpc_pipe_client **presult)
2573 struct rpc_pipe_client *result;
2574 struct sockaddr_un addr;
2575 NTSTATUS status;
2577 result = talloc(mem_ctx, struct rpc_pipe_client);
2578 if (result == NULL) {
2579 return NT_STATUS_NO_MEMORY;
2582 result->transport_type = NCACN_UNIX_STREAM;
2584 result->abstract_syntax = abstract_syntax;
2585 result->transfer_syntax = &ndr_transfer_syntax;
2587 result->desthost = get_myname(result);
2588 result->srv_name_slash = talloc_asprintf_strupper_m(
2589 result, "\\\\%s", result->desthost);
2590 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2591 status = NT_STATUS_NO_MEMORY;
2592 goto fail;
2595 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2596 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2598 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2599 if (result->trans.sock.fd == -1) {
2600 status = map_nt_error_from_unix(errno);
2601 goto fail;
2604 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2606 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2607 if (result->dc == NULL) {
2608 status = NT_STATUS_NO_MEMORY;
2609 goto fail;
2612 ZERO_STRUCT(addr);
2613 addr.sun_family = AF_UNIX;
2614 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2616 if (sys_connect(result->trans.sock.fd,
2617 (struct sockaddr *)&addr) == -1) {
2618 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2619 strerror(errno)));
2620 close(result->trans.sock.fd);
2621 return map_nt_error_from_unix(errno);
2624 *presult = result;
2625 return NT_STATUS_OK;
2627 fail:
2628 TALLOC_FREE(result);
2629 return status;
2633 /****************************************************************************
2634 Open a named pipe over SMB to a remote server.
2636 * CAVEAT CALLER OF THIS FUNCTION:
2637 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2638 * so be sure that this function is called AFTER any structure (vs pointer)
2639 * assignment of the cli. In particular, libsmbclient does structure
2640 * assignments of cli, which invalidates the data in the returned
2641 * rpc_pipe_client if this function is called before the structure assignment
2642 * of cli.
2644 ****************************************************************************/
2646 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2648 struct rpc_pipe_client *result;
2649 int fnum;
2651 *perr = NT_STATUS_NO_MEMORY;
2653 /* sanity check to protect against crashes */
2655 if ( !cli ) {
2656 *perr = NT_STATUS_INVALID_HANDLE;
2657 return NULL;
2660 /* The pipe name index must fall within our array */
2661 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2663 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2664 if (result == NULL) {
2665 *perr = NT_STATUS_NO_MEMORY;
2666 return NULL;
2669 result->transport_type = NCACN_NP;
2671 result->trans.np.pipe_name = cli_get_pipe_name(pipe_idx);
2673 result->trans.np.cli = cli;
2674 result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2675 result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2676 result->desthost = talloc_strdup(result, cli->desthost);
2677 result->srv_name_slash = talloc_asprintf_strupper_m(
2678 result, "\\\\%s", result->desthost);
2680 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2681 *perr = NT_STATUS_NO_MEMORY;
2682 TALLOC_FREE(result);
2683 return NULL;
2686 if (pipe_idx == PI_NETLOGON) {
2687 /* Set up a netlogon credential chain for a netlogon pipe. */
2688 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2689 if (result->dc == NULL) {
2690 *perr = NT_STATUS_NO_MEMORY;
2691 TALLOC_FREE(result);
2692 return NULL;
2696 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2697 DESIRED_ACCESS_PIPE);
2698 if (fnum == -1) {
2699 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2700 "to machine %s. Error was %s\n",
2701 result->trans.np.pipe_name, cli->desthost,
2702 cli_errstr(cli)));
2703 *perr = cli_get_nt_error(cli);
2704 talloc_destroy(result);
2705 return NULL;
2708 result->trans.np.fnum = fnum;
2710 DLIST_ADD(cli->pipe_list, result);
2711 talloc_set_destructor(result, rpc_pipe_destructor);
2713 *perr = NT_STATUS_OK;
2715 return result;
2718 /****************************************************************************
2719 Open a named pipe to an SMB server and bind anonymously.
2720 ****************************************************************************/
2722 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2724 struct rpc_pipe_client *result;
2725 struct cli_pipe_auth_data *auth;
2727 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2728 if (result == NULL) {
2729 return NULL;
2732 *perr = rpccli_anon_bind_data(result, &auth);
2733 if (!NT_STATUS_IS_OK(*perr)) {
2734 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2735 nt_errstr(*perr)));
2736 TALLOC_FREE(result);
2737 return NULL;
2741 * This is a bit of an abstraction violation due to the fact that an
2742 * anonymous bind on an authenticated SMB inherits the user/domain
2743 * from the enclosing SMB creds
2746 TALLOC_FREE(auth->user_name);
2747 TALLOC_FREE(auth->domain);
2749 auth->user_name = talloc_strdup(auth, cli->user_name);
2750 auth->domain = talloc_strdup(auth, cli->domain);
2752 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2753 *perr = NT_STATUS_NO_MEMORY;
2754 TALLOC_FREE(result);
2755 return NULL;
2758 *perr = rpc_pipe_bind(result, auth);
2759 if (!NT_STATUS_IS_OK(*perr)) {
2760 int lvl = 0;
2761 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2762 /* non AD domains just don't have this pipe, avoid
2763 * level 0 statement in that case - gd */
2764 lvl = 3;
2766 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2767 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2768 TALLOC_FREE(result);
2769 return NULL;
2772 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2773 "%s and bound anonymously.\n", result->trans.np.pipe_name,
2774 cli->desthost ));
2776 return result;
2779 /****************************************************************************
2780 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2781 ****************************************************************************/
2783 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2784 int pipe_idx,
2785 enum pipe_auth_type auth_type,
2786 enum pipe_auth_level auth_level,
2787 const char *domain,
2788 const char *username,
2789 const char *password,
2790 NTSTATUS *perr)
2792 struct rpc_pipe_client *result;
2793 struct cli_pipe_auth_data *auth;
2795 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2796 if (result == NULL) {
2797 return NULL;
2800 *perr = rpccli_ntlmssp_bind_data(
2801 result, auth_type, auth_level, domain, username,
2802 cli->pwd.null_pwd ? NULL : password, &auth);
2803 if (!NT_STATUS_IS_OK(*perr)) {
2804 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2805 nt_errstr(*perr)));
2806 TALLOC_FREE(result);
2807 return NULL;
2810 *perr = rpc_pipe_bind(result, auth);
2811 if (!NT_STATUS_IS_OK(*perr)) {
2812 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2813 nt_errstr(*perr) ));
2814 goto err;
2817 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2818 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2819 result->trans.np.pipe_name, cli->desthost,
2820 domain, username ));
2822 return result;
2824 err:
2826 TALLOC_FREE(result);
2827 return NULL;
2830 /****************************************************************************
2831 External interface.
2832 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2833 ****************************************************************************/
2835 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2836 int pipe_idx,
2837 enum pipe_auth_level auth_level,
2838 const char *domain,
2839 const char *username,
2840 const char *password,
2841 NTSTATUS *perr)
2843 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2844 pipe_idx,
2845 PIPE_AUTH_TYPE_NTLMSSP,
2846 auth_level,
2847 domain,
2848 username,
2849 password,
2850 perr);
2853 /****************************************************************************
2854 External interface.
2855 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2856 ****************************************************************************/
2858 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2859 int pipe_idx,
2860 enum pipe_auth_level auth_level,
2861 const char *domain,
2862 const char *username,
2863 const char *password,
2864 NTSTATUS *perr)
2866 return cli_rpc_pipe_open_ntlmssp_internal(cli,
2867 pipe_idx,
2868 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2869 auth_level,
2870 domain,
2871 username,
2872 password,
2873 perr);
2876 /****************************************************************************
2877 Get a the schannel session key out of an already opened netlogon pipe.
2878 ****************************************************************************/
2879 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2880 struct cli_state *cli,
2881 const char *domain,
2882 uint32 *pneg_flags,
2883 NTSTATUS *perr)
2885 uint32 sec_chan_type = 0;
2886 unsigned char machine_pwd[16];
2887 const char *machine_account;
2889 /* Get the machine account credentials from secrets.tdb. */
2890 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2891 &sec_chan_type))
2893 DEBUG(0, ("get_schannel_session_key: could not fetch "
2894 "trust account password for domain '%s'\n",
2895 domain));
2896 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2897 return false;
2900 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2901 cli->desthost, /* server name */
2902 domain, /* domain */
2903 global_myname(), /* client name */
2904 machine_account, /* machine account name */
2905 machine_pwd,
2906 sec_chan_type,
2907 pneg_flags);
2909 if (!NT_STATUS_IS_OK(*perr)) {
2910 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2911 "failed with result %s to server %s, domain %s, machine account %s.\n",
2912 nt_errstr(*perr), cli->desthost, domain, machine_account ));
2913 return false;
2916 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2917 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2918 cli->desthost));
2919 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2920 return false;
2923 return true;
2926 /****************************************************************************
2927 Open a netlogon pipe and get the schannel session key.
2928 Now exposed to external callers.
2929 ****************************************************************************/
2932 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2933 const char *domain,
2934 uint32 *pneg_flags,
2935 NTSTATUS *perr)
2937 struct rpc_pipe_client *netlogon_pipe = NULL;
2939 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2940 if (!netlogon_pipe) {
2941 return NULL;
2944 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2945 pneg_flags, perr))
2947 TALLOC_FREE(netlogon_pipe);
2948 return NULL;
2951 return netlogon_pipe;
2954 /****************************************************************************
2955 External interface.
2956 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2957 using session_key. sign and seal.
2958 ****************************************************************************/
2960 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2961 int pipe_idx,
2962 enum pipe_auth_level auth_level,
2963 const char *domain,
2964 const struct dcinfo *pdc,
2965 NTSTATUS *perr)
2967 struct rpc_pipe_client *result;
2968 struct cli_pipe_auth_data *auth;
2970 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2971 if (result == NULL) {
2972 return NULL;
2975 *perr = rpccli_schannel_bind_data(result, domain, auth_level,
2976 pdc->sess_key, &auth);
2977 if (!NT_STATUS_IS_OK(*perr)) {
2978 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2979 nt_errstr(*perr)));
2980 TALLOC_FREE(result);
2981 return NULL;
2984 *perr = rpc_pipe_bind(result, auth);
2985 if (!NT_STATUS_IS_OK(*perr)) {
2986 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2987 nt_errstr(*perr) ));
2988 TALLOC_FREE(result);
2989 return NULL;
2992 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2993 if (result->dc) {
2994 *result->dc = *pdc;
2997 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2998 "for domain %s "
2999 "and bound using schannel.\n",
3000 result->trans.np.pipe_name, cli->desthost, domain ));
3002 return result;
3005 /****************************************************************************
3006 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3007 Fetch the session key ourselves using a temporary netlogon pipe. This
3008 version uses an ntlmssp auth bound netlogon pipe to get the key.
3009 ****************************************************************************/
3011 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3012 const char *domain,
3013 const char *username,
3014 const char *password,
3015 uint32 *pneg_flags,
3016 NTSTATUS *perr)
3018 struct rpc_pipe_client *netlogon_pipe = NULL;
3020 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
3021 if (!netlogon_pipe) {
3022 return NULL;
3025 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
3026 pneg_flags, perr))
3028 TALLOC_FREE(netlogon_pipe);
3029 return NULL;
3032 return netlogon_pipe;
3035 /****************************************************************************
3036 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3037 Fetch the session key ourselves using a temporary netlogon pipe. This version
3038 uses an ntlmssp bind to get the session key.
3039 ****************************************************************************/
3041 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3042 int pipe_idx,
3043 enum pipe_auth_level auth_level,
3044 const char *domain,
3045 const char *username,
3046 const char *password,
3047 NTSTATUS *perr)
3049 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3050 struct rpc_pipe_client *netlogon_pipe = NULL;
3051 struct rpc_pipe_client *result = NULL;
3053 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
3054 password, &neg_flags, perr);
3055 if (!netlogon_pipe) {
3056 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3057 "key from server %s for domain %s.\n",
3058 cli->desthost, domain ));
3059 return NULL;
3062 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
3063 auth_level,
3064 domain, netlogon_pipe->dc, perr);
3066 /* Now we've bound using the session key we can close the netlog pipe. */
3067 TALLOC_FREE(netlogon_pipe);
3069 return result;
3072 /****************************************************************************
3073 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3074 Fetch the session key ourselves using a temporary netlogon pipe.
3075 ****************************************************************************/
3077 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
3078 int pipe_idx,
3079 enum pipe_auth_level auth_level,
3080 const char *domain,
3081 NTSTATUS *perr)
3083 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3084 struct rpc_pipe_client *netlogon_pipe = NULL;
3085 struct rpc_pipe_client *result = NULL;
3087 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
3088 if (!netlogon_pipe) {
3089 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3090 "key from server %s for domain %s.\n",
3091 cli->desthost, domain ));
3092 return NULL;
3095 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
3096 auth_level,
3097 domain, netlogon_pipe->dc, perr);
3099 /* Now we've bound using the session key we can close the netlog pipe. */
3100 TALLOC_FREE(netlogon_pipe);
3102 return result;
3105 /****************************************************************************
3106 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3107 The idea is this can be called with service_princ, username and password all
3108 NULL so long as the caller has a TGT.
3109 ****************************************************************************/
3111 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
3112 int pipe_idx,
3113 enum pipe_auth_level auth_level,
3114 const char *service_princ,
3115 const char *username,
3116 const char *password,
3117 NTSTATUS *perr)
3119 #ifdef HAVE_KRB5
3120 struct rpc_pipe_client *result;
3121 struct cli_pipe_auth_data *auth;
3123 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3124 if (result == NULL) {
3125 return NULL;
3128 *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3129 username, password, &auth);
3130 if (!NT_STATUS_IS_OK(*perr)) {
3131 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3132 nt_errstr(*perr)));
3133 TALLOC_FREE(result);
3134 return NULL;
3137 *perr = rpc_pipe_bind(result, auth);
3138 if (!NT_STATUS_IS_OK(*perr)) {
3139 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
3140 nt_errstr(*perr) ));
3141 TALLOC_FREE(result);
3142 return NULL;
3145 return result;
3146 #else
3147 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3148 return NULL;
3149 #endif