2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
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/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
24 #define DBGC_CLASS DBGC_RPC_CLI
26 /*******************************************************************
27 interface/version dce/rpc pipe identification
28 ********************************************************************/
30 static const struct ndr_syntax_id syntax_spoolss = {
32 0x12345678, 0x1234, 0xabcd,
35 0x45, 0x67, 0x89, 0xab }
39 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
40 #define PIPE_SAMR "\\PIPE\\samr"
41 #define PIPE_WINREG "\\PIPE\\winreg"
42 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
43 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
44 #define PIPE_NTLSA "\\PIPE\\ntlsa"
45 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
46 #define PIPE_LSASS "\\PIPE\\lsass"
47 #define PIPE_LSARPC "\\PIPE\\lsarpc"
48 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
49 #define PIPE_NETDFS "\\PIPE\\netdfs"
50 #define PIPE_ECHO "\\PIPE\\rpcecho"
51 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
52 #define PIPE_EPM "\\PIPE\\epmapper"
53 #define PIPE_SVCCTL "\\PIPE\\svcctl"
54 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
55 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
56 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
59 * IMPORTANT!! If you update this structure, make sure to
60 * update the index #defines in smb.h.
63 static const struct pipe_id_info pipe_names [] =
65 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id,
66 PIPE_LSASS, &ndr_transfer_syntax },
67 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id,
68 PIPE_LSASS, &ndr_transfer_syntax },
69 { PIPE_SAMR, &ndr_table_samr.syntax_id,
70 PIPE_LSASS, &ndr_transfer_syntax },
71 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id,
72 PIPE_LSASS, &ndr_transfer_syntax },
73 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id,
74 PIPE_NTSVCS, &ndr_transfer_syntax },
75 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id,
76 PIPE_NTSVCS, &ndr_transfer_syntax },
77 { PIPE_WINREG, &ndr_table_winreg.syntax_id,
78 PIPE_WINREG, &ndr_transfer_syntax },
79 { PIPE_SPOOLSS, &syntax_spoolss,
80 PIPE_SPOOLSS, &ndr_transfer_syntax },
81 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id,
82 PIPE_NETDFS, &ndr_transfer_syntax },
83 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id,
84 PIPE_ECHO, &ndr_transfer_syntax },
85 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id,
86 PIPE_SHUTDOWN, &ndr_transfer_syntax },
87 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id,
88 PIPE_NTSVCS, &ndr_transfer_syntax },
89 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id,
90 PIPE_EVENTLOG, &ndr_transfer_syntax },
91 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id,
92 PIPE_NTSVCS, &ndr_transfer_syntax },
93 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id,
94 PIPE_EPMAPPER, &ndr_transfer_syntax },
95 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id,
96 PIPE_DRSUAPI, &ndr_transfer_syntax },
97 { NULL, NULL, NULL, NULL }
100 /****************************************************************************
101 Return the pipe name from the index.
102 ****************************************************************************/
104 const char *cli_get_pipe_name(int pipe_idx)
106 return &pipe_names[pipe_idx].client_pipe[5];
109 /****************************************************************************
110 Return the pipe idx from the syntax.
111 ****************************************************************************/
112 int cli_get_pipe_idx(const RPC_IFACE *syntax)
115 for (i = 0; pipe_names[i].client_pipe; i++) {
116 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax, syntax)) {
124 /********************************************************************
125 Map internal value to wire value.
126 ********************************************************************/
128 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
132 case PIPE_AUTH_TYPE_NONE:
133 return RPC_ANONYMOUS_AUTH_TYPE;
135 case PIPE_AUTH_TYPE_NTLMSSP:
136 return RPC_NTLMSSP_AUTH_TYPE;
138 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
139 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
140 return RPC_SPNEGO_AUTH_TYPE;
142 case PIPE_AUTH_TYPE_SCHANNEL:
143 return RPC_SCHANNEL_AUTH_TYPE;
145 case PIPE_AUTH_TYPE_KRB5:
146 return RPC_KRB5_AUTH_TYPE;
149 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
151 (unsigned int)auth_type ));
157 /********************************************************************
158 Pipe description for a DEBUG
159 ********************************************************************/
160 static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli)
164 switch (cli->transport_type) {
166 result = talloc_asprintf(mem_ctx, "host %s, pipe %s, "
169 cli->trans.np.pipe_name,
170 (unsigned int)(cli->trans.np.fnum));
173 case NCACN_UNIX_STREAM:
174 result = talloc_asprintf(mem_ctx, "host %s, fd %d",
175 cli->desthost, cli->trans.sock.fd);
178 result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
181 SMB_ASSERT(result != NULL);
185 /********************************************************************
187 ********************************************************************/
189 static uint32 get_rpc_call_id(void)
191 static uint32 call_id = 0;
195 /*******************************************************************
196 Read from a RPC named pipe
197 ********************************************************************/
198 static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name,
199 int fnum, char *buf, off_t offset, size_t size,
204 num_read = cli_read(cli, fnum, buf, offset, size);
206 DEBUG(5,("rpc_read_np: num_read = %d, read offset: %u, to read: %u\n",
207 (int)num_read, (unsigned int)offset, (unsigned int)size));
210 * A dos error of ERRDOS/ERRmoredata is not an error.
212 if (cli_is_dos_error(cli)) {
215 cli_dos_error(cli, &eclass, &ecode);
216 if (eclass != ERRDOS && ecode != ERRmoredata) {
217 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read "
218 "on fnum 0x%x\n", eclass, (unsigned int)ecode,
219 cli_errstr(cli), fnum));
220 return dos_to_ntstatus(eclass, ecode);
225 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
227 if (cli_is_nt_error(cli)) {
228 if (!NT_STATUS_EQUAL(cli_nt_error(cli),
229 NT_STATUS_BUFFER_TOO_SMALL)) {
230 DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum "
231 "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum));
232 return cli_nt_error(cli);
236 if (num_read == -1) {
237 DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned "
239 return cli_get_nt_error(cli);
242 *pnum_read = num_read;
247 /*******************************************************************
248 Use SMBreadX to get rest of one fragment's worth of rpc data.
249 Will expand the current_pdu struct to the correct size.
250 ********************************************************************/
252 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
253 prs_struct *current_pdu,
255 uint32 *current_pdu_offset)
257 size_t size = (size_t)cli->max_recv_frag;
258 uint32 stream_offset = 0;
259 ssize_t num_read = 0;
261 ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
263 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
264 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
267 * Grow the buffer if needed to accommodate the data to be read.
270 if (extra_data_size > 0) {
271 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
272 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
273 return NT_STATUS_NO_MEMORY;
275 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
278 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
283 /* read data using SMBreadX */
284 if (size > (size_t)data_to_read) {
285 size = (size_t)data_to_read;
288 switch (cli->transport_type) {
290 status = rpc_read_np(cli->trans.np.cli,
291 cli->trans.np.pipe_name,
292 cli->trans.np.fnum, pdata,
293 (off_t)stream_offset, size,
297 case NCACN_UNIX_STREAM:
298 status = NT_STATUS_OK;
299 num_read = sys_read(cli->trans.sock.fd, pdata, size);
300 if (num_read == -1) {
301 status = map_nt_error_from_unix(errno);
304 status = NT_STATUS_END_OF_FILE;
308 DEBUG(0, ("unknown transport type %d\n",
309 cli->transport_type));
310 return NT_STATUS_INTERNAL_ERROR;
313 data_to_read -= num_read;
314 stream_offset += num_read;
317 } while (num_read > 0 && data_to_read > 0);
318 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
321 * Update the current offset into current_pdu by the amount read.
323 *current_pdu_offset += stream_offset;
327 /****************************************************************************
328 Try and get a PDU's worth of data from current_pdu. If not, then read more
330 ****************************************************************************/
332 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
334 NTSTATUS ret = NT_STATUS_OK;
335 uint32 current_pdu_len = prs_data_size(current_pdu);
337 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
338 if (current_pdu_len < RPC_HEADER_LEN) {
339 /* rpc_read expands the current_pdu struct as neccessary. */
340 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, ¤t_pdu_len);
341 if (!NT_STATUS_IS_OK(ret)) {
346 /* This next call sets the endian bit correctly in current_pdu. */
347 /* We will propagate this to rbuf later. */
348 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
349 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
350 return NT_STATUS_BUFFER_TOO_SMALL;
353 /* Ensure we have frag_len bytes of data. */
354 if (current_pdu_len < prhdr->frag_len) {
355 /* rpc_read expands the current_pdu struct as neccessary. */
356 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, ¤t_pdu_len);
357 if (!NT_STATUS_IS_OK(ret)) {
362 if (current_pdu_len < prhdr->frag_len) {
363 return NT_STATUS_BUFFER_TOO_SMALL;
369 /****************************************************************************
370 NTLMSSP specific sign/seal.
371 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
372 In fact I should probably abstract these into identical pieces of code... JRA.
373 ****************************************************************************/
375 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
376 prs_struct *current_pdu,
377 uint8 *p_ss_padding_len)
379 RPC_HDR_AUTH auth_info;
380 uint32 save_offset = prs_offset(current_pdu);
381 uint32 auth_len = prhdr->auth_len;
382 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
383 unsigned char *data = NULL;
385 unsigned char *full_packet_data = NULL;
386 size_t full_packet_data_len;
390 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
391 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
395 if (!ntlmssp_state) {
396 return NT_STATUS_INVALID_PARAMETER;
399 /* Ensure there's enough data for an authenticated response. */
400 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
401 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
402 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
403 (unsigned int)auth_len ));
404 return NT_STATUS_BUFFER_TOO_SMALL;
408 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
409 * after the RPC header.
410 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
411 * functions as NTLMv2 checks the rpc headers also.
414 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
415 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
417 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
418 full_packet_data_len = prhdr->frag_len - auth_len;
420 /* Pull the auth header and the following data into a blob. */
421 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
422 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
423 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
424 return NT_STATUS_BUFFER_TOO_SMALL;
427 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
428 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
429 return NT_STATUS_BUFFER_TOO_SMALL;
432 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
433 auth_blob.length = auth_len;
435 switch (cli->auth->auth_level) {
436 case PIPE_AUTH_LEVEL_PRIVACY:
437 /* Data is encrypted. */
438 status = ntlmssp_unseal_packet(ntlmssp_state,
441 full_packet_data_len,
443 if (!NT_STATUS_IS_OK(status)) {
444 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
445 "packet from %s. Error was %s.\n",
446 rpccli_pipe_txt(debug_ctx(), cli),
447 nt_errstr(status) ));
451 case PIPE_AUTH_LEVEL_INTEGRITY:
452 /* Data is signed. */
453 status = ntlmssp_check_packet(ntlmssp_state,
456 full_packet_data_len,
458 if (!NT_STATUS_IS_OK(status)) {
459 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
460 "packet from %s. Error was %s.\n",
461 rpccli_pipe_txt(debug_ctx(), cli),
462 nt_errstr(status) ));
467 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
468 "auth level %d\n", cli->auth->auth_level));
469 return NT_STATUS_INVALID_INFO_CLASS;
473 * Return the current pointer to the data offset.
476 if(!prs_set_offset(current_pdu, save_offset)) {
477 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
478 (unsigned int)save_offset ));
479 return NT_STATUS_BUFFER_TOO_SMALL;
483 * Remember the padding length. We must remove it from the real data
484 * stream once the sign/seal is done.
487 *p_ss_padding_len = auth_info.auth_pad_len;
492 /****************************************************************************
493 schannel specific sign/seal.
494 ****************************************************************************/
496 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
497 prs_struct *current_pdu,
498 uint8 *p_ss_padding_len)
500 RPC_HDR_AUTH auth_info;
501 RPC_AUTH_SCHANNEL_CHK schannel_chk;
502 uint32 auth_len = prhdr->auth_len;
503 uint32 save_offset = prs_offset(current_pdu);
504 struct schannel_auth_struct *schannel_auth =
505 cli->auth->a_u.schannel_auth;
508 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
509 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
513 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
514 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
515 return NT_STATUS_INVALID_PARAMETER;
518 if (!schannel_auth) {
519 return NT_STATUS_INVALID_PARAMETER;
522 /* Ensure there's enough data for an authenticated response. */
523 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
524 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
525 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
526 (unsigned int)auth_len ));
527 return NT_STATUS_INVALID_PARAMETER;
530 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
532 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
533 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
534 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
535 return NT_STATUS_BUFFER_TOO_SMALL;
538 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
539 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
540 return NT_STATUS_BUFFER_TOO_SMALL;
543 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
544 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
545 auth_info.auth_type));
546 return NT_STATUS_BUFFER_TOO_SMALL;
549 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
550 &schannel_chk, current_pdu, 0)) {
551 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
552 return NT_STATUS_BUFFER_TOO_SMALL;
555 if (!schannel_decode(schannel_auth,
556 cli->auth->auth_level,
559 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
561 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
562 "Connection to %s.\n",
563 rpccli_pipe_txt(debug_ctx(), cli)));
564 return NT_STATUS_INVALID_PARAMETER;
567 /* The sequence number gets incremented on both send and receive. */
568 schannel_auth->seq_num++;
571 * Return the current pointer to the data offset.
574 if(!prs_set_offset(current_pdu, save_offset)) {
575 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
576 (unsigned int)save_offset ));
577 return NT_STATUS_BUFFER_TOO_SMALL;
581 * Remember the padding length. We must remove it from the real data
582 * stream once the sign/seal is done.
585 *p_ss_padding_len = auth_info.auth_pad_len;
590 /****************************************************************************
591 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
592 ****************************************************************************/
594 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
595 prs_struct *current_pdu,
596 uint8 *p_ss_padding_len)
598 NTSTATUS ret = NT_STATUS_OK;
600 /* Paranioa checks for auth_len. */
601 if (prhdr->auth_len) {
602 if (prhdr->auth_len > prhdr->frag_len) {
603 return NT_STATUS_INVALID_PARAMETER;
606 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
607 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
608 /* Integer wrap attempt. */
609 return NT_STATUS_INVALID_PARAMETER;
614 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
617 switch(cli->auth->auth_type) {
618 case PIPE_AUTH_TYPE_NONE:
619 if (prhdr->auth_len) {
620 DEBUG(3, ("cli_pipe_validate_rpc_response: "
621 "Connection to %s - got non-zero "
623 rpccli_pipe_txt(debug_ctx(), cli),
624 (unsigned int)prhdr->auth_len ));
625 return NT_STATUS_INVALID_PARAMETER;
629 case PIPE_AUTH_TYPE_NTLMSSP:
630 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
631 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
632 if (!NT_STATUS_IS_OK(ret)) {
637 case PIPE_AUTH_TYPE_SCHANNEL:
638 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
639 if (!NT_STATUS_IS_OK(ret)) {
644 case PIPE_AUTH_TYPE_KRB5:
645 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
647 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
648 "to %s - unknown internal auth type %u.\n",
649 rpccli_pipe_txt(debug_ctx(), cli),
650 cli->auth->auth_type ));
651 return NT_STATUS_INVALID_INFO_CLASS;
657 /****************************************************************************
658 Do basic authentication checks on an incoming pdu.
659 ****************************************************************************/
661 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
662 prs_struct *current_pdu,
663 uint8 expected_pkt_type,
666 prs_struct *return_data)
669 NTSTATUS ret = NT_STATUS_OK;
670 uint32 current_pdu_len = prs_data_size(current_pdu);
672 if (current_pdu_len != prhdr->frag_len) {
673 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
674 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
675 return NT_STATUS_INVALID_PARAMETER;
679 * Point the return values at the real data including the RPC
680 * header. Just in case the caller wants it.
682 *ppdata = prs_data_p(current_pdu);
683 *pdata_len = current_pdu_len;
685 /* Ensure we have the correct type. */
686 switch (prhdr->pkt_type) {
687 case RPC_ALTCONTRESP:
690 /* Alter context and bind ack share the same packet definitions. */
696 RPC_HDR_RESP rhdr_resp;
697 uint8 ss_padding_len = 0;
699 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
700 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
701 return NT_STATUS_BUFFER_TOO_SMALL;
704 /* Here's where we deal with incoming sign/seal. */
705 ret = cli_pipe_validate_rpc_response(cli, prhdr,
706 current_pdu, &ss_padding_len);
707 if (!NT_STATUS_IS_OK(ret)) {
711 /* Point the return values at the NDR data. Remember to remove any ss padding. */
712 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
714 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
715 return NT_STATUS_BUFFER_TOO_SMALL;
718 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
720 /* Remember to remove the auth footer. */
721 if (prhdr->auth_len) {
722 /* We've already done integer wrap tests on auth_len in
723 cli_pipe_validate_rpc_response(). */
724 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
725 return NT_STATUS_BUFFER_TOO_SMALL;
727 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
730 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
731 current_pdu_len, *pdata_len, ss_padding_len ));
734 * If this is the first reply, and the allocation hint is reasonably, try and
735 * set up the return_data parse_struct to the correct size.
738 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
739 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
740 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
741 "too large to allocate\n",
742 (unsigned int)rhdr_resp.alloc_hint ));
743 return NT_STATUS_NO_MEMORY;
751 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
752 "received from %s!\n",
753 rpccli_pipe_txt(debug_ctx(), cli)));
754 /* Use this for now... */
755 return NT_STATUS_NETWORK_ACCESS_DENIED;
759 RPC_HDR_RESP rhdr_resp;
760 RPC_HDR_FAULT fault_resp;
762 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
763 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
764 return NT_STATUS_BUFFER_TOO_SMALL;
767 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
768 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
769 return NT_STATUS_BUFFER_TOO_SMALL;
772 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
773 "code %s received from %s!\n",
774 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
775 rpccli_pipe_txt(debug_ctx(), cli)));
776 if (NT_STATUS_IS_OK(fault_resp.status)) {
777 return NT_STATUS_UNSUCCESSFUL;
779 return fault_resp.status;
784 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
786 (unsigned int)prhdr->pkt_type,
787 rpccli_pipe_txt(debug_ctx(), cli)));
788 return NT_STATUS_INVALID_INFO_CLASS;
791 if (prhdr->pkt_type != expected_pkt_type) {
792 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
793 "got an unexpected RPC packet type - %u, not %u\n",
794 rpccli_pipe_txt(debug_ctx(), cli),
797 return NT_STATUS_INVALID_INFO_CLASS;
800 /* Do this just before return - we don't want to modify any rpc header
801 data before now as we may have needed to do cryptographic actions on
804 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
805 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
806 "setting fragment first/last ON.\n"));
807 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
813 /****************************************************************************
814 Ensure we eat the just processed pdu from the current_pdu prs_struct.
815 Normally the frag_len and buffer size will match, but on the first trans
816 reply there is a theoretical chance that buffer size > frag_len, so we must
818 ****************************************************************************/
820 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
822 uint32 current_pdu_len = prs_data_size(current_pdu);
824 if (current_pdu_len < prhdr->frag_len) {
825 return NT_STATUS_BUFFER_TOO_SMALL;
829 if (current_pdu_len == (uint32)prhdr->frag_len) {
830 prs_mem_free(current_pdu);
831 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
832 /* Make current_pdu dynamic with no memory. */
833 prs_give_memory(current_pdu, 0, 0, True);
838 * Oh no ! More data in buffer than we processed in current pdu.
839 * Cheat. Move the data down and shrink the buffer.
842 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
843 current_pdu_len - prhdr->frag_len);
845 /* Remember to set the read offset back to zero. */
846 prs_set_offset(current_pdu, 0);
848 /* Shrink the buffer. */
849 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
850 return NT_STATUS_BUFFER_TOO_SMALL;
856 /****************************************************************************
857 Send data on an rpc pipe via trans. The prs_struct data must be the last
858 pdu fragment of an NDR data stream.
860 Receive response data from an rpc pipe, which may be large...
862 Read the first fragment: unfortunately have to use SMBtrans for the first
863 bit, then SMBreadX for subsequent bits.
865 If first fragment received also wasn't the last fragment, continue
866 getting fragments until we _do_ receive the last fragment.
868 Request/Response PDU's look like the following...
870 |<------------------PDU len----------------------------------------------->|
871 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
873 +------------+-----------------+-------------+---------------+-------------+
874 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
875 +------------+-----------------+-------------+---------------+-------------+
877 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
878 signing & sealing being negotiated.
880 ****************************************************************************/
882 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
883 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
884 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
885 uint8 expected_pkt_type)
887 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
889 uint32 rparam_len = 0;
890 char *pdata = prs_data_p(data);
891 uint32 data_len = prs_offset(data);
893 uint32 rdata_len = 0;
894 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
895 uint32 current_rbuf_offset = 0;
896 prs_struct current_pdu;
899 /* Ensure we're not sending too much. */
900 SMB_ASSERT(data_len <= max_data);
903 /* Set up the current pdu parse struct. */
904 prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
906 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
908 switch (cli->transport_type) {
911 /* Create setup parameters - must be in native byte order. */
912 setup[0] = TRANSACT_DCERPCCMD;
913 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
916 * Send the last (or only) fragment of an RPC request. For
917 * small amounts of data (about 1024 bytes or so) the RPC
918 * request and response appears in a SMBtrans request and
922 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
923 setup, 2, 0, /* Setup, length, max */
924 NULL, 0, 0, /* Params, length, max */
925 pdata, data_len, max_data, /* data, length,
927 &rparam, &rparam_len, /* return params,
929 &prdata, &rdata_len)) /* return data, len */
931 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
933 rpccli_pipe_txt(debug_ctx(), cli),
934 cli_errstr(cli->trans.np.cli)));
935 ret = cli_get_nt_error(cli->trans.np.cli);
943 case NCACN_UNIX_STREAM:
945 ssize_t nwritten, nread;
946 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
947 if (nwritten == -1) {
948 ret = map_nt_error_from_unix(errno);
949 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
954 prdata = SMB_MALLOC_ARRAY(char, 1);
955 if (prdata == NULL) {
956 return NT_STATUS_NO_MEMORY;
958 nread = sys_read(cli->trans.sock.fd, prdata, 1);
963 ret = NT_STATUS_END_OF_FILE;
970 DEBUG(0, ("unknown transport type %d\n",
971 cli->transport_type));
972 return NT_STATUS_INTERNAL_ERROR;
975 /* Throw away returned params - we know we won't use them. */
979 if (prdata == NULL) {
980 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
981 rpccli_pipe_txt(debug_ctx(), cli)));
982 /* Yes - some calls can truely return no data... */
983 prs_mem_free(¤t_pdu);
988 * Give this memory as dynamic to the current pdu.
991 prs_give_memory(¤t_pdu, prdata, rdata_len, True);
993 /* Ensure we can mess with the return prs_struct. */
994 SMB_ASSERT(UNMARSHALLING(rbuf));
995 SMB_ASSERT(prs_data_size(rbuf) == 0);
997 /* Make rbuf dynamic with no memory. */
998 prs_give_memory(rbuf, 0, 0, True);
1003 uint32 ret_data_len;
1005 /* Ensure we have enough data for a pdu. */
1006 ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu);
1007 if (!NT_STATUS_IS_OK(ret)) {
1011 /* We pass in rbuf here so if the alloc hint is set correctly
1012 we can set the output size and avoid reallocs. */
1014 ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type,
1015 &ret_data, &ret_data_len, rbuf);
1017 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
1018 prs_data_size(¤t_pdu), current_rbuf_offset ));
1020 if (!NT_STATUS_IS_OK(ret)) {
1024 if ((rhdr.flags & RPC_FLG_FIRST)) {
1025 if (rhdr.pack_type[0] == 0) {
1026 /* Set the data type correctly for big-endian data on the first packet. */
1027 DEBUG(10,("rpc_api_pipe: On %s "
1028 "PDU data format is big-endian.\n",
1029 rpccli_pipe_txt(debug_ctx(), cli)));
1031 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
1033 /* Check endianness on subsequent packets. */
1034 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
1035 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1036 rbuf->bigendian_data ? "big" : "little",
1037 current_pdu.bigendian_data ? "big" : "little" ));
1038 ret = NT_STATUS_INVALID_PARAMETER;
1044 /* Now copy the data portion out of the pdu into rbuf. */
1045 if (!prs_force_grow(rbuf, ret_data_len)) {
1046 ret = NT_STATUS_NO_MEMORY;
1049 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
1050 current_rbuf_offset += ret_data_len;
1052 /* See if we've finished with all the data in current_pdu yet ? */
1053 ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu);
1054 if (!NT_STATUS_IS_OK(ret)) {
1058 if (rhdr.flags & RPC_FLG_LAST) {
1059 break; /* We're done. */
1063 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1064 rpccli_pipe_txt(debug_ctx(), cli),
1065 (unsigned int)prs_data_size(rbuf) ));
1067 prs_mem_free(¤t_pdu);
1068 return NT_STATUS_OK;
1072 prs_mem_free(¤t_pdu);
1077 /*******************************************************************
1078 Creates krb5 auth bind.
1079 ********************************************************************/
1081 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1082 enum pipe_auth_level auth_level,
1083 RPC_HDR_AUTH *pauth_out,
1084 prs_struct *auth_data)
1088 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1089 DATA_BLOB tkt = data_blob_null;
1090 DATA_BLOB tkt_wrapped = data_blob_null;
1092 /* We may change the pad length before marshalling. */
1093 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1095 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1096 a->service_principal ));
1098 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1100 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1101 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1104 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1106 a->service_principal,
1107 error_message(ret) ));
1109 data_blob_free(&tkt);
1110 prs_mem_free(auth_data);
1111 return NT_STATUS_INVALID_PARAMETER;
1114 /* wrap that up in a nice GSS-API wrapping */
1115 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1117 data_blob_free(&tkt);
1119 /* Auth len in the rpc header doesn't include auth_header. */
1120 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1121 data_blob_free(&tkt_wrapped);
1122 prs_mem_free(auth_data);
1123 return NT_STATUS_NO_MEMORY;
1126 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1127 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1129 data_blob_free(&tkt_wrapped);
1130 return NT_STATUS_OK;
1132 return NT_STATUS_INVALID_PARAMETER;
1136 /*******************************************************************
1137 Creates SPNEGO NTLMSSP auth bind.
1138 ********************************************************************/
1140 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1141 enum pipe_auth_level auth_level,
1142 RPC_HDR_AUTH *pauth_out,
1143 prs_struct *auth_data)
1146 DATA_BLOB null_blob = data_blob_null;
1147 DATA_BLOB request = data_blob_null;
1148 DATA_BLOB spnego_msg = data_blob_null;
1150 /* We may change the pad length before marshalling. */
1151 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1153 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1154 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1158 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1159 data_blob_free(&request);
1160 prs_mem_free(auth_data);
1164 /* Wrap this in SPNEGO. */
1165 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1167 data_blob_free(&request);
1169 /* Auth len in the rpc header doesn't include auth_header. */
1170 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1171 data_blob_free(&spnego_msg);
1172 prs_mem_free(auth_data);
1173 return NT_STATUS_NO_MEMORY;
1176 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1177 dump_data(5, spnego_msg.data, spnego_msg.length);
1179 data_blob_free(&spnego_msg);
1180 return NT_STATUS_OK;
1183 /*******************************************************************
1184 Creates NTLMSSP auth bind.
1185 ********************************************************************/
1187 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1188 enum pipe_auth_level auth_level,
1189 RPC_HDR_AUTH *pauth_out,
1190 prs_struct *auth_data)
1193 DATA_BLOB null_blob = data_blob_null;
1194 DATA_BLOB request = data_blob_null;
1196 /* We may change the pad length before marshalling. */
1197 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1199 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1200 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1204 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1205 data_blob_free(&request);
1206 prs_mem_free(auth_data);
1210 /* Auth len in the rpc header doesn't include auth_header. */
1211 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1212 data_blob_free(&request);
1213 prs_mem_free(auth_data);
1214 return NT_STATUS_NO_MEMORY;
1217 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1218 dump_data(5, request.data, request.length);
1220 data_blob_free(&request);
1221 return NT_STATUS_OK;
1224 /*******************************************************************
1225 Creates schannel auth bind.
1226 ********************************************************************/
1228 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1229 enum pipe_auth_level auth_level,
1230 RPC_HDR_AUTH *pauth_out,
1231 prs_struct *auth_data)
1233 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1235 /* We may change the pad length before marshalling. */
1236 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1238 /* Use lp_workgroup() if domain not specified */
1240 if (!cli->auth->domain || !cli->auth->domain[0]) {
1241 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1242 if (cli->auth->domain == NULL) {
1243 return NT_STATUS_NO_MEMORY;
1247 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1251 * Now marshall the data into the auth parse_struct.
1254 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1255 &schannel_neg, auth_data, 0)) {
1256 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1257 prs_mem_free(auth_data);
1258 return NT_STATUS_NO_MEMORY;
1261 return NT_STATUS_OK;
1264 /*******************************************************************
1265 Creates the internals of a DCE/RPC bind request or alter context PDU.
1266 ********************************************************************/
1268 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1269 prs_struct *rpc_out,
1271 const RPC_IFACE *abstract,
1272 const RPC_IFACE *transfer,
1273 RPC_HDR_AUTH *phdr_auth,
1274 prs_struct *pauth_info)
1278 RPC_CONTEXT rpc_ctx;
1279 uint16 auth_len = prs_offset(pauth_info);
1280 uint8 ss_padding_len = 0;
1281 uint16 frag_len = 0;
1283 /* create the RPC context. */
1284 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1286 /* create the bind request RPC_HDR_RB */
1287 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1289 /* Start building the frag length. */
1290 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1292 /* Do we need to pad ? */
1294 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1296 ss_padding_len = 8 - (data_len % 8);
1297 phdr_auth->auth_pad_len = ss_padding_len;
1299 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1302 /* Create the request RPC_HDR */
1303 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1305 /* Marshall the RPC header */
1306 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1307 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1308 return NT_STATUS_NO_MEMORY;
1311 /* Marshall the bind request data */
1312 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1313 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1314 return NT_STATUS_NO_MEMORY;
1318 * Grow the outgoing buffer to store any auth info.
1322 if (ss_padding_len) {
1324 memset(pad, '\0', 8);
1325 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1326 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1327 return NT_STATUS_NO_MEMORY;
1331 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1332 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1333 return NT_STATUS_NO_MEMORY;
1337 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1338 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1339 return NT_STATUS_NO_MEMORY;
1343 return NT_STATUS_OK;
1346 /*******************************************************************
1347 Creates a DCE/RPC bind request.
1348 ********************************************************************/
1350 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1351 prs_struct *rpc_out,
1353 const RPC_IFACE *abstract,
1354 const RPC_IFACE *transfer,
1355 enum pipe_auth_type auth_type,
1356 enum pipe_auth_level auth_level)
1358 RPC_HDR_AUTH hdr_auth;
1359 prs_struct auth_info;
1360 NTSTATUS ret = NT_STATUS_OK;
1362 ZERO_STRUCT(hdr_auth);
1363 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1364 return NT_STATUS_NO_MEMORY;
1366 switch (auth_type) {
1367 case PIPE_AUTH_TYPE_SCHANNEL:
1368 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1369 if (!NT_STATUS_IS_OK(ret)) {
1370 prs_mem_free(&auth_info);
1375 case PIPE_AUTH_TYPE_NTLMSSP:
1376 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1377 if (!NT_STATUS_IS_OK(ret)) {
1378 prs_mem_free(&auth_info);
1383 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1384 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1385 if (!NT_STATUS_IS_OK(ret)) {
1386 prs_mem_free(&auth_info);
1391 case PIPE_AUTH_TYPE_KRB5:
1392 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1393 if (!NT_STATUS_IS_OK(ret)) {
1394 prs_mem_free(&auth_info);
1399 case PIPE_AUTH_TYPE_NONE:
1403 /* "Can't" happen. */
1404 return NT_STATUS_INVALID_INFO_CLASS;
1407 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1415 prs_mem_free(&auth_info);
1419 /*******************************************************************
1420 Create and add the NTLMSSP sign/seal auth header and data.
1421 ********************************************************************/
1423 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1425 uint32 ss_padding_len,
1426 prs_struct *outgoing_pdu)
1428 RPC_HDR_AUTH auth_info;
1430 DATA_BLOB auth_blob = data_blob_null;
1431 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1433 if (!cli->auth->a_u.ntlmssp_state) {
1434 return NT_STATUS_INVALID_PARAMETER;
1437 /* Init and marshall the auth header. */
1438 init_rpc_hdr_auth(&auth_info,
1439 map_pipe_auth_type_to_rpc_auth_type(
1440 cli->auth->auth_type),
1441 cli->auth->auth_level,
1443 1 /* context id. */);
1445 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1446 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1447 data_blob_free(&auth_blob);
1448 return NT_STATUS_NO_MEMORY;
1451 switch (cli->auth->auth_level) {
1452 case PIPE_AUTH_LEVEL_PRIVACY:
1453 /* Data portion is encrypted. */
1454 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1455 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1457 (unsigned char *)prs_data_p(outgoing_pdu),
1458 (size_t)prs_offset(outgoing_pdu),
1460 if (!NT_STATUS_IS_OK(status)) {
1461 data_blob_free(&auth_blob);
1466 case PIPE_AUTH_LEVEL_INTEGRITY:
1467 /* Data is signed. */
1468 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1469 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1471 (unsigned char *)prs_data_p(outgoing_pdu),
1472 (size_t)prs_offset(outgoing_pdu),
1474 if (!NT_STATUS_IS_OK(status)) {
1475 data_blob_free(&auth_blob);
1482 smb_panic("bad auth level");
1484 return NT_STATUS_INVALID_PARAMETER;
1487 /* Finally marshall the blob. */
1489 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1490 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1491 (unsigned int)NTLMSSP_SIG_SIZE));
1492 data_blob_free(&auth_blob);
1493 return NT_STATUS_NO_MEMORY;
1496 data_blob_free(&auth_blob);
1497 return NT_STATUS_OK;
1500 /*******************************************************************
1501 Create and add the schannel sign/seal auth header and data.
1502 ********************************************************************/
1504 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1506 uint32 ss_padding_len,
1507 prs_struct *outgoing_pdu)
1509 RPC_HDR_AUTH auth_info;
1510 RPC_AUTH_SCHANNEL_CHK verf;
1511 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1512 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1513 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1516 return NT_STATUS_INVALID_PARAMETER;
1519 /* Init and marshall the auth header. */
1520 init_rpc_hdr_auth(&auth_info,
1521 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1522 cli->auth->auth_level,
1524 1 /* context id. */);
1526 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1527 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1528 return NT_STATUS_NO_MEMORY;
1531 switch (cli->auth->auth_level) {
1532 case PIPE_AUTH_LEVEL_PRIVACY:
1533 case PIPE_AUTH_LEVEL_INTEGRITY:
1534 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1537 schannel_encode(sas,
1538 cli->auth->auth_level,
1539 SENDER_IS_INITIATOR,
1549 smb_panic("bad auth level");
1551 return NT_STATUS_INVALID_PARAMETER;
1554 /* Finally marshall the blob. */
1555 smb_io_rpc_auth_schannel_chk("",
1556 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1561 return NT_STATUS_OK;
1564 /*******************************************************************
1565 Calculate how much data we're going to send in this packet, also
1566 work out any sign/seal padding length.
1567 ********************************************************************/
1569 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1573 uint32 *p_ss_padding)
1575 uint32 data_space, data_len;
1577 switch (cli->auth->auth_level) {
1578 case PIPE_AUTH_LEVEL_NONE:
1579 case PIPE_AUTH_LEVEL_CONNECT:
1580 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1581 data_len = MIN(data_space, data_left);
1584 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1587 case PIPE_AUTH_LEVEL_INTEGRITY:
1588 case PIPE_AUTH_LEVEL_PRIVACY:
1589 /* Treat the same for all authenticated rpc requests. */
1590 switch(cli->auth->auth_type) {
1591 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1592 case PIPE_AUTH_TYPE_NTLMSSP:
1593 *p_auth_len = NTLMSSP_SIG_SIZE;
1595 case PIPE_AUTH_TYPE_SCHANNEL:
1596 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1599 smb_panic("bad auth type");
1603 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1604 RPC_HDR_AUTH_LEN - *p_auth_len;
1606 data_len = MIN(data_space, data_left);
1608 *p_ss_padding = 8 - (data_len % 8);
1610 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1611 data_len + *p_ss_padding + /* data plus padding. */
1612 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1616 smb_panic("bad auth level");
1622 /*******************************************************************
1624 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1625 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1626 and deals with signing/sealing details.
1627 ********************************************************************/
1629 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1631 prs_struct *in_data,
1632 prs_struct *out_data)
1635 uint32 data_left = prs_offset(in_data);
1636 uint32 alloc_hint = prs_offset(in_data);
1637 uint32 data_sent_thistime = 0;
1638 uint32 current_data_offset = 0;
1639 uint32 call_id = get_rpc_call_id();
1641 prs_struct outgoing_pdu;
1643 memset(pad, '\0', 8);
1645 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1646 /* Server is screwed up ! */
1647 return NT_STATUS_INVALID_PARAMETER;
1650 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1651 return NT_STATUS_NO_MEMORY;
1655 RPC_HDR_REQ hdr_req;
1656 uint16 auth_len = 0;
1657 uint16 frag_len = 0;
1659 uint32 ss_padding = 0;
1661 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1662 &frag_len, &auth_len, &ss_padding);
1664 if (current_data_offset == 0) {
1665 flags = RPC_FLG_FIRST;
1668 if (data_sent_thistime == data_left) {
1669 flags |= RPC_FLG_LAST;
1672 /* Create and marshall the header and request header. */
1673 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1675 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1676 prs_mem_free(&outgoing_pdu);
1677 return NT_STATUS_NO_MEMORY;
1680 /* Create the rpc request RPC_HDR_REQ */
1681 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1683 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1684 prs_mem_free(&outgoing_pdu);
1685 return NT_STATUS_NO_MEMORY;
1688 /* Copy in the data, plus any ss padding. */
1689 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1690 prs_mem_free(&outgoing_pdu);
1691 return NT_STATUS_NO_MEMORY;
1694 /* Copy the sign/seal padding data. */
1696 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1697 prs_mem_free(&outgoing_pdu);
1698 return NT_STATUS_NO_MEMORY;
1702 /* Generate any auth sign/seal and add the auth footer. */
1704 switch (cli->auth->auth_type) {
1705 case PIPE_AUTH_TYPE_NONE:
1707 case PIPE_AUTH_TYPE_NTLMSSP:
1708 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1709 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1710 if (!NT_STATUS_IS_OK(ret)) {
1711 prs_mem_free(&outgoing_pdu);
1715 case PIPE_AUTH_TYPE_SCHANNEL:
1716 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1717 if (!NT_STATUS_IS_OK(ret)) {
1718 prs_mem_free(&outgoing_pdu);
1723 smb_panic("bad auth type");
1724 break; /* notreached */
1728 /* Actually send the packet. */
1729 if (flags & RPC_FLG_LAST) {
1730 /* Last packet - send the data, get the reply and return. */
1731 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1732 prs_mem_free(&outgoing_pdu);
1734 if ((DEBUGLEVEL >= 50)
1735 && (cli->transport_type == NCACN_NP)) {
1736 char *dump_name = NULL;
1737 /* Also capture received data */
1738 if (asprintf(&dump_name, "%s/reply_%s_%d",
1739 get_dyn_LOGFILEBASE(),
1740 cli->trans.np.pipe_name, op_num) > 0) {
1741 prs_dump(dump_name, op_num, out_data);
1742 SAFE_FREE(dump_name);
1748 /* More packets to come - write and continue. */
1749 ssize_t num_written;
1751 switch (cli->transport_type) {
1753 num_written = cli_write(cli->trans.np.cli,
1755 8, /* 8 means message mode. */
1756 prs_data_p(&outgoing_pdu),
1758 (size_t)hdr.frag_len);
1760 if (num_written != hdr.frag_len) {
1761 prs_mem_free(&outgoing_pdu);
1762 return cli_get_nt_error(
1767 case NCACN_UNIX_STREAM:
1768 num_written = write_data(
1770 prs_data_p(&outgoing_pdu),
1771 (size_t)hdr.frag_len);
1772 if (num_written != hdr.frag_len) {
1774 status = map_nt_error_from_unix(errno);
1775 prs_mem_free(&outgoing_pdu);
1780 DEBUG(0, ("unknown transport type %d\n",
1781 cli->transport_type));
1782 return NT_STATUS_INTERNAL_ERROR;
1786 current_data_offset += data_sent_thistime;
1787 data_left -= data_sent_thistime;
1789 /* Reset the marshalling position back to zero. */
1790 if (!prs_set_offset(&outgoing_pdu, 0)) {
1791 prs_mem_free(&outgoing_pdu);
1792 return NT_STATUS_NO_MEMORY;
1797 /****************************************************************************
1798 Set the handle state.
1799 ****************************************************************************/
1801 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1802 const char *pipe_name, uint16 device_state)
1804 bool state_set = False;
1806 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1807 char *rparam = NULL;
1809 uint32 rparam_len, rdata_len;
1811 if (pipe_name == NULL)
1814 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1815 cli->fnum, pipe_name, device_state));
1817 /* create parameters: device state */
1818 SSVAL(param, 0, device_state);
1820 /* create setup parameters. */
1822 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1824 /* send the data on \PIPE\ */
1825 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1826 setup, 2, 0, /* setup, length, max */
1827 param, 2, 0, /* param, length, max */
1828 NULL, 0, 1024, /* data, length, max */
1829 &rparam, &rparam_len, /* return param, length */
1830 &rdata, &rdata_len)) /* return data, length */
1832 DEBUG(5, ("Set Handle state: return OK\n"));
1843 /****************************************************************************
1844 Check the rpc bind acknowledge response.
1845 ****************************************************************************/
1847 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1849 if ( hdr_ba->addr.len == 0) {
1850 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1853 /* check the transfer syntax */
1854 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1855 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1856 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1860 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1861 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1862 hdr_ba->res.num_results, hdr_ba->res.reason));
1865 DEBUG(5,("check_bind_response: accepted!\n"));
1869 /*******************************************************************
1870 Creates a DCE/RPC bind authentication response.
1871 This is the packet that is sent back to the server once we
1872 have received a BIND-ACK, to finish the third leg of
1873 the authentication handshake.
1874 ********************************************************************/
1876 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1878 enum pipe_auth_type auth_type,
1879 enum pipe_auth_level auth_level,
1880 DATA_BLOB *pauth_blob,
1881 prs_struct *rpc_out)
1884 RPC_HDR_AUTH hdr_auth;
1887 /* Create the request RPC_HDR */
1888 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1889 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1890 pauth_blob->length );
1893 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1894 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1895 return NT_STATUS_NO_MEMORY;
1899 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1900 about padding - shouldn't this pad to length 8 ? JRA.
1903 /* 4 bytes padding. */
1904 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1905 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1906 return NT_STATUS_NO_MEMORY;
1909 /* Create the request RPC_HDR_AUTHA */
1910 init_rpc_hdr_auth(&hdr_auth,
1911 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1914 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1915 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1916 return NT_STATUS_NO_MEMORY;
1920 * Append the auth data to the outgoing buffer.
1923 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1924 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1925 return NT_STATUS_NO_MEMORY;
1928 return NT_STATUS_OK;
1931 /****************************************************************************
1932 Create and send the third packet in an RPC auth.
1933 ****************************************************************************/
1935 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1939 enum pipe_auth_type auth_type,
1940 enum pipe_auth_level auth_level)
1942 DATA_BLOB server_response = data_blob_null;
1943 DATA_BLOB client_reply = data_blob_null;
1944 RPC_HDR_AUTH hdr_auth;
1949 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1950 return NT_STATUS_INVALID_PARAMETER;
1953 /* Process the returned NTLMSSP blob first. */
1954 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1955 return NT_STATUS_INVALID_PARAMETER;
1958 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1959 return NT_STATUS_INVALID_PARAMETER;
1962 /* TODO - check auth_type/auth_level match. */
1964 server_response = data_blob(NULL, phdr->auth_len);
1965 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1967 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1971 if (!NT_STATUS_IS_OK(nt_status)) {
1972 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1973 data_blob_free(&server_response);
1977 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1979 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1980 auth_type, auth_level,
1981 &client_reply, &rpc_out);
1983 if (!NT_STATUS_IS_OK(nt_status)) {
1984 prs_mem_free(&rpc_out);
1985 data_blob_free(&client_reply);
1986 data_blob_free(&server_response);
1990 switch (cli->transport_type) {
1992 /* 8 here is named pipe message mode. */
1993 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
1994 0x8, prs_data_p(&rpc_out), 0,
1995 (size_t)prs_offset(&rpc_out));
1998 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1999 nt_status = cli_get_nt_error(cli->trans.np.cli);
2002 case NCACN_UNIX_STREAM:
2003 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
2004 (size_t)prs_offset(&rpc_out));
2005 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2006 nt_status = map_nt_error_from_unix(errno);
2010 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
2011 return NT_STATUS_INTERNAL_ERROR;
2014 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2015 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
2016 nt_errstr(nt_status)));
2017 prs_mem_free(&rpc_out);
2018 data_blob_free(&client_reply);
2019 data_blob_free(&server_response);
2023 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2024 rpccli_pipe_txt(debug_ctx(), cli)));
2026 prs_mem_free(&rpc_out);
2027 data_blob_free(&client_reply);
2028 data_blob_free(&server_response);
2029 return NT_STATUS_OK;
2032 /*******************************************************************
2033 Creates a DCE/RPC bind alter context authentication request which
2034 may contain a spnego auth blobl
2035 ********************************************************************/
2037 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2038 const RPC_IFACE *abstract,
2039 const RPC_IFACE *transfer,
2040 enum pipe_auth_level auth_level,
2041 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2042 prs_struct *rpc_out)
2044 RPC_HDR_AUTH hdr_auth;
2045 prs_struct auth_info;
2046 NTSTATUS ret = NT_STATUS_OK;
2048 ZERO_STRUCT(hdr_auth);
2049 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2050 return NT_STATUS_NO_MEMORY;
2052 /* We may change the pad length before marshalling. */
2053 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2055 if (pauth_blob->length) {
2056 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2057 prs_mem_free(&auth_info);
2058 return NT_STATUS_NO_MEMORY;
2062 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2069 prs_mem_free(&auth_info);
2073 /*******************************************************************
2074 Third leg of the SPNEGO bind mechanism - sends alter context PDU
2075 and gets a response.
2076 ********************************************************************/
2078 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
2082 const RPC_IFACE *abstract,
2083 const RPC_IFACE *transfer,
2084 enum pipe_auth_type auth_type,
2085 enum pipe_auth_level auth_level)
2087 DATA_BLOB server_spnego_response = data_blob_null;
2088 DATA_BLOB server_ntlm_response = data_blob_null;
2089 DATA_BLOB client_reply = data_blob_null;
2090 DATA_BLOB tmp_blob = data_blob_null;
2091 RPC_HDR_AUTH hdr_auth;
2095 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2096 return NT_STATUS_INVALID_PARAMETER;
2099 /* Process the returned NTLMSSP blob first. */
2100 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2101 return NT_STATUS_INVALID_PARAMETER;
2104 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2105 return NT_STATUS_INVALID_PARAMETER;
2108 server_spnego_response = data_blob(NULL, phdr->auth_len);
2109 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2111 /* The server might give us back two challenges - tmp_blob is for the second. */
2112 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2113 data_blob_free(&server_spnego_response);
2114 data_blob_free(&server_ntlm_response);
2115 data_blob_free(&tmp_blob);
2116 return NT_STATUS_INVALID_PARAMETER;
2119 /* We're finished with the server spnego response and the tmp_blob. */
2120 data_blob_free(&server_spnego_response);
2121 data_blob_free(&tmp_blob);
2123 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2124 server_ntlm_response,
2127 /* Finished with the server_ntlm response */
2128 data_blob_free(&server_ntlm_response);
2130 if (!NT_STATUS_IS_OK(nt_status)) {
2131 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2132 data_blob_free(&client_reply);
2136 /* SPNEGO wrap the client reply. */
2137 tmp_blob = spnego_gen_auth(client_reply);
2138 data_blob_free(&client_reply);
2139 client_reply = tmp_blob;
2140 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2142 /* Now prepare the alter context pdu. */
2143 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2145 nt_status = create_rpc_alter_context(rpc_call_id,
2152 data_blob_free(&client_reply);
2154 if (!NT_STATUS_IS_OK(nt_status)) {
2155 prs_mem_free(&rpc_out);
2159 /* Initialize the returning data struct. */
2161 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2163 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2164 if (!NT_STATUS_IS_OK(nt_status)) {
2165 prs_mem_free(&rpc_out);
2169 prs_mem_free(&rpc_out);
2171 /* Get the auth blob from the reply. */
2172 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2173 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2174 return NT_STATUS_BUFFER_TOO_SMALL;
2177 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2178 return NT_STATUS_INVALID_PARAMETER;
2181 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2182 return NT_STATUS_INVALID_PARAMETER;
2185 server_spnego_response = data_blob(NULL, phdr->auth_len);
2186 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2188 /* Check we got a valid auth response. */
2189 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2190 data_blob_free(&server_spnego_response);
2191 data_blob_free(&tmp_blob);
2192 return NT_STATUS_INVALID_PARAMETER;
2195 data_blob_free(&server_spnego_response);
2196 data_blob_free(&tmp_blob);
2198 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2199 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2201 return NT_STATUS_OK;
2204 /****************************************************************************
2206 ****************************************************************************/
2208 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2209 struct cli_pipe_auth_data *auth)
2218 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2219 rpccli_pipe_txt(debug_ctx(), cli),
2220 (unsigned int)auth->auth_type,
2221 (unsigned int)auth->auth_level ));
2223 cli->auth = talloc_move(cli, &auth);
2225 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2227 rpc_call_id = get_rpc_call_id();
2229 /* Marshall the outgoing data. */
2230 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2231 cli->abstract_syntax,
2232 cli->transfer_syntax,
2233 cli->auth->auth_type,
2234 cli->auth->auth_level);
2236 if (!NT_STATUS_IS_OK(status)) {
2237 prs_mem_free(&rpc_out);
2241 /* Initialize the incoming data struct. */
2242 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2244 /* send data on \PIPE\. receive a response */
2245 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2246 if (!NT_STATUS_IS_OK(status)) {
2247 prs_mem_free(&rpc_out);
2251 prs_mem_free(&rpc_out);
2253 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2254 rpccli_pipe_txt(debug_ctx(), cli)));
2256 /* Unmarshall the RPC header */
2257 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2258 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2259 prs_mem_free(&rbuf);
2260 return NT_STATUS_BUFFER_TOO_SMALL;
2263 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2264 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2265 prs_mem_free(&rbuf);
2266 return NT_STATUS_BUFFER_TOO_SMALL;
2269 if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2270 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2271 prs_mem_free(&rbuf);
2272 return NT_STATUS_BUFFER_TOO_SMALL;
2275 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2276 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2278 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2279 switch(cli->auth->auth_type) {
2281 case PIPE_AUTH_TYPE_NONE:
2282 case PIPE_AUTH_TYPE_SCHANNEL:
2283 /* Bind complete. */
2286 case PIPE_AUTH_TYPE_NTLMSSP:
2287 /* Need to send AUTH3 packet - no reply. */
2288 status = rpc_finish_auth3_bind(
2289 cli, &hdr, &rbuf, rpc_call_id,
2290 cli->auth->auth_type,
2291 cli->auth->auth_level);
2292 if (!NT_STATUS_IS_OK(status)) {
2293 prs_mem_free(&rbuf);
2298 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2299 /* Need to send alter context request and reply. */
2300 status = rpc_finish_spnego_ntlmssp_bind(
2301 cli, &hdr, &rbuf, rpc_call_id,
2302 cli->abstract_syntax, cli->transfer_syntax,
2303 cli->auth->auth_type, cli->auth->auth_level);
2304 if (!NT_STATUS_IS_OK(status)) {
2305 prs_mem_free(&rbuf);
2310 case PIPE_AUTH_TYPE_KRB5:
2314 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2315 "%u\n", (unsigned int)cli->auth->auth_type));
2316 prs_mem_free(&rbuf);
2317 return NT_STATUS_INVALID_INFO_CLASS;
2320 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2321 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2322 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2323 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2324 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2325 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2326 prs_mem_free(&rbuf);
2327 return NT_STATUS_INVALID_PARAMETER;
2330 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2331 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2332 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2333 prs_mem_free(&rbuf);
2334 return NT_STATUS_INVALID_PARAMETER;
2339 prs_mem_free(&rbuf);
2340 return NT_STATUS_OK;
2343 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2344 unsigned int timeout)
2346 return cli_set_timeout(cli->trans.np.cli, timeout);
2349 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2351 return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
2354 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2356 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2357 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2358 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2362 if (cli->transport_type == NCACN_NP) {
2363 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2370 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2372 if (p->transport_type == NCACN_NP) {
2373 return p->trans.np.cli;
2378 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2380 if (p->transport_type == NCACN_NP) {
2382 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2384 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2385 "pipe %s. Error was %s\n",
2386 rpccli_pipe_txt(debug_ctx(), p),
2387 cli_errstr(p->trans.np.cli)));
2390 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2391 rpccli_pipe_txt(debug_ctx(), p)));
2393 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2394 return ret ? -1 : 0;
2400 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2401 struct cli_pipe_auth_data **presult)
2403 struct cli_pipe_auth_data *result;
2405 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2406 if (result == NULL) {
2407 return NT_STATUS_NO_MEMORY;
2410 result->auth_type = PIPE_AUTH_TYPE_NONE;
2411 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2413 result->user_name = talloc_strdup(result, "");
2414 result->domain = talloc_strdup(result, "");
2415 if ((result->user_name == NULL) || (result->domain == NULL)) {
2416 TALLOC_FREE(result);
2417 return NT_STATUS_NO_MEMORY;
2421 return NT_STATUS_OK;
2424 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2426 ntlmssp_end(&auth->a_u.ntlmssp_state);
2430 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2431 enum pipe_auth_type auth_type,
2432 enum pipe_auth_level auth_level,
2434 const char *username,
2435 const char *password,
2436 struct cli_pipe_auth_data **presult)
2438 struct cli_pipe_auth_data *result;
2441 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2442 if (result == NULL) {
2443 return NT_STATUS_NO_MEMORY;
2446 result->auth_type = auth_type;
2447 result->auth_level = auth_level;
2449 result->user_name = talloc_strdup(result, username);
2450 result->domain = talloc_strdup(result, domain);
2451 if ((result->user_name == NULL) || (result->domain == NULL)) {
2452 status = NT_STATUS_NO_MEMORY;
2456 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2457 if (!NT_STATUS_IS_OK(status)) {
2461 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2463 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2464 if (!NT_STATUS_IS_OK(status)) {
2468 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2469 if (!NT_STATUS_IS_OK(status)) {
2473 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2474 if (!NT_STATUS_IS_OK(status)) {
2479 * Turn off sign+seal to allow selected auth level to turn it back on.
2481 result->a_u.ntlmssp_state->neg_flags &=
2482 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2484 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2485 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2486 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2487 result->a_u.ntlmssp_state->neg_flags
2488 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2492 return NT_STATUS_OK;
2495 TALLOC_FREE(result);
2499 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2500 enum pipe_auth_level auth_level,
2501 const uint8_t sess_key[16],
2502 struct cli_pipe_auth_data **presult)
2504 struct cli_pipe_auth_data *result;
2506 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2507 if (result == NULL) {
2508 return NT_STATUS_NO_MEMORY;
2511 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2512 result->auth_level = auth_level;
2514 result->user_name = talloc_strdup(result, "");
2515 result->domain = talloc_strdup(result, domain);
2516 if ((result->user_name == NULL) || (result->domain == NULL)) {
2520 result->a_u.schannel_auth = talloc(result,
2521 struct schannel_auth_struct);
2522 if (result->a_u.schannel_auth == NULL) {
2526 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2527 sizeof(result->a_u.schannel_auth->sess_key));
2528 result->a_u.schannel_auth->seq_num = 0;
2531 return NT_STATUS_OK;
2534 TALLOC_FREE(result);
2535 return NT_STATUS_NO_MEMORY;
2539 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2541 data_blob_free(&auth->session_key);
2546 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2547 enum pipe_auth_level auth_level,
2548 const char *service_princ,
2549 const char *username,
2550 const char *password,
2551 struct cli_pipe_auth_data **presult)
2554 struct cli_pipe_auth_data *result;
2556 if ((username != NULL) && (password != NULL)) {
2557 int ret = kerberos_kinit_password(username, password, 0, NULL);
2559 return NT_STATUS_ACCESS_DENIED;
2563 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2564 if (result == NULL) {
2565 return NT_STATUS_NO_MEMORY;
2568 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2569 result->auth_level = auth_level;
2572 * Username / domain need fixing!
2574 result->user_name = talloc_strdup(result, "");
2575 result->domain = talloc_strdup(result, "");
2576 if ((result->user_name == NULL) || (result->domain == NULL)) {
2580 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2581 result, struct kerberos_auth_struct);
2582 if (result->a_u.kerberos_auth == NULL) {
2585 talloc_set_destructor(result->a_u.kerberos_auth,
2586 cli_auth_kerberos_data_destructor);
2588 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2589 result, service_princ);
2590 if (result->a_u.kerberos_auth->service_principal == NULL) {
2595 return NT_STATUS_OK;
2598 TALLOC_FREE(result);
2599 return NT_STATUS_NO_MEMORY;
2601 return NT_STATUS_NOT_SUPPORTED;
2605 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2607 close(p->trans.sock.fd);
2612 * Create an rpc pipe client struct, connecting to a tcp port.
2614 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2616 const struct ndr_syntax_id *abstract_syntax,
2617 struct rpc_pipe_client **presult)
2619 struct rpc_pipe_client *result;
2620 struct sockaddr_storage addr;
2623 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2624 if (result == NULL) {
2625 return NT_STATUS_NO_MEMORY;
2628 result->transport_type = NCACN_IP_TCP;
2630 result->abstract_syntax = abstract_syntax;
2631 result->transfer_syntax = &ndr_transfer_syntax;
2633 result->desthost = talloc_strdup(result, host);
2634 result->srv_name_slash = talloc_asprintf_strupper_m(
2635 result, "\\\\%s", result->desthost);
2636 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2637 status = NT_STATUS_NO_MEMORY;
2641 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2642 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2644 if (!resolve_name(host, &addr, 0)) {
2645 status = NT_STATUS_NOT_FOUND;
2649 result->trans.sock.fd = open_socket_out(SOCK_STREAM, &addr, port, 60);
2650 if (result->trans.sock.fd == -1) {
2651 status = map_nt_error_from_unix(errno);
2655 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2658 return NT_STATUS_OK;
2661 TALLOC_FREE(result);
2666 * Determine the tcp port on which a dcerpc interface is listening
2667 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2670 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2671 const struct ndr_syntax_id *abstract_syntax,
2675 struct rpc_pipe_client *epm_pipe = NULL;
2676 struct cli_pipe_auth_data *auth = NULL;
2677 struct dcerpc_binding *map_binding = NULL;
2678 struct dcerpc_binding *res_binding = NULL;
2679 struct epm_twr_t *map_tower = NULL;
2680 struct epm_twr_t *res_towers = NULL;
2681 struct policy_handle *entry_handle = NULL;
2682 uint32_t num_towers = 0;
2683 uint32_t max_towers = 1;
2684 struct epm_twr_p_t towers;
2685 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2687 if (pport == NULL) {
2688 status = NT_STATUS_INVALID_PARAMETER;
2692 /* open the connection to the endpoint mapper */
2693 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2694 &ndr_table_epmapper.syntax_id,
2697 if (!NT_STATUS_IS_OK(status)) {
2701 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2702 if (!NT_STATUS_IS_OK(status)) {
2706 status = rpc_pipe_bind(epm_pipe, auth);
2707 if (!NT_STATUS_IS_OK(status)) {
2711 /* create tower for asking the epmapper */
2713 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2714 if (map_binding == NULL) {
2715 status = NT_STATUS_NO_MEMORY;
2719 map_binding->transport = NCACN_IP_TCP;
2720 map_binding->object = *abstract_syntax;
2721 map_binding->host = host; /* needed? */
2722 map_binding->endpoint = "0"; /* correct? needed? */
2724 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2725 if (map_tower == NULL) {
2726 status = NT_STATUS_NO_MEMORY;
2730 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2731 &(map_tower->tower));
2732 if (!NT_STATUS_IS_OK(status)) {
2736 /* allocate further parameters for the epm_Map call */
2738 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2739 if (res_towers == NULL) {
2740 status = NT_STATUS_NO_MEMORY;
2743 towers.twr = res_towers;
2745 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2746 if (entry_handle == NULL) {
2747 status = NT_STATUS_NO_MEMORY;
2751 /* ask the endpoint mapper for the port */
2753 status = rpccli_epm_Map(epm_pipe,
2755 CONST_DISCARD(struct GUID *,
2756 &(abstract_syntax->uuid)),
2763 if (!NT_STATUS_IS_OK(status)) {
2767 if (num_towers != 1) {
2768 status = NT_STATUS_UNSUCCESSFUL;
2772 /* extract the port from the answer */
2774 status = dcerpc_binding_from_tower(tmp_ctx,
2775 &(towers.twr->tower),
2777 if (!NT_STATUS_IS_OK(status)) {
2781 /* are further checks here necessary? */
2782 if (res_binding->transport != NCACN_IP_TCP) {
2783 status = NT_STATUS_UNSUCCESSFUL;
2787 *pport = (uint16_t)atoi(res_binding->endpoint);
2790 TALLOC_FREE(tmp_ctx);
2795 * Create a rpc pipe client struct, connecting to a host via tcp.
2796 * The port is determined by asking the endpoint mapper on the given
2799 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2800 const struct ndr_syntax_id *abstract_syntax,
2801 struct rpc_pipe_client **presult)
2808 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2809 if (!NT_STATUS_IS_OK(status)) {
2813 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2814 abstract_syntax, presult);
2820 /********************************************************************
2821 Create a rpc pipe client struct, connecting to a unix domain socket
2822 ********************************************************************/
2823 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2824 const struct ndr_syntax_id *abstract_syntax,
2825 struct rpc_pipe_client **presult)
2827 struct rpc_pipe_client *result;
2828 struct sockaddr_un addr;
2831 result = talloc(mem_ctx, struct rpc_pipe_client);
2832 if (result == NULL) {
2833 return NT_STATUS_NO_MEMORY;
2836 result->transport_type = NCACN_UNIX_STREAM;
2838 result->abstract_syntax = abstract_syntax;
2839 result->transfer_syntax = &ndr_transfer_syntax;
2841 result->desthost = get_myname(result);
2842 result->srv_name_slash = talloc_asprintf_strupper_m(
2843 result, "\\\\%s", result->desthost);
2844 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2845 status = NT_STATUS_NO_MEMORY;
2849 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2850 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2852 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2853 if (result->trans.sock.fd == -1) {
2854 status = map_nt_error_from_unix(errno);
2858 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2860 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2861 if (result->dc == NULL) {
2862 status = NT_STATUS_NO_MEMORY;
2867 addr.sun_family = AF_UNIX;
2868 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2870 if (sys_connect(result->trans.sock.fd,
2871 (struct sockaddr *)&addr) == -1) {
2872 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2874 close(result->trans.sock.fd);
2875 return map_nt_error_from_unix(errno);
2879 return NT_STATUS_OK;
2882 TALLOC_FREE(result);
2887 /****************************************************************************
2888 Open a named pipe over SMB to a remote server.
2890 * CAVEAT CALLER OF THIS FUNCTION:
2891 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2892 * so be sure that this function is called AFTER any structure (vs pointer)
2893 * assignment of the cli. In particular, libsmbclient does structure
2894 * assignments of cli, which invalidates the data in the returned
2895 * rpc_pipe_client if this function is called before the structure assignment
2898 ****************************************************************************/
2900 static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2902 struct rpc_pipe_client *result;
2905 *perr = NT_STATUS_NO_MEMORY;
2907 /* sanity check to protect against crashes */
2910 *perr = NT_STATUS_INVALID_HANDLE;
2914 /* The pipe name index must fall within our array */
2915 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2917 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2918 if (result == NULL) {
2919 *perr = NT_STATUS_NO_MEMORY;
2923 result->transport_type = NCACN_NP;
2925 result->trans.np.pipe_name = cli_get_pipe_name(pipe_idx);
2927 result->trans.np.cli = cli;
2928 result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2929 result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2930 result->desthost = talloc_strdup(result, cli->desthost);
2931 result->srv_name_slash = talloc_asprintf_strupper_m(
2932 result, "\\\\%s", result->desthost);
2934 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2935 *perr = NT_STATUS_NO_MEMORY;
2936 TALLOC_FREE(result);
2940 if (pipe_idx == PI_NETLOGON) {
2941 /* Set up a netlogon credential chain for a netlogon pipe. */
2942 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2943 if (result->dc == NULL) {
2944 *perr = NT_STATUS_NO_MEMORY;
2945 TALLOC_FREE(result);
2950 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2951 DESIRED_ACCESS_PIPE);
2953 DEBUG(1,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
2954 "to machine %s. Error was %s\n",
2955 result->trans.np.pipe_name, cli->desthost,
2957 *perr = cli_get_nt_error(cli);
2958 talloc_destroy(result);
2962 result->trans.np.fnum = fnum;
2964 DLIST_ADD(cli->pipe_list, result);
2965 talloc_set_destructor(result, rpc_pipe_destructor);
2967 *perr = NT_STATUS_OK;
2972 /****************************************************************************
2973 Open a pipe to a remote server.
2974 ****************************************************************************/
2976 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli,
2980 struct rpc_pipe_client *result = NULL;
2982 *perr = NT_STATUS_PIPE_NOT_AVAILABLE;
2986 *perr = rpc_pipe_open_tcp(NULL, cli->desthost,
2987 &ndr_table_drsuapi.syntax_id,
2989 if (!NT_STATUS_IS_OK(*perr)) {
2994 result = rpc_pipe_open_np(cli, pipe_idx, perr);
2995 if (result == NULL) {
3001 *perr = NT_STATUS_OK;
3006 /****************************************************************************
3007 Open a named pipe to an SMB server and bind anonymously.
3008 ****************************************************************************/
3010 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
3012 struct rpc_pipe_client *result;
3013 struct cli_pipe_auth_data *auth;
3015 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3016 if (result == NULL) {
3020 *perr = rpccli_anon_bind_data(result, &auth);
3021 if (!NT_STATUS_IS_OK(*perr)) {
3022 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3024 TALLOC_FREE(result);
3029 * This is a bit of an abstraction violation due to the fact that an
3030 * anonymous bind on an authenticated SMB inherits the user/domain
3031 * from the enclosing SMB creds
3034 TALLOC_FREE(auth->user_name);
3035 TALLOC_FREE(auth->domain);
3037 auth->user_name = talloc_strdup(auth, cli->user_name);
3038 auth->domain = talloc_strdup(auth, cli->domain);
3040 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3041 *perr = NT_STATUS_NO_MEMORY;
3042 TALLOC_FREE(result);
3046 *perr = rpc_pipe_bind(result, auth);
3047 if (!NT_STATUS_IS_OK(*perr)) {
3049 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
3050 /* non AD domains just don't have this pipe, avoid
3051 * level 0 statement in that case - gd */
3054 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
3055 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
3056 TALLOC_FREE(result);
3060 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3061 "%s and bound anonymously.\n", result->trans.np.pipe_name,
3067 /****************************************************************************
3068 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3069 ****************************************************************************/
3071 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3073 enum pipe_auth_type auth_type,
3074 enum pipe_auth_level auth_level,
3076 const char *username,
3077 const char *password,
3080 struct rpc_pipe_client *result;
3081 struct cli_pipe_auth_data *auth;
3083 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3084 if (result == NULL) {
3088 *perr = rpccli_ntlmssp_bind_data(
3089 result, auth_type, auth_level, domain, username,
3090 cli->pwd.null_pwd ? NULL : password, &auth);
3091 if (!NT_STATUS_IS_OK(*perr)) {
3092 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3094 TALLOC_FREE(result);
3098 *perr = rpc_pipe_bind(result, auth);
3099 if (!NT_STATUS_IS_OK(*perr)) {
3100 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3101 nt_errstr(*perr) ));
3105 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3106 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3107 result->trans.np.pipe_name, cli->desthost,
3108 domain, username ));
3114 TALLOC_FREE(result);
3118 /****************************************************************************
3120 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3121 ****************************************************************************/
3123 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3125 enum pipe_auth_level auth_level,
3127 const char *username,
3128 const char *password,
3131 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3133 PIPE_AUTH_TYPE_NTLMSSP,
3141 /****************************************************************************
3143 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3144 ****************************************************************************/
3146 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3148 enum pipe_auth_level auth_level,
3150 const char *username,
3151 const char *password,
3154 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3156 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3164 /****************************************************************************
3165 Get a the schannel session key out of an already opened netlogon pipe.
3166 ****************************************************************************/
3167 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3168 struct cli_state *cli,
3173 uint32 sec_chan_type = 0;
3174 unsigned char machine_pwd[16];
3175 const char *machine_account;
3177 /* Get the machine account credentials from secrets.tdb. */
3178 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3181 DEBUG(0, ("get_schannel_session_key: could not fetch "
3182 "trust account password for domain '%s'\n",
3184 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3188 *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
3189 cli->desthost, /* server name */
3190 domain, /* domain */
3191 global_myname(), /* client name */
3192 machine_account, /* machine account name */
3197 if (!NT_STATUS_IS_OK(*perr)) {
3198 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
3199 "failed with result %s to server %s, domain %s, machine account %s.\n",
3200 nt_errstr(*perr), cli->desthost, domain, machine_account ));
3204 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3205 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3207 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
3214 /****************************************************************************
3215 Open a netlogon pipe and get the schannel session key.
3216 Now exposed to external callers.
3217 ****************************************************************************/
3220 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
3225 struct rpc_pipe_client *netlogon_pipe = NULL;
3227 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
3228 if (!netlogon_pipe) {
3232 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
3235 TALLOC_FREE(netlogon_pipe);
3239 return netlogon_pipe;
3242 /****************************************************************************
3244 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3245 using session_key. sign and seal.
3246 ****************************************************************************/
3248 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3250 enum pipe_auth_level auth_level,
3252 const struct dcinfo *pdc,
3255 struct rpc_pipe_client *result;
3256 struct cli_pipe_auth_data *auth;
3258 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3259 if (result == NULL) {
3263 *perr = rpccli_schannel_bind_data(result, domain, auth_level,
3264 pdc->sess_key, &auth);
3265 if (!NT_STATUS_IS_OK(*perr)) {
3266 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3268 TALLOC_FREE(result);
3272 *perr = rpc_pipe_bind(result, auth);
3273 if (!NT_STATUS_IS_OK(*perr)) {
3274 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
3275 nt_errstr(*perr) ));
3276 TALLOC_FREE(result);
3280 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
3285 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3287 "and bound using schannel.\n",
3288 result->trans.np.pipe_name, cli->desthost, domain ));
3293 /****************************************************************************
3294 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3295 Fetch the session key ourselves using a temporary netlogon pipe. This
3296 version uses an ntlmssp auth bound netlogon pipe to get the key.
3297 ****************************************************************************/
3299 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3301 const char *username,
3302 const char *password,
3306 struct rpc_pipe_client *netlogon_pipe = NULL;
3308 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
3309 if (!netlogon_pipe) {
3313 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
3316 TALLOC_FREE(netlogon_pipe);
3320 return netlogon_pipe;
3323 /****************************************************************************
3324 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3325 Fetch the session key ourselves using a temporary netlogon pipe. This version
3326 uses an ntlmssp bind to get the session key.
3327 ****************************************************************************/
3329 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3331 enum pipe_auth_level auth_level,
3333 const char *username,
3334 const char *password,
3337 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3338 struct rpc_pipe_client *netlogon_pipe = NULL;
3339 struct rpc_pipe_client *result = NULL;
3341 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
3342 password, &neg_flags, perr);
3343 if (!netlogon_pipe) {
3344 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3345 "key from server %s for domain %s.\n",
3346 cli->desthost, domain ));
3350 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
3352 domain, netlogon_pipe->dc, perr);
3354 /* Now we've bound using the session key we can close the netlog pipe. */
3355 TALLOC_FREE(netlogon_pipe);
3360 /****************************************************************************
3361 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3362 Fetch the session key ourselves using a temporary netlogon pipe.
3363 ****************************************************************************/
3365 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
3367 enum pipe_auth_level auth_level,
3371 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3372 struct rpc_pipe_client *netlogon_pipe = NULL;
3373 struct rpc_pipe_client *result = NULL;
3375 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
3376 if (!netlogon_pipe) {
3377 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3378 "key from server %s for domain %s.\n",
3379 cli->desthost, domain ));
3383 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
3385 domain, netlogon_pipe->dc, perr);
3387 /* Now we've bound using the session key we can close the netlog pipe. */
3388 TALLOC_FREE(netlogon_pipe);
3393 /****************************************************************************
3394 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3395 The idea is this can be called with service_princ, username and password all
3396 NULL so long as the caller has a TGT.
3397 ****************************************************************************/
3399 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
3401 enum pipe_auth_level auth_level,
3402 const char *service_princ,
3403 const char *username,
3404 const char *password,
3408 struct rpc_pipe_client *result;
3409 struct cli_pipe_auth_data *auth;
3411 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3412 if (result == NULL) {
3416 *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3417 username, password, &auth);
3418 if (!NT_STATUS_IS_OK(*perr)) {
3419 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3421 TALLOC_FREE(result);
3425 *perr = rpc_pipe_bind(result, auth);
3426 if (!NT_STATUS_IS_OK(*perr)) {
3427 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
3428 nt_errstr(*perr) ));
3429 TALLOC_FREE(result);
3435 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3440 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3441 struct rpc_pipe_client *cli,
3442 DATA_BLOB *session_key)
3444 if (!session_key || !cli) {
3445 return NT_STATUS_INVALID_PARAMETER;
3449 return NT_STATUS_INVALID_PARAMETER;
3452 switch (cli->auth->auth_type) {
3453 case PIPE_AUTH_TYPE_SCHANNEL:
3454 *session_key = data_blob_talloc(mem_ctx,
3455 cli->auth->a_u.schannel_auth->sess_key, 16);
3457 case PIPE_AUTH_TYPE_NTLMSSP:
3458 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3459 *session_key = data_blob_talloc(mem_ctx,
3460 cli->auth->a_u.ntlmssp_state->session_key.data,
3461 cli->auth->a_u.ntlmssp_state->session_key.length);
3463 case PIPE_AUTH_TYPE_KRB5:
3464 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3465 *session_key = data_blob_talloc(mem_ctx,
3466 cli->auth->a_u.kerberos_auth->session_key.data,
3467 cli->auth->a_u.kerberos_auth->session_key.length);
3469 case PIPE_AUTH_TYPE_NONE:
3471 return NT_STATUS_NO_USER_SESSION_KEY;
3474 return NT_STATUS_OK;