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 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
31 #define PIPE_SAMR "\\PIPE\\samr"
32 #define PIPE_WINREG "\\PIPE\\winreg"
33 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
34 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
35 #define PIPE_NTLSA "\\PIPE\\ntlsa"
36 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
37 #define PIPE_LSASS "\\PIPE\\lsass"
38 #define PIPE_LSARPC "\\PIPE\\lsarpc"
39 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
40 #define PIPE_NETDFS "\\PIPE\\netdfs"
41 #define PIPE_ECHO "\\PIPE\\rpcecho"
42 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
43 #define PIPE_EPM "\\PIPE\\epmapper"
44 #define PIPE_SVCCTL "\\PIPE\\svcctl"
45 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
46 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
47 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
50 * IMPORTANT!! If you update this structure, make sure to
51 * update the index #defines in smb.h.
54 static const struct pipe_id_info {
55 /* the names appear not to matter: the syntaxes _do_ matter */
57 const char *client_pipe;
58 const RPC_IFACE *abstr_syntax; /* this one is the abstract syntax id */
61 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
62 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
63 { PIPE_SAMR, &ndr_table_samr.syntax_id },
64 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
65 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
66 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
67 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
68 { PIPE_SPOOLSS, &syntax_spoolss },
69 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
70 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
71 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
72 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
73 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
74 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
75 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
76 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
80 /****************************************************************************
81 Return the pipe name from the interface.
82 ****************************************************************************/
84 const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx,
85 struct cli_state *cli,
86 const struct ndr_syntax_id *interface)
89 for (i = 0; pipe_names[i].client_pipe; i++) {
90 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
92 return &pipe_names[i].client_pipe[5];
97 * Here we should ask \\epmapper, but for now our code is only
98 * interested in the known pipes mentioned in pipe_names[]
104 /********************************************************************
105 Map internal value to wire value.
106 ********************************************************************/
108 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
112 case PIPE_AUTH_TYPE_NONE:
113 return RPC_ANONYMOUS_AUTH_TYPE;
115 case PIPE_AUTH_TYPE_NTLMSSP:
116 return RPC_NTLMSSP_AUTH_TYPE;
118 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
119 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
120 return RPC_SPNEGO_AUTH_TYPE;
122 case PIPE_AUTH_TYPE_SCHANNEL:
123 return RPC_SCHANNEL_AUTH_TYPE;
125 case PIPE_AUTH_TYPE_KRB5:
126 return RPC_KRB5_AUTH_TYPE;
129 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
131 (unsigned int)auth_type ));
137 /********************************************************************
138 Pipe description for a DEBUG
139 ********************************************************************/
140 static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli)
144 switch (cli->transport_type) {
146 result = talloc_asprintf(mem_ctx, "host %s, pipe %s, "
149 cli->trans.np.pipe_name,
150 (unsigned int)(cli->trans.np.fnum));
153 case NCACN_UNIX_STREAM:
154 result = talloc_asprintf(mem_ctx, "host %s, fd %d",
155 cli->desthost, cli->trans.sock.fd);
158 result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
161 SMB_ASSERT(result != NULL);
165 /********************************************************************
167 ********************************************************************/
169 static uint32 get_rpc_call_id(void)
171 static uint32 call_id = 0;
175 /*******************************************************************
176 Read from a RPC named pipe
177 ********************************************************************/
178 static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name,
179 int fnum, char *buf, off_t offset, size_t size,
184 num_read = cli_read(cli, fnum, buf, offset, size);
186 DEBUG(5,("rpc_read_np: num_read = %d, read offset: %u, to read: %u\n",
187 (int)num_read, (unsigned int)offset, (unsigned int)size));
190 * A dos error of ERRDOS/ERRmoredata is not an error.
192 if (cli_is_dos_error(cli)) {
195 cli_dos_error(cli, &eclass, &ecode);
196 if (eclass != ERRDOS && ecode != ERRmoredata) {
197 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read "
198 "on fnum 0x%x\n", eclass, (unsigned int)ecode,
199 cli_errstr(cli), fnum));
200 return dos_to_ntstatus(eclass, ecode);
205 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
207 if (cli_is_nt_error(cli)) {
208 if (!NT_STATUS_EQUAL(cli_nt_error(cli),
209 NT_STATUS_BUFFER_TOO_SMALL)) {
210 DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum "
211 "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum));
212 return cli_nt_error(cli);
216 if (num_read == -1) {
217 DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned "
219 return cli_get_nt_error(cli);
222 *pnum_read = num_read;
227 /*******************************************************************
228 Use SMBreadX to get rest of one fragment's worth of rpc data.
229 Will expand the current_pdu struct to the correct size.
230 ********************************************************************/
232 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
233 prs_struct *current_pdu,
235 uint32 *current_pdu_offset)
237 size_t size = (size_t)cli->max_recv_frag;
238 uint32 stream_offset = 0;
239 ssize_t num_read = 0;
241 ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
243 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
244 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
247 * Grow the buffer if needed to accommodate the data to be read.
250 if (extra_data_size > 0) {
251 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
252 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
253 return NT_STATUS_NO_MEMORY;
255 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
258 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
263 /* read data using SMBreadX */
264 if (size > (size_t)data_to_read) {
265 size = (size_t)data_to_read;
268 switch (cli->transport_type) {
270 status = rpc_read_np(cli->trans.np.cli,
271 cli->trans.np.pipe_name,
272 cli->trans.np.fnum, pdata,
273 (off_t)stream_offset, size,
277 case NCACN_UNIX_STREAM:
278 status = NT_STATUS_OK;
279 num_read = sys_read(cli->trans.sock.fd, pdata, size);
280 if (num_read == -1) {
281 status = map_nt_error_from_unix(errno);
284 status = NT_STATUS_END_OF_FILE;
288 DEBUG(0, ("unknown transport type %d\n",
289 cli->transport_type));
290 return NT_STATUS_INTERNAL_ERROR;
293 data_to_read -= num_read;
294 stream_offset += num_read;
297 } while (num_read > 0 && data_to_read > 0);
298 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
301 * Update the current offset into current_pdu by the amount read.
303 *current_pdu_offset += stream_offset;
307 /****************************************************************************
308 Try and get a PDU's worth of data from current_pdu. If not, then read more
310 ****************************************************************************/
312 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
314 NTSTATUS ret = NT_STATUS_OK;
315 uint32 current_pdu_len = prs_data_size(current_pdu);
317 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
318 if (current_pdu_len < RPC_HEADER_LEN) {
319 /* rpc_read expands the current_pdu struct as neccessary. */
320 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, ¤t_pdu_len);
321 if (!NT_STATUS_IS_OK(ret)) {
326 /* This next call sets the endian bit correctly in current_pdu. */
327 /* We will propagate this to rbuf later. */
328 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
329 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
330 return NT_STATUS_BUFFER_TOO_SMALL;
333 /* Ensure we have frag_len bytes of data. */
334 if (current_pdu_len < prhdr->frag_len) {
335 /* rpc_read expands the current_pdu struct as neccessary. */
336 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, ¤t_pdu_len);
337 if (!NT_STATUS_IS_OK(ret)) {
342 if (current_pdu_len < prhdr->frag_len) {
343 return NT_STATUS_BUFFER_TOO_SMALL;
349 /****************************************************************************
350 NTLMSSP specific sign/seal.
351 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
352 In fact I should probably abstract these into identical pieces of code... JRA.
353 ****************************************************************************/
355 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
356 prs_struct *current_pdu,
357 uint8 *p_ss_padding_len)
359 RPC_HDR_AUTH auth_info;
360 uint32 save_offset = prs_offset(current_pdu);
361 uint32 auth_len = prhdr->auth_len;
362 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
363 unsigned char *data = NULL;
365 unsigned char *full_packet_data = NULL;
366 size_t full_packet_data_len;
370 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
371 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
375 if (!ntlmssp_state) {
376 return NT_STATUS_INVALID_PARAMETER;
379 /* Ensure there's enough data for an authenticated response. */
380 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
381 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
382 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
383 (unsigned int)auth_len ));
384 return NT_STATUS_BUFFER_TOO_SMALL;
388 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
389 * after the RPC header.
390 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
391 * functions as NTLMv2 checks the rpc headers also.
394 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
395 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
397 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
398 full_packet_data_len = prhdr->frag_len - auth_len;
400 /* Pull the auth header and the following data into a blob. */
401 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
402 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
403 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
404 return NT_STATUS_BUFFER_TOO_SMALL;
407 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
408 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
409 return NT_STATUS_BUFFER_TOO_SMALL;
412 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
413 auth_blob.length = auth_len;
415 switch (cli->auth->auth_level) {
416 case PIPE_AUTH_LEVEL_PRIVACY:
417 /* Data is encrypted. */
418 status = ntlmssp_unseal_packet(ntlmssp_state,
421 full_packet_data_len,
423 if (!NT_STATUS_IS_OK(status)) {
424 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
425 "packet from %s. Error was %s.\n",
426 rpccli_pipe_txt(debug_ctx(), cli),
427 nt_errstr(status) ));
431 case PIPE_AUTH_LEVEL_INTEGRITY:
432 /* Data is signed. */
433 status = ntlmssp_check_packet(ntlmssp_state,
436 full_packet_data_len,
438 if (!NT_STATUS_IS_OK(status)) {
439 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
440 "packet from %s. Error was %s.\n",
441 rpccli_pipe_txt(debug_ctx(), cli),
442 nt_errstr(status) ));
447 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
448 "auth level %d\n", cli->auth->auth_level));
449 return NT_STATUS_INVALID_INFO_CLASS;
453 * Return the current pointer to the data offset.
456 if(!prs_set_offset(current_pdu, save_offset)) {
457 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
458 (unsigned int)save_offset ));
459 return NT_STATUS_BUFFER_TOO_SMALL;
463 * Remember the padding length. We must remove it from the real data
464 * stream once the sign/seal is done.
467 *p_ss_padding_len = auth_info.auth_pad_len;
472 /****************************************************************************
473 schannel specific sign/seal.
474 ****************************************************************************/
476 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
477 prs_struct *current_pdu,
478 uint8 *p_ss_padding_len)
480 RPC_HDR_AUTH auth_info;
481 RPC_AUTH_SCHANNEL_CHK schannel_chk;
482 uint32 auth_len = prhdr->auth_len;
483 uint32 save_offset = prs_offset(current_pdu);
484 struct schannel_auth_struct *schannel_auth =
485 cli->auth->a_u.schannel_auth;
488 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
489 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
493 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
494 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
495 return NT_STATUS_INVALID_PARAMETER;
498 if (!schannel_auth) {
499 return NT_STATUS_INVALID_PARAMETER;
502 /* Ensure there's enough data for an authenticated response. */
503 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
504 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
505 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
506 (unsigned int)auth_len ));
507 return NT_STATUS_INVALID_PARAMETER;
510 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
512 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
513 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
514 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
515 return NT_STATUS_BUFFER_TOO_SMALL;
518 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
519 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
520 return NT_STATUS_BUFFER_TOO_SMALL;
523 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
524 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
525 auth_info.auth_type));
526 return NT_STATUS_BUFFER_TOO_SMALL;
529 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
530 &schannel_chk, current_pdu, 0)) {
531 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
532 return NT_STATUS_BUFFER_TOO_SMALL;
535 if (!schannel_decode(schannel_auth,
536 cli->auth->auth_level,
539 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
541 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
542 "Connection to %s.\n",
543 rpccli_pipe_txt(debug_ctx(), cli)));
544 return NT_STATUS_INVALID_PARAMETER;
547 /* The sequence number gets incremented on both send and receive. */
548 schannel_auth->seq_num++;
551 * Return the current pointer to the data offset.
554 if(!prs_set_offset(current_pdu, save_offset)) {
555 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
556 (unsigned int)save_offset ));
557 return NT_STATUS_BUFFER_TOO_SMALL;
561 * Remember the padding length. We must remove it from the real data
562 * stream once the sign/seal is done.
565 *p_ss_padding_len = auth_info.auth_pad_len;
570 /****************************************************************************
571 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
572 ****************************************************************************/
574 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
575 prs_struct *current_pdu,
576 uint8 *p_ss_padding_len)
578 NTSTATUS ret = NT_STATUS_OK;
580 /* Paranioa checks for auth_len. */
581 if (prhdr->auth_len) {
582 if (prhdr->auth_len > prhdr->frag_len) {
583 return NT_STATUS_INVALID_PARAMETER;
586 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
587 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
588 /* Integer wrap attempt. */
589 return NT_STATUS_INVALID_PARAMETER;
594 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
597 switch(cli->auth->auth_type) {
598 case PIPE_AUTH_TYPE_NONE:
599 if (prhdr->auth_len) {
600 DEBUG(3, ("cli_pipe_validate_rpc_response: "
601 "Connection to %s - got non-zero "
603 rpccli_pipe_txt(debug_ctx(), cli),
604 (unsigned int)prhdr->auth_len ));
605 return NT_STATUS_INVALID_PARAMETER;
609 case PIPE_AUTH_TYPE_NTLMSSP:
610 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
611 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
612 if (!NT_STATUS_IS_OK(ret)) {
617 case PIPE_AUTH_TYPE_SCHANNEL:
618 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
619 if (!NT_STATUS_IS_OK(ret)) {
624 case PIPE_AUTH_TYPE_KRB5:
625 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
627 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
628 "to %s - unknown internal auth type %u.\n",
629 rpccli_pipe_txt(debug_ctx(), cli),
630 cli->auth->auth_type ));
631 return NT_STATUS_INVALID_INFO_CLASS;
637 /****************************************************************************
638 Do basic authentication checks on an incoming pdu.
639 ****************************************************************************/
641 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
642 prs_struct *current_pdu,
643 uint8 expected_pkt_type,
646 prs_struct *return_data)
649 NTSTATUS ret = NT_STATUS_OK;
650 uint32 current_pdu_len = prs_data_size(current_pdu);
652 if (current_pdu_len != prhdr->frag_len) {
653 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
654 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
655 return NT_STATUS_INVALID_PARAMETER;
659 * Point the return values at the real data including the RPC
660 * header. Just in case the caller wants it.
662 *ppdata = prs_data_p(current_pdu);
663 *pdata_len = current_pdu_len;
665 /* Ensure we have the correct type. */
666 switch (prhdr->pkt_type) {
667 case RPC_ALTCONTRESP:
670 /* Alter context and bind ack share the same packet definitions. */
676 RPC_HDR_RESP rhdr_resp;
677 uint8 ss_padding_len = 0;
679 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
680 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
681 return NT_STATUS_BUFFER_TOO_SMALL;
684 /* Here's where we deal with incoming sign/seal. */
685 ret = cli_pipe_validate_rpc_response(cli, prhdr,
686 current_pdu, &ss_padding_len);
687 if (!NT_STATUS_IS_OK(ret)) {
691 /* Point the return values at the NDR data. Remember to remove any ss padding. */
692 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
694 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
695 return NT_STATUS_BUFFER_TOO_SMALL;
698 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
700 /* Remember to remove the auth footer. */
701 if (prhdr->auth_len) {
702 /* We've already done integer wrap tests on auth_len in
703 cli_pipe_validate_rpc_response(). */
704 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
705 return NT_STATUS_BUFFER_TOO_SMALL;
707 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
710 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
711 current_pdu_len, *pdata_len, ss_padding_len ));
714 * If this is the first reply, and the allocation hint is reasonably, try and
715 * set up the return_data parse_struct to the correct size.
718 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
719 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
720 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
721 "too large to allocate\n",
722 (unsigned int)rhdr_resp.alloc_hint ));
723 return NT_STATUS_NO_MEMORY;
731 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
732 "received from %s!\n",
733 rpccli_pipe_txt(debug_ctx(), cli)));
734 /* Use this for now... */
735 return NT_STATUS_NETWORK_ACCESS_DENIED;
739 RPC_HDR_RESP rhdr_resp;
740 RPC_HDR_FAULT fault_resp;
742 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
743 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
744 return NT_STATUS_BUFFER_TOO_SMALL;
747 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
748 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
749 return NT_STATUS_BUFFER_TOO_SMALL;
752 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
753 "code %s received from %s!\n",
754 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
755 rpccli_pipe_txt(debug_ctx(), cli)));
756 if (NT_STATUS_IS_OK(fault_resp.status)) {
757 return NT_STATUS_UNSUCCESSFUL;
759 return fault_resp.status;
764 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
766 (unsigned int)prhdr->pkt_type,
767 rpccli_pipe_txt(debug_ctx(), cli)));
768 return NT_STATUS_INVALID_INFO_CLASS;
771 if (prhdr->pkt_type != expected_pkt_type) {
772 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
773 "got an unexpected RPC packet type - %u, not %u\n",
774 rpccli_pipe_txt(debug_ctx(), cli),
777 return NT_STATUS_INVALID_INFO_CLASS;
780 /* Do this just before return - we don't want to modify any rpc header
781 data before now as we may have needed to do cryptographic actions on
784 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
785 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
786 "setting fragment first/last ON.\n"));
787 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
793 /****************************************************************************
794 Ensure we eat the just processed pdu from the current_pdu prs_struct.
795 Normally the frag_len and buffer size will match, but on the first trans
796 reply there is a theoretical chance that buffer size > frag_len, so we must
798 ****************************************************************************/
800 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
802 uint32 current_pdu_len = prs_data_size(current_pdu);
804 if (current_pdu_len < prhdr->frag_len) {
805 return NT_STATUS_BUFFER_TOO_SMALL;
809 if (current_pdu_len == (uint32)prhdr->frag_len) {
810 prs_mem_free(current_pdu);
811 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
812 /* Make current_pdu dynamic with no memory. */
813 prs_give_memory(current_pdu, 0, 0, True);
818 * Oh no ! More data in buffer than we processed in current pdu.
819 * Cheat. Move the data down and shrink the buffer.
822 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
823 current_pdu_len - prhdr->frag_len);
825 /* Remember to set the read offset back to zero. */
826 prs_set_offset(current_pdu, 0);
828 /* Shrink the buffer. */
829 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
830 return NT_STATUS_BUFFER_TOO_SMALL;
836 /****************************************************************************
837 Send data on an rpc pipe via trans. The prs_struct data must be the last
838 pdu fragment of an NDR data stream.
840 Receive response data from an rpc pipe, which may be large...
842 Read the first fragment: unfortunately have to use SMBtrans for the first
843 bit, then SMBreadX for subsequent bits.
845 If first fragment received also wasn't the last fragment, continue
846 getting fragments until we _do_ receive the last fragment.
848 Request/Response PDU's look like the following...
850 |<------------------PDU len----------------------------------------------->|
851 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
853 +------------+-----------------+-------------+---------------+-------------+
854 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
855 +------------+-----------------+-------------+---------------+-------------+
857 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
858 signing & sealing being negotiated.
860 ****************************************************************************/
862 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
863 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
864 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
865 uint8 expected_pkt_type)
867 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
869 uint32 rparam_len = 0;
870 char *pdata = prs_data_p(data);
871 uint32 data_len = prs_offset(data);
873 uint32 rdata_len = 0;
874 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
875 uint32 current_rbuf_offset = 0;
876 prs_struct current_pdu;
879 /* Ensure we're not sending too much. */
880 SMB_ASSERT(data_len <= max_data);
883 /* Set up the current pdu parse struct. */
884 prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
886 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
888 switch (cli->transport_type) {
891 /* Create setup parameters - must be in native byte order. */
892 setup[0] = TRANSACT_DCERPCCMD;
893 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
896 * Send the last (or only) fragment of an RPC request. For
897 * small amounts of data (about 1024 bytes or so) the RPC
898 * request and response appears in a SMBtrans request and
902 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
903 setup, 2, 0, /* Setup, length, max */
904 NULL, 0, 0, /* Params, length, max */
905 pdata, data_len, max_data, /* data, length,
907 &rparam, &rparam_len, /* return params,
909 &prdata, &rdata_len)) /* return data, len */
911 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
913 rpccli_pipe_txt(debug_ctx(), cli),
914 cli_errstr(cli->trans.np.cli)));
915 ret = cli_get_nt_error(cli->trans.np.cli);
923 case NCACN_UNIX_STREAM:
925 ssize_t nwritten, nread;
926 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
927 if (nwritten == -1) {
928 ret = map_nt_error_from_unix(errno);
929 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
934 prdata = SMB_MALLOC_ARRAY(char, 1);
935 if (prdata == NULL) {
936 return NT_STATUS_NO_MEMORY;
938 nread = sys_read(cli->trans.sock.fd, prdata, 1);
943 ret = NT_STATUS_END_OF_FILE;
950 DEBUG(0, ("unknown transport type %d\n",
951 cli->transport_type));
952 return NT_STATUS_INTERNAL_ERROR;
955 /* Throw away returned params - we know we won't use them. */
959 if (prdata == NULL) {
960 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
961 rpccli_pipe_txt(debug_ctx(), cli)));
962 /* Yes - some calls can truely return no data... */
963 prs_mem_free(¤t_pdu);
968 * Give this memory as dynamic to the current pdu.
971 prs_give_memory(¤t_pdu, prdata, rdata_len, True);
973 /* Ensure we can mess with the return prs_struct. */
974 SMB_ASSERT(UNMARSHALLING(rbuf));
975 SMB_ASSERT(prs_data_size(rbuf) == 0);
977 /* Make rbuf dynamic with no memory. */
978 prs_give_memory(rbuf, 0, 0, True);
982 char *ret_data = NULL;
983 uint32 ret_data_len = 0;
985 /* Ensure we have enough data for a pdu. */
986 ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu);
987 if (!NT_STATUS_IS_OK(ret)) {
991 /* We pass in rbuf here so if the alloc hint is set correctly
992 we can set the output size and avoid reallocs. */
994 ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type,
995 &ret_data, &ret_data_len, rbuf);
997 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
998 prs_data_size(¤t_pdu), current_rbuf_offset ));
1000 if (!NT_STATUS_IS_OK(ret)) {
1004 if ((rhdr.flags & RPC_FLG_FIRST)) {
1005 if (rhdr.pack_type[0] == 0) {
1006 /* Set the data type correctly for big-endian data on the first packet. */
1007 DEBUG(10,("rpc_api_pipe: On %s "
1008 "PDU data format is big-endian.\n",
1009 rpccli_pipe_txt(debug_ctx(), cli)));
1011 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
1013 /* Check endianness on subsequent packets. */
1014 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
1015 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1016 rbuf->bigendian_data ? "big" : "little",
1017 current_pdu.bigendian_data ? "big" : "little" ));
1018 ret = NT_STATUS_INVALID_PARAMETER;
1024 /* Now copy the data portion out of the pdu into rbuf. */
1025 if (!prs_force_grow(rbuf, ret_data_len)) {
1026 ret = NT_STATUS_NO_MEMORY;
1029 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
1030 current_rbuf_offset += ret_data_len;
1032 /* See if we've finished with all the data in current_pdu yet ? */
1033 ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu);
1034 if (!NT_STATUS_IS_OK(ret)) {
1038 if (rhdr.flags & RPC_FLG_LAST) {
1039 break; /* We're done. */
1043 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1044 rpccli_pipe_txt(debug_ctx(), cli),
1045 (unsigned int)prs_data_size(rbuf) ));
1047 prs_mem_free(¤t_pdu);
1048 return NT_STATUS_OK;
1052 prs_mem_free(¤t_pdu);
1057 /*******************************************************************
1058 Creates krb5 auth bind.
1059 ********************************************************************/
1061 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1062 enum pipe_auth_level auth_level,
1063 RPC_HDR_AUTH *pauth_out,
1064 prs_struct *auth_data)
1068 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1069 DATA_BLOB tkt = data_blob_null;
1070 DATA_BLOB tkt_wrapped = data_blob_null;
1072 /* We may change the pad length before marshalling. */
1073 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1075 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1076 a->service_principal ));
1078 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1080 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1081 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1084 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1086 a->service_principal,
1087 error_message(ret) ));
1089 data_blob_free(&tkt);
1090 prs_mem_free(auth_data);
1091 return NT_STATUS_INVALID_PARAMETER;
1094 /* wrap that up in a nice GSS-API wrapping */
1095 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1097 data_blob_free(&tkt);
1099 /* Auth len in the rpc header doesn't include auth_header. */
1100 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1101 data_blob_free(&tkt_wrapped);
1102 prs_mem_free(auth_data);
1103 return NT_STATUS_NO_MEMORY;
1106 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1107 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1109 data_blob_free(&tkt_wrapped);
1110 return NT_STATUS_OK;
1112 return NT_STATUS_INVALID_PARAMETER;
1116 /*******************************************************************
1117 Creates SPNEGO NTLMSSP auth bind.
1118 ********************************************************************/
1120 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1121 enum pipe_auth_level auth_level,
1122 RPC_HDR_AUTH *pauth_out,
1123 prs_struct *auth_data)
1126 DATA_BLOB null_blob = data_blob_null;
1127 DATA_BLOB request = data_blob_null;
1128 DATA_BLOB spnego_msg = data_blob_null;
1130 /* We may change the pad length before marshalling. */
1131 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1133 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1134 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1138 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1139 data_blob_free(&request);
1140 prs_mem_free(auth_data);
1144 /* Wrap this in SPNEGO. */
1145 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1147 data_blob_free(&request);
1149 /* Auth len in the rpc header doesn't include auth_header. */
1150 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1151 data_blob_free(&spnego_msg);
1152 prs_mem_free(auth_data);
1153 return NT_STATUS_NO_MEMORY;
1156 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1157 dump_data(5, spnego_msg.data, spnego_msg.length);
1159 data_blob_free(&spnego_msg);
1160 return NT_STATUS_OK;
1163 /*******************************************************************
1164 Creates NTLMSSP auth bind.
1165 ********************************************************************/
1167 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1168 enum pipe_auth_level auth_level,
1169 RPC_HDR_AUTH *pauth_out,
1170 prs_struct *auth_data)
1173 DATA_BLOB null_blob = data_blob_null;
1174 DATA_BLOB request = data_blob_null;
1176 /* We may change the pad length before marshalling. */
1177 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1179 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1180 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1184 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1185 data_blob_free(&request);
1186 prs_mem_free(auth_data);
1190 /* Auth len in the rpc header doesn't include auth_header. */
1191 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1192 data_blob_free(&request);
1193 prs_mem_free(auth_data);
1194 return NT_STATUS_NO_MEMORY;
1197 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1198 dump_data(5, request.data, request.length);
1200 data_blob_free(&request);
1201 return NT_STATUS_OK;
1204 /*******************************************************************
1205 Creates schannel auth bind.
1206 ********************************************************************/
1208 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1209 enum pipe_auth_level auth_level,
1210 RPC_HDR_AUTH *pauth_out,
1211 prs_struct *auth_data)
1213 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1215 /* We may change the pad length before marshalling. */
1216 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1218 /* Use lp_workgroup() if domain not specified */
1220 if (!cli->auth->domain || !cli->auth->domain[0]) {
1221 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1222 if (cli->auth->domain == NULL) {
1223 return NT_STATUS_NO_MEMORY;
1227 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1231 * Now marshall the data into the auth parse_struct.
1234 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1235 &schannel_neg, auth_data, 0)) {
1236 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1237 prs_mem_free(auth_data);
1238 return NT_STATUS_NO_MEMORY;
1241 return NT_STATUS_OK;
1244 /*******************************************************************
1245 Creates the internals of a DCE/RPC bind request or alter context PDU.
1246 ********************************************************************/
1248 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1249 prs_struct *rpc_out,
1251 const RPC_IFACE *abstract,
1252 const RPC_IFACE *transfer,
1253 RPC_HDR_AUTH *phdr_auth,
1254 prs_struct *pauth_info)
1258 RPC_CONTEXT rpc_ctx;
1259 uint16 auth_len = prs_offset(pauth_info);
1260 uint8 ss_padding_len = 0;
1261 uint16 frag_len = 0;
1263 /* create the RPC context. */
1264 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1266 /* create the bind request RPC_HDR_RB */
1267 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1269 /* Start building the frag length. */
1270 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1272 /* Do we need to pad ? */
1274 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1276 ss_padding_len = 8 - (data_len % 8);
1277 phdr_auth->auth_pad_len = ss_padding_len;
1279 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1282 /* Create the request RPC_HDR */
1283 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1285 /* Marshall the RPC header */
1286 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1287 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1288 return NT_STATUS_NO_MEMORY;
1291 /* Marshall the bind request data */
1292 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1293 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1294 return NT_STATUS_NO_MEMORY;
1298 * Grow the outgoing buffer to store any auth info.
1302 if (ss_padding_len) {
1304 memset(pad, '\0', 8);
1305 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1306 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1307 return NT_STATUS_NO_MEMORY;
1311 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1312 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1313 return NT_STATUS_NO_MEMORY;
1317 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1318 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1319 return NT_STATUS_NO_MEMORY;
1323 return NT_STATUS_OK;
1326 /*******************************************************************
1327 Creates a DCE/RPC bind request.
1328 ********************************************************************/
1330 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1331 prs_struct *rpc_out,
1333 const RPC_IFACE *abstract,
1334 const RPC_IFACE *transfer,
1335 enum pipe_auth_type auth_type,
1336 enum pipe_auth_level auth_level)
1338 RPC_HDR_AUTH hdr_auth;
1339 prs_struct auth_info;
1340 NTSTATUS ret = NT_STATUS_OK;
1342 ZERO_STRUCT(hdr_auth);
1343 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1344 return NT_STATUS_NO_MEMORY;
1346 switch (auth_type) {
1347 case PIPE_AUTH_TYPE_SCHANNEL:
1348 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1349 if (!NT_STATUS_IS_OK(ret)) {
1350 prs_mem_free(&auth_info);
1355 case PIPE_AUTH_TYPE_NTLMSSP:
1356 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1357 if (!NT_STATUS_IS_OK(ret)) {
1358 prs_mem_free(&auth_info);
1363 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1364 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1365 if (!NT_STATUS_IS_OK(ret)) {
1366 prs_mem_free(&auth_info);
1371 case PIPE_AUTH_TYPE_KRB5:
1372 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1373 if (!NT_STATUS_IS_OK(ret)) {
1374 prs_mem_free(&auth_info);
1379 case PIPE_AUTH_TYPE_NONE:
1383 /* "Can't" happen. */
1384 return NT_STATUS_INVALID_INFO_CLASS;
1387 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1395 prs_mem_free(&auth_info);
1399 /*******************************************************************
1400 Create and add the NTLMSSP sign/seal auth header and data.
1401 ********************************************************************/
1403 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1405 uint32 ss_padding_len,
1406 prs_struct *outgoing_pdu)
1408 RPC_HDR_AUTH auth_info;
1410 DATA_BLOB auth_blob = data_blob_null;
1411 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1413 if (!cli->auth->a_u.ntlmssp_state) {
1414 return NT_STATUS_INVALID_PARAMETER;
1417 /* Init and marshall the auth header. */
1418 init_rpc_hdr_auth(&auth_info,
1419 map_pipe_auth_type_to_rpc_auth_type(
1420 cli->auth->auth_type),
1421 cli->auth->auth_level,
1423 1 /* context id. */);
1425 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1426 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1427 data_blob_free(&auth_blob);
1428 return NT_STATUS_NO_MEMORY;
1431 switch (cli->auth->auth_level) {
1432 case PIPE_AUTH_LEVEL_PRIVACY:
1433 /* Data portion is encrypted. */
1434 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1435 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1437 (unsigned char *)prs_data_p(outgoing_pdu),
1438 (size_t)prs_offset(outgoing_pdu),
1440 if (!NT_STATUS_IS_OK(status)) {
1441 data_blob_free(&auth_blob);
1446 case PIPE_AUTH_LEVEL_INTEGRITY:
1447 /* Data is signed. */
1448 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1449 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1451 (unsigned char *)prs_data_p(outgoing_pdu),
1452 (size_t)prs_offset(outgoing_pdu),
1454 if (!NT_STATUS_IS_OK(status)) {
1455 data_blob_free(&auth_blob);
1462 smb_panic("bad auth level");
1464 return NT_STATUS_INVALID_PARAMETER;
1467 /* Finally marshall the blob. */
1469 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1470 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1471 (unsigned int)NTLMSSP_SIG_SIZE));
1472 data_blob_free(&auth_blob);
1473 return NT_STATUS_NO_MEMORY;
1476 data_blob_free(&auth_blob);
1477 return NT_STATUS_OK;
1480 /*******************************************************************
1481 Create and add the schannel sign/seal auth header and data.
1482 ********************************************************************/
1484 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1486 uint32 ss_padding_len,
1487 prs_struct *outgoing_pdu)
1489 RPC_HDR_AUTH auth_info;
1490 RPC_AUTH_SCHANNEL_CHK verf;
1491 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1492 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1493 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1496 return NT_STATUS_INVALID_PARAMETER;
1499 /* Init and marshall the auth header. */
1500 init_rpc_hdr_auth(&auth_info,
1501 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1502 cli->auth->auth_level,
1504 1 /* context id. */);
1506 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1507 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1508 return NT_STATUS_NO_MEMORY;
1511 switch (cli->auth->auth_level) {
1512 case PIPE_AUTH_LEVEL_PRIVACY:
1513 case PIPE_AUTH_LEVEL_INTEGRITY:
1514 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1517 schannel_encode(sas,
1518 cli->auth->auth_level,
1519 SENDER_IS_INITIATOR,
1529 smb_panic("bad auth level");
1531 return NT_STATUS_INVALID_PARAMETER;
1534 /* Finally marshall the blob. */
1535 smb_io_rpc_auth_schannel_chk("",
1536 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1541 return NT_STATUS_OK;
1544 /*******************************************************************
1545 Calculate how much data we're going to send in this packet, also
1546 work out any sign/seal padding length.
1547 ********************************************************************/
1549 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1553 uint32 *p_ss_padding)
1555 uint32 data_space, data_len;
1557 switch (cli->auth->auth_level) {
1558 case PIPE_AUTH_LEVEL_NONE:
1559 case PIPE_AUTH_LEVEL_CONNECT:
1560 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1561 data_len = MIN(data_space, data_left);
1564 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1567 case PIPE_AUTH_LEVEL_INTEGRITY:
1568 case PIPE_AUTH_LEVEL_PRIVACY:
1569 /* Treat the same for all authenticated rpc requests. */
1570 switch(cli->auth->auth_type) {
1571 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1572 case PIPE_AUTH_TYPE_NTLMSSP:
1573 *p_auth_len = NTLMSSP_SIG_SIZE;
1575 case PIPE_AUTH_TYPE_SCHANNEL:
1576 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1579 smb_panic("bad auth type");
1583 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1584 RPC_HDR_AUTH_LEN - *p_auth_len;
1586 data_len = MIN(data_space, data_left);
1588 *p_ss_padding = 8 - (data_len % 8);
1590 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1591 data_len + *p_ss_padding + /* data plus padding. */
1592 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1596 smb_panic("bad auth level");
1602 /*******************************************************************
1604 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1605 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1606 and deals with signing/sealing details.
1607 ********************************************************************/
1609 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1611 prs_struct *in_data,
1612 prs_struct *out_data)
1615 uint32 data_left = prs_offset(in_data);
1616 uint32 alloc_hint = prs_offset(in_data);
1617 uint32 data_sent_thistime = 0;
1618 uint32 current_data_offset = 0;
1619 uint32 call_id = get_rpc_call_id();
1621 prs_struct outgoing_pdu;
1623 memset(pad, '\0', 8);
1625 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1626 /* Server is screwed up ! */
1627 return NT_STATUS_INVALID_PARAMETER;
1630 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1631 return NT_STATUS_NO_MEMORY;
1635 RPC_HDR_REQ hdr_req;
1636 uint16 auth_len = 0;
1637 uint16 frag_len = 0;
1639 uint32 ss_padding = 0;
1640 ssize_t num_written;
1642 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1643 &frag_len, &auth_len, &ss_padding);
1645 if (current_data_offset == 0) {
1646 flags = RPC_FLG_FIRST;
1649 if (data_sent_thistime == data_left) {
1650 flags |= RPC_FLG_LAST;
1653 /* Create and marshall the header and request header. */
1654 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1656 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1657 prs_mem_free(&outgoing_pdu);
1658 return NT_STATUS_NO_MEMORY;
1661 /* Create the rpc request RPC_HDR_REQ */
1662 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1664 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1665 prs_mem_free(&outgoing_pdu);
1666 return NT_STATUS_NO_MEMORY;
1669 /* Copy in the data, plus any ss padding. */
1670 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1671 prs_mem_free(&outgoing_pdu);
1672 return NT_STATUS_NO_MEMORY;
1675 /* Copy the sign/seal padding data. */
1677 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1678 prs_mem_free(&outgoing_pdu);
1679 return NT_STATUS_NO_MEMORY;
1683 /* Generate any auth sign/seal and add the auth footer. */
1685 switch (cli->auth->auth_type) {
1686 case PIPE_AUTH_TYPE_NONE:
1688 case PIPE_AUTH_TYPE_NTLMSSP:
1689 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1690 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1691 if (!NT_STATUS_IS_OK(ret)) {
1692 prs_mem_free(&outgoing_pdu);
1696 case PIPE_AUTH_TYPE_SCHANNEL:
1697 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1698 if (!NT_STATUS_IS_OK(ret)) {
1699 prs_mem_free(&outgoing_pdu);
1704 smb_panic("bad auth type");
1705 break; /* notreached */
1709 /* Actually send the packet. */
1710 if (flags & RPC_FLG_LAST) {
1711 /* Last packet - send the data, get the reply and return. */
1712 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1713 prs_mem_free(&outgoing_pdu);
1715 if ((DEBUGLEVEL >= 50)
1716 && (cli->transport_type == NCACN_NP)) {
1717 char *dump_name = NULL;
1718 /* Also capture received data */
1719 if (asprintf(&dump_name, "%s/reply_%s_%d",
1720 get_dyn_LOGFILEBASE(),
1721 cli->trans.np.pipe_name, op_num) > 0) {
1722 prs_dump(dump_name, op_num, out_data);
1723 SAFE_FREE(dump_name);
1730 switch (cli->transport_type) {
1732 num_written = cli_write(cli->trans.np.cli,
1734 8, /* 8 means message mode. */
1735 prs_data_p(&outgoing_pdu),
1737 (size_t)hdr.frag_len);
1739 if (num_written != hdr.frag_len) {
1740 prs_mem_free(&outgoing_pdu);
1741 return cli_get_nt_error(cli->trans.np.cli);
1745 case NCACN_UNIX_STREAM:
1746 num_written = write_data(
1748 prs_data_p(&outgoing_pdu),
1749 (size_t)hdr.frag_len);
1750 if (num_written != hdr.frag_len) {
1752 status = map_nt_error_from_unix(errno);
1753 prs_mem_free(&outgoing_pdu);
1758 DEBUG(0, ("unknown transport type %d\n",
1759 cli->transport_type));
1760 return NT_STATUS_INTERNAL_ERROR;
1763 current_data_offset += data_sent_thistime;
1764 data_left -= data_sent_thistime;
1766 /* Reset the marshalling position back to zero. */
1767 if (!prs_set_offset(&outgoing_pdu, 0)) {
1768 prs_mem_free(&outgoing_pdu);
1769 return NT_STATUS_NO_MEMORY;
1774 /****************************************************************************
1775 Set the handle state.
1776 ****************************************************************************/
1778 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1779 const char *pipe_name, uint16 device_state)
1781 bool state_set = False;
1783 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1784 char *rparam = NULL;
1786 uint32 rparam_len, rdata_len;
1788 if (pipe_name == NULL)
1791 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1792 cli->fnum, pipe_name, device_state));
1794 /* create parameters: device state */
1795 SSVAL(param, 0, device_state);
1797 /* create setup parameters. */
1799 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1801 /* send the data on \PIPE\ */
1802 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1803 setup, 2, 0, /* setup, length, max */
1804 param, 2, 0, /* param, length, max */
1805 NULL, 0, 1024, /* data, length, max */
1806 &rparam, &rparam_len, /* return param, length */
1807 &rdata, &rdata_len)) /* return data, length */
1809 DEBUG(5, ("Set Handle state: return OK\n"));
1820 /****************************************************************************
1821 Check the rpc bind acknowledge response.
1822 ****************************************************************************/
1824 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1826 if ( hdr_ba->addr.len == 0) {
1827 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1830 /* check the transfer syntax */
1831 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1832 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1833 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1837 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1838 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1839 hdr_ba->res.num_results, hdr_ba->res.reason));
1842 DEBUG(5,("check_bind_response: accepted!\n"));
1846 /*******************************************************************
1847 Creates a DCE/RPC bind authentication response.
1848 This is the packet that is sent back to the server once we
1849 have received a BIND-ACK, to finish the third leg of
1850 the authentication handshake.
1851 ********************************************************************/
1853 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1855 enum pipe_auth_type auth_type,
1856 enum pipe_auth_level auth_level,
1857 DATA_BLOB *pauth_blob,
1858 prs_struct *rpc_out)
1861 RPC_HDR_AUTH hdr_auth;
1864 /* Create the request RPC_HDR */
1865 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1866 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1867 pauth_blob->length );
1870 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1871 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1872 return NT_STATUS_NO_MEMORY;
1876 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1877 about padding - shouldn't this pad to length 8 ? JRA.
1880 /* 4 bytes padding. */
1881 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1882 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1883 return NT_STATUS_NO_MEMORY;
1886 /* Create the request RPC_HDR_AUTHA */
1887 init_rpc_hdr_auth(&hdr_auth,
1888 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1891 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1892 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1893 return NT_STATUS_NO_MEMORY;
1897 * Append the auth data to the outgoing buffer.
1900 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1901 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1902 return NT_STATUS_NO_MEMORY;
1905 return NT_STATUS_OK;
1908 /****************************************************************************
1909 Create and send the third packet in an RPC auth.
1910 ****************************************************************************/
1912 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1916 enum pipe_auth_type auth_type,
1917 enum pipe_auth_level auth_level)
1919 DATA_BLOB server_response = data_blob_null;
1920 DATA_BLOB client_reply = data_blob_null;
1921 RPC_HDR_AUTH hdr_auth;
1926 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1927 return NT_STATUS_INVALID_PARAMETER;
1930 /* Process the returned NTLMSSP blob first. */
1931 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1932 return NT_STATUS_INVALID_PARAMETER;
1935 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1936 return NT_STATUS_INVALID_PARAMETER;
1939 /* TODO - check auth_type/auth_level match. */
1941 server_response = data_blob(NULL, phdr->auth_len);
1942 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1944 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1948 if (!NT_STATUS_IS_OK(nt_status)) {
1949 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1950 data_blob_free(&server_response);
1954 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1956 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1957 auth_type, auth_level,
1958 &client_reply, &rpc_out);
1960 if (!NT_STATUS_IS_OK(nt_status)) {
1961 prs_mem_free(&rpc_out);
1962 data_blob_free(&client_reply);
1963 data_blob_free(&server_response);
1967 switch (cli->transport_type) {
1969 /* 8 here is named pipe message mode. */
1970 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
1971 0x8, prs_data_p(&rpc_out), 0,
1972 (size_t)prs_offset(&rpc_out));
1975 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1976 nt_status = cli_get_nt_error(cli->trans.np.cli);
1979 case NCACN_UNIX_STREAM:
1980 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
1981 (size_t)prs_offset(&rpc_out));
1982 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1983 nt_status = map_nt_error_from_unix(errno);
1987 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
1988 return NT_STATUS_INTERNAL_ERROR;
1991 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1992 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
1993 nt_errstr(nt_status)));
1994 prs_mem_free(&rpc_out);
1995 data_blob_free(&client_reply);
1996 data_blob_free(&server_response);
2000 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2001 rpccli_pipe_txt(debug_ctx(), cli)));
2003 prs_mem_free(&rpc_out);
2004 data_blob_free(&client_reply);
2005 data_blob_free(&server_response);
2006 return NT_STATUS_OK;
2009 /*******************************************************************
2010 Creates a DCE/RPC bind alter context authentication request which
2011 may contain a spnego auth blobl
2012 ********************************************************************/
2014 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2015 const RPC_IFACE *abstract,
2016 const RPC_IFACE *transfer,
2017 enum pipe_auth_level auth_level,
2018 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2019 prs_struct *rpc_out)
2021 RPC_HDR_AUTH hdr_auth;
2022 prs_struct auth_info;
2023 NTSTATUS ret = NT_STATUS_OK;
2025 ZERO_STRUCT(hdr_auth);
2026 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2027 return NT_STATUS_NO_MEMORY;
2029 /* We may change the pad length before marshalling. */
2030 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2032 if (pauth_blob->length) {
2033 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2034 prs_mem_free(&auth_info);
2035 return NT_STATUS_NO_MEMORY;
2039 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2046 prs_mem_free(&auth_info);
2050 /*******************************************************************
2051 Third leg of the SPNEGO bind mechanism - sends alter context PDU
2052 and gets a response.
2053 ********************************************************************/
2055 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
2059 const RPC_IFACE *abstract,
2060 const RPC_IFACE *transfer,
2061 enum pipe_auth_type auth_type,
2062 enum pipe_auth_level auth_level)
2064 DATA_BLOB server_spnego_response = data_blob_null;
2065 DATA_BLOB server_ntlm_response = data_blob_null;
2066 DATA_BLOB client_reply = data_blob_null;
2067 DATA_BLOB tmp_blob = data_blob_null;
2068 RPC_HDR_AUTH hdr_auth;
2072 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2073 return NT_STATUS_INVALID_PARAMETER;
2076 /* Process the returned NTLMSSP blob first. */
2077 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2078 return NT_STATUS_INVALID_PARAMETER;
2081 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2082 return NT_STATUS_INVALID_PARAMETER;
2085 server_spnego_response = data_blob(NULL, phdr->auth_len);
2086 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2088 /* The server might give us back two challenges - tmp_blob is for the second. */
2089 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2090 data_blob_free(&server_spnego_response);
2091 data_blob_free(&server_ntlm_response);
2092 data_blob_free(&tmp_blob);
2093 return NT_STATUS_INVALID_PARAMETER;
2096 /* We're finished with the server spnego response and the tmp_blob. */
2097 data_blob_free(&server_spnego_response);
2098 data_blob_free(&tmp_blob);
2100 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2101 server_ntlm_response,
2104 /* Finished with the server_ntlm response */
2105 data_blob_free(&server_ntlm_response);
2107 if (!NT_STATUS_IS_OK(nt_status)) {
2108 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2109 data_blob_free(&client_reply);
2113 /* SPNEGO wrap the client reply. */
2114 tmp_blob = spnego_gen_auth(client_reply);
2115 data_blob_free(&client_reply);
2116 client_reply = tmp_blob;
2117 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2119 /* Now prepare the alter context pdu. */
2120 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2122 nt_status = create_rpc_alter_context(rpc_call_id,
2129 data_blob_free(&client_reply);
2131 if (!NT_STATUS_IS_OK(nt_status)) {
2132 prs_mem_free(&rpc_out);
2136 /* Initialize the returning data struct. */
2138 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2140 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2141 if (!NT_STATUS_IS_OK(nt_status)) {
2142 prs_mem_free(&rpc_out);
2146 prs_mem_free(&rpc_out);
2148 /* Get the auth blob from the reply. */
2149 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2150 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2151 return NT_STATUS_BUFFER_TOO_SMALL;
2154 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2155 return NT_STATUS_INVALID_PARAMETER;
2158 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2159 return NT_STATUS_INVALID_PARAMETER;
2162 server_spnego_response = data_blob(NULL, phdr->auth_len);
2163 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2165 /* Check we got a valid auth response. */
2166 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2167 data_blob_free(&server_spnego_response);
2168 data_blob_free(&tmp_blob);
2169 return NT_STATUS_INVALID_PARAMETER;
2172 data_blob_free(&server_spnego_response);
2173 data_blob_free(&tmp_blob);
2175 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2176 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2178 return NT_STATUS_OK;
2181 /****************************************************************************
2183 ****************************************************************************/
2185 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2186 struct cli_pipe_auth_data *auth)
2195 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2196 rpccli_pipe_txt(debug_ctx(), cli),
2197 (unsigned int)auth->auth_type,
2198 (unsigned int)auth->auth_level ));
2200 cli->auth = talloc_move(cli, &auth);
2202 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2204 rpc_call_id = get_rpc_call_id();
2206 /* Marshall the outgoing data. */
2207 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2208 &cli->abstract_syntax,
2209 &cli->transfer_syntax,
2210 cli->auth->auth_type,
2211 cli->auth->auth_level);
2213 if (!NT_STATUS_IS_OK(status)) {
2214 prs_mem_free(&rpc_out);
2218 /* Initialize the incoming data struct. */
2219 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2221 /* send data on \PIPE\. receive a response */
2222 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2223 if (!NT_STATUS_IS_OK(status)) {
2224 prs_mem_free(&rpc_out);
2228 prs_mem_free(&rpc_out);
2230 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2231 rpccli_pipe_txt(debug_ctx(), cli)));
2233 /* Unmarshall the RPC header */
2234 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2235 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2236 prs_mem_free(&rbuf);
2237 return NT_STATUS_BUFFER_TOO_SMALL;
2240 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2241 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2242 prs_mem_free(&rbuf);
2243 return NT_STATUS_BUFFER_TOO_SMALL;
2246 if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) {
2247 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2248 prs_mem_free(&rbuf);
2249 return NT_STATUS_BUFFER_TOO_SMALL;
2252 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2253 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2255 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2256 switch(cli->auth->auth_type) {
2258 case PIPE_AUTH_TYPE_NONE:
2259 case PIPE_AUTH_TYPE_SCHANNEL:
2260 /* Bind complete. */
2263 case PIPE_AUTH_TYPE_NTLMSSP:
2264 /* Need to send AUTH3 packet - no reply. */
2265 status = rpc_finish_auth3_bind(
2266 cli, &hdr, &rbuf, rpc_call_id,
2267 cli->auth->auth_type,
2268 cli->auth->auth_level);
2269 if (!NT_STATUS_IS_OK(status)) {
2270 prs_mem_free(&rbuf);
2275 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2276 /* Need to send alter context request and reply. */
2277 status = rpc_finish_spnego_ntlmssp_bind(
2278 cli, &hdr, &rbuf, rpc_call_id,
2279 &cli->abstract_syntax, &cli->transfer_syntax,
2280 cli->auth->auth_type, cli->auth->auth_level);
2281 if (!NT_STATUS_IS_OK(status)) {
2282 prs_mem_free(&rbuf);
2287 case PIPE_AUTH_TYPE_KRB5:
2291 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2292 "%u\n", (unsigned int)cli->auth->auth_type));
2293 prs_mem_free(&rbuf);
2294 return NT_STATUS_INVALID_INFO_CLASS;
2297 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2298 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2299 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2300 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2301 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2302 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2303 prs_mem_free(&rbuf);
2304 return NT_STATUS_INVALID_PARAMETER;
2307 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2308 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2309 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2310 prs_mem_free(&rbuf);
2311 return NT_STATUS_INVALID_PARAMETER;
2316 prs_mem_free(&rbuf);
2317 return NT_STATUS_OK;
2320 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2321 unsigned int timeout)
2323 return cli_set_timeout(cli->trans.np.cli, timeout);
2326 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2328 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2329 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2330 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2334 if (cli->transport_type == NCACN_NP) {
2335 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2342 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2344 if (p->transport_type == NCACN_NP) {
2345 return p->trans.np.cli;
2350 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2352 if (p->transport_type == NCACN_NP) {
2354 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2356 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2357 "pipe %s. Error was %s\n",
2358 rpccli_pipe_txt(debug_ctx(), p),
2359 cli_errstr(p->trans.np.cli)));
2362 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2363 rpccli_pipe_txt(debug_ctx(), p)));
2365 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2366 return ret ? -1 : 0;
2372 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2373 struct cli_pipe_auth_data **presult)
2375 struct cli_pipe_auth_data *result;
2377 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2378 if (result == NULL) {
2379 return NT_STATUS_NO_MEMORY;
2382 result->auth_type = PIPE_AUTH_TYPE_NONE;
2383 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2385 result->user_name = talloc_strdup(result, "");
2386 result->domain = talloc_strdup(result, "");
2387 if ((result->user_name == NULL) || (result->domain == NULL)) {
2388 TALLOC_FREE(result);
2389 return NT_STATUS_NO_MEMORY;
2393 return NT_STATUS_OK;
2396 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2398 ntlmssp_end(&auth->a_u.ntlmssp_state);
2402 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2403 enum pipe_auth_type auth_type,
2404 enum pipe_auth_level auth_level,
2406 const char *username,
2407 const char *password,
2408 struct cli_pipe_auth_data **presult)
2410 struct cli_pipe_auth_data *result;
2413 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2414 if (result == NULL) {
2415 return NT_STATUS_NO_MEMORY;
2418 result->auth_type = auth_type;
2419 result->auth_level = auth_level;
2421 result->user_name = talloc_strdup(result, username);
2422 result->domain = talloc_strdup(result, domain);
2423 if ((result->user_name == NULL) || (result->domain == NULL)) {
2424 status = NT_STATUS_NO_MEMORY;
2428 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2429 if (!NT_STATUS_IS_OK(status)) {
2433 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2435 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2436 if (!NT_STATUS_IS_OK(status)) {
2440 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2441 if (!NT_STATUS_IS_OK(status)) {
2445 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2446 if (!NT_STATUS_IS_OK(status)) {
2451 * Turn off sign+seal to allow selected auth level to turn it back on.
2453 result->a_u.ntlmssp_state->neg_flags &=
2454 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2456 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2457 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2458 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2459 result->a_u.ntlmssp_state->neg_flags
2460 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2464 return NT_STATUS_OK;
2467 TALLOC_FREE(result);
2471 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2472 enum pipe_auth_level auth_level,
2473 const uint8_t sess_key[16],
2474 struct cli_pipe_auth_data **presult)
2476 struct cli_pipe_auth_data *result;
2478 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2479 if (result == NULL) {
2480 return NT_STATUS_NO_MEMORY;
2483 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2484 result->auth_level = auth_level;
2486 result->user_name = talloc_strdup(result, "");
2487 result->domain = talloc_strdup(result, domain);
2488 if ((result->user_name == NULL) || (result->domain == NULL)) {
2492 result->a_u.schannel_auth = talloc(result,
2493 struct schannel_auth_struct);
2494 if (result->a_u.schannel_auth == NULL) {
2498 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2499 sizeof(result->a_u.schannel_auth->sess_key));
2500 result->a_u.schannel_auth->seq_num = 0;
2503 return NT_STATUS_OK;
2506 TALLOC_FREE(result);
2507 return NT_STATUS_NO_MEMORY;
2511 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2513 data_blob_free(&auth->session_key);
2518 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2519 enum pipe_auth_level auth_level,
2520 const char *service_princ,
2521 const char *username,
2522 const char *password,
2523 struct cli_pipe_auth_data **presult)
2526 struct cli_pipe_auth_data *result;
2528 if ((username != NULL) && (password != NULL)) {
2529 int ret = kerberos_kinit_password(username, password, 0, NULL);
2531 return NT_STATUS_ACCESS_DENIED;
2535 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2536 if (result == NULL) {
2537 return NT_STATUS_NO_MEMORY;
2540 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2541 result->auth_level = auth_level;
2544 * Username / domain need fixing!
2546 result->user_name = talloc_strdup(result, "");
2547 result->domain = talloc_strdup(result, "");
2548 if ((result->user_name == NULL) || (result->domain == NULL)) {
2552 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2553 result, struct kerberos_auth_struct);
2554 if (result->a_u.kerberos_auth == NULL) {
2557 talloc_set_destructor(result->a_u.kerberos_auth,
2558 cli_auth_kerberos_data_destructor);
2560 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2561 result, service_princ);
2562 if (result->a_u.kerberos_auth->service_principal == NULL) {
2567 return NT_STATUS_OK;
2570 TALLOC_FREE(result);
2571 return NT_STATUS_NO_MEMORY;
2573 return NT_STATUS_NOT_SUPPORTED;
2577 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2579 close(p->trans.sock.fd);
2584 * Create an rpc pipe client struct, connecting to a tcp port.
2586 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2588 const struct ndr_syntax_id *abstract_syntax,
2589 struct rpc_pipe_client **presult)
2591 struct rpc_pipe_client *result;
2592 struct sockaddr_storage addr;
2595 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2596 if (result == NULL) {
2597 return NT_STATUS_NO_MEMORY;
2600 result->transport_type = NCACN_IP_TCP;
2602 result->abstract_syntax = *abstract_syntax;
2603 result->transfer_syntax = ndr_transfer_syntax;
2605 result->desthost = talloc_strdup(result, host);
2606 result->srv_name_slash = talloc_asprintf_strupper_m(
2607 result, "\\\\%s", result->desthost);
2608 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2609 status = NT_STATUS_NO_MEMORY;
2613 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2614 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2616 if (!resolve_name(host, &addr, 0)) {
2617 status = NT_STATUS_NOT_FOUND;
2621 status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
2622 if (!NT_STATUS_IS_OK(status)) {
2626 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2629 return NT_STATUS_OK;
2632 TALLOC_FREE(result);
2637 * Determine the tcp port on which a dcerpc interface is listening
2638 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2641 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2642 const struct ndr_syntax_id *abstract_syntax,
2646 struct rpc_pipe_client *epm_pipe = NULL;
2647 struct cli_pipe_auth_data *auth = NULL;
2648 struct dcerpc_binding *map_binding = NULL;
2649 struct dcerpc_binding *res_binding = NULL;
2650 struct epm_twr_t *map_tower = NULL;
2651 struct epm_twr_t *res_towers = NULL;
2652 struct policy_handle *entry_handle = NULL;
2653 uint32_t num_towers = 0;
2654 uint32_t max_towers = 1;
2655 struct epm_twr_p_t towers;
2656 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2658 if (pport == NULL) {
2659 status = NT_STATUS_INVALID_PARAMETER;
2663 /* open the connection to the endpoint mapper */
2664 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2665 &ndr_table_epmapper.syntax_id,
2668 if (!NT_STATUS_IS_OK(status)) {
2672 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2673 if (!NT_STATUS_IS_OK(status)) {
2677 status = rpc_pipe_bind(epm_pipe, auth);
2678 if (!NT_STATUS_IS_OK(status)) {
2682 /* create tower for asking the epmapper */
2684 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2685 if (map_binding == NULL) {
2686 status = NT_STATUS_NO_MEMORY;
2690 map_binding->transport = NCACN_IP_TCP;
2691 map_binding->object = *abstract_syntax;
2692 map_binding->host = host; /* needed? */
2693 map_binding->endpoint = "0"; /* correct? needed? */
2695 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2696 if (map_tower == NULL) {
2697 status = NT_STATUS_NO_MEMORY;
2701 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2702 &(map_tower->tower));
2703 if (!NT_STATUS_IS_OK(status)) {
2707 /* allocate further parameters for the epm_Map call */
2709 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2710 if (res_towers == NULL) {
2711 status = NT_STATUS_NO_MEMORY;
2714 towers.twr = res_towers;
2716 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2717 if (entry_handle == NULL) {
2718 status = NT_STATUS_NO_MEMORY;
2722 /* ask the endpoint mapper for the port */
2724 status = rpccli_epm_Map(epm_pipe,
2726 CONST_DISCARD(struct GUID *,
2727 &(abstract_syntax->uuid)),
2734 if (!NT_STATUS_IS_OK(status)) {
2738 if (num_towers != 1) {
2739 status = NT_STATUS_UNSUCCESSFUL;
2743 /* extract the port from the answer */
2745 status = dcerpc_binding_from_tower(tmp_ctx,
2746 &(towers.twr->tower),
2748 if (!NT_STATUS_IS_OK(status)) {
2752 /* are further checks here necessary? */
2753 if (res_binding->transport != NCACN_IP_TCP) {
2754 status = NT_STATUS_UNSUCCESSFUL;
2758 *pport = (uint16_t)atoi(res_binding->endpoint);
2761 TALLOC_FREE(tmp_ctx);
2766 * Create a rpc pipe client struct, connecting to a host via tcp.
2767 * The port is determined by asking the endpoint mapper on the given
2770 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2771 const struct ndr_syntax_id *abstract_syntax,
2772 struct rpc_pipe_client **presult)
2779 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2780 if (!NT_STATUS_IS_OK(status)) {
2784 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2785 abstract_syntax, presult);
2791 /********************************************************************
2792 Create a rpc pipe client struct, connecting to a unix domain socket
2793 ********************************************************************/
2794 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2795 const struct ndr_syntax_id *abstract_syntax,
2796 struct rpc_pipe_client **presult)
2798 struct rpc_pipe_client *result;
2799 struct sockaddr_un addr;
2802 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2803 if (result == NULL) {
2804 return NT_STATUS_NO_MEMORY;
2807 result->transport_type = NCACN_UNIX_STREAM;
2809 result->abstract_syntax = *abstract_syntax;
2810 result->transfer_syntax = ndr_transfer_syntax;
2812 result->desthost = talloc_get_myname(result);
2813 result->srv_name_slash = talloc_asprintf_strupper_m(
2814 result, "\\\\%s", result->desthost);
2815 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2816 status = NT_STATUS_NO_MEMORY;
2820 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2821 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2823 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2824 if (result->trans.sock.fd == -1) {
2825 status = map_nt_error_from_unix(errno);
2829 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2832 addr.sun_family = AF_UNIX;
2833 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2835 if (sys_connect(result->trans.sock.fd,
2836 (struct sockaddr *)&addr) == -1) {
2837 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2839 close(result->trans.sock.fd);
2840 return map_nt_error_from_unix(errno);
2844 return NT_STATUS_OK;
2847 TALLOC_FREE(result);
2852 /****************************************************************************
2853 Open a named pipe over SMB to a remote server.
2855 * CAVEAT CALLER OF THIS FUNCTION:
2856 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2857 * so be sure that this function is called AFTER any structure (vs pointer)
2858 * assignment of the cli. In particular, libsmbclient does structure
2859 * assignments of cli, which invalidates the data in the returned
2860 * rpc_pipe_client if this function is called before the structure assignment
2863 ****************************************************************************/
2865 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2866 const struct ndr_syntax_id *abstract_syntax,
2867 struct rpc_pipe_client **presult)
2869 struct rpc_pipe_client *result;
2872 /* sanity check to protect against crashes */
2875 return NT_STATUS_INVALID_HANDLE;
2878 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2879 if (result == NULL) {
2880 return NT_STATUS_NO_MEMORY;
2883 result->transport_type = NCACN_NP;
2885 result->trans.np.pipe_name = cli_get_pipe_name_from_iface(
2886 result, cli, abstract_syntax);
2887 if (result->trans.np.pipe_name == NULL) {
2888 DEBUG(1, ("Could not find pipe for interface\n"));
2889 TALLOC_FREE(result);
2890 return NT_STATUS_INVALID_PARAMETER;
2893 result->trans.np.cli = cli;
2894 result->abstract_syntax = *abstract_syntax;
2895 result->transfer_syntax = ndr_transfer_syntax;
2896 result->desthost = talloc_strdup(result, cli->desthost);
2897 result->srv_name_slash = talloc_asprintf_strupper_m(
2898 result, "\\\\%s", result->desthost);
2900 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2901 TALLOC_FREE(result);
2902 return NT_STATUS_NO_MEMORY;
2905 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2906 DESIRED_ACCESS_PIPE);
2908 DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
2909 "to machine %s. Error was %s\n",
2910 result->trans.np.pipe_name, cli->desthost,
2912 TALLOC_FREE(result);
2913 return cli_get_nt_error(cli);
2916 result->trans.np.fnum = fnum;
2918 DLIST_ADD(cli->pipe_list, result);
2919 talloc_set_destructor(result, rpc_pipe_destructor);
2922 return NT_STATUS_OK;
2925 /****************************************************************************
2926 Open a pipe to a remote server.
2927 ****************************************************************************/
2929 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2930 const struct ndr_syntax_id *interface,
2931 struct rpc_pipe_client **presult)
2933 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
2935 * We should have a better way to figure out this drsuapi
2938 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2942 return rpc_pipe_open_np(cli, interface, presult);
2945 /****************************************************************************
2946 Open a named pipe to an SMB server and bind anonymously.
2947 ****************************************************************************/
2949 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2950 const struct ndr_syntax_id *interface,
2951 struct rpc_pipe_client **presult)
2953 struct rpc_pipe_client *result;
2954 struct cli_pipe_auth_data *auth;
2957 status = cli_rpc_pipe_open(cli, interface, &result);
2958 if (!NT_STATUS_IS_OK(status)) {
2962 status = rpccli_anon_bind_data(result, &auth);
2963 if (!NT_STATUS_IS_OK(status)) {
2964 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2965 nt_errstr(status)));
2966 TALLOC_FREE(result);
2971 * This is a bit of an abstraction violation due to the fact that an
2972 * anonymous bind on an authenticated SMB inherits the user/domain
2973 * from the enclosing SMB creds
2976 TALLOC_FREE(auth->user_name);
2977 TALLOC_FREE(auth->domain);
2979 auth->user_name = talloc_strdup(auth, cli->user_name);
2980 auth->domain = talloc_strdup(auth, cli->domain);
2981 auth->user_session_key = data_blob_talloc(auth,
2982 cli->user_session_key.data,
2983 cli->user_session_key.length);
2985 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2986 TALLOC_FREE(result);
2987 return NT_STATUS_NO_MEMORY;
2990 status = rpc_pipe_bind(result, auth);
2991 if (!NT_STATUS_IS_OK(status)) {
2993 if (ndr_syntax_id_equal(interface,
2994 &ndr_table_dssetup.syntax_id)) {
2995 /* non AD domains just don't have this pipe, avoid
2996 * level 0 statement in that case - gd */
2999 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3000 "%s failed with error %s\n",
3001 cli_get_pipe_name_from_iface(debug_ctx(), cli,
3003 nt_errstr(status) ));
3004 TALLOC_FREE(result);
3008 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3009 "%s and bound anonymously.\n", result->trans.np.pipe_name,
3013 return NT_STATUS_OK;
3016 /****************************************************************************
3017 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3018 ****************************************************************************/
3020 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3021 const struct ndr_syntax_id *interface,
3022 enum pipe_auth_type auth_type,
3023 enum pipe_auth_level auth_level,
3025 const char *username,
3026 const char *password,
3027 struct rpc_pipe_client **presult)
3029 struct rpc_pipe_client *result;
3030 struct cli_pipe_auth_data *auth;
3033 status = cli_rpc_pipe_open(cli, interface, &result);
3034 if (!NT_STATUS_IS_OK(status)) {
3038 status = rpccli_ntlmssp_bind_data(
3039 result, auth_type, auth_level, domain, username,
3040 cli->pwd.null_pwd ? NULL : password, &auth);
3041 if (!NT_STATUS_IS_OK(status)) {
3042 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3043 nt_errstr(status)));
3047 status = rpc_pipe_bind(result, auth);
3048 if (!NT_STATUS_IS_OK(status)) {
3049 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3050 nt_errstr(status) ));
3054 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3055 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3056 result->trans.np.pipe_name, cli->desthost,
3057 domain, username ));
3060 return NT_STATUS_OK;
3064 TALLOC_FREE(result);
3068 /****************************************************************************
3070 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3071 ****************************************************************************/
3073 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3074 const struct ndr_syntax_id *interface,
3075 enum pipe_auth_level auth_level,
3077 const char *username,
3078 const char *password,
3079 struct rpc_pipe_client **presult)
3081 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3083 PIPE_AUTH_TYPE_NTLMSSP,
3091 /****************************************************************************
3093 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3094 ****************************************************************************/
3096 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3097 const struct ndr_syntax_id *interface,
3098 enum pipe_auth_level auth_level,
3100 const char *username,
3101 const char *password,
3102 struct rpc_pipe_client **presult)
3104 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3106 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3114 /****************************************************************************
3115 Get a the schannel session key out of an already opened netlogon pipe.
3116 ****************************************************************************/
3117 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3118 struct cli_state *cli,
3122 uint32 sec_chan_type = 0;
3123 unsigned char machine_pwd[16];
3124 const char *machine_account;
3127 /* Get the machine account credentials from secrets.tdb. */
3128 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3131 DEBUG(0, ("get_schannel_session_key: could not fetch "
3132 "trust account password for domain '%s'\n",
3134 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3137 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3138 cli->desthost, /* server name */
3139 domain, /* domain */
3140 global_myname(), /* client name */
3141 machine_account, /* machine account name */
3146 if (!NT_STATUS_IS_OK(status)) {
3147 DEBUG(3, ("get_schannel_session_key_common: "
3148 "rpccli_netlogon_setup_creds failed with result %s "
3149 "to server %s, domain %s, machine account %s.\n",
3150 nt_errstr(status), cli->desthost, domain,
3155 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3156 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3158 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3161 return NT_STATUS_OK;;
3164 /****************************************************************************
3165 Open a netlogon pipe and get the schannel session key.
3166 Now exposed to external callers.
3167 ****************************************************************************/
3170 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3173 struct rpc_pipe_client **presult)
3175 struct rpc_pipe_client *netlogon_pipe = NULL;
3178 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3180 if (!NT_STATUS_IS_OK(status)) {
3184 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3186 if (!NT_STATUS_IS_OK(status)) {
3187 TALLOC_FREE(netlogon_pipe);
3191 *presult = netlogon_pipe;
3192 return NT_STATUS_OK;
3195 /****************************************************************************
3197 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3198 using session_key. sign and seal.
3199 ****************************************************************************/
3201 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3202 const struct ndr_syntax_id *interface,
3203 enum pipe_auth_level auth_level,
3205 const struct dcinfo *pdc,
3206 struct rpc_pipe_client **presult)
3208 struct rpc_pipe_client *result;
3209 struct cli_pipe_auth_data *auth;
3212 status = cli_rpc_pipe_open(cli, interface, &result);
3213 if (!NT_STATUS_IS_OK(status)) {
3217 status = rpccli_schannel_bind_data(result, domain, auth_level,
3218 pdc->sess_key, &auth);
3219 if (!NT_STATUS_IS_OK(status)) {
3220 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3221 nt_errstr(status)));
3222 TALLOC_FREE(result);
3226 status = rpc_pipe_bind(result, auth);
3227 if (!NT_STATUS_IS_OK(status)) {
3228 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3229 "cli_rpc_pipe_bind failed with error %s\n",
3230 nt_errstr(status) ));
3231 TALLOC_FREE(result);
3236 * The credentials on a new netlogon pipe are the ones we are passed
3237 * in - copy them over.
3239 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3240 if (result->dc == NULL) {
3241 DEBUG(0, ("talloc failed\n"));
3242 TALLOC_FREE(result);
3243 return NT_STATUS_NO_MEMORY;
3246 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3248 "and bound using schannel.\n",
3249 result->trans.np.pipe_name, cli->desthost, domain ));
3252 return NT_STATUS_OK;
3255 /****************************************************************************
3256 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3257 Fetch the session key ourselves using a temporary netlogon pipe. This
3258 version uses an ntlmssp auth bound netlogon pipe to get the key.
3259 ****************************************************************************/
3261 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3263 const char *username,
3264 const char *password,
3266 struct rpc_pipe_client **presult)
3268 struct rpc_pipe_client *netlogon_pipe = NULL;
3271 status = cli_rpc_pipe_open_spnego_ntlmssp(
3272 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3273 domain, username, password, &netlogon_pipe);
3274 if (!NT_STATUS_IS_OK(status)) {
3278 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3280 if (!NT_STATUS_IS_OK(status)) {
3281 TALLOC_FREE(netlogon_pipe);
3285 *presult = netlogon_pipe;
3286 return NT_STATUS_OK;
3289 /****************************************************************************
3290 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3291 Fetch the session key ourselves using a temporary netlogon pipe. This version
3292 uses an ntlmssp bind to get the session key.
3293 ****************************************************************************/
3295 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3296 const struct ndr_syntax_id *interface,
3297 enum pipe_auth_level auth_level,
3299 const char *username,
3300 const char *password,
3301 struct rpc_pipe_client **presult)
3303 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3304 struct rpc_pipe_client *netlogon_pipe = NULL;
3305 struct rpc_pipe_client *result = NULL;
3308 status = get_schannel_session_key_auth_ntlmssp(
3309 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3310 if (!NT_STATUS_IS_OK(status)) {
3311 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3312 "key from server %s for domain %s.\n",
3313 cli->desthost, domain ));
3317 status = cli_rpc_pipe_open_schannel_with_key(
3318 cli, interface, auth_level, domain, netlogon_pipe->dc,
3321 /* Now we've bound using the session key we can close the netlog pipe. */
3322 TALLOC_FREE(netlogon_pipe);
3324 if (NT_STATUS_IS_OK(status)) {
3330 /****************************************************************************
3331 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3332 Fetch the session key ourselves using a temporary netlogon pipe.
3333 ****************************************************************************/
3335 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3336 const struct ndr_syntax_id *interface,
3337 enum pipe_auth_level auth_level,
3339 struct rpc_pipe_client **presult)
3341 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3342 struct rpc_pipe_client *netlogon_pipe = NULL;
3343 struct rpc_pipe_client *result = NULL;
3346 status = get_schannel_session_key(cli, domain, &neg_flags,
3348 if (!NT_STATUS_IS_OK(status)) {
3349 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3350 "key from server %s for domain %s.\n",
3351 cli->desthost, domain ));
3355 status = cli_rpc_pipe_open_schannel_with_key(
3356 cli, interface, auth_level, domain, netlogon_pipe->dc,
3359 /* Now we've bound using the session key we can close the netlog pipe. */
3360 TALLOC_FREE(netlogon_pipe);
3362 if (NT_STATUS_IS_OK(status)) {
3366 return NT_STATUS_OK;
3369 /****************************************************************************
3370 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3371 The idea is this can be called with service_princ, username and password all
3372 NULL so long as the caller has a TGT.
3373 ****************************************************************************/
3375 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3376 const struct ndr_syntax_id *interface,
3377 enum pipe_auth_level auth_level,
3378 const char *service_princ,
3379 const char *username,
3380 const char *password,
3381 struct rpc_pipe_client **presult)
3384 struct rpc_pipe_client *result;
3385 struct cli_pipe_auth_data *auth;
3388 status = cli_rpc_pipe_open(cli, interface, &result);
3389 if (!NT_STATUS_IS_OK(status)) {
3393 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3394 username, password, &auth);
3395 if (!NT_STATUS_IS_OK(status)) {
3396 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3397 nt_errstr(status)));
3398 TALLOC_FREE(result);
3402 status = rpc_pipe_bind(result, auth);
3403 if (!NT_STATUS_IS_OK(status)) {
3404 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3405 "with error %s\n", nt_errstr(status)));
3406 TALLOC_FREE(result);
3411 return NT_STATUS_OK;
3413 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3414 return NT_STATUS_NOT_IMPLEMENTED;
3418 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3419 struct rpc_pipe_client *cli,
3420 DATA_BLOB *session_key)
3422 if (!session_key || !cli) {
3423 return NT_STATUS_INVALID_PARAMETER;
3427 return NT_STATUS_INVALID_PARAMETER;
3430 switch (cli->auth->auth_type) {
3431 case PIPE_AUTH_TYPE_SCHANNEL:
3432 *session_key = data_blob_talloc(mem_ctx,
3433 cli->auth->a_u.schannel_auth->sess_key, 16);
3435 case PIPE_AUTH_TYPE_NTLMSSP:
3436 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3437 *session_key = data_blob_talloc(mem_ctx,
3438 cli->auth->a_u.ntlmssp_state->session_key.data,
3439 cli->auth->a_u.ntlmssp_state->session_key.length);
3441 case PIPE_AUTH_TYPE_KRB5:
3442 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3443 *session_key = data_blob_talloc(mem_ctx,
3444 cli->auth->a_u.kerberos_auth->session_key.data,
3445 cli->auth->a_u.kerberos_auth->session_key.length);
3447 case PIPE_AUTH_TYPE_NONE:
3448 *session_key = data_blob_talloc(mem_ctx,
3449 cli->auth->user_session_key.data,
3450 cli->auth->user_session_key.length);
3453 return NT_STATUS_NO_USER_SESSION_KEY;
3456 return NT_STATUS_OK;