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 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
838 ****************************************************************************/
840 static bool cli_api_pipe(struct cli_state *cli, const char *pipe_name,
841 uint16 *setup, uint32 setup_count,
842 uint32 max_setup_count,
843 char *params, uint32 param_count,
844 uint32 max_param_count,
845 char *data, uint32 data_count,
846 uint32 max_data_count,
847 char **rparam, uint32 *rparam_count,
848 char **rdata, uint32 *rdata_count)
850 cli_send_trans(cli, SMBtrans,
852 0,0, /* fid, flags */
853 setup, setup_count, max_setup_count,
854 params, param_count, max_param_count,
855 data, data_count, max_data_count);
857 return (cli_receive_trans(cli, SMBtrans,
858 rparam, (unsigned int *)rparam_count,
859 rdata, (unsigned int *)rdata_count));
862 /****************************************************************************
863 Send data on an rpc pipe via trans. The prs_struct data must be the last
864 pdu fragment of an NDR data stream.
866 Receive response data from an rpc pipe, which may be large...
868 Read the first fragment: unfortunately have to use SMBtrans for the first
869 bit, then SMBreadX for subsequent bits.
871 If first fragment received also wasn't the last fragment, continue
872 getting fragments until we _do_ receive the last fragment.
874 Request/Response PDU's look like the following...
876 |<------------------PDU len----------------------------------------------->|
877 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
879 +------------+-----------------+-------------+---------------+-------------+
880 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
881 +------------+-----------------+-------------+---------------+-------------+
883 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
884 signing & sealing being negotiated.
886 ****************************************************************************/
888 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
889 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
890 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
891 uint8 expected_pkt_type)
893 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
895 uint32 rparam_len = 0;
896 char *pdata = prs_data_p(data);
897 uint32 data_len = prs_offset(data);
899 uint32 rdata_len = 0;
900 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
901 uint32 current_rbuf_offset = 0;
902 prs_struct current_pdu;
905 /* Ensure we're not sending too much. */
906 SMB_ASSERT(data_len <= max_data);
909 /* Set up the current pdu parse struct. */
910 prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
912 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
914 switch (cli->transport_type) {
917 /* Create setup parameters - must be in native byte order. */
918 setup[0] = TRANSACT_DCERPCCMD;
919 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
922 * Send the last (or only) fragment of an RPC request. For
923 * small amounts of data (about 1024 bytes or so) the RPC
924 * request and response appears in a SMBtrans request and
928 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
929 setup, 2, 0, /* Setup, length, max */
930 NULL, 0, 0, /* Params, length, max */
931 pdata, data_len, max_data, /* data, length,
933 &rparam, &rparam_len, /* return params,
935 &prdata, &rdata_len)) /* return data, len */
937 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
939 rpccli_pipe_txt(debug_ctx(), cli),
940 cli_errstr(cli->trans.np.cli)));
941 ret = cli_get_nt_error(cli->trans.np.cli);
949 case NCACN_UNIX_STREAM:
951 ssize_t nwritten, nread;
952 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
953 if (nwritten == -1) {
954 ret = map_nt_error_from_unix(errno);
955 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
960 prdata = SMB_MALLOC_ARRAY(char, 1);
961 if (prdata == NULL) {
962 return NT_STATUS_NO_MEMORY;
964 nread = sys_read(cli->trans.sock.fd, prdata, 1);
969 ret = NT_STATUS_END_OF_FILE;
976 DEBUG(0, ("unknown transport type %d\n",
977 cli->transport_type));
978 return NT_STATUS_INTERNAL_ERROR;
981 /* Throw away returned params - we know we won't use them. */
985 if (prdata == NULL) {
986 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
987 rpccli_pipe_txt(debug_ctx(), cli)));
988 /* Yes - some calls can truely return no data... */
989 prs_mem_free(¤t_pdu);
994 * Give this memory as dynamic to the current pdu.
997 prs_give_memory(¤t_pdu, prdata, rdata_len, True);
999 /* Ensure we can mess with the return prs_struct. */
1000 SMB_ASSERT(UNMARSHALLING(rbuf));
1001 SMB_ASSERT(prs_data_size(rbuf) == 0);
1003 /* Make rbuf dynamic with no memory. */
1004 prs_give_memory(rbuf, 0, 0, True);
1008 char *ret_data = NULL;
1009 uint32 ret_data_len = 0;
1011 /* Ensure we have enough data for a pdu. */
1012 ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu);
1013 if (!NT_STATUS_IS_OK(ret)) {
1017 /* We pass in rbuf here so if the alloc hint is set correctly
1018 we can set the output size and avoid reallocs. */
1020 ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type,
1021 &ret_data, &ret_data_len, rbuf);
1023 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
1024 prs_data_size(¤t_pdu), current_rbuf_offset ));
1026 if (!NT_STATUS_IS_OK(ret)) {
1030 if ((rhdr.flags & RPC_FLG_FIRST)) {
1031 if (rhdr.pack_type[0] == 0) {
1032 /* Set the data type correctly for big-endian data on the first packet. */
1033 DEBUG(10,("rpc_api_pipe: On %s "
1034 "PDU data format is big-endian.\n",
1035 rpccli_pipe_txt(debug_ctx(), cli)));
1037 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
1039 /* Check endianness on subsequent packets. */
1040 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
1041 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1042 rbuf->bigendian_data ? "big" : "little",
1043 current_pdu.bigendian_data ? "big" : "little" ));
1044 ret = NT_STATUS_INVALID_PARAMETER;
1050 /* Now copy the data portion out of the pdu into rbuf. */
1051 if (!prs_force_grow(rbuf, ret_data_len)) {
1052 ret = NT_STATUS_NO_MEMORY;
1055 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
1056 current_rbuf_offset += ret_data_len;
1058 /* See if we've finished with all the data in current_pdu yet ? */
1059 ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu);
1060 if (!NT_STATUS_IS_OK(ret)) {
1064 if (rhdr.flags & RPC_FLG_LAST) {
1065 break; /* We're done. */
1069 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1070 rpccli_pipe_txt(debug_ctx(), cli),
1071 (unsigned int)prs_data_size(rbuf) ));
1073 prs_mem_free(¤t_pdu);
1074 return NT_STATUS_OK;
1078 prs_mem_free(¤t_pdu);
1083 /*******************************************************************
1084 Creates krb5 auth bind.
1085 ********************************************************************/
1087 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1088 enum pipe_auth_level auth_level,
1089 RPC_HDR_AUTH *pauth_out,
1090 prs_struct *auth_data)
1094 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1095 DATA_BLOB tkt = data_blob_null;
1096 DATA_BLOB tkt_wrapped = data_blob_null;
1098 /* We may change the pad length before marshalling. */
1099 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1101 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1102 a->service_principal ));
1104 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1106 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1107 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1110 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1112 a->service_principal,
1113 error_message(ret) ));
1115 data_blob_free(&tkt);
1116 prs_mem_free(auth_data);
1117 return NT_STATUS_INVALID_PARAMETER;
1120 /* wrap that up in a nice GSS-API wrapping */
1121 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1123 data_blob_free(&tkt);
1125 /* Auth len in the rpc header doesn't include auth_header. */
1126 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1127 data_blob_free(&tkt_wrapped);
1128 prs_mem_free(auth_data);
1129 return NT_STATUS_NO_MEMORY;
1132 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1133 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1135 data_blob_free(&tkt_wrapped);
1136 return NT_STATUS_OK;
1138 return NT_STATUS_INVALID_PARAMETER;
1142 /*******************************************************************
1143 Creates SPNEGO NTLMSSP auth bind.
1144 ********************************************************************/
1146 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1147 enum pipe_auth_level auth_level,
1148 RPC_HDR_AUTH *pauth_out,
1149 prs_struct *auth_data)
1152 DATA_BLOB null_blob = data_blob_null;
1153 DATA_BLOB request = data_blob_null;
1154 DATA_BLOB spnego_msg = data_blob_null;
1156 /* We may change the pad length before marshalling. */
1157 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1159 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1160 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1164 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1165 data_blob_free(&request);
1166 prs_mem_free(auth_data);
1170 /* Wrap this in SPNEGO. */
1171 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1173 data_blob_free(&request);
1175 /* Auth len in the rpc header doesn't include auth_header. */
1176 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1177 data_blob_free(&spnego_msg);
1178 prs_mem_free(auth_data);
1179 return NT_STATUS_NO_MEMORY;
1182 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1183 dump_data(5, spnego_msg.data, spnego_msg.length);
1185 data_blob_free(&spnego_msg);
1186 return NT_STATUS_OK;
1189 /*******************************************************************
1190 Creates NTLMSSP auth bind.
1191 ********************************************************************/
1193 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1194 enum pipe_auth_level auth_level,
1195 RPC_HDR_AUTH *pauth_out,
1196 prs_struct *auth_data)
1199 DATA_BLOB null_blob = data_blob_null;
1200 DATA_BLOB request = data_blob_null;
1202 /* We may change the pad length before marshalling. */
1203 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1205 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1206 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1210 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1211 data_blob_free(&request);
1212 prs_mem_free(auth_data);
1216 /* Auth len in the rpc header doesn't include auth_header. */
1217 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1218 data_blob_free(&request);
1219 prs_mem_free(auth_data);
1220 return NT_STATUS_NO_MEMORY;
1223 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1224 dump_data(5, request.data, request.length);
1226 data_blob_free(&request);
1227 return NT_STATUS_OK;
1230 /*******************************************************************
1231 Creates schannel auth bind.
1232 ********************************************************************/
1234 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1235 enum pipe_auth_level auth_level,
1236 RPC_HDR_AUTH *pauth_out,
1237 prs_struct *auth_data)
1239 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1241 /* We may change the pad length before marshalling. */
1242 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1244 /* Use lp_workgroup() if domain not specified */
1246 if (!cli->auth->domain || !cli->auth->domain[0]) {
1247 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1248 if (cli->auth->domain == NULL) {
1249 return NT_STATUS_NO_MEMORY;
1253 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1257 * Now marshall the data into the auth parse_struct.
1260 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1261 &schannel_neg, auth_data, 0)) {
1262 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1263 prs_mem_free(auth_data);
1264 return NT_STATUS_NO_MEMORY;
1267 return NT_STATUS_OK;
1270 /*******************************************************************
1271 Creates the internals of a DCE/RPC bind request or alter context PDU.
1272 ********************************************************************/
1274 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1275 prs_struct *rpc_out,
1277 const RPC_IFACE *abstract,
1278 const RPC_IFACE *transfer,
1279 RPC_HDR_AUTH *phdr_auth,
1280 prs_struct *pauth_info)
1284 RPC_CONTEXT rpc_ctx;
1285 uint16 auth_len = prs_offset(pauth_info);
1286 uint8 ss_padding_len = 0;
1287 uint16 frag_len = 0;
1289 /* create the RPC context. */
1290 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1292 /* create the bind request RPC_HDR_RB */
1293 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1295 /* Start building the frag length. */
1296 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1298 /* Do we need to pad ? */
1300 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1302 ss_padding_len = 8 - (data_len % 8);
1303 phdr_auth->auth_pad_len = ss_padding_len;
1305 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1308 /* Create the request RPC_HDR */
1309 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1311 /* Marshall the RPC header */
1312 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1313 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1314 return NT_STATUS_NO_MEMORY;
1317 /* Marshall the bind request data */
1318 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1319 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1320 return NT_STATUS_NO_MEMORY;
1324 * Grow the outgoing buffer to store any auth info.
1328 if (ss_padding_len) {
1330 memset(pad, '\0', 8);
1331 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1332 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1333 return NT_STATUS_NO_MEMORY;
1337 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1338 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1339 return NT_STATUS_NO_MEMORY;
1343 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1344 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1345 return NT_STATUS_NO_MEMORY;
1349 return NT_STATUS_OK;
1352 /*******************************************************************
1353 Creates a DCE/RPC bind request.
1354 ********************************************************************/
1356 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1357 prs_struct *rpc_out,
1359 const RPC_IFACE *abstract,
1360 const RPC_IFACE *transfer,
1361 enum pipe_auth_type auth_type,
1362 enum pipe_auth_level auth_level)
1364 RPC_HDR_AUTH hdr_auth;
1365 prs_struct auth_info;
1366 NTSTATUS ret = NT_STATUS_OK;
1368 ZERO_STRUCT(hdr_auth);
1369 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1370 return NT_STATUS_NO_MEMORY;
1372 switch (auth_type) {
1373 case PIPE_AUTH_TYPE_SCHANNEL:
1374 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1375 if (!NT_STATUS_IS_OK(ret)) {
1376 prs_mem_free(&auth_info);
1381 case PIPE_AUTH_TYPE_NTLMSSP:
1382 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1383 if (!NT_STATUS_IS_OK(ret)) {
1384 prs_mem_free(&auth_info);
1389 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1390 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1391 if (!NT_STATUS_IS_OK(ret)) {
1392 prs_mem_free(&auth_info);
1397 case PIPE_AUTH_TYPE_KRB5:
1398 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1399 if (!NT_STATUS_IS_OK(ret)) {
1400 prs_mem_free(&auth_info);
1405 case PIPE_AUTH_TYPE_NONE:
1409 /* "Can't" happen. */
1410 return NT_STATUS_INVALID_INFO_CLASS;
1413 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1421 prs_mem_free(&auth_info);
1425 /*******************************************************************
1426 Create and add the NTLMSSP sign/seal auth header and data.
1427 ********************************************************************/
1429 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1431 uint32 ss_padding_len,
1432 prs_struct *outgoing_pdu)
1434 RPC_HDR_AUTH auth_info;
1436 DATA_BLOB auth_blob = data_blob_null;
1437 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1439 if (!cli->auth->a_u.ntlmssp_state) {
1440 return NT_STATUS_INVALID_PARAMETER;
1443 /* Init and marshall the auth header. */
1444 init_rpc_hdr_auth(&auth_info,
1445 map_pipe_auth_type_to_rpc_auth_type(
1446 cli->auth->auth_type),
1447 cli->auth->auth_level,
1449 1 /* context id. */);
1451 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1452 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1453 data_blob_free(&auth_blob);
1454 return NT_STATUS_NO_MEMORY;
1457 switch (cli->auth->auth_level) {
1458 case PIPE_AUTH_LEVEL_PRIVACY:
1459 /* Data portion is encrypted. */
1460 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1461 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1463 (unsigned char *)prs_data_p(outgoing_pdu),
1464 (size_t)prs_offset(outgoing_pdu),
1466 if (!NT_STATUS_IS_OK(status)) {
1467 data_blob_free(&auth_blob);
1472 case PIPE_AUTH_LEVEL_INTEGRITY:
1473 /* Data is signed. */
1474 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1475 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1477 (unsigned char *)prs_data_p(outgoing_pdu),
1478 (size_t)prs_offset(outgoing_pdu),
1480 if (!NT_STATUS_IS_OK(status)) {
1481 data_blob_free(&auth_blob);
1488 smb_panic("bad auth level");
1490 return NT_STATUS_INVALID_PARAMETER;
1493 /* Finally marshall the blob. */
1495 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1496 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1497 (unsigned int)NTLMSSP_SIG_SIZE));
1498 data_blob_free(&auth_blob);
1499 return NT_STATUS_NO_MEMORY;
1502 data_blob_free(&auth_blob);
1503 return NT_STATUS_OK;
1506 /*******************************************************************
1507 Create and add the schannel sign/seal auth header and data.
1508 ********************************************************************/
1510 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1512 uint32 ss_padding_len,
1513 prs_struct *outgoing_pdu)
1515 RPC_HDR_AUTH auth_info;
1516 RPC_AUTH_SCHANNEL_CHK verf;
1517 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1518 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1519 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1522 return NT_STATUS_INVALID_PARAMETER;
1525 /* Init and marshall the auth header. */
1526 init_rpc_hdr_auth(&auth_info,
1527 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1528 cli->auth->auth_level,
1530 1 /* context id. */);
1532 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1533 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1534 return NT_STATUS_NO_MEMORY;
1537 switch (cli->auth->auth_level) {
1538 case PIPE_AUTH_LEVEL_PRIVACY:
1539 case PIPE_AUTH_LEVEL_INTEGRITY:
1540 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1543 schannel_encode(sas,
1544 cli->auth->auth_level,
1545 SENDER_IS_INITIATOR,
1555 smb_panic("bad auth level");
1557 return NT_STATUS_INVALID_PARAMETER;
1560 /* Finally marshall the blob. */
1561 smb_io_rpc_auth_schannel_chk("",
1562 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1567 return NT_STATUS_OK;
1570 /*******************************************************************
1571 Calculate how much data we're going to send in this packet, also
1572 work out any sign/seal padding length.
1573 ********************************************************************/
1575 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1579 uint32 *p_ss_padding)
1581 uint32 data_space, data_len;
1583 switch (cli->auth->auth_level) {
1584 case PIPE_AUTH_LEVEL_NONE:
1585 case PIPE_AUTH_LEVEL_CONNECT:
1586 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1587 data_len = MIN(data_space, data_left);
1590 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1593 case PIPE_AUTH_LEVEL_INTEGRITY:
1594 case PIPE_AUTH_LEVEL_PRIVACY:
1595 /* Treat the same for all authenticated rpc requests. */
1596 switch(cli->auth->auth_type) {
1597 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1598 case PIPE_AUTH_TYPE_NTLMSSP:
1599 *p_auth_len = NTLMSSP_SIG_SIZE;
1601 case PIPE_AUTH_TYPE_SCHANNEL:
1602 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1605 smb_panic("bad auth type");
1609 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1610 RPC_HDR_AUTH_LEN - *p_auth_len;
1612 data_len = MIN(data_space, data_left);
1614 *p_ss_padding = 8 - (data_len % 8);
1616 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1617 data_len + *p_ss_padding + /* data plus padding. */
1618 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1622 smb_panic("bad auth level");
1628 /*******************************************************************
1630 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1631 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1632 and deals with signing/sealing details.
1633 ********************************************************************/
1635 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1637 prs_struct *in_data,
1638 prs_struct *out_data)
1641 uint32 data_left = prs_offset(in_data);
1642 uint32 alloc_hint = prs_offset(in_data);
1643 uint32 data_sent_thistime = 0;
1644 uint32 current_data_offset = 0;
1645 uint32 call_id = get_rpc_call_id();
1647 prs_struct outgoing_pdu;
1649 memset(pad, '\0', 8);
1651 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1652 /* Server is screwed up ! */
1653 return NT_STATUS_INVALID_PARAMETER;
1656 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1657 return NT_STATUS_NO_MEMORY;
1661 RPC_HDR_REQ hdr_req;
1662 uint16 auth_len = 0;
1663 uint16 frag_len = 0;
1665 uint32 ss_padding = 0;
1666 ssize_t num_written;
1668 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1669 &frag_len, &auth_len, &ss_padding);
1671 if (current_data_offset == 0) {
1672 flags = RPC_FLG_FIRST;
1675 if (data_sent_thistime == data_left) {
1676 flags |= RPC_FLG_LAST;
1679 /* Create and marshall the header and request header. */
1680 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1682 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1683 prs_mem_free(&outgoing_pdu);
1684 return NT_STATUS_NO_MEMORY;
1687 /* Create the rpc request RPC_HDR_REQ */
1688 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1690 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1691 prs_mem_free(&outgoing_pdu);
1692 return NT_STATUS_NO_MEMORY;
1695 /* Copy in the data, plus any ss padding. */
1696 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1697 prs_mem_free(&outgoing_pdu);
1698 return NT_STATUS_NO_MEMORY;
1701 /* Copy the sign/seal padding data. */
1703 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1704 prs_mem_free(&outgoing_pdu);
1705 return NT_STATUS_NO_MEMORY;
1709 /* Generate any auth sign/seal and add the auth footer. */
1711 switch (cli->auth->auth_type) {
1712 case PIPE_AUTH_TYPE_NONE:
1714 case PIPE_AUTH_TYPE_NTLMSSP:
1715 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1716 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1717 if (!NT_STATUS_IS_OK(ret)) {
1718 prs_mem_free(&outgoing_pdu);
1722 case PIPE_AUTH_TYPE_SCHANNEL:
1723 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1724 if (!NT_STATUS_IS_OK(ret)) {
1725 prs_mem_free(&outgoing_pdu);
1730 smb_panic("bad auth type");
1731 break; /* notreached */
1735 /* Actually send the packet. */
1736 if (flags & RPC_FLG_LAST) {
1737 /* Last packet - send the data, get the reply and return. */
1738 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1739 prs_mem_free(&outgoing_pdu);
1741 if ((DEBUGLEVEL >= 50)
1742 && (cli->transport_type == NCACN_NP)) {
1743 char *dump_name = NULL;
1744 /* Also capture received data */
1745 if (asprintf(&dump_name, "%s/reply_%s_%d",
1746 get_dyn_LOGFILEBASE(),
1747 cli->trans.np.pipe_name, op_num) > 0) {
1748 prs_dump(dump_name, op_num, out_data);
1749 SAFE_FREE(dump_name);
1756 switch (cli->transport_type) {
1758 num_written = cli_write(cli->trans.np.cli,
1760 8, /* 8 means message mode. */
1761 prs_data_p(&outgoing_pdu),
1763 (size_t)hdr.frag_len);
1765 if (num_written != hdr.frag_len) {
1766 prs_mem_free(&outgoing_pdu);
1767 return cli_get_nt_error(cli->trans.np.cli);
1771 case NCACN_UNIX_STREAM:
1772 num_written = write_data(
1774 prs_data_p(&outgoing_pdu),
1775 (size_t)hdr.frag_len);
1776 if (num_written != hdr.frag_len) {
1778 status = map_nt_error_from_unix(errno);
1779 prs_mem_free(&outgoing_pdu);
1784 DEBUG(0, ("unknown transport type %d\n",
1785 cli->transport_type));
1786 return NT_STATUS_INTERNAL_ERROR;
1789 current_data_offset += data_sent_thistime;
1790 data_left -= data_sent_thistime;
1792 /* Reset the marshalling position back to zero. */
1793 if (!prs_set_offset(&outgoing_pdu, 0)) {
1794 prs_mem_free(&outgoing_pdu);
1795 return NT_STATUS_NO_MEMORY;
1800 /****************************************************************************
1801 Set the handle state.
1802 ****************************************************************************/
1804 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1805 const char *pipe_name, uint16 device_state)
1807 bool state_set = False;
1809 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1810 char *rparam = NULL;
1812 uint32 rparam_len, rdata_len;
1814 if (pipe_name == NULL)
1817 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1818 cli->fnum, pipe_name, device_state));
1820 /* create parameters: device state */
1821 SSVAL(param, 0, device_state);
1823 /* create setup parameters. */
1825 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1827 /* send the data on \PIPE\ */
1828 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1829 setup, 2, 0, /* setup, length, max */
1830 param, 2, 0, /* param, length, max */
1831 NULL, 0, 1024, /* data, length, max */
1832 &rparam, &rparam_len, /* return param, length */
1833 &rdata, &rdata_len)) /* return data, length */
1835 DEBUG(5, ("Set Handle state: return OK\n"));
1846 /****************************************************************************
1847 Check the rpc bind acknowledge response.
1848 ****************************************************************************/
1850 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1852 if ( hdr_ba->addr.len == 0) {
1853 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1856 /* check the transfer syntax */
1857 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1858 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1859 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1863 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1864 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1865 hdr_ba->res.num_results, hdr_ba->res.reason));
1868 DEBUG(5,("check_bind_response: accepted!\n"));
1872 /*******************************************************************
1873 Creates a DCE/RPC bind authentication response.
1874 This is the packet that is sent back to the server once we
1875 have received a BIND-ACK, to finish the third leg of
1876 the authentication handshake.
1877 ********************************************************************/
1879 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1881 enum pipe_auth_type auth_type,
1882 enum pipe_auth_level auth_level,
1883 DATA_BLOB *pauth_blob,
1884 prs_struct *rpc_out)
1887 RPC_HDR_AUTH hdr_auth;
1890 /* Create the request RPC_HDR */
1891 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1892 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1893 pauth_blob->length );
1896 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1897 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1898 return NT_STATUS_NO_MEMORY;
1902 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1903 about padding - shouldn't this pad to length 8 ? JRA.
1906 /* 4 bytes padding. */
1907 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1908 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1909 return NT_STATUS_NO_MEMORY;
1912 /* Create the request RPC_HDR_AUTHA */
1913 init_rpc_hdr_auth(&hdr_auth,
1914 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1917 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1918 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1919 return NT_STATUS_NO_MEMORY;
1923 * Append the auth data to the outgoing buffer.
1926 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1927 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1928 return NT_STATUS_NO_MEMORY;
1931 return NT_STATUS_OK;
1934 /****************************************************************************
1935 Create and send the third packet in an RPC auth.
1936 ****************************************************************************/
1938 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1942 enum pipe_auth_type auth_type,
1943 enum pipe_auth_level auth_level)
1945 DATA_BLOB server_response = data_blob_null;
1946 DATA_BLOB client_reply = data_blob_null;
1947 RPC_HDR_AUTH hdr_auth;
1952 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1953 return NT_STATUS_INVALID_PARAMETER;
1956 /* Process the returned NTLMSSP blob first. */
1957 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1958 return NT_STATUS_INVALID_PARAMETER;
1961 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1962 return NT_STATUS_INVALID_PARAMETER;
1965 /* TODO - check auth_type/auth_level match. */
1967 server_response = data_blob(NULL, phdr->auth_len);
1968 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1970 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1974 if (!NT_STATUS_IS_OK(nt_status)) {
1975 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1976 data_blob_free(&server_response);
1980 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1982 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1983 auth_type, auth_level,
1984 &client_reply, &rpc_out);
1986 if (!NT_STATUS_IS_OK(nt_status)) {
1987 prs_mem_free(&rpc_out);
1988 data_blob_free(&client_reply);
1989 data_blob_free(&server_response);
1993 switch (cli->transport_type) {
1995 /* 8 here is named pipe message mode. */
1996 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
1997 0x8, prs_data_p(&rpc_out), 0,
1998 (size_t)prs_offset(&rpc_out));
2001 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2002 nt_status = cli_get_nt_error(cli->trans.np.cli);
2005 case NCACN_UNIX_STREAM:
2006 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
2007 (size_t)prs_offset(&rpc_out));
2008 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2009 nt_status = map_nt_error_from_unix(errno);
2013 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
2014 return NT_STATUS_INTERNAL_ERROR;
2017 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2018 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
2019 nt_errstr(nt_status)));
2020 prs_mem_free(&rpc_out);
2021 data_blob_free(&client_reply);
2022 data_blob_free(&server_response);
2026 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2027 rpccli_pipe_txt(debug_ctx(), cli)));
2029 prs_mem_free(&rpc_out);
2030 data_blob_free(&client_reply);
2031 data_blob_free(&server_response);
2032 return NT_STATUS_OK;
2035 /*******************************************************************
2036 Creates a DCE/RPC bind alter context authentication request which
2037 may contain a spnego auth blobl
2038 ********************************************************************/
2040 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2041 const RPC_IFACE *abstract,
2042 const RPC_IFACE *transfer,
2043 enum pipe_auth_level auth_level,
2044 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2045 prs_struct *rpc_out)
2047 RPC_HDR_AUTH hdr_auth;
2048 prs_struct auth_info;
2049 NTSTATUS ret = NT_STATUS_OK;
2051 ZERO_STRUCT(hdr_auth);
2052 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2053 return NT_STATUS_NO_MEMORY;
2055 /* We may change the pad length before marshalling. */
2056 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2058 if (pauth_blob->length) {
2059 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2060 prs_mem_free(&auth_info);
2061 return NT_STATUS_NO_MEMORY;
2065 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2072 prs_mem_free(&auth_info);
2076 /*******************************************************************
2077 Third leg of the SPNEGO bind mechanism - sends alter context PDU
2078 and gets a response.
2079 ********************************************************************/
2081 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
2085 const RPC_IFACE *abstract,
2086 const RPC_IFACE *transfer,
2087 enum pipe_auth_type auth_type,
2088 enum pipe_auth_level auth_level)
2090 DATA_BLOB server_spnego_response = data_blob_null;
2091 DATA_BLOB server_ntlm_response = data_blob_null;
2092 DATA_BLOB client_reply = data_blob_null;
2093 DATA_BLOB tmp_blob = data_blob_null;
2094 RPC_HDR_AUTH hdr_auth;
2098 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2099 return NT_STATUS_INVALID_PARAMETER;
2102 /* Process the returned NTLMSSP blob first. */
2103 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2104 return NT_STATUS_INVALID_PARAMETER;
2107 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2108 return NT_STATUS_INVALID_PARAMETER;
2111 server_spnego_response = data_blob(NULL, phdr->auth_len);
2112 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2114 /* The server might give us back two challenges - tmp_blob is for the second. */
2115 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2116 data_blob_free(&server_spnego_response);
2117 data_blob_free(&server_ntlm_response);
2118 data_blob_free(&tmp_blob);
2119 return NT_STATUS_INVALID_PARAMETER;
2122 /* We're finished with the server spnego response and the tmp_blob. */
2123 data_blob_free(&server_spnego_response);
2124 data_blob_free(&tmp_blob);
2126 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2127 server_ntlm_response,
2130 /* Finished with the server_ntlm response */
2131 data_blob_free(&server_ntlm_response);
2133 if (!NT_STATUS_IS_OK(nt_status)) {
2134 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2135 data_blob_free(&client_reply);
2139 /* SPNEGO wrap the client reply. */
2140 tmp_blob = spnego_gen_auth(client_reply);
2141 data_blob_free(&client_reply);
2142 client_reply = tmp_blob;
2143 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2145 /* Now prepare the alter context pdu. */
2146 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2148 nt_status = create_rpc_alter_context(rpc_call_id,
2155 data_blob_free(&client_reply);
2157 if (!NT_STATUS_IS_OK(nt_status)) {
2158 prs_mem_free(&rpc_out);
2162 /* Initialize the returning data struct. */
2164 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2166 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2167 if (!NT_STATUS_IS_OK(nt_status)) {
2168 prs_mem_free(&rpc_out);
2172 prs_mem_free(&rpc_out);
2174 /* Get the auth blob from the reply. */
2175 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2176 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2177 return NT_STATUS_BUFFER_TOO_SMALL;
2180 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2181 return NT_STATUS_INVALID_PARAMETER;
2184 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2185 return NT_STATUS_INVALID_PARAMETER;
2188 server_spnego_response = data_blob(NULL, phdr->auth_len);
2189 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2191 /* Check we got a valid auth response. */
2192 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2193 data_blob_free(&server_spnego_response);
2194 data_blob_free(&tmp_blob);
2195 return NT_STATUS_INVALID_PARAMETER;
2198 data_blob_free(&server_spnego_response);
2199 data_blob_free(&tmp_blob);
2201 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2202 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2204 return NT_STATUS_OK;
2207 /****************************************************************************
2209 ****************************************************************************/
2211 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2212 struct cli_pipe_auth_data *auth)
2221 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2222 rpccli_pipe_txt(debug_ctx(), cli),
2223 (unsigned int)auth->auth_type,
2224 (unsigned int)auth->auth_level ));
2226 cli->auth = talloc_move(cli, &auth);
2228 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2230 rpc_call_id = get_rpc_call_id();
2232 /* Marshall the outgoing data. */
2233 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2234 &cli->abstract_syntax,
2235 &cli->transfer_syntax,
2236 cli->auth->auth_type,
2237 cli->auth->auth_level);
2239 if (!NT_STATUS_IS_OK(status)) {
2240 prs_mem_free(&rpc_out);
2244 /* Initialize the incoming data struct. */
2245 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2247 /* send data on \PIPE\. receive a response */
2248 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2249 if (!NT_STATUS_IS_OK(status)) {
2250 prs_mem_free(&rpc_out);
2254 prs_mem_free(&rpc_out);
2256 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2257 rpccli_pipe_txt(debug_ctx(), cli)));
2259 /* Unmarshall the RPC header */
2260 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2261 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2262 prs_mem_free(&rbuf);
2263 return NT_STATUS_BUFFER_TOO_SMALL;
2266 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2267 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2268 prs_mem_free(&rbuf);
2269 return NT_STATUS_BUFFER_TOO_SMALL;
2272 if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) {
2273 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2274 prs_mem_free(&rbuf);
2275 return NT_STATUS_BUFFER_TOO_SMALL;
2278 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2279 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2281 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2282 switch(cli->auth->auth_type) {
2284 case PIPE_AUTH_TYPE_NONE:
2285 case PIPE_AUTH_TYPE_SCHANNEL:
2286 /* Bind complete. */
2289 case PIPE_AUTH_TYPE_NTLMSSP:
2290 /* Need to send AUTH3 packet - no reply. */
2291 status = rpc_finish_auth3_bind(
2292 cli, &hdr, &rbuf, rpc_call_id,
2293 cli->auth->auth_type,
2294 cli->auth->auth_level);
2295 if (!NT_STATUS_IS_OK(status)) {
2296 prs_mem_free(&rbuf);
2301 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2302 /* Need to send alter context request and reply. */
2303 status = rpc_finish_spnego_ntlmssp_bind(
2304 cli, &hdr, &rbuf, rpc_call_id,
2305 &cli->abstract_syntax, &cli->transfer_syntax,
2306 cli->auth->auth_type, cli->auth->auth_level);
2307 if (!NT_STATUS_IS_OK(status)) {
2308 prs_mem_free(&rbuf);
2313 case PIPE_AUTH_TYPE_KRB5:
2317 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2318 "%u\n", (unsigned int)cli->auth->auth_type));
2319 prs_mem_free(&rbuf);
2320 return NT_STATUS_INVALID_INFO_CLASS;
2323 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2324 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2325 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2326 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2327 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2328 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2329 prs_mem_free(&rbuf);
2330 return NT_STATUS_INVALID_PARAMETER;
2333 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2334 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2335 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2336 prs_mem_free(&rbuf);
2337 return NT_STATUS_INVALID_PARAMETER;
2342 prs_mem_free(&rbuf);
2343 return NT_STATUS_OK;
2346 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2347 unsigned int timeout)
2349 return cli_set_timeout(cli->trans.np.cli, timeout);
2352 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2354 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2355 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2356 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2360 if (cli->transport_type == NCACN_NP) {
2361 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2368 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2370 if (p->transport_type == NCACN_NP) {
2371 return p->trans.np.cli;
2376 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2378 if (p->transport_type == NCACN_NP) {
2380 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2382 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2383 "pipe %s. Error was %s\n",
2384 rpccli_pipe_txt(debug_ctx(), p),
2385 cli_errstr(p->trans.np.cli)));
2388 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2389 rpccli_pipe_txt(debug_ctx(), p)));
2391 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2392 return ret ? -1 : 0;
2398 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2399 struct cli_pipe_auth_data **presult)
2401 struct cli_pipe_auth_data *result;
2403 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2404 if (result == NULL) {
2405 return NT_STATUS_NO_MEMORY;
2408 result->auth_type = PIPE_AUTH_TYPE_NONE;
2409 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2411 result->user_name = talloc_strdup(result, "");
2412 result->domain = talloc_strdup(result, "");
2413 if ((result->user_name == NULL) || (result->domain == NULL)) {
2414 TALLOC_FREE(result);
2415 return NT_STATUS_NO_MEMORY;
2419 return NT_STATUS_OK;
2422 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2424 ntlmssp_end(&auth->a_u.ntlmssp_state);
2428 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2429 enum pipe_auth_type auth_type,
2430 enum pipe_auth_level auth_level,
2432 const char *username,
2433 const char *password,
2434 struct cli_pipe_auth_data **presult)
2436 struct cli_pipe_auth_data *result;
2439 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2440 if (result == NULL) {
2441 return NT_STATUS_NO_MEMORY;
2444 result->auth_type = auth_type;
2445 result->auth_level = auth_level;
2447 result->user_name = talloc_strdup(result, username);
2448 result->domain = talloc_strdup(result, domain);
2449 if ((result->user_name == NULL) || (result->domain == NULL)) {
2450 status = NT_STATUS_NO_MEMORY;
2454 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2455 if (!NT_STATUS_IS_OK(status)) {
2459 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2461 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2462 if (!NT_STATUS_IS_OK(status)) {
2466 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2467 if (!NT_STATUS_IS_OK(status)) {
2471 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2472 if (!NT_STATUS_IS_OK(status)) {
2477 * Turn off sign+seal to allow selected auth level to turn it back on.
2479 result->a_u.ntlmssp_state->neg_flags &=
2480 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2482 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2483 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2484 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2485 result->a_u.ntlmssp_state->neg_flags
2486 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2490 return NT_STATUS_OK;
2493 TALLOC_FREE(result);
2497 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2498 enum pipe_auth_level auth_level,
2499 const uint8_t sess_key[16],
2500 struct cli_pipe_auth_data **presult)
2502 struct cli_pipe_auth_data *result;
2504 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2505 if (result == NULL) {
2506 return NT_STATUS_NO_MEMORY;
2509 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2510 result->auth_level = auth_level;
2512 result->user_name = talloc_strdup(result, "");
2513 result->domain = talloc_strdup(result, domain);
2514 if ((result->user_name == NULL) || (result->domain == NULL)) {
2518 result->a_u.schannel_auth = talloc(result,
2519 struct schannel_auth_struct);
2520 if (result->a_u.schannel_auth == NULL) {
2524 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2525 sizeof(result->a_u.schannel_auth->sess_key));
2526 result->a_u.schannel_auth->seq_num = 0;
2529 return NT_STATUS_OK;
2532 TALLOC_FREE(result);
2533 return NT_STATUS_NO_MEMORY;
2537 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2539 data_blob_free(&auth->session_key);
2544 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2545 enum pipe_auth_level auth_level,
2546 const char *service_princ,
2547 const char *username,
2548 const char *password,
2549 struct cli_pipe_auth_data **presult)
2552 struct cli_pipe_auth_data *result;
2554 if ((username != NULL) && (password != NULL)) {
2555 int ret = kerberos_kinit_password(username, password, 0, NULL);
2557 return NT_STATUS_ACCESS_DENIED;
2561 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2562 if (result == NULL) {
2563 return NT_STATUS_NO_MEMORY;
2566 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2567 result->auth_level = auth_level;
2570 * Username / domain need fixing!
2572 result->user_name = talloc_strdup(result, "");
2573 result->domain = talloc_strdup(result, "");
2574 if ((result->user_name == NULL) || (result->domain == NULL)) {
2578 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2579 result, struct kerberos_auth_struct);
2580 if (result->a_u.kerberos_auth == NULL) {
2583 talloc_set_destructor(result->a_u.kerberos_auth,
2584 cli_auth_kerberos_data_destructor);
2586 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2587 result, service_princ);
2588 if (result->a_u.kerberos_auth->service_principal == NULL) {
2593 return NT_STATUS_OK;
2596 TALLOC_FREE(result);
2597 return NT_STATUS_NO_MEMORY;
2599 return NT_STATUS_NOT_SUPPORTED;
2603 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2605 close(p->trans.sock.fd);
2610 * Create an rpc pipe client struct, connecting to a tcp port.
2612 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2614 const struct ndr_syntax_id *abstract_syntax,
2615 struct rpc_pipe_client **presult)
2617 struct rpc_pipe_client *result;
2618 struct sockaddr_storage addr;
2621 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2622 if (result == NULL) {
2623 return NT_STATUS_NO_MEMORY;
2626 result->transport_type = NCACN_IP_TCP;
2628 result->abstract_syntax = *abstract_syntax;
2629 result->transfer_syntax = ndr_transfer_syntax;
2631 result->desthost = talloc_strdup(result, host);
2632 result->srv_name_slash = talloc_asprintf_strupper_m(
2633 result, "\\\\%s", result->desthost);
2634 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2635 status = NT_STATUS_NO_MEMORY;
2639 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2640 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2642 if (!resolve_name(host, &addr, 0)) {
2643 status = NT_STATUS_NOT_FOUND;
2647 status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
2648 if (!NT_STATUS_IS_OK(status)) {
2652 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2655 return NT_STATUS_OK;
2658 TALLOC_FREE(result);
2663 * Determine the tcp port on which a dcerpc interface is listening
2664 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2667 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2668 const struct ndr_syntax_id *abstract_syntax,
2672 struct rpc_pipe_client *epm_pipe = NULL;
2673 struct cli_pipe_auth_data *auth = NULL;
2674 struct dcerpc_binding *map_binding = NULL;
2675 struct dcerpc_binding *res_binding = NULL;
2676 struct epm_twr_t *map_tower = NULL;
2677 struct epm_twr_t *res_towers = NULL;
2678 struct policy_handle *entry_handle = NULL;
2679 uint32_t num_towers = 0;
2680 uint32_t max_towers = 1;
2681 struct epm_twr_p_t towers;
2682 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2684 if (pport == NULL) {
2685 status = NT_STATUS_INVALID_PARAMETER;
2689 /* open the connection to the endpoint mapper */
2690 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2691 &ndr_table_epmapper.syntax_id,
2694 if (!NT_STATUS_IS_OK(status)) {
2698 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2699 if (!NT_STATUS_IS_OK(status)) {
2703 status = rpc_pipe_bind(epm_pipe, auth);
2704 if (!NT_STATUS_IS_OK(status)) {
2708 /* create tower for asking the epmapper */
2710 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2711 if (map_binding == NULL) {
2712 status = NT_STATUS_NO_MEMORY;
2716 map_binding->transport = NCACN_IP_TCP;
2717 map_binding->object = *abstract_syntax;
2718 map_binding->host = host; /* needed? */
2719 map_binding->endpoint = "0"; /* correct? needed? */
2721 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2722 if (map_tower == NULL) {
2723 status = NT_STATUS_NO_MEMORY;
2727 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2728 &(map_tower->tower));
2729 if (!NT_STATUS_IS_OK(status)) {
2733 /* allocate further parameters for the epm_Map call */
2735 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2736 if (res_towers == NULL) {
2737 status = NT_STATUS_NO_MEMORY;
2740 towers.twr = res_towers;
2742 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2743 if (entry_handle == NULL) {
2744 status = NT_STATUS_NO_MEMORY;
2748 /* ask the endpoint mapper for the port */
2750 status = rpccli_epm_Map(epm_pipe,
2752 CONST_DISCARD(struct GUID *,
2753 &(abstract_syntax->uuid)),
2760 if (!NT_STATUS_IS_OK(status)) {
2764 if (num_towers != 1) {
2765 status = NT_STATUS_UNSUCCESSFUL;
2769 /* extract the port from the answer */
2771 status = dcerpc_binding_from_tower(tmp_ctx,
2772 &(towers.twr->tower),
2774 if (!NT_STATUS_IS_OK(status)) {
2778 /* are further checks here necessary? */
2779 if (res_binding->transport != NCACN_IP_TCP) {
2780 status = NT_STATUS_UNSUCCESSFUL;
2784 *pport = (uint16_t)atoi(res_binding->endpoint);
2787 TALLOC_FREE(tmp_ctx);
2792 * Create a rpc pipe client struct, connecting to a host via tcp.
2793 * The port is determined by asking the endpoint mapper on the given
2796 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2797 const struct ndr_syntax_id *abstract_syntax,
2798 struct rpc_pipe_client **presult)
2805 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2806 if (!NT_STATUS_IS_OK(status)) {
2810 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2811 abstract_syntax, presult);
2817 /********************************************************************
2818 Create a rpc pipe client struct, connecting to a unix domain socket
2819 ********************************************************************/
2820 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2821 const struct ndr_syntax_id *abstract_syntax,
2822 struct rpc_pipe_client **presult)
2824 struct rpc_pipe_client *result;
2825 struct sockaddr_un addr;
2828 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2829 if (result == NULL) {
2830 return NT_STATUS_NO_MEMORY;
2833 result->transport_type = NCACN_UNIX_STREAM;
2835 result->abstract_syntax = *abstract_syntax;
2836 result->transfer_syntax = ndr_transfer_syntax;
2838 result->desthost = talloc_get_myname(result);
2839 result->srv_name_slash = talloc_asprintf_strupper_m(
2840 result, "\\\\%s", result->desthost);
2841 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2842 status = NT_STATUS_NO_MEMORY;
2846 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2847 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2849 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2850 if (result->trans.sock.fd == -1) {
2851 status = map_nt_error_from_unix(errno);
2855 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2858 addr.sun_family = AF_UNIX;
2859 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2861 if (sys_connect(result->trans.sock.fd,
2862 (struct sockaddr *)&addr) == -1) {
2863 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2865 close(result->trans.sock.fd);
2866 return map_nt_error_from_unix(errno);
2870 return NT_STATUS_OK;
2873 TALLOC_FREE(result);
2878 /****************************************************************************
2879 Open a named pipe over SMB to a remote server.
2881 * CAVEAT CALLER OF THIS FUNCTION:
2882 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2883 * so be sure that this function is called AFTER any structure (vs pointer)
2884 * assignment of the cli. In particular, libsmbclient does structure
2885 * assignments of cli, which invalidates the data in the returned
2886 * rpc_pipe_client if this function is called before the structure assignment
2889 ****************************************************************************/
2891 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2892 const struct ndr_syntax_id *abstract_syntax,
2893 struct rpc_pipe_client **presult)
2895 struct rpc_pipe_client *result;
2898 /* sanity check to protect against crashes */
2901 return NT_STATUS_INVALID_HANDLE;
2904 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2905 if (result == NULL) {
2906 return NT_STATUS_NO_MEMORY;
2909 result->transport_type = NCACN_NP;
2911 result->trans.np.pipe_name = cli_get_pipe_name_from_iface(
2912 result, cli, abstract_syntax);
2913 if (result->trans.np.pipe_name == NULL) {
2914 DEBUG(1, ("Could not find pipe for interface\n"));
2915 TALLOC_FREE(result);
2916 return NT_STATUS_INVALID_PARAMETER;
2919 result->trans.np.cli = cli;
2920 result->abstract_syntax = *abstract_syntax;
2921 result->transfer_syntax = ndr_transfer_syntax;
2922 result->desthost = talloc_strdup(result, cli->desthost);
2923 result->srv_name_slash = talloc_asprintf_strupper_m(
2924 result, "\\\\%s", result->desthost);
2926 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2927 TALLOC_FREE(result);
2928 return NT_STATUS_NO_MEMORY;
2931 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2932 DESIRED_ACCESS_PIPE);
2934 DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
2935 "to machine %s. Error was %s\n",
2936 result->trans.np.pipe_name, cli->desthost,
2938 TALLOC_FREE(result);
2939 return cli_get_nt_error(cli);
2942 result->trans.np.fnum = fnum;
2944 DLIST_ADD(cli->pipe_list, result);
2945 talloc_set_destructor(result, rpc_pipe_destructor);
2948 return NT_STATUS_OK;
2951 /****************************************************************************
2952 Open a pipe to a remote server.
2953 ****************************************************************************/
2955 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2956 const struct ndr_syntax_id *interface,
2957 struct rpc_pipe_client **presult)
2959 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
2961 * We should have a better way to figure out this drsuapi
2964 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2968 return rpc_pipe_open_np(cli, interface, presult);
2971 /****************************************************************************
2972 Open a named pipe to an SMB server and bind anonymously.
2973 ****************************************************************************/
2975 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2976 const struct ndr_syntax_id *interface,
2977 struct rpc_pipe_client **presult)
2979 struct rpc_pipe_client *result;
2980 struct cli_pipe_auth_data *auth;
2983 status = cli_rpc_pipe_open(cli, interface, &result);
2984 if (!NT_STATUS_IS_OK(status)) {
2988 status = rpccli_anon_bind_data(result, &auth);
2989 if (!NT_STATUS_IS_OK(status)) {
2990 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2991 nt_errstr(status)));
2992 TALLOC_FREE(result);
2997 * This is a bit of an abstraction violation due to the fact that an
2998 * anonymous bind on an authenticated SMB inherits the user/domain
2999 * from the enclosing SMB creds
3002 TALLOC_FREE(auth->user_name);
3003 TALLOC_FREE(auth->domain);
3005 auth->user_name = talloc_strdup(auth, cli->user_name);
3006 auth->domain = talloc_strdup(auth, cli->domain);
3007 auth->user_session_key = data_blob_talloc(auth,
3008 cli->user_session_key.data,
3009 cli->user_session_key.length);
3011 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3012 TALLOC_FREE(result);
3013 return NT_STATUS_NO_MEMORY;
3016 status = rpc_pipe_bind(result, auth);
3017 if (!NT_STATUS_IS_OK(status)) {
3019 if (ndr_syntax_id_equal(interface,
3020 &ndr_table_dssetup.syntax_id)) {
3021 /* non AD domains just don't have this pipe, avoid
3022 * level 0 statement in that case - gd */
3025 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3026 "%s failed with error %s\n",
3027 cli_get_pipe_name_from_iface(debug_ctx(), cli,
3029 nt_errstr(status) ));
3030 TALLOC_FREE(result);
3034 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3035 "%s and bound anonymously.\n", result->trans.np.pipe_name,
3039 return NT_STATUS_OK;
3042 /****************************************************************************
3043 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3044 ****************************************************************************/
3046 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3047 const struct ndr_syntax_id *interface,
3048 enum pipe_auth_type auth_type,
3049 enum pipe_auth_level auth_level,
3051 const char *username,
3052 const char *password,
3053 struct rpc_pipe_client **presult)
3055 struct rpc_pipe_client *result;
3056 struct cli_pipe_auth_data *auth;
3059 status = cli_rpc_pipe_open(cli, interface, &result);
3060 if (!NT_STATUS_IS_OK(status)) {
3064 status = rpccli_ntlmssp_bind_data(
3065 result, auth_type, auth_level, domain, username,
3066 cli->pwd.null_pwd ? NULL : password, &auth);
3067 if (!NT_STATUS_IS_OK(status)) {
3068 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3069 nt_errstr(status)));
3073 status = rpc_pipe_bind(result, auth);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3076 nt_errstr(status) ));
3080 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3081 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3082 result->trans.np.pipe_name, cli->desthost,
3083 domain, username ));
3086 return NT_STATUS_OK;
3090 TALLOC_FREE(result);
3094 /****************************************************************************
3096 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3097 ****************************************************************************/
3099 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3100 const struct ndr_syntax_id *interface,
3101 enum pipe_auth_level auth_level,
3103 const char *username,
3104 const char *password,
3105 struct rpc_pipe_client **presult)
3107 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3109 PIPE_AUTH_TYPE_NTLMSSP,
3117 /****************************************************************************
3119 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3120 ****************************************************************************/
3122 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3123 const struct ndr_syntax_id *interface,
3124 enum pipe_auth_level auth_level,
3126 const char *username,
3127 const char *password,
3128 struct rpc_pipe_client **presult)
3130 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3132 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3140 /****************************************************************************
3141 Get a the schannel session key out of an already opened netlogon pipe.
3142 ****************************************************************************/
3143 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3144 struct cli_state *cli,
3148 uint32 sec_chan_type = 0;
3149 unsigned char machine_pwd[16];
3150 const char *machine_account;
3153 /* Get the machine account credentials from secrets.tdb. */
3154 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3157 DEBUG(0, ("get_schannel_session_key: could not fetch "
3158 "trust account password for domain '%s'\n",
3160 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3163 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3164 cli->desthost, /* server name */
3165 domain, /* domain */
3166 global_myname(), /* client name */
3167 machine_account, /* machine account name */
3172 if (!NT_STATUS_IS_OK(status)) {
3173 DEBUG(3, ("get_schannel_session_key_common: "
3174 "rpccli_netlogon_setup_creds failed with result %s "
3175 "to server %s, domain %s, machine account %s.\n",
3176 nt_errstr(status), cli->desthost, domain,
3181 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3182 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3184 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3187 return NT_STATUS_OK;;
3190 /****************************************************************************
3191 Open a netlogon pipe and get the schannel session key.
3192 Now exposed to external callers.
3193 ****************************************************************************/
3196 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3199 struct rpc_pipe_client **presult)
3201 struct rpc_pipe_client *netlogon_pipe = NULL;
3204 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3206 if (!NT_STATUS_IS_OK(status)) {
3210 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3212 if (!NT_STATUS_IS_OK(status)) {
3213 TALLOC_FREE(netlogon_pipe);
3217 *presult = netlogon_pipe;
3218 return NT_STATUS_OK;
3221 /****************************************************************************
3223 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3224 using session_key. sign and seal.
3225 ****************************************************************************/
3227 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3228 const struct ndr_syntax_id *interface,
3229 enum pipe_auth_level auth_level,
3231 const struct dcinfo *pdc,
3232 struct rpc_pipe_client **presult)
3234 struct rpc_pipe_client *result;
3235 struct cli_pipe_auth_data *auth;
3238 status = cli_rpc_pipe_open(cli, interface, &result);
3239 if (!NT_STATUS_IS_OK(status)) {
3243 status = rpccli_schannel_bind_data(result, domain, auth_level,
3244 pdc->sess_key, &auth);
3245 if (!NT_STATUS_IS_OK(status)) {
3246 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3247 nt_errstr(status)));
3248 TALLOC_FREE(result);
3252 status = rpc_pipe_bind(result, auth);
3253 if (!NT_STATUS_IS_OK(status)) {
3254 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3255 "cli_rpc_pipe_bind failed with error %s\n",
3256 nt_errstr(status) ));
3257 TALLOC_FREE(result);
3262 * The credentials on a new netlogon pipe are the ones we are passed
3263 * in - copy them over.
3265 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3266 if (result->dc == NULL) {
3267 DEBUG(0, ("talloc failed\n"));
3268 TALLOC_FREE(result);
3269 return NT_STATUS_NO_MEMORY;
3272 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3274 "and bound using schannel.\n",
3275 result->trans.np.pipe_name, cli->desthost, domain ));
3278 return NT_STATUS_OK;
3281 /****************************************************************************
3282 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3283 Fetch the session key ourselves using a temporary netlogon pipe. This
3284 version uses an ntlmssp auth bound netlogon pipe to get the key.
3285 ****************************************************************************/
3287 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3289 const char *username,
3290 const char *password,
3292 struct rpc_pipe_client **presult)
3294 struct rpc_pipe_client *netlogon_pipe = NULL;
3297 status = cli_rpc_pipe_open_spnego_ntlmssp(
3298 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3299 domain, username, password, &netlogon_pipe);
3300 if (!NT_STATUS_IS_OK(status)) {
3304 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3306 if (!NT_STATUS_IS_OK(status)) {
3307 TALLOC_FREE(netlogon_pipe);
3311 *presult = netlogon_pipe;
3312 return NT_STATUS_OK;
3315 /****************************************************************************
3316 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3317 Fetch the session key ourselves using a temporary netlogon pipe. This version
3318 uses an ntlmssp bind to get the session key.
3319 ****************************************************************************/
3321 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3322 const struct ndr_syntax_id *interface,
3323 enum pipe_auth_level auth_level,
3325 const char *username,
3326 const char *password,
3327 struct rpc_pipe_client **presult)
3329 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3330 struct rpc_pipe_client *netlogon_pipe = NULL;
3331 struct rpc_pipe_client *result = NULL;
3334 status = get_schannel_session_key_auth_ntlmssp(
3335 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3336 if (!NT_STATUS_IS_OK(status)) {
3337 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3338 "key from server %s for domain %s.\n",
3339 cli->desthost, domain ));
3343 status = cli_rpc_pipe_open_schannel_with_key(
3344 cli, interface, auth_level, domain, netlogon_pipe->dc,
3347 /* Now we've bound using the session key we can close the netlog pipe. */
3348 TALLOC_FREE(netlogon_pipe);
3350 if (NT_STATUS_IS_OK(status)) {
3356 /****************************************************************************
3357 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3358 Fetch the session key ourselves using a temporary netlogon pipe.
3359 ****************************************************************************/
3361 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3362 const struct ndr_syntax_id *interface,
3363 enum pipe_auth_level auth_level,
3365 struct rpc_pipe_client **presult)
3367 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3368 struct rpc_pipe_client *netlogon_pipe = NULL;
3369 struct rpc_pipe_client *result = NULL;
3372 status = get_schannel_session_key(cli, domain, &neg_flags,
3374 if (!NT_STATUS_IS_OK(status)) {
3375 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3376 "key from server %s for domain %s.\n",
3377 cli->desthost, domain ));
3381 status = cli_rpc_pipe_open_schannel_with_key(
3382 cli, interface, auth_level, domain, netlogon_pipe->dc,
3385 /* Now we've bound using the session key we can close the netlog pipe. */
3386 TALLOC_FREE(netlogon_pipe);
3388 if (NT_STATUS_IS_OK(status)) {
3392 return NT_STATUS_OK;
3395 /****************************************************************************
3396 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3397 The idea is this can be called with service_princ, username and password all
3398 NULL so long as the caller has a TGT.
3399 ****************************************************************************/
3401 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3402 const struct ndr_syntax_id *interface,
3403 enum pipe_auth_level auth_level,
3404 const char *service_princ,
3405 const char *username,
3406 const char *password,
3407 struct rpc_pipe_client **presult)
3410 struct rpc_pipe_client *result;
3411 struct cli_pipe_auth_data *auth;
3414 status = cli_rpc_pipe_open(cli, interface, &result);
3415 if (!NT_STATUS_IS_OK(status)) {
3419 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3420 username, password, &auth);
3421 if (!NT_STATUS_IS_OK(status)) {
3422 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3423 nt_errstr(status)));
3424 TALLOC_FREE(result);
3428 status = rpc_pipe_bind(result, auth);
3429 if (!NT_STATUS_IS_OK(status)) {
3430 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3431 "with error %s\n", nt_errstr(status)));
3432 TALLOC_FREE(result);
3437 return NT_STATUS_OK;
3439 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3440 return NT_STATUS_NOT_IMPLEMENTED;
3444 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3445 struct rpc_pipe_client *cli,
3446 DATA_BLOB *session_key)
3448 if (!session_key || !cli) {
3449 return NT_STATUS_INVALID_PARAMETER;
3453 return NT_STATUS_INVALID_PARAMETER;
3456 switch (cli->auth->auth_type) {
3457 case PIPE_AUTH_TYPE_SCHANNEL:
3458 *session_key = data_blob_talloc(mem_ctx,
3459 cli->auth->a_u.schannel_auth->sess_key, 16);
3461 case PIPE_AUTH_TYPE_NTLMSSP:
3462 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3463 *session_key = data_blob_talloc(mem_ctx,
3464 cli->auth->a_u.ntlmssp_state->session_key.data,
3465 cli->auth->a_u.ntlmssp_state->session_key.length);
3467 case PIPE_AUTH_TYPE_KRB5:
3468 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3469 *session_key = data_blob_talloc(mem_ctx,
3470 cli->auth->a_u.kerberos_auth->session_key.data,
3471 cli->auth->a_u.kerberos_auth->session_key.length);
3473 case PIPE_AUTH_TYPE_NONE:
3474 *session_key = data_blob_talloc(mem_ctx,
3475 cli->auth->user_session_key.data,
3476 cli->auth->user_session_key.length);
3479 return NT_STATUS_NO_USER_SESSION_KEY;
3482 return NT_STATUS_OK;