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, size_t size,
184 num_read = cli_read(cli, fnum, buf, 0, size);
186 DEBUG(5,("rpc_read_np: num_read = %d, to read: %u\n", (int)num_read,
187 (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 * Realloc pdu to have a least "size" bytes
230 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
234 if (prs_data_size(pdu) >= size) {
238 extra_size = size - prs_data_size(pdu);
240 if (!prs_force_grow(pdu, extra_size)) {
241 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
242 "%d bytes.\n", (int)extra_size));
246 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
247 (int)extra_size, prs_data_size(pdu)));
252 /*******************************************************************
253 Use SMBreadX to get rest of one fragment's worth of rpc data.
254 ********************************************************************/
256 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
257 prs_struct *current_pdu,
259 uint32 *current_pdu_offset)
261 size_t size = (size_t)cli->max_recv_frag;
262 uint32 stream_offset = 0;
263 ssize_t num_read = 0;
266 DEBUG(5, ("rpc_read: data_to_read: %u current_pdu offset: %d\n",
267 (unsigned int)data_to_read,
268 (unsigned int)*current_pdu_offset));
270 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
275 /* read data using SMBreadX */
276 if (size > (size_t)data_to_read) {
277 size = (size_t)data_to_read;
280 switch (cli->transport_type) {
282 status = rpc_read_np(cli->trans.np.cli,
283 cli->trans.np.pipe_name,
284 cli->trans.np.fnum, pdata,
288 case NCACN_UNIX_STREAM:
289 status = NT_STATUS_OK;
290 num_read = sys_read(cli->trans.sock.fd, pdata, size);
291 if (num_read == -1) {
292 status = map_nt_error_from_unix(errno);
295 status = NT_STATUS_END_OF_FILE;
299 DEBUG(0, ("unknown transport type %d\n",
300 cli->transport_type));
301 return NT_STATUS_INTERNAL_ERROR;
304 data_to_read -= num_read;
305 stream_offset += num_read;
308 } while (num_read > 0 && data_to_read > 0);
309 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
312 * Update the current offset into current_pdu by the amount read.
314 *current_pdu_offset += stream_offset;
318 /****************************************************************************
319 Try and get a PDU's worth of data from current_pdu. If not, then read more
321 ****************************************************************************/
323 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
325 NTSTATUS ret = NT_STATUS_OK;
326 uint32 current_pdu_len = prs_data_size(current_pdu);
328 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
329 if (current_pdu_len < RPC_HEADER_LEN) {
330 if (!rpc_grow_buffer(current_pdu, RPC_HEADER_LEN)) {
331 return NT_STATUS_NO_MEMORY;
333 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, ¤t_pdu_len);
334 if (!NT_STATUS_IS_OK(ret)) {
339 /* This next call sets the endian bit correctly in current_pdu. */
340 /* We will propagate this to rbuf later. */
341 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
342 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
343 return NT_STATUS_BUFFER_TOO_SMALL;
346 /* Ensure we have frag_len bytes of data. */
347 if (current_pdu_len < prhdr->frag_len) {
348 if (!rpc_grow_buffer(current_pdu, prhdr->frag_len)) {
349 return NT_STATUS_NO_MEMORY;
351 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, ¤t_pdu_len);
352 if (!NT_STATUS_IS_OK(ret)) {
357 if (current_pdu_len < prhdr->frag_len) {
358 return NT_STATUS_BUFFER_TOO_SMALL;
364 /****************************************************************************
365 NTLMSSP specific sign/seal.
366 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
367 In fact I should probably abstract these into identical pieces of code... JRA.
368 ****************************************************************************/
370 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
371 prs_struct *current_pdu,
372 uint8 *p_ss_padding_len)
374 RPC_HDR_AUTH auth_info;
375 uint32 save_offset = prs_offset(current_pdu);
376 uint32 auth_len = prhdr->auth_len;
377 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
378 unsigned char *data = NULL;
380 unsigned char *full_packet_data = NULL;
381 size_t full_packet_data_len;
385 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
386 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
390 if (!ntlmssp_state) {
391 return NT_STATUS_INVALID_PARAMETER;
394 /* Ensure there's enough data for an authenticated response. */
395 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
396 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
397 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
398 (unsigned int)auth_len ));
399 return NT_STATUS_BUFFER_TOO_SMALL;
403 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
404 * after the RPC header.
405 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
406 * functions as NTLMv2 checks the rpc headers also.
409 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
410 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
412 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
413 full_packet_data_len = prhdr->frag_len - auth_len;
415 /* Pull the auth header and the following data into a blob. */
416 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
417 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
418 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
419 return NT_STATUS_BUFFER_TOO_SMALL;
422 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
423 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
424 return NT_STATUS_BUFFER_TOO_SMALL;
427 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
428 auth_blob.length = auth_len;
430 switch (cli->auth->auth_level) {
431 case PIPE_AUTH_LEVEL_PRIVACY:
432 /* Data is encrypted. */
433 status = ntlmssp_unseal_packet(ntlmssp_state,
436 full_packet_data_len,
438 if (!NT_STATUS_IS_OK(status)) {
439 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
440 "packet from %s. Error was %s.\n",
441 rpccli_pipe_txt(debug_ctx(), cli),
442 nt_errstr(status) ));
446 case PIPE_AUTH_LEVEL_INTEGRITY:
447 /* Data is signed. */
448 status = ntlmssp_check_packet(ntlmssp_state,
451 full_packet_data_len,
453 if (!NT_STATUS_IS_OK(status)) {
454 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
455 "packet from %s. Error was %s.\n",
456 rpccli_pipe_txt(debug_ctx(), cli),
457 nt_errstr(status) ));
462 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
463 "auth level %d\n", cli->auth->auth_level));
464 return NT_STATUS_INVALID_INFO_CLASS;
468 * Return the current pointer to the data offset.
471 if(!prs_set_offset(current_pdu, save_offset)) {
472 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
473 (unsigned int)save_offset ));
474 return NT_STATUS_BUFFER_TOO_SMALL;
478 * Remember the padding length. We must remove it from the real data
479 * stream once the sign/seal is done.
482 *p_ss_padding_len = auth_info.auth_pad_len;
487 /****************************************************************************
488 schannel specific sign/seal.
489 ****************************************************************************/
491 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
492 prs_struct *current_pdu,
493 uint8 *p_ss_padding_len)
495 RPC_HDR_AUTH auth_info;
496 RPC_AUTH_SCHANNEL_CHK schannel_chk;
497 uint32 auth_len = prhdr->auth_len;
498 uint32 save_offset = prs_offset(current_pdu);
499 struct schannel_auth_struct *schannel_auth =
500 cli->auth->a_u.schannel_auth;
503 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
504 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
508 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
509 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
510 return NT_STATUS_INVALID_PARAMETER;
513 if (!schannel_auth) {
514 return NT_STATUS_INVALID_PARAMETER;
517 /* Ensure there's enough data for an authenticated response. */
518 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
519 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
520 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
521 (unsigned int)auth_len ));
522 return NT_STATUS_INVALID_PARAMETER;
525 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
527 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
528 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
529 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
530 return NT_STATUS_BUFFER_TOO_SMALL;
533 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
534 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
535 return NT_STATUS_BUFFER_TOO_SMALL;
538 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
539 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
540 auth_info.auth_type));
541 return NT_STATUS_BUFFER_TOO_SMALL;
544 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
545 &schannel_chk, current_pdu, 0)) {
546 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
547 return NT_STATUS_BUFFER_TOO_SMALL;
550 if (!schannel_decode(schannel_auth,
551 cli->auth->auth_level,
554 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
556 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
557 "Connection to %s.\n",
558 rpccli_pipe_txt(debug_ctx(), cli)));
559 return NT_STATUS_INVALID_PARAMETER;
562 /* The sequence number gets incremented on both send and receive. */
563 schannel_auth->seq_num++;
566 * Return the current pointer to the data offset.
569 if(!prs_set_offset(current_pdu, save_offset)) {
570 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
571 (unsigned int)save_offset ));
572 return NT_STATUS_BUFFER_TOO_SMALL;
576 * Remember the padding length. We must remove it from the real data
577 * stream once the sign/seal is done.
580 *p_ss_padding_len = auth_info.auth_pad_len;
585 /****************************************************************************
586 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
587 ****************************************************************************/
589 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
590 prs_struct *current_pdu,
591 uint8 *p_ss_padding_len)
593 NTSTATUS ret = NT_STATUS_OK;
595 /* Paranioa checks for auth_len. */
596 if (prhdr->auth_len) {
597 if (prhdr->auth_len > prhdr->frag_len) {
598 return NT_STATUS_INVALID_PARAMETER;
601 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
602 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
603 /* Integer wrap attempt. */
604 return NT_STATUS_INVALID_PARAMETER;
609 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
612 switch(cli->auth->auth_type) {
613 case PIPE_AUTH_TYPE_NONE:
614 if (prhdr->auth_len) {
615 DEBUG(3, ("cli_pipe_validate_rpc_response: "
616 "Connection to %s - got non-zero "
618 rpccli_pipe_txt(debug_ctx(), cli),
619 (unsigned int)prhdr->auth_len ));
620 return NT_STATUS_INVALID_PARAMETER;
624 case PIPE_AUTH_TYPE_NTLMSSP:
625 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
626 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
627 if (!NT_STATUS_IS_OK(ret)) {
632 case PIPE_AUTH_TYPE_SCHANNEL:
633 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
634 if (!NT_STATUS_IS_OK(ret)) {
639 case PIPE_AUTH_TYPE_KRB5:
640 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
642 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
643 "to %s - unknown internal auth type %u.\n",
644 rpccli_pipe_txt(debug_ctx(), cli),
645 cli->auth->auth_type ));
646 return NT_STATUS_INVALID_INFO_CLASS;
652 /****************************************************************************
653 Do basic authentication checks on an incoming pdu.
654 ****************************************************************************/
656 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
657 prs_struct *current_pdu,
658 uint8 expected_pkt_type,
661 prs_struct *return_data)
664 NTSTATUS ret = NT_STATUS_OK;
665 uint32 current_pdu_len = prs_data_size(current_pdu);
667 if (current_pdu_len != prhdr->frag_len) {
668 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
669 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
670 return NT_STATUS_INVALID_PARAMETER;
674 * Point the return values at the real data including the RPC
675 * header. Just in case the caller wants it.
677 *ppdata = prs_data_p(current_pdu);
678 *pdata_len = current_pdu_len;
680 /* Ensure we have the correct type. */
681 switch (prhdr->pkt_type) {
682 case RPC_ALTCONTRESP:
685 /* Alter context and bind ack share the same packet definitions. */
691 RPC_HDR_RESP rhdr_resp;
692 uint8 ss_padding_len = 0;
694 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
695 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
696 return NT_STATUS_BUFFER_TOO_SMALL;
699 /* Here's where we deal with incoming sign/seal. */
700 ret = cli_pipe_validate_rpc_response(cli, prhdr,
701 current_pdu, &ss_padding_len);
702 if (!NT_STATUS_IS_OK(ret)) {
706 /* Point the return values at the NDR data. Remember to remove any ss padding. */
707 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
709 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
710 return NT_STATUS_BUFFER_TOO_SMALL;
713 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
715 /* Remember to remove the auth footer. */
716 if (prhdr->auth_len) {
717 /* We've already done integer wrap tests on auth_len in
718 cli_pipe_validate_rpc_response(). */
719 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
720 return NT_STATUS_BUFFER_TOO_SMALL;
722 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
725 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
726 current_pdu_len, *pdata_len, ss_padding_len ));
729 * If this is the first reply, and the allocation hint is reasonably, try and
730 * set up the return_data parse_struct to the correct size.
733 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
734 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
735 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
736 "too large to allocate\n",
737 (unsigned int)rhdr_resp.alloc_hint ));
738 return NT_STATUS_NO_MEMORY;
746 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
747 "received from %s!\n",
748 rpccli_pipe_txt(debug_ctx(), cli)));
749 /* Use this for now... */
750 return NT_STATUS_NETWORK_ACCESS_DENIED;
754 RPC_HDR_RESP rhdr_resp;
755 RPC_HDR_FAULT fault_resp;
757 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
758 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
759 return NT_STATUS_BUFFER_TOO_SMALL;
762 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
763 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
764 return NT_STATUS_BUFFER_TOO_SMALL;
767 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
768 "code %s received from %s!\n",
769 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
770 rpccli_pipe_txt(debug_ctx(), cli)));
771 if (NT_STATUS_IS_OK(fault_resp.status)) {
772 return NT_STATUS_UNSUCCESSFUL;
774 return fault_resp.status;
779 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
781 (unsigned int)prhdr->pkt_type,
782 rpccli_pipe_txt(debug_ctx(), cli)));
783 return NT_STATUS_INVALID_INFO_CLASS;
786 if (prhdr->pkt_type != expected_pkt_type) {
787 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
788 "got an unexpected RPC packet type - %u, not %u\n",
789 rpccli_pipe_txt(debug_ctx(), cli),
792 return NT_STATUS_INVALID_INFO_CLASS;
795 /* Do this just before return - we don't want to modify any rpc header
796 data before now as we may have needed to do cryptographic actions on
799 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
800 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
801 "setting fragment first/last ON.\n"));
802 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
808 /****************************************************************************
809 Ensure we eat the just processed pdu from the current_pdu prs_struct.
810 Normally the frag_len and buffer size will match, but on the first trans
811 reply there is a theoretical chance that buffer size > frag_len, so we must
813 ****************************************************************************/
815 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
817 uint32 current_pdu_len = prs_data_size(current_pdu);
819 if (current_pdu_len < prhdr->frag_len) {
820 return NT_STATUS_BUFFER_TOO_SMALL;
824 if (current_pdu_len == (uint32)prhdr->frag_len) {
825 prs_mem_free(current_pdu);
826 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
827 /* Make current_pdu dynamic with no memory. */
828 prs_give_memory(current_pdu, 0, 0, True);
833 * Oh no ! More data in buffer than we processed in current pdu.
834 * Cheat. Move the data down and shrink the buffer.
837 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
838 current_pdu_len - prhdr->frag_len);
840 /* Remember to set the read offset back to zero. */
841 prs_set_offset(current_pdu, 0);
843 /* Shrink the buffer. */
844 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
845 return NT_STATUS_BUFFER_TOO_SMALL;
851 /****************************************************************************
852 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
853 ****************************************************************************/
855 static bool cli_api_pipe(struct cli_state *cli, const char *pipe_name,
856 uint16 *setup, uint32 setup_count,
857 uint32 max_setup_count,
858 char *params, uint32 param_count,
859 uint32 max_param_count,
860 char *data, uint32 data_count,
861 uint32 max_data_count,
862 char **rparam, uint32 *rparam_count,
863 char **rdata, uint32 *rdata_count)
865 cli_send_trans(cli, SMBtrans,
867 0,0, /* fid, flags */
868 setup, setup_count, max_setup_count,
869 params, param_count, max_param_count,
870 data, data_count, max_data_count);
872 return (cli_receive_trans(cli, SMBtrans,
873 rparam, (unsigned int *)rparam_count,
874 rdata, (unsigned int *)rdata_count));
877 /****************************************************************************
878 Send data on an rpc pipe via trans. The prs_struct data must be the last
879 pdu fragment of an NDR data stream.
881 Receive response data from an rpc pipe, which may be large...
883 Read the first fragment: unfortunately have to use SMBtrans for the first
884 bit, then SMBreadX for subsequent bits.
886 If first fragment received also wasn't the last fragment, continue
887 getting fragments until we _do_ receive the last fragment.
889 Request/Response PDU's look like the following...
891 |<------------------PDU len----------------------------------------------->|
892 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
894 +------------+-----------------+-------------+---------------+-------------+
895 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
896 +------------+-----------------+-------------+---------------+-------------+
898 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
899 signing & sealing being negotiated.
901 ****************************************************************************/
903 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
904 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
905 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
906 uint8 expected_pkt_type)
908 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
910 uint32 rparam_len = 0;
911 char *pdata = prs_data_p(data);
912 uint32 data_len = prs_offset(data);
914 uint32 rdata_len = 0;
915 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
916 uint32 current_rbuf_offset = 0;
917 prs_struct current_pdu;
920 /* Ensure we're not sending too much. */
921 SMB_ASSERT(data_len <= max_data);
924 /* Set up the current pdu parse struct. */
925 prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
927 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
929 switch (cli->transport_type) {
932 /* Create setup parameters - must be in native byte order. */
933 setup[0] = TRANSACT_DCERPCCMD;
934 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
937 * Send the last (or only) fragment of an RPC request. For
938 * small amounts of data (about 1024 bytes or so) the RPC
939 * request and response appears in a SMBtrans request and
943 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
944 setup, 2, 0, /* Setup, length, max */
945 NULL, 0, 0, /* Params, length, max */
946 pdata, data_len, max_data, /* data, length,
948 &rparam, &rparam_len, /* return params,
950 &prdata, &rdata_len)) /* return data, len */
952 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
954 rpccli_pipe_txt(debug_ctx(), cli),
955 cli_errstr(cli->trans.np.cli)));
956 ret = cli_get_nt_error(cli->trans.np.cli);
964 case NCACN_UNIX_STREAM:
966 ssize_t nwritten, nread;
967 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
968 if (nwritten == -1) {
969 ret = map_nt_error_from_unix(errno);
970 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
975 prdata = SMB_MALLOC_ARRAY(char, 1);
976 if (prdata == NULL) {
977 return NT_STATUS_NO_MEMORY;
979 nread = sys_read(cli->trans.sock.fd, prdata, 1);
984 ret = NT_STATUS_END_OF_FILE;
991 DEBUG(0, ("unknown transport type %d\n",
992 cli->transport_type));
993 return NT_STATUS_INTERNAL_ERROR;
996 /* Throw away returned params - we know we won't use them. */
1000 if (prdata == NULL) {
1001 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1002 rpccli_pipe_txt(debug_ctx(), cli)));
1003 /* Yes - some calls can truely return no data... */
1004 prs_mem_free(¤t_pdu);
1005 return NT_STATUS_OK;
1009 * Give this memory as dynamic to the current pdu.
1012 prs_give_memory(¤t_pdu, prdata, rdata_len, True);
1014 /* Ensure we can mess with the return prs_struct. */
1015 SMB_ASSERT(UNMARSHALLING(rbuf));
1016 SMB_ASSERT(prs_data_size(rbuf) == 0);
1018 /* Make rbuf dynamic with no memory. */
1019 prs_give_memory(rbuf, 0, 0, True);
1023 char *ret_data = NULL;
1024 uint32 ret_data_len = 0;
1026 /* Ensure we have enough data for a pdu. */
1027 ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu);
1028 if (!NT_STATUS_IS_OK(ret)) {
1032 /* We pass in rbuf here so if the alloc hint is set correctly
1033 we can set the output size and avoid reallocs. */
1035 ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type,
1036 &ret_data, &ret_data_len, rbuf);
1038 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
1039 prs_data_size(¤t_pdu), current_rbuf_offset ));
1041 if (!NT_STATUS_IS_OK(ret)) {
1045 if ((rhdr.flags & RPC_FLG_FIRST)) {
1046 if (rhdr.pack_type[0] == 0) {
1047 /* Set the data type correctly for big-endian data on the first packet. */
1048 DEBUG(10,("rpc_api_pipe: On %s "
1049 "PDU data format is big-endian.\n",
1050 rpccli_pipe_txt(debug_ctx(), cli)));
1052 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
1054 /* Check endianness on subsequent packets. */
1055 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
1056 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1057 rbuf->bigendian_data ? "big" : "little",
1058 current_pdu.bigendian_data ? "big" : "little" ));
1059 ret = NT_STATUS_INVALID_PARAMETER;
1065 /* Now copy the data portion out of the pdu into rbuf. */
1066 if (!prs_force_grow(rbuf, ret_data_len)) {
1067 ret = NT_STATUS_NO_MEMORY;
1070 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
1071 current_rbuf_offset += ret_data_len;
1073 /* See if we've finished with all the data in current_pdu yet ? */
1074 ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu);
1075 if (!NT_STATUS_IS_OK(ret)) {
1079 if (rhdr.flags & RPC_FLG_LAST) {
1080 break; /* We're done. */
1084 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1085 rpccli_pipe_txt(debug_ctx(), cli),
1086 (unsigned int)prs_data_size(rbuf) ));
1088 prs_mem_free(¤t_pdu);
1089 return NT_STATUS_OK;
1093 prs_mem_free(¤t_pdu);
1098 /*******************************************************************
1099 Creates krb5 auth bind.
1100 ********************************************************************/
1102 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1103 enum pipe_auth_level auth_level,
1104 RPC_HDR_AUTH *pauth_out,
1105 prs_struct *auth_data)
1109 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1110 DATA_BLOB tkt = data_blob_null;
1111 DATA_BLOB tkt_wrapped = data_blob_null;
1113 /* We may change the pad length before marshalling. */
1114 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1116 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1117 a->service_principal ));
1119 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1121 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1122 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1125 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1127 a->service_principal,
1128 error_message(ret) ));
1130 data_blob_free(&tkt);
1131 prs_mem_free(auth_data);
1132 return NT_STATUS_INVALID_PARAMETER;
1135 /* wrap that up in a nice GSS-API wrapping */
1136 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1138 data_blob_free(&tkt);
1140 /* Auth len in the rpc header doesn't include auth_header. */
1141 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1142 data_blob_free(&tkt_wrapped);
1143 prs_mem_free(auth_data);
1144 return NT_STATUS_NO_MEMORY;
1147 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1148 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1150 data_blob_free(&tkt_wrapped);
1151 return NT_STATUS_OK;
1153 return NT_STATUS_INVALID_PARAMETER;
1157 /*******************************************************************
1158 Creates SPNEGO NTLMSSP auth bind.
1159 ********************************************************************/
1161 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1162 enum pipe_auth_level auth_level,
1163 RPC_HDR_AUTH *pauth_out,
1164 prs_struct *auth_data)
1167 DATA_BLOB null_blob = data_blob_null;
1168 DATA_BLOB request = data_blob_null;
1169 DATA_BLOB spnego_msg = data_blob_null;
1171 /* We may change the pad length before marshalling. */
1172 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1174 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1175 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1179 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1180 data_blob_free(&request);
1181 prs_mem_free(auth_data);
1185 /* Wrap this in SPNEGO. */
1186 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1188 data_blob_free(&request);
1190 /* Auth len in the rpc header doesn't include auth_header. */
1191 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1192 data_blob_free(&spnego_msg);
1193 prs_mem_free(auth_data);
1194 return NT_STATUS_NO_MEMORY;
1197 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1198 dump_data(5, spnego_msg.data, spnego_msg.length);
1200 data_blob_free(&spnego_msg);
1201 return NT_STATUS_OK;
1204 /*******************************************************************
1205 Creates NTLMSSP auth bind.
1206 ********************************************************************/
1208 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1209 enum pipe_auth_level auth_level,
1210 RPC_HDR_AUTH *pauth_out,
1211 prs_struct *auth_data)
1214 DATA_BLOB null_blob = data_blob_null;
1215 DATA_BLOB request = data_blob_null;
1217 /* We may change the pad length before marshalling. */
1218 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1220 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1221 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1225 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1226 data_blob_free(&request);
1227 prs_mem_free(auth_data);
1231 /* Auth len in the rpc header doesn't include auth_header. */
1232 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1233 data_blob_free(&request);
1234 prs_mem_free(auth_data);
1235 return NT_STATUS_NO_MEMORY;
1238 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1239 dump_data(5, request.data, request.length);
1241 data_blob_free(&request);
1242 return NT_STATUS_OK;
1245 /*******************************************************************
1246 Creates schannel auth bind.
1247 ********************************************************************/
1249 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1250 enum pipe_auth_level auth_level,
1251 RPC_HDR_AUTH *pauth_out,
1252 prs_struct *auth_data)
1254 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1256 /* We may change the pad length before marshalling. */
1257 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1259 /* Use lp_workgroup() if domain not specified */
1261 if (!cli->auth->domain || !cli->auth->domain[0]) {
1262 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1263 if (cli->auth->domain == NULL) {
1264 return NT_STATUS_NO_MEMORY;
1268 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1272 * Now marshall the data into the auth parse_struct.
1275 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1276 &schannel_neg, auth_data, 0)) {
1277 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1278 prs_mem_free(auth_data);
1279 return NT_STATUS_NO_MEMORY;
1282 return NT_STATUS_OK;
1285 /*******************************************************************
1286 Creates the internals of a DCE/RPC bind request or alter context PDU.
1287 ********************************************************************/
1289 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1290 prs_struct *rpc_out,
1292 const RPC_IFACE *abstract,
1293 const RPC_IFACE *transfer,
1294 RPC_HDR_AUTH *phdr_auth,
1295 prs_struct *pauth_info)
1299 RPC_CONTEXT rpc_ctx;
1300 uint16 auth_len = prs_offset(pauth_info);
1301 uint8 ss_padding_len = 0;
1302 uint16 frag_len = 0;
1304 /* create the RPC context. */
1305 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1307 /* create the bind request RPC_HDR_RB */
1308 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1310 /* Start building the frag length. */
1311 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1313 /* Do we need to pad ? */
1315 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1317 ss_padding_len = 8 - (data_len % 8);
1318 phdr_auth->auth_pad_len = ss_padding_len;
1320 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1323 /* Create the request RPC_HDR */
1324 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1326 /* Marshall the RPC header */
1327 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1328 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1329 return NT_STATUS_NO_MEMORY;
1332 /* Marshall the bind request data */
1333 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1334 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1335 return NT_STATUS_NO_MEMORY;
1339 * Grow the outgoing buffer to store any auth info.
1343 if (ss_padding_len) {
1345 memset(pad, '\0', 8);
1346 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1347 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1348 return NT_STATUS_NO_MEMORY;
1352 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1353 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1354 return NT_STATUS_NO_MEMORY;
1358 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1359 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1360 return NT_STATUS_NO_MEMORY;
1364 return NT_STATUS_OK;
1367 /*******************************************************************
1368 Creates a DCE/RPC bind request.
1369 ********************************************************************/
1371 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1372 prs_struct *rpc_out,
1374 const RPC_IFACE *abstract,
1375 const RPC_IFACE *transfer,
1376 enum pipe_auth_type auth_type,
1377 enum pipe_auth_level auth_level)
1379 RPC_HDR_AUTH hdr_auth;
1380 prs_struct auth_info;
1381 NTSTATUS ret = NT_STATUS_OK;
1383 ZERO_STRUCT(hdr_auth);
1384 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1385 return NT_STATUS_NO_MEMORY;
1387 switch (auth_type) {
1388 case PIPE_AUTH_TYPE_SCHANNEL:
1389 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1390 if (!NT_STATUS_IS_OK(ret)) {
1391 prs_mem_free(&auth_info);
1396 case PIPE_AUTH_TYPE_NTLMSSP:
1397 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1398 if (!NT_STATUS_IS_OK(ret)) {
1399 prs_mem_free(&auth_info);
1404 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1405 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1406 if (!NT_STATUS_IS_OK(ret)) {
1407 prs_mem_free(&auth_info);
1412 case PIPE_AUTH_TYPE_KRB5:
1413 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1414 if (!NT_STATUS_IS_OK(ret)) {
1415 prs_mem_free(&auth_info);
1420 case PIPE_AUTH_TYPE_NONE:
1424 /* "Can't" happen. */
1425 return NT_STATUS_INVALID_INFO_CLASS;
1428 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1436 prs_mem_free(&auth_info);
1440 /*******************************************************************
1441 Create and add the NTLMSSP sign/seal auth header and data.
1442 ********************************************************************/
1444 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1446 uint32 ss_padding_len,
1447 prs_struct *outgoing_pdu)
1449 RPC_HDR_AUTH auth_info;
1451 DATA_BLOB auth_blob = data_blob_null;
1452 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1454 if (!cli->auth->a_u.ntlmssp_state) {
1455 return NT_STATUS_INVALID_PARAMETER;
1458 /* Init and marshall the auth header. */
1459 init_rpc_hdr_auth(&auth_info,
1460 map_pipe_auth_type_to_rpc_auth_type(
1461 cli->auth->auth_type),
1462 cli->auth->auth_level,
1464 1 /* context id. */);
1466 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1467 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1468 data_blob_free(&auth_blob);
1469 return NT_STATUS_NO_MEMORY;
1472 switch (cli->auth->auth_level) {
1473 case PIPE_AUTH_LEVEL_PRIVACY:
1474 /* Data portion is encrypted. */
1475 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1476 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1478 (unsigned char *)prs_data_p(outgoing_pdu),
1479 (size_t)prs_offset(outgoing_pdu),
1481 if (!NT_STATUS_IS_OK(status)) {
1482 data_blob_free(&auth_blob);
1487 case PIPE_AUTH_LEVEL_INTEGRITY:
1488 /* Data is signed. */
1489 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1490 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1492 (unsigned char *)prs_data_p(outgoing_pdu),
1493 (size_t)prs_offset(outgoing_pdu),
1495 if (!NT_STATUS_IS_OK(status)) {
1496 data_blob_free(&auth_blob);
1503 smb_panic("bad auth level");
1505 return NT_STATUS_INVALID_PARAMETER;
1508 /* Finally marshall the blob. */
1510 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1511 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1512 (unsigned int)NTLMSSP_SIG_SIZE));
1513 data_blob_free(&auth_blob);
1514 return NT_STATUS_NO_MEMORY;
1517 data_blob_free(&auth_blob);
1518 return NT_STATUS_OK;
1521 /*******************************************************************
1522 Create and add the schannel sign/seal auth header and data.
1523 ********************************************************************/
1525 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1527 uint32 ss_padding_len,
1528 prs_struct *outgoing_pdu)
1530 RPC_HDR_AUTH auth_info;
1531 RPC_AUTH_SCHANNEL_CHK verf;
1532 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1533 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1534 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1537 return NT_STATUS_INVALID_PARAMETER;
1540 /* Init and marshall the auth header. */
1541 init_rpc_hdr_auth(&auth_info,
1542 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1543 cli->auth->auth_level,
1545 1 /* context id. */);
1547 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1548 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1549 return NT_STATUS_NO_MEMORY;
1552 switch (cli->auth->auth_level) {
1553 case PIPE_AUTH_LEVEL_PRIVACY:
1554 case PIPE_AUTH_LEVEL_INTEGRITY:
1555 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1558 schannel_encode(sas,
1559 cli->auth->auth_level,
1560 SENDER_IS_INITIATOR,
1570 smb_panic("bad auth level");
1572 return NT_STATUS_INVALID_PARAMETER;
1575 /* Finally marshall the blob. */
1576 smb_io_rpc_auth_schannel_chk("",
1577 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1582 return NT_STATUS_OK;
1585 /*******************************************************************
1586 Calculate how much data we're going to send in this packet, also
1587 work out any sign/seal padding length.
1588 ********************************************************************/
1590 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1594 uint32 *p_ss_padding)
1596 uint32 data_space, data_len;
1598 switch (cli->auth->auth_level) {
1599 case PIPE_AUTH_LEVEL_NONE:
1600 case PIPE_AUTH_LEVEL_CONNECT:
1601 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1602 data_len = MIN(data_space, data_left);
1605 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1608 case PIPE_AUTH_LEVEL_INTEGRITY:
1609 case PIPE_AUTH_LEVEL_PRIVACY:
1610 /* Treat the same for all authenticated rpc requests. */
1611 switch(cli->auth->auth_type) {
1612 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1613 case PIPE_AUTH_TYPE_NTLMSSP:
1614 *p_auth_len = NTLMSSP_SIG_SIZE;
1616 case PIPE_AUTH_TYPE_SCHANNEL:
1617 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1620 smb_panic("bad auth type");
1624 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1625 RPC_HDR_AUTH_LEN - *p_auth_len;
1627 data_len = MIN(data_space, data_left);
1629 *p_ss_padding = 8 - (data_len % 8);
1631 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1632 data_len + *p_ss_padding + /* data plus padding. */
1633 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1637 smb_panic("bad auth level");
1643 /*******************************************************************
1645 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1646 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1647 and deals with signing/sealing details.
1648 ********************************************************************/
1650 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1652 prs_struct *in_data,
1653 prs_struct *out_data)
1656 uint32 data_left = prs_offset(in_data);
1657 uint32 alloc_hint = prs_offset(in_data);
1658 uint32 data_sent_thistime = 0;
1659 uint32 current_data_offset = 0;
1660 uint32 call_id = get_rpc_call_id();
1662 prs_struct outgoing_pdu;
1664 memset(pad, '\0', 8);
1666 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1667 /* Server is screwed up ! */
1668 return NT_STATUS_INVALID_PARAMETER;
1671 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1672 return NT_STATUS_NO_MEMORY;
1676 RPC_HDR_REQ hdr_req;
1677 uint16 auth_len = 0;
1678 uint16 frag_len = 0;
1680 uint32 ss_padding = 0;
1681 ssize_t num_written;
1683 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1684 &frag_len, &auth_len, &ss_padding);
1686 if (current_data_offset == 0) {
1687 flags = RPC_FLG_FIRST;
1690 if (data_sent_thistime == data_left) {
1691 flags |= RPC_FLG_LAST;
1694 /* Create and marshall the header and request header. */
1695 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1697 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1698 prs_mem_free(&outgoing_pdu);
1699 return NT_STATUS_NO_MEMORY;
1702 /* Create the rpc request RPC_HDR_REQ */
1703 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1705 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1706 prs_mem_free(&outgoing_pdu);
1707 return NT_STATUS_NO_MEMORY;
1710 /* Copy in the data, plus any ss padding. */
1711 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1712 prs_mem_free(&outgoing_pdu);
1713 return NT_STATUS_NO_MEMORY;
1716 /* Copy the sign/seal padding data. */
1718 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1719 prs_mem_free(&outgoing_pdu);
1720 return NT_STATUS_NO_MEMORY;
1724 /* Generate any auth sign/seal and add the auth footer. */
1726 switch (cli->auth->auth_type) {
1727 case PIPE_AUTH_TYPE_NONE:
1729 case PIPE_AUTH_TYPE_NTLMSSP:
1730 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1731 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1732 if (!NT_STATUS_IS_OK(ret)) {
1733 prs_mem_free(&outgoing_pdu);
1737 case PIPE_AUTH_TYPE_SCHANNEL:
1738 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1739 if (!NT_STATUS_IS_OK(ret)) {
1740 prs_mem_free(&outgoing_pdu);
1745 smb_panic("bad auth type");
1746 break; /* notreached */
1750 /* Actually send the packet. */
1751 if (flags & RPC_FLG_LAST) {
1752 /* Last packet - send the data, get the reply and return. */
1753 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1754 prs_mem_free(&outgoing_pdu);
1756 if ((DEBUGLEVEL >= 50)
1757 && (cli->transport_type == NCACN_NP)) {
1758 char *dump_name = NULL;
1759 /* Also capture received data */
1760 if (asprintf(&dump_name, "%s/reply_%s_%d",
1761 get_dyn_LOGFILEBASE(),
1762 cli->trans.np.pipe_name, op_num) > 0) {
1763 prs_dump(dump_name, op_num, out_data);
1764 SAFE_FREE(dump_name);
1771 switch (cli->transport_type) {
1773 num_written = cli_write(cli->trans.np.cli,
1775 8, /* 8 means message mode. */
1776 prs_data_p(&outgoing_pdu),
1778 (size_t)hdr.frag_len);
1780 if (num_written != hdr.frag_len) {
1781 prs_mem_free(&outgoing_pdu);
1782 return cli_get_nt_error(cli->trans.np.cli);
1786 case NCACN_UNIX_STREAM:
1787 num_written = write_data(
1789 prs_data_p(&outgoing_pdu),
1790 (size_t)hdr.frag_len);
1791 if (num_written != hdr.frag_len) {
1793 status = map_nt_error_from_unix(errno);
1794 prs_mem_free(&outgoing_pdu);
1799 DEBUG(0, ("unknown transport type %d\n",
1800 cli->transport_type));
1801 return NT_STATUS_INTERNAL_ERROR;
1804 current_data_offset += data_sent_thistime;
1805 data_left -= data_sent_thistime;
1807 /* Reset the marshalling position back to zero. */
1808 if (!prs_set_offset(&outgoing_pdu, 0)) {
1809 prs_mem_free(&outgoing_pdu);
1810 return NT_STATUS_NO_MEMORY;
1815 /****************************************************************************
1816 Set the handle state.
1817 ****************************************************************************/
1819 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1820 const char *pipe_name, uint16 device_state)
1822 bool state_set = False;
1824 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1825 char *rparam = NULL;
1827 uint32 rparam_len, rdata_len;
1829 if (pipe_name == NULL)
1832 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1833 cli->fnum, pipe_name, device_state));
1835 /* create parameters: device state */
1836 SSVAL(param, 0, device_state);
1838 /* create setup parameters. */
1840 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1842 /* send the data on \PIPE\ */
1843 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1844 setup, 2, 0, /* setup, length, max */
1845 param, 2, 0, /* param, length, max */
1846 NULL, 0, 1024, /* data, length, max */
1847 &rparam, &rparam_len, /* return param, length */
1848 &rdata, &rdata_len)) /* return data, length */
1850 DEBUG(5, ("Set Handle state: return OK\n"));
1861 /****************************************************************************
1862 Check the rpc bind acknowledge response.
1863 ****************************************************************************/
1865 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1867 if ( hdr_ba->addr.len == 0) {
1868 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1871 /* check the transfer syntax */
1872 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1873 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1874 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1878 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1879 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1880 hdr_ba->res.num_results, hdr_ba->res.reason));
1883 DEBUG(5,("check_bind_response: accepted!\n"));
1887 /*******************************************************************
1888 Creates a DCE/RPC bind authentication response.
1889 This is the packet that is sent back to the server once we
1890 have received a BIND-ACK, to finish the third leg of
1891 the authentication handshake.
1892 ********************************************************************/
1894 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1896 enum pipe_auth_type auth_type,
1897 enum pipe_auth_level auth_level,
1898 DATA_BLOB *pauth_blob,
1899 prs_struct *rpc_out)
1902 RPC_HDR_AUTH hdr_auth;
1905 /* Create the request RPC_HDR */
1906 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1907 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1908 pauth_blob->length );
1911 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1912 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1913 return NT_STATUS_NO_MEMORY;
1917 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1918 about padding - shouldn't this pad to length 8 ? JRA.
1921 /* 4 bytes padding. */
1922 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1923 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1924 return NT_STATUS_NO_MEMORY;
1927 /* Create the request RPC_HDR_AUTHA */
1928 init_rpc_hdr_auth(&hdr_auth,
1929 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1932 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1933 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1934 return NT_STATUS_NO_MEMORY;
1938 * Append the auth data to the outgoing buffer.
1941 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1942 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1943 return NT_STATUS_NO_MEMORY;
1946 return NT_STATUS_OK;
1949 /****************************************************************************
1950 Create and send the third packet in an RPC auth.
1951 ****************************************************************************/
1953 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1957 enum pipe_auth_type auth_type,
1958 enum pipe_auth_level auth_level)
1960 DATA_BLOB server_response = data_blob_null;
1961 DATA_BLOB client_reply = data_blob_null;
1962 RPC_HDR_AUTH hdr_auth;
1967 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1968 return NT_STATUS_INVALID_PARAMETER;
1971 /* Process the returned NTLMSSP blob first. */
1972 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1973 return NT_STATUS_INVALID_PARAMETER;
1976 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1977 return NT_STATUS_INVALID_PARAMETER;
1980 /* TODO - check auth_type/auth_level match. */
1982 server_response = data_blob(NULL, phdr->auth_len);
1983 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1985 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1989 if (!NT_STATUS_IS_OK(nt_status)) {
1990 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1991 data_blob_free(&server_response);
1995 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1997 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1998 auth_type, auth_level,
1999 &client_reply, &rpc_out);
2001 if (!NT_STATUS_IS_OK(nt_status)) {
2002 prs_mem_free(&rpc_out);
2003 data_blob_free(&client_reply);
2004 data_blob_free(&server_response);
2008 switch (cli->transport_type) {
2010 /* 8 here is named pipe message mode. */
2011 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
2012 0x8, prs_data_p(&rpc_out), 0,
2013 (size_t)prs_offset(&rpc_out));
2016 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2017 nt_status = cli_get_nt_error(cli->trans.np.cli);
2020 case NCACN_UNIX_STREAM:
2021 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
2022 (size_t)prs_offset(&rpc_out));
2023 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2024 nt_status = map_nt_error_from_unix(errno);
2028 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
2029 return NT_STATUS_INTERNAL_ERROR;
2032 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2033 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
2034 nt_errstr(nt_status)));
2035 prs_mem_free(&rpc_out);
2036 data_blob_free(&client_reply);
2037 data_blob_free(&server_response);
2041 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2042 rpccli_pipe_txt(debug_ctx(), cli)));
2044 prs_mem_free(&rpc_out);
2045 data_blob_free(&client_reply);
2046 data_blob_free(&server_response);
2047 return NT_STATUS_OK;
2050 /*******************************************************************
2051 Creates a DCE/RPC bind alter context authentication request which
2052 may contain a spnego auth blobl
2053 ********************************************************************/
2055 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2056 const RPC_IFACE *abstract,
2057 const RPC_IFACE *transfer,
2058 enum pipe_auth_level auth_level,
2059 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2060 prs_struct *rpc_out)
2062 RPC_HDR_AUTH hdr_auth;
2063 prs_struct auth_info;
2064 NTSTATUS ret = NT_STATUS_OK;
2066 ZERO_STRUCT(hdr_auth);
2067 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2068 return NT_STATUS_NO_MEMORY;
2070 /* We may change the pad length before marshalling. */
2071 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2073 if (pauth_blob->length) {
2074 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2075 prs_mem_free(&auth_info);
2076 return NT_STATUS_NO_MEMORY;
2080 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2087 prs_mem_free(&auth_info);
2091 /*******************************************************************
2092 Third leg of the SPNEGO bind mechanism - sends alter context PDU
2093 and gets a response.
2094 ********************************************************************/
2096 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
2100 const RPC_IFACE *abstract,
2101 const RPC_IFACE *transfer,
2102 enum pipe_auth_type auth_type,
2103 enum pipe_auth_level auth_level)
2105 DATA_BLOB server_spnego_response = data_blob_null;
2106 DATA_BLOB server_ntlm_response = data_blob_null;
2107 DATA_BLOB client_reply = data_blob_null;
2108 DATA_BLOB tmp_blob = data_blob_null;
2109 RPC_HDR_AUTH hdr_auth;
2113 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2114 return NT_STATUS_INVALID_PARAMETER;
2117 /* Process the returned NTLMSSP blob first. */
2118 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2119 return NT_STATUS_INVALID_PARAMETER;
2122 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2123 return NT_STATUS_INVALID_PARAMETER;
2126 server_spnego_response = data_blob(NULL, phdr->auth_len);
2127 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2129 /* The server might give us back two challenges - tmp_blob is for the second. */
2130 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2131 data_blob_free(&server_spnego_response);
2132 data_blob_free(&server_ntlm_response);
2133 data_blob_free(&tmp_blob);
2134 return NT_STATUS_INVALID_PARAMETER;
2137 /* We're finished with the server spnego response and the tmp_blob. */
2138 data_blob_free(&server_spnego_response);
2139 data_blob_free(&tmp_blob);
2141 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2142 server_ntlm_response,
2145 /* Finished with the server_ntlm response */
2146 data_blob_free(&server_ntlm_response);
2148 if (!NT_STATUS_IS_OK(nt_status)) {
2149 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2150 data_blob_free(&client_reply);
2154 /* SPNEGO wrap the client reply. */
2155 tmp_blob = spnego_gen_auth(client_reply);
2156 data_blob_free(&client_reply);
2157 client_reply = tmp_blob;
2158 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2160 /* Now prepare the alter context pdu. */
2161 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2163 nt_status = create_rpc_alter_context(rpc_call_id,
2170 data_blob_free(&client_reply);
2172 if (!NT_STATUS_IS_OK(nt_status)) {
2173 prs_mem_free(&rpc_out);
2177 /* Initialize the returning data struct. */
2179 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2181 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2182 if (!NT_STATUS_IS_OK(nt_status)) {
2183 prs_mem_free(&rpc_out);
2187 prs_mem_free(&rpc_out);
2189 /* Get the auth blob from the reply. */
2190 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2191 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2192 return NT_STATUS_BUFFER_TOO_SMALL;
2195 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2196 return NT_STATUS_INVALID_PARAMETER;
2199 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2200 return NT_STATUS_INVALID_PARAMETER;
2203 server_spnego_response = data_blob(NULL, phdr->auth_len);
2204 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2206 /* Check we got a valid auth response. */
2207 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2208 data_blob_free(&server_spnego_response);
2209 data_blob_free(&tmp_blob);
2210 return NT_STATUS_INVALID_PARAMETER;
2213 data_blob_free(&server_spnego_response);
2214 data_blob_free(&tmp_blob);
2216 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2217 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2219 return NT_STATUS_OK;
2222 /****************************************************************************
2224 ****************************************************************************/
2226 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2227 struct cli_pipe_auth_data *auth)
2236 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2237 rpccli_pipe_txt(debug_ctx(), cli),
2238 (unsigned int)auth->auth_type,
2239 (unsigned int)auth->auth_level ));
2241 cli->auth = talloc_move(cli, &auth);
2243 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2245 rpc_call_id = get_rpc_call_id();
2247 /* Marshall the outgoing data. */
2248 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2249 &cli->abstract_syntax,
2250 &cli->transfer_syntax,
2251 cli->auth->auth_type,
2252 cli->auth->auth_level);
2254 if (!NT_STATUS_IS_OK(status)) {
2255 prs_mem_free(&rpc_out);
2259 /* Initialize the incoming data struct. */
2260 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2262 /* send data on \PIPE\. receive a response */
2263 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2264 if (!NT_STATUS_IS_OK(status)) {
2265 prs_mem_free(&rpc_out);
2269 prs_mem_free(&rpc_out);
2271 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2272 rpccli_pipe_txt(debug_ctx(), cli)));
2274 /* Unmarshall the RPC header */
2275 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2276 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2277 prs_mem_free(&rbuf);
2278 return NT_STATUS_BUFFER_TOO_SMALL;
2281 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2282 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2283 prs_mem_free(&rbuf);
2284 return NT_STATUS_BUFFER_TOO_SMALL;
2287 if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) {
2288 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2289 prs_mem_free(&rbuf);
2290 return NT_STATUS_BUFFER_TOO_SMALL;
2293 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2294 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2296 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2297 switch(cli->auth->auth_type) {
2299 case PIPE_AUTH_TYPE_NONE:
2300 case PIPE_AUTH_TYPE_SCHANNEL:
2301 /* Bind complete. */
2304 case PIPE_AUTH_TYPE_NTLMSSP:
2305 /* Need to send AUTH3 packet - no reply. */
2306 status = rpc_finish_auth3_bind(
2307 cli, &hdr, &rbuf, rpc_call_id,
2308 cli->auth->auth_type,
2309 cli->auth->auth_level);
2310 if (!NT_STATUS_IS_OK(status)) {
2311 prs_mem_free(&rbuf);
2316 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2317 /* Need to send alter context request and reply. */
2318 status = rpc_finish_spnego_ntlmssp_bind(
2319 cli, &hdr, &rbuf, rpc_call_id,
2320 &cli->abstract_syntax, &cli->transfer_syntax,
2321 cli->auth->auth_type, cli->auth->auth_level);
2322 if (!NT_STATUS_IS_OK(status)) {
2323 prs_mem_free(&rbuf);
2328 case PIPE_AUTH_TYPE_KRB5:
2332 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2333 "%u\n", (unsigned int)cli->auth->auth_type));
2334 prs_mem_free(&rbuf);
2335 return NT_STATUS_INVALID_INFO_CLASS;
2338 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2339 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2340 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2341 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2342 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2343 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2344 prs_mem_free(&rbuf);
2345 return NT_STATUS_INVALID_PARAMETER;
2348 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2349 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2350 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2351 prs_mem_free(&rbuf);
2352 return NT_STATUS_INVALID_PARAMETER;
2357 prs_mem_free(&rbuf);
2358 return NT_STATUS_OK;
2361 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2362 unsigned int timeout)
2364 return cli_set_timeout(cli->trans.np.cli, timeout);
2367 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2369 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2370 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2371 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2375 if (cli->transport_type == NCACN_NP) {
2376 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2383 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2385 if (p->transport_type == NCACN_NP) {
2386 return p->trans.np.cli;
2391 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2393 if (p->transport_type == NCACN_NP) {
2395 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2397 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2398 "pipe %s. Error was %s\n",
2399 rpccli_pipe_txt(debug_ctx(), p),
2400 cli_errstr(p->trans.np.cli)));
2403 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2404 rpccli_pipe_txt(debug_ctx(), p)));
2406 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2407 return ret ? -1 : 0;
2413 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2414 struct cli_pipe_auth_data **presult)
2416 struct cli_pipe_auth_data *result;
2418 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2419 if (result == NULL) {
2420 return NT_STATUS_NO_MEMORY;
2423 result->auth_type = PIPE_AUTH_TYPE_NONE;
2424 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2426 result->user_name = talloc_strdup(result, "");
2427 result->domain = talloc_strdup(result, "");
2428 if ((result->user_name == NULL) || (result->domain == NULL)) {
2429 TALLOC_FREE(result);
2430 return NT_STATUS_NO_MEMORY;
2434 return NT_STATUS_OK;
2437 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2439 ntlmssp_end(&auth->a_u.ntlmssp_state);
2443 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2444 enum pipe_auth_type auth_type,
2445 enum pipe_auth_level auth_level,
2447 const char *username,
2448 const char *password,
2449 struct cli_pipe_auth_data **presult)
2451 struct cli_pipe_auth_data *result;
2454 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2455 if (result == NULL) {
2456 return NT_STATUS_NO_MEMORY;
2459 result->auth_type = auth_type;
2460 result->auth_level = auth_level;
2462 result->user_name = talloc_strdup(result, username);
2463 result->domain = talloc_strdup(result, domain);
2464 if ((result->user_name == NULL) || (result->domain == NULL)) {
2465 status = NT_STATUS_NO_MEMORY;
2469 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2470 if (!NT_STATUS_IS_OK(status)) {
2474 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2476 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2477 if (!NT_STATUS_IS_OK(status)) {
2481 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2482 if (!NT_STATUS_IS_OK(status)) {
2486 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2487 if (!NT_STATUS_IS_OK(status)) {
2492 * Turn off sign+seal to allow selected auth level to turn it back on.
2494 result->a_u.ntlmssp_state->neg_flags &=
2495 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2497 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2498 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2499 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2500 result->a_u.ntlmssp_state->neg_flags
2501 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2505 return NT_STATUS_OK;
2508 TALLOC_FREE(result);
2512 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2513 enum pipe_auth_level auth_level,
2514 const uint8_t sess_key[16],
2515 struct cli_pipe_auth_data **presult)
2517 struct cli_pipe_auth_data *result;
2519 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2520 if (result == NULL) {
2521 return NT_STATUS_NO_MEMORY;
2524 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2525 result->auth_level = auth_level;
2527 result->user_name = talloc_strdup(result, "");
2528 result->domain = talloc_strdup(result, domain);
2529 if ((result->user_name == NULL) || (result->domain == NULL)) {
2533 result->a_u.schannel_auth = talloc(result,
2534 struct schannel_auth_struct);
2535 if (result->a_u.schannel_auth == NULL) {
2539 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2540 sizeof(result->a_u.schannel_auth->sess_key));
2541 result->a_u.schannel_auth->seq_num = 0;
2544 return NT_STATUS_OK;
2547 TALLOC_FREE(result);
2548 return NT_STATUS_NO_MEMORY;
2552 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2554 data_blob_free(&auth->session_key);
2559 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2560 enum pipe_auth_level auth_level,
2561 const char *service_princ,
2562 const char *username,
2563 const char *password,
2564 struct cli_pipe_auth_data **presult)
2567 struct cli_pipe_auth_data *result;
2569 if ((username != NULL) && (password != NULL)) {
2570 int ret = kerberos_kinit_password(username, password, 0, NULL);
2572 return NT_STATUS_ACCESS_DENIED;
2576 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2577 if (result == NULL) {
2578 return NT_STATUS_NO_MEMORY;
2581 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2582 result->auth_level = auth_level;
2585 * Username / domain need fixing!
2587 result->user_name = talloc_strdup(result, "");
2588 result->domain = talloc_strdup(result, "");
2589 if ((result->user_name == NULL) || (result->domain == NULL)) {
2593 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2594 result, struct kerberos_auth_struct);
2595 if (result->a_u.kerberos_auth == NULL) {
2598 talloc_set_destructor(result->a_u.kerberos_auth,
2599 cli_auth_kerberos_data_destructor);
2601 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2602 result, service_princ);
2603 if (result->a_u.kerberos_auth->service_principal == NULL) {
2608 return NT_STATUS_OK;
2611 TALLOC_FREE(result);
2612 return NT_STATUS_NO_MEMORY;
2614 return NT_STATUS_NOT_SUPPORTED;
2618 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2620 close(p->trans.sock.fd);
2625 * Create an rpc pipe client struct, connecting to a tcp port.
2627 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2629 const struct ndr_syntax_id *abstract_syntax,
2630 struct rpc_pipe_client **presult)
2632 struct rpc_pipe_client *result;
2633 struct sockaddr_storage addr;
2636 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2637 if (result == NULL) {
2638 return NT_STATUS_NO_MEMORY;
2641 result->transport_type = NCACN_IP_TCP;
2643 result->abstract_syntax = *abstract_syntax;
2644 result->transfer_syntax = ndr_transfer_syntax;
2646 result->desthost = talloc_strdup(result, host);
2647 result->srv_name_slash = talloc_asprintf_strupper_m(
2648 result, "\\\\%s", result->desthost);
2649 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2650 status = NT_STATUS_NO_MEMORY;
2654 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2655 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2657 if (!resolve_name(host, &addr, 0)) {
2658 status = NT_STATUS_NOT_FOUND;
2662 status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
2663 if (!NT_STATUS_IS_OK(status)) {
2667 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2670 return NT_STATUS_OK;
2673 TALLOC_FREE(result);
2678 * Determine the tcp port on which a dcerpc interface is listening
2679 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2682 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2683 const struct ndr_syntax_id *abstract_syntax,
2687 struct rpc_pipe_client *epm_pipe = NULL;
2688 struct cli_pipe_auth_data *auth = NULL;
2689 struct dcerpc_binding *map_binding = NULL;
2690 struct dcerpc_binding *res_binding = NULL;
2691 struct epm_twr_t *map_tower = NULL;
2692 struct epm_twr_t *res_towers = NULL;
2693 struct policy_handle *entry_handle = NULL;
2694 uint32_t num_towers = 0;
2695 uint32_t max_towers = 1;
2696 struct epm_twr_p_t towers;
2697 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2699 if (pport == NULL) {
2700 status = NT_STATUS_INVALID_PARAMETER;
2704 /* open the connection to the endpoint mapper */
2705 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2706 &ndr_table_epmapper.syntax_id,
2709 if (!NT_STATUS_IS_OK(status)) {
2713 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2714 if (!NT_STATUS_IS_OK(status)) {
2718 status = rpc_pipe_bind(epm_pipe, auth);
2719 if (!NT_STATUS_IS_OK(status)) {
2723 /* create tower for asking the epmapper */
2725 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2726 if (map_binding == NULL) {
2727 status = NT_STATUS_NO_MEMORY;
2731 map_binding->transport = NCACN_IP_TCP;
2732 map_binding->object = *abstract_syntax;
2733 map_binding->host = host; /* needed? */
2734 map_binding->endpoint = "0"; /* correct? needed? */
2736 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2737 if (map_tower == NULL) {
2738 status = NT_STATUS_NO_MEMORY;
2742 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2743 &(map_tower->tower));
2744 if (!NT_STATUS_IS_OK(status)) {
2748 /* allocate further parameters for the epm_Map call */
2750 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2751 if (res_towers == NULL) {
2752 status = NT_STATUS_NO_MEMORY;
2755 towers.twr = res_towers;
2757 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2758 if (entry_handle == NULL) {
2759 status = NT_STATUS_NO_MEMORY;
2763 /* ask the endpoint mapper for the port */
2765 status = rpccli_epm_Map(epm_pipe,
2767 CONST_DISCARD(struct GUID *,
2768 &(abstract_syntax->uuid)),
2775 if (!NT_STATUS_IS_OK(status)) {
2779 if (num_towers != 1) {
2780 status = NT_STATUS_UNSUCCESSFUL;
2784 /* extract the port from the answer */
2786 status = dcerpc_binding_from_tower(tmp_ctx,
2787 &(towers.twr->tower),
2789 if (!NT_STATUS_IS_OK(status)) {
2793 /* are further checks here necessary? */
2794 if (res_binding->transport != NCACN_IP_TCP) {
2795 status = NT_STATUS_UNSUCCESSFUL;
2799 *pport = (uint16_t)atoi(res_binding->endpoint);
2802 TALLOC_FREE(tmp_ctx);
2807 * Create a rpc pipe client struct, connecting to a host via tcp.
2808 * The port is determined by asking the endpoint mapper on the given
2811 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2812 const struct ndr_syntax_id *abstract_syntax,
2813 struct rpc_pipe_client **presult)
2820 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2821 if (!NT_STATUS_IS_OK(status)) {
2825 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2826 abstract_syntax, presult);
2832 /********************************************************************
2833 Create a rpc pipe client struct, connecting to a unix domain socket
2834 ********************************************************************/
2835 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2836 const struct ndr_syntax_id *abstract_syntax,
2837 struct rpc_pipe_client **presult)
2839 struct rpc_pipe_client *result;
2840 struct sockaddr_un addr;
2843 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2844 if (result == NULL) {
2845 return NT_STATUS_NO_MEMORY;
2848 result->transport_type = NCACN_UNIX_STREAM;
2850 result->abstract_syntax = *abstract_syntax;
2851 result->transfer_syntax = ndr_transfer_syntax;
2853 result->desthost = talloc_get_myname(result);
2854 result->srv_name_slash = talloc_asprintf_strupper_m(
2855 result, "\\\\%s", result->desthost);
2856 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2857 status = NT_STATUS_NO_MEMORY;
2861 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2862 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2864 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2865 if (result->trans.sock.fd == -1) {
2866 status = map_nt_error_from_unix(errno);
2870 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2873 addr.sun_family = AF_UNIX;
2874 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2876 if (sys_connect(result->trans.sock.fd,
2877 (struct sockaddr *)&addr) == -1) {
2878 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2880 close(result->trans.sock.fd);
2881 return map_nt_error_from_unix(errno);
2885 return NT_STATUS_OK;
2888 TALLOC_FREE(result);
2893 /****************************************************************************
2894 Open a named pipe over SMB to a remote server.
2896 * CAVEAT CALLER OF THIS FUNCTION:
2897 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2898 * so be sure that this function is called AFTER any structure (vs pointer)
2899 * assignment of the cli. In particular, libsmbclient does structure
2900 * assignments of cli, which invalidates the data in the returned
2901 * rpc_pipe_client if this function is called before the structure assignment
2904 ****************************************************************************/
2906 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2907 const struct ndr_syntax_id *abstract_syntax,
2908 struct rpc_pipe_client **presult)
2910 struct rpc_pipe_client *result;
2913 /* sanity check to protect against crashes */
2916 return NT_STATUS_INVALID_HANDLE;
2919 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2920 if (result == NULL) {
2921 return NT_STATUS_NO_MEMORY;
2924 result->transport_type = NCACN_NP;
2926 result->trans.np.pipe_name = cli_get_pipe_name_from_iface(
2927 result, cli, abstract_syntax);
2928 if (result->trans.np.pipe_name == NULL) {
2929 DEBUG(1, ("Could not find pipe for interface\n"));
2930 TALLOC_FREE(result);
2931 return NT_STATUS_INVALID_PARAMETER;
2934 result->trans.np.cli = cli;
2935 result->abstract_syntax = *abstract_syntax;
2936 result->transfer_syntax = ndr_transfer_syntax;
2937 result->desthost = talloc_strdup(result, cli->desthost);
2938 result->srv_name_slash = talloc_asprintf_strupper_m(
2939 result, "\\\\%s", result->desthost);
2941 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2942 TALLOC_FREE(result);
2943 return NT_STATUS_NO_MEMORY;
2946 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2947 DESIRED_ACCESS_PIPE);
2949 DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
2950 "to machine %s. Error was %s\n",
2951 result->trans.np.pipe_name, cli->desthost,
2953 TALLOC_FREE(result);
2954 return cli_get_nt_error(cli);
2957 result->trans.np.fnum = fnum;
2959 DLIST_ADD(cli->pipe_list, result);
2960 talloc_set_destructor(result, rpc_pipe_destructor);
2963 return NT_STATUS_OK;
2966 /****************************************************************************
2967 Open a pipe to a remote server.
2968 ****************************************************************************/
2970 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2971 const struct ndr_syntax_id *interface,
2972 struct rpc_pipe_client **presult)
2974 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
2976 * We should have a better way to figure out this drsuapi
2979 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2983 return rpc_pipe_open_np(cli, interface, presult);
2986 /****************************************************************************
2987 Open a named pipe to an SMB server and bind anonymously.
2988 ****************************************************************************/
2990 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2991 const struct ndr_syntax_id *interface,
2992 struct rpc_pipe_client **presult)
2994 struct rpc_pipe_client *result;
2995 struct cli_pipe_auth_data *auth;
2998 status = cli_rpc_pipe_open(cli, interface, &result);
2999 if (!NT_STATUS_IS_OK(status)) {
3003 status = rpccli_anon_bind_data(result, &auth);
3004 if (!NT_STATUS_IS_OK(status)) {
3005 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3006 nt_errstr(status)));
3007 TALLOC_FREE(result);
3012 * This is a bit of an abstraction violation due to the fact that an
3013 * anonymous bind on an authenticated SMB inherits the user/domain
3014 * from the enclosing SMB creds
3017 TALLOC_FREE(auth->user_name);
3018 TALLOC_FREE(auth->domain);
3020 auth->user_name = talloc_strdup(auth, cli->user_name);
3021 auth->domain = talloc_strdup(auth, cli->domain);
3022 auth->user_session_key = data_blob_talloc(auth,
3023 cli->user_session_key.data,
3024 cli->user_session_key.length);
3026 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3027 TALLOC_FREE(result);
3028 return NT_STATUS_NO_MEMORY;
3031 status = rpc_pipe_bind(result, auth);
3032 if (!NT_STATUS_IS_OK(status)) {
3034 if (ndr_syntax_id_equal(interface,
3035 &ndr_table_dssetup.syntax_id)) {
3036 /* non AD domains just don't have this pipe, avoid
3037 * level 0 statement in that case - gd */
3040 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3041 "%s failed with error %s\n",
3042 cli_get_pipe_name_from_iface(debug_ctx(), cli,
3044 nt_errstr(status) ));
3045 TALLOC_FREE(result);
3049 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3050 "%s and bound anonymously.\n", result->trans.np.pipe_name,
3054 return NT_STATUS_OK;
3057 /****************************************************************************
3058 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3059 ****************************************************************************/
3061 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3062 const struct ndr_syntax_id *interface,
3063 enum pipe_auth_type auth_type,
3064 enum pipe_auth_level auth_level,
3066 const char *username,
3067 const char *password,
3068 struct rpc_pipe_client **presult)
3070 struct rpc_pipe_client *result;
3071 struct cli_pipe_auth_data *auth;
3074 status = cli_rpc_pipe_open(cli, interface, &result);
3075 if (!NT_STATUS_IS_OK(status)) {
3079 status = rpccli_ntlmssp_bind_data(
3080 result, auth_type, auth_level, domain, username,
3081 cli->pwd.null_pwd ? NULL : password, &auth);
3082 if (!NT_STATUS_IS_OK(status)) {
3083 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3084 nt_errstr(status)));
3088 status = rpc_pipe_bind(result, auth);
3089 if (!NT_STATUS_IS_OK(status)) {
3090 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3091 nt_errstr(status) ));
3095 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3096 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3097 result->trans.np.pipe_name, cli->desthost,
3098 domain, username ));
3101 return NT_STATUS_OK;
3105 TALLOC_FREE(result);
3109 /****************************************************************************
3111 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3112 ****************************************************************************/
3114 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3115 const struct ndr_syntax_id *interface,
3116 enum pipe_auth_level auth_level,
3118 const char *username,
3119 const char *password,
3120 struct rpc_pipe_client **presult)
3122 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3124 PIPE_AUTH_TYPE_NTLMSSP,
3132 /****************************************************************************
3134 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3135 ****************************************************************************/
3137 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3138 const struct ndr_syntax_id *interface,
3139 enum pipe_auth_level auth_level,
3141 const char *username,
3142 const char *password,
3143 struct rpc_pipe_client **presult)
3145 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3147 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3155 /****************************************************************************
3156 Get a the schannel session key out of an already opened netlogon pipe.
3157 ****************************************************************************/
3158 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3159 struct cli_state *cli,
3163 uint32 sec_chan_type = 0;
3164 unsigned char machine_pwd[16];
3165 const char *machine_account;
3168 /* Get the machine account credentials from secrets.tdb. */
3169 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3172 DEBUG(0, ("get_schannel_session_key: could not fetch "
3173 "trust account password for domain '%s'\n",
3175 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3178 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3179 cli->desthost, /* server name */
3180 domain, /* domain */
3181 global_myname(), /* client name */
3182 machine_account, /* machine account name */
3187 if (!NT_STATUS_IS_OK(status)) {
3188 DEBUG(3, ("get_schannel_session_key_common: "
3189 "rpccli_netlogon_setup_creds failed with result %s "
3190 "to server %s, domain %s, machine account %s.\n",
3191 nt_errstr(status), cli->desthost, domain,
3196 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3197 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3199 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3202 return NT_STATUS_OK;;
3205 /****************************************************************************
3206 Open a netlogon pipe and get the schannel session key.
3207 Now exposed to external callers.
3208 ****************************************************************************/
3211 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3214 struct rpc_pipe_client **presult)
3216 struct rpc_pipe_client *netlogon_pipe = NULL;
3219 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3221 if (!NT_STATUS_IS_OK(status)) {
3225 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3227 if (!NT_STATUS_IS_OK(status)) {
3228 TALLOC_FREE(netlogon_pipe);
3232 *presult = netlogon_pipe;
3233 return NT_STATUS_OK;
3236 /****************************************************************************
3238 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3239 using session_key. sign and seal.
3240 ****************************************************************************/
3242 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3243 const struct ndr_syntax_id *interface,
3244 enum pipe_auth_level auth_level,
3246 const struct dcinfo *pdc,
3247 struct rpc_pipe_client **presult)
3249 struct rpc_pipe_client *result;
3250 struct cli_pipe_auth_data *auth;
3253 status = cli_rpc_pipe_open(cli, interface, &result);
3254 if (!NT_STATUS_IS_OK(status)) {
3258 status = rpccli_schannel_bind_data(result, domain, auth_level,
3259 pdc->sess_key, &auth);
3260 if (!NT_STATUS_IS_OK(status)) {
3261 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3262 nt_errstr(status)));
3263 TALLOC_FREE(result);
3267 status = rpc_pipe_bind(result, auth);
3268 if (!NT_STATUS_IS_OK(status)) {
3269 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3270 "cli_rpc_pipe_bind failed with error %s\n",
3271 nt_errstr(status) ));
3272 TALLOC_FREE(result);
3277 * The credentials on a new netlogon pipe are the ones we are passed
3278 * in - copy them over.
3280 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3281 if (result->dc == NULL) {
3282 DEBUG(0, ("talloc failed\n"));
3283 TALLOC_FREE(result);
3284 return NT_STATUS_NO_MEMORY;
3287 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3289 "and bound using schannel.\n",
3290 result->trans.np.pipe_name, cli->desthost, domain ));
3293 return NT_STATUS_OK;
3296 /****************************************************************************
3297 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3298 Fetch the session key ourselves using a temporary netlogon pipe. This
3299 version uses an ntlmssp auth bound netlogon pipe to get the key.
3300 ****************************************************************************/
3302 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3304 const char *username,
3305 const char *password,
3307 struct rpc_pipe_client **presult)
3309 struct rpc_pipe_client *netlogon_pipe = NULL;
3312 status = cli_rpc_pipe_open_spnego_ntlmssp(
3313 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3314 domain, username, password, &netlogon_pipe);
3315 if (!NT_STATUS_IS_OK(status)) {
3319 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3321 if (!NT_STATUS_IS_OK(status)) {
3322 TALLOC_FREE(netlogon_pipe);
3326 *presult = netlogon_pipe;
3327 return NT_STATUS_OK;
3330 /****************************************************************************
3331 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3332 Fetch the session key ourselves using a temporary netlogon pipe. This version
3333 uses an ntlmssp bind to get the session key.
3334 ****************************************************************************/
3336 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3337 const struct ndr_syntax_id *interface,
3338 enum pipe_auth_level auth_level,
3340 const char *username,
3341 const char *password,
3342 struct rpc_pipe_client **presult)
3344 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3345 struct rpc_pipe_client *netlogon_pipe = NULL;
3346 struct rpc_pipe_client *result = NULL;
3349 status = get_schannel_session_key_auth_ntlmssp(
3350 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3351 if (!NT_STATUS_IS_OK(status)) {
3352 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3353 "key from server %s for domain %s.\n",
3354 cli->desthost, domain ));
3358 status = cli_rpc_pipe_open_schannel_with_key(
3359 cli, interface, auth_level, domain, netlogon_pipe->dc,
3362 /* Now we've bound using the session key we can close the netlog pipe. */
3363 TALLOC_FREE(netlogon_pipe);
3365 if (NT_STATUS_IS_OK(status)) {
3371 /****************************************************************************
3372 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3373 Fetch the session key ourselves using a temporary netlogon pipe.
3374 ****************************************************************************/
3376 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3377 const struct ndr_syntax_id *interface,
3378 enum pipe_auth_level auth_level,
3380 struct rpc_pipe_client **presult)
3382 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3383 struct rpc_pipe_client *netlogon_pipe = NULL;
3384 struct rpc_pipe_client *result = NULL;
3387 status = get_schannel_session_key(cli, domain, &neg_flags,
3389 if (!NT_STATUS_IS_OK(status)) {
3390 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3391 "key from server %s for domain %s.\n",
3392 cli->desthost, domain ));
3396 status = cli_rpc_pipe_open_schannel_with_key(
3397 cli, interface, auth_level, domain, netlogon_pipe->dc,
3400 /* Now we've bound using the session key we can close the netlog pipe. */
3401 TALLOC_FREE(netlogon_pipe);
3403 if (NT_STATUS_IS_OK(status)) {
3407 return NT_STATUS_OK;
3410 /****************************************************************************
3411 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3412 The idea is this can be called with service_princ, username and password all
3413 NULL so long as the caller has a TGT.
3414 ****************************************************************************/
3416 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3417 const struct ndr_syntax_id *interface,
3418 enum pipe_auth_level auth_level,
3419 const char *service_princ,
3420 const char *username,
3421 const char *password,
3422 struct rpc_pipe_client **presult)
3425 struct rpc_pipe_client *result;
3426 struct cli_pipe_auth_data *auth;
3429 status = cli_rpc_pipe_open(cli, interface, &result);
3430 if (!NT_STATUS_IS_OK(status)) {
3434 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3435 username, password, &auth);
3436 if (!NT_STATUS_IS_OK(status)) {
3437 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3438 nt_errstr(status)));
3439 TALLOC_FREE(result);
3443 status = rpc_pipe_bind(result, auth);
3444 if (!NT_STATUS_IS_OK(status)) {
3445 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3446 "with error %s\n", nt_errstr(status)));
3447 TALLOC_FREE(result);
3452 return NT_STATUS_OK;
3454 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3455 return NT_STATUS_NOT_IMPLEMENTED;
3459 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3460 struct rpc_pipe_client *cli,
3461 DATA_BLOB *session_key)
3463 if (!session_key || !cli) {
3464 return NT_STATUS_INVALID_PARAMETER;
3468 return NT_STATUS_INVALID_PARAMETER;
3471 switch (cli->auth->auth_type) {
3472 case PIPE_AUTH_TYPE_SCHANNEL:
3473 *session_key = data_blob_talloc(mem_ctx,
3474 cli->auth->a_u.schannel_auth->sess_key, 16);
3476 case PIPE_AUTH_TYPE_NTLMSSP:
3477 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3478 *session_key = data_blob_talloc(mem_ctx,
3479 cli->auth->a_u.ntlmssp_state->session_key.data,
3480 cli->auth->a_u.ntlmssp_state->session_key.length);
3482 case PIPE_AUTH_TYPE_KRB5:
3483 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3484 *session_key = data_blob_talloc(mem_ctx,
3485 cli->auth->a_u.kerberos_auth->session_key.data,
3486 cli->auth->a_u.kerberos_auth->session_key.length);
3488 case PIPE_AUTH_TYPE_NONE:
3489 *session_key = data_blob_talloc(mem_ctx,
3490 cli->auth->user_session_key.data,
3491 cli->auth->user_session_key.length);
3494 return NT_STATUS_NO_USER_SESSION_KEY;
3497 return NT_STATUS_OK;