Store copies of the syntax ids in rpc_pipe_client
[Samba/gebeck_regimport.git] / source3 / rpc_client / cli_pipe.c
blobaf4c28195d26635c617c848cd285ef3f7a90e4ef
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "librpc/gen_ndr/cli_epmapper.h"
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_RPC_CLI
26 /*******************************************************************
27 interface/version dce/rpc pipe identification
28 ********************************************************************/
30 static const struct ndr_syntax_id syntax_spoolss = {
32 0x12345678, 0x1234, 0xabcd,
33 { 0xef, 0x00 },
34 { 0x01, 0x23,
35 0x45, 0x67, 0x89, 0xab }
36 }, 0x01
39 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
40 #define PIPE_SAMR "\\PIPE\\samr"
41 #define PIPE_WINREG "\\PIPE\\winreg"
42 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
43 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
44 #define PIPE_NTLSA "\\PIPE\\ntlsa"
45 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
46 #define PIPE_LSASS "\\PIPE\\lsass"
47 #define PIPE_LSARPC "\\PIPE\\lsarpc"
48 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
49 #define PIPE_NETDFS "\\PIPE\\netdfs"
50 #define PIPE_ECHO "\\PIPE\\rpcecho"
51 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
52 #define PIPE_EPM "\\PIPE\\epmapper"
53 #define PIPE_SVCCTL "\\PIPE\\svcctl"
54 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
55 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
56 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
59 * IMPORTANT!! If you update this structure, make sure to
60 * update the index #defines in smb.h.
63 static const struct pipe_id_info {
64 /* the names appear not to matter: the syntaxes _do_ matter */
66 const char *client_pipe;
67 const RPC_IFACE *abstr_syntax; /* this one is the abstract syntax id */
68 } pipe_names [] =
70 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
71 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
72 { PIPE_SAMR, &ndr_table_samr.syntax_id },
73 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
74 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
75 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
76 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
77 { PIPE_SPOOLSS, &syntax_spoolss },
78 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
79 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
80 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
81 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
82 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
83 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
84 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
85 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
86 { NULL, NULL }
89 /****************************************************************************
90 Return the pipe name from the index.
91 ****************************************************************************/
93 const char *cli_get_pipe_name(int pipe_idx)
95 return &pipe_names[pipe_idx].client_pipe[5];
98 /****************************************************************************
99 Return the pipe idx from the syntax.
100 ****************************************************************************/
101 int cli_get_pipe_idx(const RPC_IFACE *syntax)
103 int i;
104 for (i = 0; pipe_names[i].client_pipe; i++) {
105 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax, syntax)) {
106 return i;
110 return -1;
113 /********************************************************************
114 Map internal value to wire value.
115 ********************************************************************/
117 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
119 switch (auth_type) {
121 case PIPE_AUTH_TYPE_NONE:
122 return RPC_ANONYMOUS_AUTH_TYPE;
124 case PIPE_AUTH_TYPE_NTLMSSP:
125 return RPC_NTLMSSP_AUTH_TYPE;
127 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
128 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
129 return RPC_SPNEGO_AUTH_TYPE;
131 case PIPE_AUTH_TYPE_SCHANNEL:
132 return RPC_SCHANNEL_AUTH_TYPE;
134 case PIPE_AUTH_TYPE_KRB5:
135 return RPC_KRB5_AUTH_TYPE;
137 default:
138 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
139 "auth type %u\n",
140 (unsigned int)auth_type ));
141 break;
143 return -1;
146 /********************************************************************
147 Pipe description for a DEBUG
148 ********************************************************************/
149 static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli)
151 char *result;
153 switch (cli->transport_type) {
154 case NCACN_NP:
155 result = talloc_asprintf(mem_ctx, "host %s, pipe %s, "
156 "fnum 0x%x",
157 cli->desthost,
158 cli->trans.np.pipe_name,
159 (unsigned int)(cli->trans.np.fnum));
160 break;
161 case NCACN_IP_TCP:
162 case NCACN_UNIX_STREAM:
163 result = talloc_asprintf(mem_ctx, "host %s, fd %d",
164 cli->desthost, cli->trans.sock.fd);
165 break;
166 default:
167 result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
168 break;
170 SMB_ASSERT(result != NULL);
171 return result;
174 /********************************************************************
175 Rpc pipe call id.
176 ********************************************************************/
178 static uint32 get_rpc_call_id(void)
180 static uint32 call_id = 0;
181 return ++call_id;
184 /*******************************************************************
185 Read from a RPC named pipe
186 ********************************************************************/
187 static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name,
188 int fnum, char *buf, off_t offset, size_t size,
189 ssize_t *pnum_read)
191 ssize_t num_read;
193 num_read = cli_read(cli, fnum, buf, offset, size);
195 DEBUG(5,("rpc_read_np: num_read = %d, read offset: %u, to read: %u\n",
196 (int)num_read, (unsigned int)offset, (unsigned int)size));
199 * A dos error of ERRDOS/ERRmoredata is not an error.
201 if (cli_is_dos_error(cli)) {
202 uint32 ecode;
203 uint8 eclass;
204 cli_dos_error(cli, &eclass, &ecode);
205 if (eclass != ERRDOS && ecode != ERRmoredata) {
206 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read "
207 "on fnum 0x%x\n", eclass, (unsigned int)ecode,
208 cli_errstr(cli), fnum));
209 return dos_to_ntstatus(eclass, ecode);
214 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
216 if (cli_is_nt_error(cli)) {
217 if (!NT_STATUS_EQUAL(cli_nt_error(cli),
218 NT_STATUS_BUFFER_TOO_SMALL)) {
219 DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum "
220 "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum));
221 return cli_nt_error(cli);
225 if (num_read == -1) {
226 DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned "
227 "-1\n", fnum));
228 return cli_get_nt_error(cli);
231 *pnum_read = num_read;
232 return NT_STATUS_OK;
236 /*******************************************************************
237 Use SMBreadX to get rest of one fragment's worth of rpc data.
238 Will expand the current_pdu struct to the correct size.
239 ********************************************************************/
241 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
242 prs_struct *current_pdu,
243 uint32 data_to_read,
244 uint32 *current_pdu_offset)
246 size_t size = (size_t)cli->max_recv_frag;
247 uint32 stream_offset = 0;
248 ssize_t num_read = 0;
249 char *pdata;
250 ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
252 DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
253 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
256 * Grow the buffer if needed to accommodate the data to be read.
259 if (extra_data_size > 0) {
260 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
261 DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
262 return NT_STATUS_NO_MEMORY;
264 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
267 pdata = prs_data_p(current_pdu) + *current_pdu_offset;
269 do {
270 NTSTATUS status;
272 /* read data using SMBreadX */
273 if (size > (size_t)data_to_read) {
274 size = (size_t)data_to_read;
277 switch (cli->transport_type) {
278 case NCACN_NP:
279 status = rpc_read_np(cli->trans.np.cli,
280 cli->trans.np.pipe_name,
281 cli->trans.np.fnum, pdata,
282 (off_t)stream_offset, size,
283 &num_read);
284 break;
285 case NCACN_IP_TCP:
286 case NCACN_UNIX_STREAM:
287 status = NT_STATUS_OK;
288 num_read = sys_read(cli->trans.sock.fd, pdata, size);
289 if (num_read == -1) {
290 status = map_nt_error_from_unix(errno);
292 if (num_read == 0) {
293 status = NT_STATUS_END_OF_FILE;
295 break;
296 default:
297 DEBUG(0, ("unknown transport type %d\n",
298 cli->transport_type));
299 return NT_STATUS_INTERNAL_ERROR;
302 data_to_read -= num_read;
303 stream_offset += num_read;
304 pdata += num_read;
306 } while (num_read > 0 && data_to_read > 0);
307 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
310 * Update the current offset into current_pdu by the amount read.
312 *current_pdu_offset += stream_offset;
313 return NT_STATUS_OK;
316 /****************************************************************************
317 Try and get a PDU's worth of data from current_pdu. If not, then read more
318 from the wire.
319 ****************************************************************************/
321 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
323 NTSTATUS ret = NT_STATUS_OK;
324 uint32 current_pdu_len = prs_data_size(current_pdu);
326 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
327 if (current_pdu_len < RPC_HEADER_LEN) {
328 /* rpc_read expands the current_pdu struct as neccessary. */
329 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
330 if (!NT_STATUS_IS_OK(ret)) {
331 return ret;
335 /* This next call sets the endian bit correctly in current_pdu. */
336 /* We will propagate this to rbuf later. */
337 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
338 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
339 return NT_STATUS_BUFFER_TOO_SMALL;
342 /* Ensure we have frag_len bytes of data. */
343 if (current_pdu_len < prhdr->frag_len) {
344 /* rpc_read expands the current_pdu struct as neccessary. */
345 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
346 if (!NT_STATUS_IS_OK(ret)) {
347 return ret;
351 if (current_pdu_len < prhdr->frag_len) {
352 return NT_STATUS_BUFFER_TOO_SMALL;
355 return NT_STATUS_OK;
358 /****************************************************************************
359 NTLMSSP specific sign/seal.
360 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
361 In fact I should probably abstract these into identical pieces of code... JRA.
362 ****************************************************************************/
364 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
365 prs_struct *current_pdu,
366 uint8 *p_ss_padding_len)
368 RPC_HDR_AUTH auth_info;
369 uint32 save_offset = prs_offset(current_pdu);
370 uint32 auth_len = prhdr->auth_len;
371 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
372 unsigned char *data = NULL;
373 size_t data_len;
374 unsigned char *full_packet_data = NULL;
375 size_t full_packet_data_len;
376 DATA_BLOB auth_blob;
377 NTSTATUS status;
379 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
380 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
381 return NT_STATUS_OK;
384 if (!ntlmssp_state) {
385 return NT_STATUS_INVALID_PARAMETER;
388 /* Ensure there's enough data for an authenticated response. */
389 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
390 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
391 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
392 (unsigned int)auth_len ));
393 return NT_STATUS_BUFFER_TOO_SMALL;
397 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
398 * after the RPC header.
399 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
400 * functions as NTLMv2 checks the rpc headers also.
403 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
404 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
406 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
407 full_packet_data_len = prhdr->frag_len - auth_len;
409 /* Pull the auth header and the following data into a blob. */
410 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
411 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
412 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
413 return NT_STATUS_BUFFER_TOO_SMALL;
416 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
417 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
418 return NT_STATUS_BUFFER_TOO_SMALL;
421 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
422 auth_blob.length = auth_len;
424 switch (cli->auth->auth_level) {
425 case PIPE_AUTH_LEVEL_PRIVACY:
426 /* Data is encrypted. */
427 status = ntlmssp_unseal_packet(ntlmssp_state,
428 data, data_len,
429 full_packet_data,
430 full_packet_data_len,
431 &auth_blob);
432 if (!NT_STATUS_IS_OK(status)) {
433 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
434 "packet from %s. Error was %s.\n",
435 rpccli_pipe_txt(debug_ctx(), cli),
436 nt_errstr(status) ));
437 return status;
439 break;
440 case PIPE_AUTH_LEVEL_INTEGRITY:
441 /* Data is signed. */
442 status = ntlmssp_check_packet(ntlmssp_state,
443 data, data_len,
444 full_packet_data,
445 full_packet_data_len,
446 &auth_blob);
447 if (!NT_STATUS_IS_OK(status)) {
448 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
449 "packet from %s. Error was %s.\n",
450 rpccli_pipe_txt(debug_ctx(), cli),
451 nt_errstr(status) ));
452 return status;
454 break;
455 default:
456 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
457 "auth level %d\n", cli->auth->auth_level));
458 return NT_STATUS_INVALID_INFO_CLASS;
462 * Return the current pointer to the data offset.
465 if(!prs_set_offset(current_pdu, save_offset)) {
466 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
467 (unsigned int)save_offset ));
468 return NT_STATUS_BUFFER_TOO_SMALL;
472 * Remember the padding length. We must remove it from the real data
473 * stream once the sign/seal is done.
476 *p_ss_padding_len = auth_info.auth_pad_len;
478 return NT_STATUS_OK;
481 /****************************************************************************
482 schannel specific sign/seal.
483 ****************************************************************************/
485 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
486 prs_struct *current_pdu,
487 uint8 *p_ss_padding_len)
489 RPC_HDR_AUTH auth_info;
490 RPC_AUTH_SCHANNEL_CHK schannel_chk;
491 uint32 auth_len = prhdr->auth_len;
492 uint32 save_offset = prs_offset(current_pdu);
493 struct schannel_auth_struct *schannel_auth =
494 cli->auth->a_u.schannel_auth;
495 uint32 data_len;
497 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
498 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
499 return NT_STATUS_OK;
502 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
503 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
504 return NT_STATUS_INVALID_PARAMETER;
507 if (!schannel_auth) {
508 return NT_STATUS_INVALID_PARAMETER;
511 /* Ensure there's enough data for an authenticated response. */
512 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
513 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
514 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
515 (unsigned int)auth_len ));
516 return NT_STATUS_INVALID_PARAMETER;
519 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
521 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
522 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
523 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
524 return NT_STATUS_BUFFER_TOO_SMALL;
527 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
528 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
529 return NT_STATUS_BUFFER_TOO_SMALL;
532 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
533 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
534 auth_info.auth_type));
535 return NT_STATUS_BUFFER_TOO_SMALL;
538 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
539 &schannel_chk, current_pdu, 0)) {
540 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
541 return NT_STATUS_BUFFER_TOO_SMALL;
544 if (!schannel_decode(schannel_auth,
545 cli->auth->auth_level,
546 SENDER_IS_ACCEPTOR,
547 &schannel_chk,
548 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
549 data_len)) {
550 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
551 "Connection to %s.\n",
552 rpccli_pipe_txt(debug_ctx(), cli)));
553 return NT_STATUS_INVALID_PARAMETER;
556 /* The sequence number gets incremented on both send and receive. */
557 schannel_auth->seq_num++;
560 * Return the current pointer to the data offset.
563 if(!prs_set_offset(current_pdu, save_offset)) {
564 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
565 (unsigned int)save_offset ));
566 return NT_STATUS_BUFFER_TOO_SMALL;
570 * Remember the padding length. We must remove it from the real data
571 * stream once the sign/seal is done.
574 *p_ss_padding_len = auth_info.auth_pad_len;
576 return NT_STATUS_OK;
579 /****************************************************************************
580 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
581 ****************************************************************************/
583 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
584 prs_struct *current_pdu,
585 uint8 *p_ss_padding_len)
587 NTSTATUS ret = NT_STATUS_OK;
589 /* Paranioa checks for auth_len. */
590 if (prhdr->auth_len) {
591 if (prhdr->auth_len > prhdr->frag_len) {
592 return NT_STATUS_INVALID_PARAMETER;
595 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
596 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
597 /* Integer wrap attempt. */
598 return NT_STATUS_INVALID_PARAMETER;
603 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
606 switch(cli->auth->auth_type) {
607 case PIPE_AUTH_TYPE_NONE:
608 if (prhdr->auth_len) {
609 DEBUG(3, ("cli_pipe_validate_rpc_response: "
610 "Connection to %s - got non-zero "
611 "auth len %u.\n",
612 rpccli_pipe_txt(debug_ctx(), cli),
613 (unsigned int)prhdr->auth_len ));
614 return NT_STATUS_INVALID_PARAMETER;
616 break;
618 case PIPE_AUTH_TYPE_NTLMSSP:
619 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
620 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
621 if (!NT_STATUS_IS_OK(ret)) {
622 return ret;
624 break;
626 case PIPE_AUTH_TYPE_SCHANNEL:
627 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
628 if (!NT_STATUS_IS_OK(ret)) {
629 return ret;
631 break;
633 case PIPE_AUTH_TYPE_KRB5:
634 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
635 default:
636 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
637 "to %s - unknown internal auth type %u.\n",
638 rpccli_pipe_txt(debug_ctx(), cli),
639 cli->auth->auth_type ));
640 return NT_STATUS_INVALID_INFO_CLASS;
643 return NT_STATUS_OK;
646 /****************************************************************************
647 Do basic authentication checks on an incoming pdu.
648 ****************************************************************************/
650 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
651 prs_struct *current_pdu,
652 uint8 expected_pkt_type,
653 char **ppdata,
654 uint32 *pdata_len,
655 prs_struct *return_data)
658 NTSTATUS ret = NT_STATUS_OK;
659 uint32 current_pdu_len = prs_data_size(current_pdu);
661 if (current_pdu_len != prhdr->frag_len) {
662 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
663 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
664 return NT_STATUS_INVALID_PARAMETER;
668 * Point the return values at the real data including the RPC
669 * header. Just in case the caller wants it.
671 *ppdata = prs_data_p(current_pdu);
672 *pdata_len = current_pdu_len;
674 /* Ensure we have the correct type. */
675 switch (prhdr->pkt_type) {
676 case RPC_ALTCONTRESP:
677 case RPC_BINDACK:
679 /* Alter context and bind ack share the same packet definitions. */
680 break;
683 case RPC_RESPONSE:
685 RPC_HDR_RESP rhdr_resp;
686 uint8 ss_padding_len = 0;
688 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
689 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
690 return NT_STATUS_BUFFER_TOO_SMALL;
693 /* Here's where we deal with incoming sign/seal. */
694 ret = cli_pipe_validate_rpc_response(cli, prhdr,
695 current_pdu, &ss_padding_len);
696 if (!NT_STATUS_IS_OK(ret)) {
697 return ret;
700 /* Point the return values at the NDR data. Remember to remove any ss padding. */
701 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
703 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
704 return NT_STATUS_BUFFER_TOO_SMALL;
707 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
709 /* Remember to remove the auth footer. */
710 if (prhdr->auth_len) {
711 /* We've already done integer wrap tests on auth_len in
712 cli_pipe_validate_rpc_response(). */
713 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
714 return NT_STATUS_BUFFER_TOO_SMALL;
716 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
719 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
720 current_pdu_len, *pdata_len, ss_padding_len ));
723 * If this is the first reply, and the allocation hint is reasonably, try and
724 * set up the return_data parse_struct to the correct size.
727 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
728 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
729 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
730 "too large to allocate\n",
731 (unsigned int)rhdr_resp.alloc_hint ));
732 return NT_STATUS_NO_MEMORY;
736 break;
739 case RPC_BINDNACK:
740 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
741 "received from %s!\n",
742 rpccli_pipe_txt(debug_ctx(), cli)));
743 /* Use this for now... */
744 return NT_STATUS_NETWORK_ACCESS_DENIED;
746 case RPC_FAULT:
748 RPC_HDR_RESP rhdr_resp;
749 RPC_HDR_FAULT fault_resp;
751 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
752 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
753 return NT_STATUS_BUFFER_TOO_SMALL;
756 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
757 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
758 return NT_STATUS_BUFFER_TOO_SMALL;
761 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
762 "code %s received from %s!\n",
763 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
764 rpccli_pipe_txt(debug_ctx(), cli)));
765 if (NT_STATUS_IS_OK(fault_resp.status)) {
766 return NT_STATUS_UNSUCCESSFUL;
767 } else {
768 return fault_resp.status;
772 default:
773 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
774 "from %s!\n",
775 (unsigned int)prhdr->pkt_type,
776 rpccli_pipe_txt(debug_ctx(), cli)));
777 return NT_STATUS_INVALID_INFO_CLASS;
780 if (prhdr->pkt_type != expected_pkt_type) {
781 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
782 "got an unexpected RPC packet type - %u, not %u\n",
783 rpccli_pipe_txt(debug_ctx(), cli),
784 prhdr->pkt_type,
785 expected_pkt_type));
786 return NT_STATUS_INVALID_INFO_CLASS;
789 /* Do this just before return - we don't want to modify any rpc header
790 data before now as we may have needed to do cryptographic actions on
791 it before. */
793 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
794 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
795 "setting fragment first/last ON.\n"));
796 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
799 return NT_STATUS_OK;
802 /****************************************************************************
803 Ensure we eat the just processed pdu from the current_pdu prs_struct.
804 Normally the frag_len and buffer size will match, but on the first trans
805 reply there is a theoretical chance that buffer size > frag_len, so we must
806 deal with that.
807 ****************************************************************************/
809 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
811 uint32 current_pdu_len = prs_data_size(current_pdu);
813 if (current_pdu_len < prhdr->frag_len) {
814 return NT_STATUS_BUFFER_TOO_SMALL;
817 /* Common case. */
818 if (current_pdu_len == (uint32)prhdr->frag_len) {
819 prs_mem_free(current_pdu);
820 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
821 /* Make current_pdu dynamic with no memory. */
822 prs_give_memory(current_pdu, 0, 0, True);
823 return NT_STATUS_OK;
827 * Oh no ! More data in buffer than we processed in current pdu.
828 * Cheat. Move the data down and shrink the buffer.
831 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
832 current_pdu_len - prhdr->frag_len);
834 /* Remember to set the read offset back to zero. */
835 prs_set_offset(current_pdu, 0);
837 /* Shrink the buffer. */
838 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
839 return NT_STATUS_BUFFER_TOO_SMALL;
842 return NT_STATUS_OK;
845 /****************************************************************************
846 Send data on an rpc pipe via trans. The prs_struct data must be the last
847 pdu fragment of an NDR data stream.
849 Receive response data from an rpc pipe, which may be large...
851 Read the first fragment: unfortunately have to use SMBtrans for the first
852 bit, then SMBreadX for subsequent bits.
854 If first fragment received also wasn't the last fragment, continue
855 getting fragments until we _do_ receive the last fragment.
857 Request/Response PDU's look like the following...
859 |<------------------PDU len----------------------------------------------->|
860 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
862 +------------+-----------------+-------------+---------------+-------------+
863 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
864 +------------+-----------------+-------------+---------------+-------------+
866 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
867 signing & sealing being negotiated.
869 ****************************************************************************/
871 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
872 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
873 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
874 uint8 expected_pkt_type)
876 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
877 char *rparam = NULL;
878 uint32 rparam_len = 0;
879 char *pdata = prs_data_p(data);
880 uint32 data_len = prs_offset(data);
881 char *prdata = NULL;
882 uint32 rdata_len = 0;
883 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
884 uint32 current_rbuf_offset = 0;
885 prs_struct current_pdu;
887 #ifdef DEVELOPER
888 /* Ensure we're not sending too much. */
889 SMB_ASSERT(data_len <= max_data);
890 #endif
892 /* Set up the current pdu parse struct. */
893 prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
895 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
897 switch (cli->transport_type) {
898 case NCACN_NP: {
899 uint16 setup[2];
900 /* Create setup parameters - must be in native byte order. */
901 setup[0] = TRANSACT_DCERPCCMD;
902 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
905 * Send the last (or only) fragment of an RPC request. For
906 * small amounts of data (about 1024 bytes or so) the RPC
907 * request and response appears in a SMBtrans request and
908 * response.
911 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
912 setup, 2, 0, /* Setup, length, max */
913 NULL, 0, 0, /* Params, length, max */
914 pdata, data_len, max_data, /* data, length,
915 * max */
916 &rparam, &rparam_len, /* return params,
917 * len */
918 &prdata, &rdata_len)) /* return data, len */
920 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
921 "Error was %s\n",
922 rpccli_pipe_txt(debug_ctx(), cli),
923 cli_errstr(cli->trans.np.cli)));
924 ret = cli_get_nt_error(cli->trans.np.cli);
925 SAFE_FREE(rparam);
926 SAFE_FREE(prdata);
927 goto err;
929 break;
931 case NCACN_IP_TCP:
932 case NCACN_UNIX_STREAM:
934 ssize_t nwritten, nread;
935 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
936 if (nwritten == -1) {
937 ret = map_nt_error_from_unix(errno);
938 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
939 strerror(errno)));
940 goto err;
942 rparam = NULL;
943 prdata = SMB_MALLOC_ARRAY(char, 1);
944 if (prdata == NULL) {
945 return NT_STATUS_NO_MEMORY;
947 nread = sys_read(cli->trans.sock.fd, prdata, 1);
948 if (nread == 0) {
949 SAFE_FREE(prdata);
951 if (nread == -1) {
952 ret = NT_STATUS_END_OF_FILE;
953 goto err;
955 rdata_len = nread;
956 break;
958 default:
959 DEBUG(0, ("unknown transport type %d\n",
960 cli->transport_type));
961 return NT_STATUS_INTERNAL_ERROR;
964 /* Throw away returned params - we know we won't use them. */
966 SAFE_FREE(rparam);
968 if (prdata == NULL) {
969 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
970 rpccli_pipe_txt(debug_ctx(), cli)));
971 /* Yes - some calls can truely return no data... */
972 prs_mem_free(&current_pdu);
973 return NT_STATUS_OK;
977 * Give this memory as dynamic to the current pdu.
980 prs_give_memory(&current_pdu, prdata, rdata_len, True);
982 /* Ensure we can mess with the return prs_struct. */
983 SMB_ASSERT(UNMARSHALLING(rbuf));
984 SMB_ASSERT(prs_data_size(rbuf) == 0);
986 /* Make rbuf dynamic with no memory. */
987 prs_give_memory(rbuf, 0, 0, True);
989 while(1) {
990 RPC_HDR rhdr;
991 char *ret_data;
992 uint32 ret_data_len;
994 /* Ensure we have enough data for a pdu. */
995 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
996 if (!NT_STATUS_IS_OK(ret)) {
997 goto err;
1000 /* We pass in rbuf here so if the alloc hint is set correctly
1001 we can set the output size and avoid reallocs. */
1003 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
1004 &ret_data, &ret_data_len, rbuf);
1006 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
1007 prs_data_size(&current_pdu), current_rbuf_offset ));
1009 if (!NT_STATUS_IS_OK(ret)) {
1010 goto err;
1013 if ((rhdr.flags & RPC_FLG_FIRST)) {
1014 if (rhdr.pack_type[0] == 0) {
1015 /* Set the data type correctly for big-endian data on the first packet. */
1016 DEBUG(10,("rpc_api_pipe: On %s "
1017 "PDU data format is big-endian.\n",
1018 rpccli_pipe_txt(debug_ctx(), cli)));
1020 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
1021 } else {
1022 /* Check endianness on subsequent packets. */
1023 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
1024 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1025 rbuf->bigendian_data ? "big" : "little",
1026 current_pdu.bigendian_data ? "big" : "little" ));
1027 ret = NT_STATUS_INVALID_PARAMETER;
1028 goto err;
1033 /* Now copy the data portion out of the pdu into rbuf. */
1034 if (!prs_force_grow(rbuf, ret_data_len)) {
1035 ret = NT_STATUS_NO_MEMORY;
1036 goto err;
1038 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
1039 current_rbuf_offset += ret_data_len;
1041 /* See if we've finished with all the data in current_pdu yet ? */
1042 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
1043 if (!NT_STATUS_IS_OK(ret)) {
1044 goto err;
1047 if (rhdr.flags & RPC_FLG_LAST) {
1048 break; /* We're done. */
1052 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1053 rpccli_pipe_txt(debug_ctx(), cli),
1054 (unsigned int)prs_data_size(rbuf) ));
1056 prs_mem_free(&current_pdu);
1057 return NT_STATUS_OK;
1059 err:
1061 prs_mem_free(&current_pdu);
1062 prs_mem_free(rbuf);
1063 return ret;
1066 /*******************************************************************
1067 Creates krb5 auth bind.
1068 ********************************************************************/
1070 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1071 enum pipe_auth_level auth_level,
1072 RPC_HDR_AUTH *pauth_out,
1073 prs_struct *auth_data)
1075 #ifdef HAVE_KRB5
1076 int ret;
1077 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1078 DATA_BLOB tkt = data_blob_null;
1079 DATA_BLOB tkt_wrapped = data_blob_null;
1081 /* We may change the pad length before marshalling. */
1082 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1084 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1085 a->service_principal ));
1087 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1089 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1090 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1092 if (ret) {
1093 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1094 "failed with %s\n",
1095 a->service_principal,
1096 error_message(ret) ));
1098 data_blob_free(&tkt);
1099 prs_mem_free(auth_data);
1100 return NT_STATUS_INVALID_PARAMETER;
1103 /* wrap that up in a nice GSS-API wrapping */
1104 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1106 data_blob_free(&tkt);
1108 /* Auth len in the rpc header doesn't include auth_header. */
1109 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1110 data_blob_free(&tkt_wrapped);
1111 prs_mem_free(auth_data);
1112 return NT_STATUS_NO_MEMORY;
1115 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1116 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1118 data_blob_free(&tkt_wrapped);
1119 return NT_STATUS_OK;
1120 #else
1121 return NT_STATUS_INVALID_PARAMETER;
1122 #endif
1125 /*******************************************************************
1126 Creates SPNEGO NTLMSSP auth bind.
1127 ********************************************************************/
1129 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1130 enum pipe_auth_level auth_level,
1131 RPC_HDR_AUTH *pauth_out,
1132 prs_struct *auth_data)
1134 NTSTATUS nt_status;
1135 DATA_BLOB null_blob = data_blob_null;
1136 DATA_BLOB request = data_blob_null;
1137 DATA_BLOB spnego_msg = data_blob_null;
1139 /* We may change the pad length before marshalling. */
1140 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1142 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1143 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1144 null_blob,
1145 &request);
1147 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1148 data_blob_free(&request);
1149 prs_mem_free(auth_data);
1150 return nt_status;
1153 /* Wrap this in SPNEGO. */
1154 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1156 data_blob_free(&request);
1158 /* Auth len in the rpc header doesn't include auth_header. */
1159 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1160 data_blob_free(&spnego_msg);
1161 prs_mem_free(auth_data);
1162 return NT_STATUS_NO_MEMORY;
1165 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1166 dump_data(5, spnego_msg.data, spnego_msg.length);
1168 data_blob_free(&spnego_msg);
1169 return NT_STATUS_OK;
1172 /*******************************************************************
1173 Creates NTLMSSP auth bind.
1174 ********************************************************************/
1176 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1177 enum pipe_auth_level auth_level,
1178 RPC_HDR_AUTH *pauth_out,
1179 prs_struct *auth_data)
1181 NTSTATUS nt_status;
1182 DATA_BLOB null_blob = data_blob_null;
1183 DATA_BLOB request = data_blob_null;
1185 /* We may change the pad length before marshalling. */
1186 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1188 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1189 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1190 null_blob,
1191 &request);
1193 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1194 data_blob_free(&request);
1195 prs_mem_free(auth_data);
1196 return nt_status;
1199 /* Auth len in the rpc header doesn't include auth_header. */
1200 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1201 data_blob_free(&request);
1202 prs_mem_free(auth_data);
1203 return NT_STATUS_NO_MEMORY;
1206 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1207 dump_data(5, request.data, request.length);
1209 data_blob_free(&request);
1210 return NT_STATUS_OK;
1213 /*******************************************************************
1214 Creates schannel auth bind.
1215 ********************************************************************/
1217 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1218 enum pipe_auth_level auth_level,
1219 RPC_HDR_AUTH *pauth_out,
1220 prs_struct *auth_data)
1222 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1224 /* We may change the pad length before marshalling. */
1225 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1227 /* Use lp_workgroup() if domain not specified */
1229 if (!cli->auth->domain || !cli->auth->domain[0]) {
1230 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1231 if (cli->auth->domain == NULL) {
1232 return NT_STATUS_NO_MEMORY;
1236 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1237 global_myname());
1240 * Now marshall the data into the auth parse_struct.
1243 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1244 &schannel_neg, auth_data, 0)) {
1245 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1246 prs_mem_free(auth_data);
1247 return NT_STATUS_NO_MEMORY;
1250 return NT_STATUS_OK;
1253 /*******************************************************************
1254 Creates the internals of a DCE/RPC bind request or alter context PDU.
1255 ********************************************************************/
1257 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1258 prs_struct *rpc_out,
1259 uint32 rpc_call_id,
1260 const RPC_IFACE *abstract,
1261 const RPC_IFACE *transfer,
1262 RPC_HDR_AUTH *phdr_auth,
1263 prs_struct *pauth_info)
1265 RPC_HDR hdr;
1266 RPC_HDR_RB hdr_rb;
1267 RPC_CONTEXT rpc_ctx;
1268 uint16 auth_len = prs_offset(pauth_info);
1269 uint8 ss_padding_len = 0;
1270 uint16 frag_len = 0;
1272 /* create the RPC context. */
1273 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1275 /* create the bind request RPC_HDR_RB */
1276 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1278 /* Start building the frag length. */
1279 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1281 /* Do we need to pad ? */
1282 if (auth_len) {
1283 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1284 if (data_len % 8) {
1285 ss_padding_len = 8 - (data_len % 8);
1286 phdr_auth->auth_pad_len = ss_padding_len;
1288 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1291 /* Create the request RPC_HDR */
1292 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1294 /* Marshall the RPC header */
1295 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1296 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1297 return NT_STATUS_NO_MEMORY;
1300 /* Marshall the bind request data */
1301 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1302 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1303 return NT_STATUS_NO_MEMORY;
1307 * Grow the outgoing buffer to store any auth info.
1310 if(auth_len != 0) {
1311 if (ss_padding_len) {
1312 char pad[8];
1313 memset(pad, '\0', 8);
1314 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1315 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1316 return NT_STATUS_NO_MEMORY;
1320 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1321 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1322 return NT_STATUS_NO_MEMORY;
1326 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1327 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1328 return NT_STATUS_NO_MEMORY;
1332 return NT_STATUS_OK;
1335 /*******************************************************************
1336 Creates a DCE/RPC bind request.
1337 ********************************************************************/
1339 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1340 prs_struct *rpc_out,
1341 uint32 rpc_call_id,
1342 const RPC_IFACE *abstract,
1343 const RPC_IFACE *transfer,
1344 enum pipe_auth_type auth_type,
1345 enum pipe_auth_level auth_level)
1347 RPC_HDR_AUTH hdr_auth;
1348 prs_struct auth_info;
1349 NTSTATUS ret = NT_STATUS_OK;
1351 ZERO_STRUCT(hdr_auth);
1352 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1353 return NT_STATUS_NO_MEMORY;
1355 switch (auth_type) {
1356 case PIPE_AUTH_TYPE_SCHANNEL:
1357 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1358 if (!NT_STATUS_IS_OK(ret)) {
1359 prs_mem_free(&auth_info);
1360 return ret;
1362 break;
1364 case PIPE_AUTH_TYPE_NTLMSSP:
1365 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1366 if (!NT_STATUS_IS_OK(ret)) {
1367 prs_mem_free(&auth_info);
1368 return ret;
1370 break;
1372 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1373 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1374 if (!NT_STATUS_IS_OK(ret)) {
1375 prs_mem_free(&auth_info);
1376 return ret;
1378 break;
1380 case PIPE_AUTH_TYPE_KRB5:
1381 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1382 if (!NT_STATUS_IS_OK(ret)) {
1383 prs_mem_free(&auth_info);
1384 return ret;
1386 break;
1388 case PIPE_AUTH_TYPE_NONE:
1389 break;
1391 default:
1392 /* "Can't" happen. */
1393 return NT_STATUS_INVALID_INFO_CLASS;
1396 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1397 rpc_out,
1398 rpc_call_id,
1399 abstract,
1400 transfer,
1401 &hdr_auth,
1402 &auth_info);
1404 prs_mem_free(&auth_info);
1405 return ret;
1408 /*******************************************************************
1409 Create and add the NTLMSSP sign/seal auth header and data.
1410 ********************************************************************/
1412 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1413 RPC_HDR *phdr,
1414 uint32 ss_padding_len,
1415 prs_struct *outgoing_pdu)
1417 RPC_HDR_AUTH auth_info;
1418 NTSTATUS status;
1419 DATA_BLOB auth_blob = data_blob_null;
1420 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1422 if (!cli->auth->a_u.ntlmssp_state) {
1423 return NT_STATUS_INVALID_PARAMETER;
1426 /* Init and marshall the auth header. */
1427 init_rpc_hdr_auth(&auth_info,
1428 map_pipe_auth_type_to_rpc_auth_type(
1429 cli->auth->auth_type),
1430 cli->auth->auth_level,
1431 ss_padding_len,
1432 1 /* context id. */);
1434 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1435 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1436 data_blob_free(&auth_blob);
1437 return NT_STATUS_NO_MEMORY;
1440 switch (cli->auth->auth_level) {
1441 case PIPE_AUTH_LEVEL_PRIVACY:
1442 /* Data portion is encrypted. */
1443 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1444 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1445 data_and_pad_len,
1446 (unsigned char *)prs_data_p(outgoing_pdu),
1447 (size_t)prs_offset(outgoing_pdu),
1448 &auth_blob);
1449 if (!NT_STATUS_IS_OK(status)) {
1450 data_blob_free(&auth_blob);
1451 return status;
1453 break;
1455 case PIPE_AUTH_LEVEL_INTEGRITY:
1456 /* Data is signed. */
1457 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1458 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1459 data_and_pad_len,
1460 (unsigned char *)prs_data_p(outgoing_pdu),
1461 (size_t)prs_offset(outgoing_pdu),
1462 &auth_blob);
1463 if (!NT_STATUS_IS_OK(status)) {
1464 data_blob_free(&auth_blob);
1465 return status;
1467 break;
1469 default:
1470 /* Can't happen. */
1471 smb_panic("bad auth level");
1472 /* Notreached. */
1473 return NT_STATUS_INVALID_PARAMETER;
1476 /* Finally marshall the blob. */
1478 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1479 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1480 (unsigned int)NTLMSSP_SIG_SIZE));
1481 data_blob_free(&auth_blob);
1482 return NT_STATUS_NO_MEMORY;
1485 data_blob_free(&auth_blob);
1486 return NT_STATUS_OK;
1489 /*******************************************************************
1490 Create and add the schannel sign/seal auth header and data.
1491 ********************************************************************/
1493 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1494 RPC_HDR *phdr,
1495 uint32 ss_padding_len,
1496 prs_struct *outgoing_pdu)
1498 RPC_HDR_AUTH auth_info;
1499 RPC_AUTH_SCHANNEL_CHK verf;
1500 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1501 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1502 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1504 if (!sas) {
1505 return NT_STATUS_INVALID_PARAMETER;
1508 /* Init and marshall the auth header. */
1509 init_rpc_hdr_auth(&auth_info,
1510 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1511 cli->auth->auth_level,
1512 ss_padding_len,
1513 1 /* context id. */);
1515 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1516 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1517 return NT_STATUS_NO_MEMORY;
1520 switch (cli->auth->auth_level) {
1521 case PIPE_AUTH_LEVEL_PRIVACY:
1522 case PIPE_AUTH_LEVEL_INTEGRITY:
1523 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1524 sas->seq_num));
1526 schannel_encode(sas,
1527 cli->auth->auth_level,
1528 SENDER_IS_INITIATOR,
1529 &verf,
1530 data_p,
1531 data_and_pad_len);
1533 sas->seq_num++;
1534 break;
1536 default:
1537 /* Can't happen. */
1538 smb_panic("bad auth level");
1539 /* Notreached. */
1540 return NT_STATUS_INVALID_PARAMETER;
1543 /* Finally marshall the blob. */
1544 smb_io_rpc_auth_schannel_chk("",
1545 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1546 &verf,
1547 outgoing_pdu,
1550 return NT_STATUS_OK;
1553 /*******************************************************************
1554 Calculate how much data we're going to send in this packet, also
1555 work out any sign/seal padding length.
1556 ********************************************************************/
1558 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1559 uint32 data_left,
1560 uint16 *p_frag_len,
1561 uint16 *p_auth_len,
1562 uint32 *p_ss_padding)
1564 uint32 data_space, data_len;
1566 switch (cli->auth->auth_level) {
1567 case PIPE_AUTH_LEVEL_NONE:
1568 case PIPE_AUTH_LEVEL_CONNECT:
1569 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1570 data_len = MIN(data_space, data_left);
1571 *p_ss_padding = 0;
1572 *p_auth_len = 0;
1573 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1574 return data_len;
1576 case PIPE_AUTH_LEVEL_INTEGRITY:
1577 case PIPE_AUTH_LEVEL_PRIVACY:
1578 /* Treat the same for all authenticated rpc requests. */
1579 switch(cli->auth->auth_type) {
1580 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1581 case PIPE_AUTH_TYPE_NTLMSSP:
1582 *p_auth_len = NTLMSSP_SIG_SIZE;
1583 break;
1584 case PIPE_AUTH_TYPE_SCHANNEL:
1585 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1586 break;
1587 default:
1588 smb_panic("bad auth type");
1589 break;
1592 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1593 RPC_HDR_AUTH_LEN - *p_auth_len;
1595 data_len = MIN(data_space, data_left);
1596 if (data_len % 8) {
1597 *p_ss_padding = 8 - (data_len % 8);
1599 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1600 data_len + *p_ss_padding + /* data plus padding. */
1601 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1602 return data_len;
1604 default:
1605 smb_panic("bad auth level");
1606 /* Notreached. */
1607 return 0;
1611 /*******************************************************************
1612 External interface.
1613 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1614 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1615 and deals with signing/sealing details.
1616 ********************************************************************/
1618 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1619 uint8 op_num,
1620 prs_struct *in_data,
1621 prs_struct *out_data)
1623 NTSTATUS ret;
1624 uint32 data_left = prs_offset(in_data);
1625 uint32 alloc_hint = prs_offset(in_data);
1626 uint32 data_sent_thistime = 0;
1627 uint32 current_data_offset = 0;
1628 uint32 call_id = get_rpc_call_id();
1629 char pad[8];
1630 prs_struct outgoing_pdu;
1632 memset(pad, '\0', 8);
1634 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1635 /* Server is screwed up ! */
1636 return NT_STATUS_INVALID_PARAMETER;
1639 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1640 return NT_STATUS_NO_MEMORY;
1642 while (1) {
1643 RPC_HDR hdr;
1644 RPC_HDR_REQ hdr_req;
1645 uint16 auth_len = 0;
1646 uint16 frag_len = 0;
1647 uint8 flags = 0;
1648 uint32 ss_padding = 0;
1650 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1651 &frag_len, &auth_len, &ss_padding);
1653 if (current_data_offset == 0) {
1654 flags = RPC_FLG_FIRST;
1657 if (data_sent_thistime == data_left) {
1658 flags |= RPC_FLG_LAST;
1661 /* Create and marshall the header and request header. */
1662 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1664 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1665 prs_mem_free(&outgoing_pdu);
1666 return NT_STATUS_NO_MEMORY;
1669 /* Create the rpc request RPC_HDR_REQ */
1670 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1672 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1673 prs_mem_free(&outgoing_pdu);
1674 return NT_STATUS_NO_MEMORY;
1677 /* Copy in the data, plus any ss padding. */
1678 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1679 prs_mem_free(&outgoing_pdu);
1680 return NT_STATUS_NO_MEMORY;
1683 /* Copy the sign/seal padding data. */
1684 if (ss_padding) {
1685 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1686 prs_mem_free(&outgoing_pdu);
1687 return NT_STATUS_NO_MEMORY;
1691 /* Generate any auth sign/seal and add the auth footer. */
1692 if (auth_len) {
1693 switch (cli->auth->auth_type) {
1694 case PIPE_AUTH_TYPE_NONE:
1695 break;
1696 case PIPE_AUTH_TYPE_NTLMSSP:
1697 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1698 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1699 if (!NT_STATUS_IS_OK(ret)) {
1700 prs_mem_free(&outgoing_pdu);
1701 return ret;
1703 break;
1704 case PIPE_AUTH_TYPE_SCHANNEL:
1705 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1706 if (!NT_STATUS_IS_OK(ret)) {
1707 prs_mem_free(&outgoing_pdu);
1708 return ret;
1710 break;
1711 default:
1712 smb_panic("bad auth type");
1713 break; /* notreached */
1717 /* Actually send the packet. */
1718 if (flags & RPC_FLG_LAST) {
1719 /* Last packet - send the data, get the reply and return. */
1720 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1721 prs_mem_free(&outgoing_pdu);
1723 if ((DEBUGLEVEL >= 50)
1724 && (cli->transport_type == NCACN_NP)) {
1725 char *dump_name = NULL;
1726 /* Also capture received data */
1727 if (asprintf(&dump_name, "%s/reply_%s_%d",
1728 get_dyn_LOGFILEBASE(),
1729 cli->trans.np.pipe_name, op_num) > 0) {
1730 prs_dump(dump_name, op_num, out_data);
1731 SAFE_FREE(dump_name);
1735 return ret;
1736 } else {
1737 /* More packets to come - write and continue. */
1738 ssize_t num_written;
1740 switch (cli->transport_type) {
1741 case NCACN_NP:
1742 num_written = cli_write(cli->trans.np.cli,
1743 cli->trans.np.fnum,
1744 8, /* 8 means message mode. */
1745 prs_data_p(&outgoing_pdu),
1746 (off_t)0,
1747 (size_t)hdr.frag_len);
1749 if (num_written != hdr.frag_len) {
1750 prs_mem_free(&outgoing_pdu);
1751 return cli_get_nt_error(
1752 cli->trans.np.cli);
1754 break;
1755 case NCACN_IP_TCP:
1756 case NCACN_UNIX_STREAM:
1757 num_written = write_data(
1758 cli->trans.sock.fd,
1759 prs_data_p(&outgoing_pdu),
1760 (size_t)hdr.frag_len);
1761 if (num_written != hdr.frag_len) {
1762 NTSTATUS status;
1763 status = map_nt_error_from_unix(errno);
1764 prs_mem_free(&outgoing_pdu);
1765 return status;
1767 break;
1768 default:
1769 DEBUG(0, ("unknown transport type %d\n",
1770 cli->transport_type));
1771 return NT_STATUS_INTERNAL_ERROR;
1775 current_data_offset += data_sent_thistime;
1776 data_left -= data_sent_thistime;
1778 /* Reset the marshalling position back to zero. */
1779 if (!prs_set_offset(&outgoing_pdu, 0)) {
1780 prs_mem_free(&outgoing_pdu);
1781 return NT_STATUS_NO_MEMORY;
1785 #if 0
1786 /****************************************************************************
1787 Set the handle state.
1788 ****************************************************************************/
1790 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1791 const char *pipe_name, uint16 device_state)
1793 bool state_set = False;
1794 char param[2];
1795 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1796 char *rparam = NULL;
1797 char *rdata = NULL;
1798 uint32 rparam_len, rdata_len;
1800 if (pipe_name == NULL)
1801 return False;
1803 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1804 cli->fnum, pipe_name, device_state));
1806 /* create parameters: device state */
1807 SSVAL(param, 0, device_state);
1809 /* create setup parameters. */
1810 setup[0] = 0x0001;
1811 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1813 /* send the data on \PIPE\ */
1814 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1815 setup, 2, 0, /* setup, length, max */
1816 param, 2, 0, /* param, length, max */
1817 NULL, 0, 1024, /* data, length, max */
1818 &rparam, &rparam_len, /* return param, length */
1819 &rdata, &rdata_len)) /* return data, length */
1821 DEBUG(5, ("Set Handle state: return OK\n"));
1822 state_set = True;
1825 SAFE_FREE(rparam);
1826 SAFE_FREE(rdata);
1828 return state_set;
1830 #endif
1832 /****************************************************************************
1833 Check the rpc bind acknowledge response.
1834 ****************************************************************************/
1836 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1838 if ( hdr_ba->addr.len == 0) {
1839 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1842 /* check the transfer syntax */
1843 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1844 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1845 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1846 return False;
1849 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1850 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1851 hdr_ba->res.num_results, hdr_ba->res.reason));
1854 DEBUG(5,("check_bind_response: accepted!\n"));
1855 return True;
1858 /*******************************************************************
1859 Creates a DCE/RPC bind authentication response.
1860 This is the packet that is sent back to the server once we
1861 have received a BIND-ACK, to finish the third leg of
1862 the authentication handshake.
1863 ********************************************************************/
1865 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1866 uint32 rpc_call_id,
1867 enum pipe_auth_type auth_type,
1868 enum pipe_auth_level auth_level,
1869 DATA_BLOB *pauth_blob,
1870 prs_struct *rpc_out)
1872 RPC_HDR hdr;
1873 RPC_HDR_AUTH hdr_auth;
1874 uint32 pad = 0;
1876 /* Create the request RPC_HDR */
1877 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1878 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1879 pauth_blob->length );
1881 /* Marshall it. */
1882 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1883 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1884 return NT_STATUS_NO_MEMORY;
1888 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1889 about padding - shouldn't this pad to length 8 ? JRA.
1892 /* 4 bytes padding. */
1893 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1894 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1895 return NT_STATUS_NO_MEMORY;
1898 /* Create the request RPC_HDR_AUTHA */
1899 init_rpc_hdr_auth(&hdr_auth,
1900 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1901 auth_level, 0, 1);
1903 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1904 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1905 return NT_STATUS_NO_MEMORY;
1909 * Append the auth data to the outgoing buffer.
1912 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1913 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1914 return NT_STATUS_NO_MEMORY;
1917 return NT_STATUS_OK;
1920 /****************************************************************************
1921 Create and send the third packet in an RPC auth.
1922 ****************************************************************************/
1924 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1925 RPC_HDR *phdr,
1926 prs_struct *rbuf,
1927 uint32 rpc_call_id,
1928 enum pipe_auth_type auth_type,
1929 enum pipe_auth_level auth_level)
1931 DATA_BLOB server_response = data_blob_null;
1932 DATA_BLOB client_reply = data_blob_null;
1933 RPC_HDR_AUTH hdr_auth;
1934 NTSTATUS nt_status;
1935 prs_struct rpc_out;
1936 ssize_t ret;
1938 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1939 return NT_STATUS_INVALID_PARAMETER;
1942 /* Process the returned NTLMSSP blob first. */
1943 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1944 return NT_STATUS_INVALID_PARAMETER;
1947 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1948 return NT_STATUS_INVALID_PARAMETER;
1951 /* TODO - check auth_type/auth_level match. */
1953 server_response = data_blob(NULL, phdr->auth_len);
1954 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1956 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1957 server_response,
1958 &client_reply);
1960 if (!NT_STATUS_IS_OK(nt_status)) {
1961 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1962 data_blob_free(&server_response);
1963 return nt_status;
1966 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1968 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1969 auth_type, auth_level,
1970 &client_reply, &rpc_out);
1972 if (!NT_STATUS_IS_OK(nt_status)) {
1973 prs_mem_free(&rpc_out);
1974 data_blob_free(&client_reply);
1975 data_blob_free(&server_response);
1976 return nt_status;
1979 switch (cli->transport_type) {
1980 case NCACN_NP:
1981 /* 8 here is named pipe message mode. */
1982 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
1983 0x8, prs_data_p(&rpc_out), 0,
1984 (size_t)prs_offset(&rpc_out));
1985 break;
1987 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1988 nt_status = cli_get_nt_error(cli->trans.np.cli);
1990 case NCACN_IP_TCP:
1991 case NCACN_UNIX_STREAM:
1992 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
1993 (size_t)prs_offset(&rpc_out));
1994 if (ret != (ssize_t)prs_offset(&rpc_out)) {
1995 nt_status = map_nt_error_from_unix(errno);
1997 break;
1998 default:
1999 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
2000 return NT_STATUS_INTERNAL_ERROR;
2003 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2004 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
2005 nt_errstr(nt_status)));
2006 prs_mem_free(&rpc_out);
2007 data_blob_free(&client_reply);
2008 data_blob_free(&server_response);
2009 return nt_status;
2012 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2013 rpccli_pipe_txt(debug_ctx(), cli)));
2015 prs_mem_free(&rpc_out);
2016 data_blob_free(&client_reply);
2017 data_blob_free(&server_response);
2018 return NT_STATUS_OK;
2021 /*******************************************************************
2022 Creates a DCE/RPC bind alter context authentication request which
2023 may contain a spnego auth blobl
2024 ********************************************************************/
2026 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2027 const RPC_IFACE *abstract,
2028 const RPC_IFACE *transfer,
2029 enum pipe_auth_level auth_level,
2030 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2031 prs_struct *rpc_out)
2033 RPC_HDR_AUTH hdr_auth;
2034 prs_struct auth_info;
2035 NTSTATUS ret = NT_STATUS_OK;
2037 ZERO_STRUCT(hdr_auth);
2038 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2039 return NT_STATUS_NO_MEMORY;
2041 /* We may change the pad length before marshalling. */
2042 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2044 if (pauth_blob->length) {
2045 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2046 prs_mem_free(&auth_info);
2047 return NT_STATUS_NO_MEMORY;
2051 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2052 rpc_out,
2053 rpc_call_id,
2054 abstract,
2055 transfer,
2056 &hdr_auth,
2057 &auth_info);
2058 prs_mem_free(&auth_info);
2059 return ret;
2062 /*******************************************************************
2063 Third leg of the SPNEGO bind mechanism - sends alter context PDU
2064 and gets a response.
2065 ********************************************************************/
2067 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
2068 RPC_HDR *phdr,
2069 prs_struct *rbuf,
2070 uint32 rpc_call_id,
2071 const RPC_IFACE *abstract,
2072 const RPC_IFACE *transfer,
2073 enum pipe_auth_type auth_type,
2074 enum pipe_auth_level auth_level)
2076 DATA_BLOB server_spnego_response = data_blob_null;
2077 DATA_BLOB server_ntlm_response = data_blob_null;
2078 DATA_BLOB client_reply = data_blob_null;
2079 DATA_BLOB tmp_blob = data_blob_null;
2080 RPC_HDR_AUTH hdr_auth;
2081 NTSTATUS nt_status;
2082 prs_struct rpc_out;
2084 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2085 return NT_STATUS_INVALID_PARAMETER;
2088 /* Process the returned NTLMSSP blob first. */
2089 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2090 return NT_STATUS_INVALID_PARAMETER;
2093 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2094 return NT_STATUS_INVALID_PARAMETER;
2097 server_spnego_response = data_blob(NULL, phdr->auth_len);
2098 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2100 /* The server might give us back two challenges - tmp_blob is for the second. */
2101 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2102 data_blob_free(&server_spnego_response);
2103 data_blob_free(&server_ntlm_response);
2104 data_blob_free(&tmp_blob);
2105 return NT_STATUS_INVALID_PARAMETER;
2108 /* We're finished with the server spnego response and the tmp_blob. */
2109 data_blob_free(&server_spnego_response);
2110 data_blob_free(&tmp_blob);
2112 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2113 server_ntlm_response,
2114 &client_reply);
2116 /* Finished with the server_ntlm response */
2117 data_blob_free(&server_ntlm_response);
2119 if (!NT_STATUS_IS_OK(nt_status)) {
2120 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2121 data_blob_free(&client_reply);
2122 return nt_status;
2125 /* SPNEGO wrap the client reply. */
2126 tmp_blob = spnego_gen_auth(client_reply);
2127 data_blob_free(&client_reply);
2128 client_reply = tmp_blob;
2129 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2131 /* Now prepare the alter context pdu. */
2132 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2134 nt_status = create_rpc_alter_context(rpc_call_id,
2135 abstract,
2136 transfer,
2137 auth_level,
2138 &client_reply,
2139 &rpc_out);
2141 data_blob_free(&client_reply);
2143 if (!NT_STATUS_IS_OK(nt_status)) {
2144 prs_mem_free(&rpc_out);
2145 return nt_status;
2148 /* Initialize the returning data struct. */
2149 prs_mem_free(rbuf);
2150 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2152 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2153 if (!NT_STATUS_IS_OK(nt_status)) {
2154 prs_mem_free(&rpc_out);
2155 return nt_status;
2158 prs_mem_free(&rpc_out);
2160 /* Get the auth blob from the reply. */
2161 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2162 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2163 return NT_STATUS_BUFFER_TOO_SMALL;
2166 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2167 return NT_STATUS_INVALID_PARAMETER;
2170 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2171 return NT_STATUS_INVALID_PARAMETER;
2174 server_spnego_response = data_blob(NULL, phdr->auth_len);
2175 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2177 /* Check we got a valid auth response. */
2178 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2179 data_blob_free(&server_spnego_response);
2180 data_blob_free(&tmp_blob);
2181 return NT_STATUS_INVALID_PARAMETER;
2184 data_blob_free(&server_spnego_response);
2185 data_blob_free(&tmp_blob);
2187 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2188 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2190 return NT_STATUS_OK;
2193 /****************************************************************************
2194 Do an rpc bind.
2195 ****************************************************************************/
2197 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2198 struct cli_pipe_auth_data *auth)
2200 RPC_HDR hdr;
2201 RPC_HDR_BA hdr_ba;
2202 prs_struct rpc_out;
2203 prs_struct rbuf;
2204 uint32 rpc_call_id;
2205 NTSTATUS status;
2207 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2208 rpccli_pipe_txt(debug_ctx(), cli),
2209 (unsigned int)auth->auth_type,
2210 (unsigned int)auth->auth_level ));
2212 cli->auth = talloc_move(cli, &auth);
2214 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2216 rpc_call_id = get_rpc_call_id();
2218 /* Marshall the outgoing data. */
2219 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2220 &cli->abstract_syntax,
2221 &cli->transfer_syntax,
2222 cli->auth->auth_type,
2223 cli->auth->auth_level);
2225 if (!NT_STATUS_IS_OK(status)) {
2226 prs_mem_free(&rpc_out);
2227 return status;
2230 /* Initialize the incoming data struct. */
2231 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2233 /* send data on \PIPE\. receive a response */
2234 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2235 if (!NT_STATUS_IS_OK(status)) {
2236 prs_mem_free(&rpc_out);
2237 return status;
2240 prs_mem_free(&rpc_out);
2242 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2243 rpccli_pipe_txt(debug_ctx(), cli)));
2245 /* Unmarshall the RPC header */
2246 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2247 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2248 prs_mem_free(&rbuf);
2249 return NT_STATUS_BUFFER_TOO_SMALL;
2252 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2253 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2254 prs_mem_free(&rbuf);
2255 return NT_STATUS_BUFFER_TOO_SMALL;
2258 if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) {
2259 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2260 prs_mem_free(&rbuf);
2261 return NT_STATUS_BUFFER_TOO_SMALL;
2264 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2265 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2267 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2268 switch(cli->auth->auth_type) {
2270 case PIPE_AUTH_TYPE_NONE:
2271 case PIPE_AUTH_TYPE_SCHANNEL:
2272 /* Bind complete. */
2273 break;
2275 case PIPE_AUTH_TYPE_NTLMSSP:
2276 /* Need to send AUTH3 packet - no reply. */
2277 status = rpc_finish_auth3_bind(
2278 cli, &hdr, &rbuf, rpc_call_id,
2279 cli->auth->auth_type,
2280 cli->auth->auth_level);
2281 if (!NT_STATUS_IS_OK(status)) {
2282 prs_mem_free(&rbuf);
2283 return status;
2285 break;
2287 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2288 /* Need to send alter context request and reply. */
2289 status = rpc_finish_spnego_ntlmssp_bind(
2290 cli, &hdr, &rbuf, rpc_call_id,
2291 &cli->abstract_syntax, &cli->transfer_syntax,
2292 cli->auth->auth_type, cli->auth->auth_level);
2293 if (!NT_STATUS_IS_OK(status)) {
2294 prs_mem_free(&rbuf);
2295 return status;
2297 break;
2299 case PIPE_AUTH_TYPE_KRB5:
2300 /* */
2302 default:
2303 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2304 "%u\n", (unsigned int)cli->auth->auth_type));
2305 prs_mem_free(&rbuf);
2306 return NT_STATUS_INVALID_INFO_CLASS;
2309 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2310 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2311 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2312 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2313 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2314 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2315 prs_mem_free(&rbuf);
2316 return NT_STATUS_INVALID_PARAMETER;
2319 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2320 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2321 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2322 prs_mem_free(&rbuf);
2323 return NT_STATUS_INVALID_PARAMETER;
2328 prs_mem_free(&rbuf);
2329 return NT_STATUS_OK;
2332 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2333 unsigned int timeout)
2335 return cli_set_timeout(cli->trans.np.cli, timeout);
2338 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2340 return ndr_syntax_id_equal(&cli->abstract_syntax,
2341 pipe_names[pipe_idx].abstr_syntax);
2344 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2346 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2347 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2348 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2349 return true;
2352 if (cli->transport_type == NCACN_NP) {
2353 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2354 return true;
2357 return false;
2360 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2362 if (p->transport_type == NCACN_NP) {
2363 return p->trans.np.cli;
2365 return NULL;
2368 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2370 if (p->transport_type == NCACN_NP) {
2371 bool ret;
2372 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2373 if (!ret) {
2374 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2375 "pipe %s. Error was %s\n",
2376 rpccli_pipe_txt(debug_ctx(), p),
2377 cli_errstr(p->trans.np.cli)));
2380 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2381 rpccli_pipe_txt(debug_ctx(), p)));
2383 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2384 return ret ? -1 : 0;
2387 return -1;
2390 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2391 struct cli_pipe_auth_data **presult)
2393 struct cli_pipe_auth_data *result;
2395 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2396 if (result == NULL) {
2397 return NT_STATUS_NO_MEMORY;
2400 result->auth_type = PIPE_AUTH_TYPE_NONE;
2401 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2403 result->user_name = talloc_strdup(result, "");
2404 result->domain = talloc_strdup(result, "");
2405 if ((result->user_name == NULL) || (result->domain == NULL)) {
2406 TALLOC_FREE(result);
2407 return NT_STATUS_NO_MEMORY;
2410 *presult = result;
2411 return NT_STATUS_OK;
2414 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2416 ntlmssp_end(&auth->a_u.ntlmssp_state);
2417 return 0;
2420 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2421 enum pipe_auth_type auth_type,
2422 enum pipe_auth_level auth_level,
2423 const char *domain,
2424 const char *username,
2425 const char *password,
2426 struct cli_pipe_auth_data **presult)
2428 struct cli_pipe_auth_data *result;
2429 NTSTATUS status;
2431 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2432 if (result == NULL) {
2433 return NT_STATUS_NO_MEMORY;
2436 result->auth_type = auth_type;
2437 result->auth_level = auth_level;
2439 result->user_name = talloc_strdup(result, username);
2440 result->domain = talloc_strdup(result, domain);
2441 if ((result->user_name == NULL) || (result->domain == NULL)) {
2442 status = NT_STATUS_NO_MEMORY;
2443 goto fail;
2446 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2447 if (!NT_STATUS_IS_OK(status)) {
2448 goto fail;
2451 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2453 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2454 if (!NT_STATUS_IS_OK(status)) {
2455 goto fail;
2458 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2459 if (!NT_STATUS_IS_OK(status)) {
2460 goto fail;
2463 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2464 if (!NT_STATUS_IS_OK(status)) {
2465 goto fail;
2469 * Turn off sign+seal to allow selected auth level to turn it back on.
2471 result->a_u.ntlmssp_state->neg_flags &=
2472 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2474 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2475 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2476 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2477 result->a_u.ntlmssp_state->neg_flags
2478 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2481 *presult = result;
2482 return NT_STATUS_OK;
2484 fail:
2485 TALLOC_FREE(result);
2486 return status;
2489 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2490 enum pipe_auth_level auth_level,
2491 const uint8_t sess_key[16],
2492 struct cli_pipe_auth_data **presult)
2494 struct cli_pipe_auth_data *result;
2496 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2497 if (result == NULL) {
2498 return NT_STATUS_NO_MEMORY;
2501 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2502 result->auth_level = auth_level;
2504 result->user_name = talloc_strdup(result, "");
2505 result->domain = talloc_strdup(result, domain);
2506 if ((result->user_name == NULL) || (result->domain == NULL)) {
2507 goto fail;
2510 result->a_u.schannel_auth = talloc(result,
2511 struct schannel_auth_struct);
2512 if (result->a_u.schannel_auth == NULL) {
2513 goto fail;
2516 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2517 sizeof(result->a_u.schannel_auth->sess_key));
2518 result->a_u.schannel_auth->seq_num = 0;
2520 *presult = result;
2521 return NT_STATUS_OK;
2523 fail:
2524 TALLOC_FREE(result);
2525 return NT_STATUS_NO_MEMORY;
2528 #ifdef HAVE_KRB5
2529 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2531 data_blob_free(&auth->session_key);
2532 return 0;
2534 #endif
2536 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2537 enum pipe_auth_level auth_level,
2538 const char *service_princ,
2539 const char *username,
2540 const char *password,
2541 struct cli_pipe_auth_data **presult)
2543 #ifdef HAVE_KRB5
2544 struct cli_pipe_auth_data *result;
2546 if ((username != NULL) && (password != NULL)) {
2547 int ret = kerberos_kinit_password(username, password, 0, NULL);
2548 if (ret != 0) {
2549 return NT_STATUS_ACCESS_DENIED;
2553 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2554 if (result == NULL) {
2555 return NT_STATUS_NO_MEMORY;
2558 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2559 result->auth_level = auth_level;
2562 * Username / domain need fixing!
2564 result->user_name = talloc_strdup(result, "");
2565 result->domain = talloc_strdup(result, "");
2566 if ((result->user_name == NULL) || (result->domain == NULL)) {
2567 goto fail;
2570 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2571 result, struct kerberos_auth_struct);
2572 if (result->a_u.kerberos_auth == NULL) {
2573 goto fail;
2575 talloc_set_destructor(result->a_u.kerberos_auth,
2576 cli_auth_kerberos_data_destructor);
2578 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2579 result, service_princ);
2580 if (result->a_u.kerberos_auth->service_principal == NULL) {
2581 goto fail;
2584 *presult = result;
2585 return NT_STATUS_OK;
2587 fail:
2588 TALLOC_FREE(result);
2589 return NT_STATUS_NO_MEMORY;
2590 #else
2591 return NT_STATUS_NOT_SUPPORTED;
2592 #endif
2595 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2597 close(p->trans.sock.fd);
2598 return 0;
2602 * Create an rpc pipe client struct, connecting to a tcp port.
2604 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2605 uint16_t port,
2606 const struct ndr_syntax_id *abstract_syntax,
2607 struct rpc_pipe_client **presult)
2609 struct rpc_pipe_client *result;
2610 struct sockaddr_storage addr;
2611 NTSTATUS status;
2613 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2614 if (result == NULL) {
2615 return NT_STATUS_NO_MEMORY;
2618 result->transport_type = NCACN_IP_TCP;
2620 result->abstract_syntax = *abstract_syntax;
2621 result->transfer_syntax = ndr_transfer_syntax;
2623 result->desthost = talloc_strdup(result, host);
2624 result->srv_name_slash = talloc_asprintf_strupper_m(
2625 result, "\\\\%s", result->desthost);
2626 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2627 status = NT_STATUS_NO_MEMORY;
2628 goto fail;
2631 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2632 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2634 if (!resolve_name(host, &addr, 0)) {
2635 status = NT_STATUS_NOT_FOUND;
2636 goto fail;
2639 result->trans.sock.fd = open_socket_out(SOCK_STREAM, &addr, port, 60);
2640 if (result->trans.sock.fd == -1) {
2641 status = map_nt_error_from_unix(errno);
2642 goto fail;
2645 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2647 *presult = result;
2648 return NT_STATUS_OK;
2650 fail:
2651 TALLOC_FREE(result);
2652 return status;
2656 * Determine the tcp port on which a dcerpc interface is listening
2657 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2658 * target host.
2660 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2661 const struct ndr_syntax_id *abstract_syntax,
2662 uint16_t *pport)
2664 NTSTATUS status;
2665 struct rpc_pipe_client *epm_pipe = NULL;
2666 struct cli_pipe_auth_data *auth = NULL;
2667 struct dcerpc_binding *map_binding = NULL;
2668 struct dcerpc_binding *res_binding = NULL;
2669 struct epm_twr_t *map_tower = NULL;
2670 struct epm_twr_t *res_towers = NULL;
2671 struct policy_handle *entry_handle = NULL;
2672 uint32_t num_towers = 0;
2673 uint32_t max_towers = 1;
2674 struct epm_twr_p_t towers;
2675 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2677 if (pport == NULL) {
2678 status = NT_STATUS_INVALID_PARAMETER;
2679 goto done;
2682 /* open the connection to the endpoint mapper */
2683 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2684 &ndr_table_epmapper.syntax_id,
2685 &epm_pipe);
2687 if (!NT_STATUS_IS_OK(status)) {
2688 goto done;
2691 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2692 if (!NT_STATUS_IS_OK(status)) {
2693 goto done;
2696 status = rpc_pipe_bind(epm_pipe, auth);
2697 if (!NT_STATUS_IS_OK(status)) {
2698 goto done;
2701 /* create tower for asking the epmapper */
2703 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2704 if (map_binding == NULL) {
2705 status = NT_STATUS_NO_MEMORY;
2706 goto done;
2709 map_binding->transport = NCACN_IP_TCP;
2710 map_binding->object = *abstract_syntax;
2711 map_binding->host = host; /* needed? */
2712 map_binding->endpoint = "0"; /* correct? needed? */
2714 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2715 if (map_tower == NULL) {
2716 status = NT_STATUS_NO_MEMORY;
2717 goto done;
2720 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2721 &(map_tower->tower));
2722 if (!NT_STATUS_IS_OK(status)) {
2723 goto done;
2726 /* allocate further parameters for the epm_Map call */
2728 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2729 if (res_towers == NULL) {
2730 status = NT_STATUS_NO_MEMORY;
2731 goto done;
2733 towers.twr = res_towers;
2735 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2736 if (entry_handle == NULL) {
2737 status = NT_STATUS_NO_MEMORY;
2738 goto done;
2741 /* ask the endpoint mapper for the port */
2743 status = rpccli_epm_Map(epm_pipe,
2744 tmp_ctx,
2745 CONST_DISCARD(struct GUID *,
2746 &(abstract_syntax->uuid)),
2747 map_tower,
2748 entry_handle,
2749 max_towers,
2750 &num_towers,
2751 &towers);
2753 if (!NT_STATUS_IS_OK(status)) {
2754 goto done;
2757 if (num_towers != 1) {
2758 status = NT_STATUS_UNSUCCESSFUL;
2759 goto done;
2762 /* extract the port from the answer */
2764 status = dcerpc_binding_from_tower(tmp_ctx,
2765 &(towers.twr->tower),
2766 &res_binding);
2767 if (!NT_STATUS_IS_OK(status)) {
2768 goto done;
2771 /* are further checks here necessary? */
2772 if (res_binding->transport != NCACN_IP_TCP) {
2773 status = NT_STATUS_UNSUCCESSFUL;
2774 goto done;
2777 *pport = (uint16_t)atoi(res_binding->endpoint);
2779 done:
2780 TALLOC_FREE(tmp_ctx);
2781 return status;
2785 * Create a rpc pipe client struct, connecting to a host via tcp.
2786 * The port is determined by asking the endpoint mapper on the given
2787 * host.
2789 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2790 const struct ndr_syntax_id *abstract_syntax,
2791 struct rpc_pipe_client **presult)
2793 NTSTATUS status;
2794 uint16_t port = 0;
2796 *presult = NULL;
2798 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2799 if (!NT_STATUS_IS_OK(status)) {
2800 goto done;
2803 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2804 abstract_syntax, presult);
2806 done:
2807 return status;
2810 /********************************************************************
2811 Create a rpc pipe client struct, connecting to a unix domain socket
2812 ********************************************************************/
2813 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2814 const struct ndr_syntax_id *abstract_syntax,
2815 struct rpc_pipe_client **presult)
2817 struct rpc_pipe_client *result;
2818 struct sockaddr_un addr;
2819 NTSTATUS status;
2821 result = talloc(mem_ctx, struct rpc_pipe_client);
2822 if (result == NULL) {
2823 return NT_STATUS_NO_MEMORY;
2826 result->transport_type = NCACN_UNIX_STREAM;
2828 result->abstract_syntax = *abstract_syntax;
2829 result->transfer_syntax = ndr_transfer_syntax;
2831 result->desthost = get_myname(result);
2832 result->srv_name_slash = talloc_asprintf_strupper_m(
2833 result, "\\\\%s", result->desthost);
2834 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2835 status = NT_STATUS_NO_MEMORY;
2836 goto fail;
2839 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2840 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2842 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2843 if (result->trans.sock.fd == -1) {
2844 status = map_nt_error_from_unix(errno);
2845 goto fail;
2848 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2850 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2851 if (result->dc == NULL) {
2852 status = NT_STATUS_NO_MEMORY;
2853 goto fail;
2856 ZERO_STRUCT(addr);
2857 addr.sun_family = AF_UNIX;
2858 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2860 if (sys_connect(result->trans.sock.fd,
2861 (struct sockaddr *)&addr) == -1) {
2862 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2863 strerror(errno)));
2864 close(result->trans.sock.fd);
2865 return map_nt_error_from_unix(errno);
2868 *presult = result;
2869 return NT_STATUS_OK;
2871 fail:
2872 TALLOC_FREE(result);
2873 return status;
2877 /****************************************************************************
2878 Open a named pipe over SMB to a remote server.
2880 * CAVEAT CALLER OF THIS FUNCTION:
2881 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2882 * so be sure that this function is called AFTER any structure (vs pointer)
2883 * assignment of the cli. In particular, libsmbclient does structure
2884 * assignments of cli, which invalidates the data in the returned
2885 * rpc_pipe_client if this function is called before the structure assignment
2886 * of cli.
2888 ****************************************************************************/
2890 static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2892 struct rpc_pipe_client *result;
2893 int fnum;
2895 *perr = NT_STATUS_NO_MEMORY;
2897 /* sanity check to protect against crashes */
2899 if ( !cli ) {
2900 *perr = NT_STATUS_INVALID_HANDLE;
2901 return NULL;
2904 /* The pipe name index must fall within our array */
2905 SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2907 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2908 if (result == NULL) {
2909 *perr = NT_STATUS_NO_MEMORY;
2910 return NULL;
2913 result->transport_type = NCACN_NP;
2915 result->trans.np.pipe_name = cli_get_pipe_name(pipe_idx);
2917 result->trans.np.cli = cli;
2918 result->abstract_syntax = *pipe_names[pipe_idx].abstr_syntax;
2919 result->transfer_syntax = ndr_transfer_syntax;
2920 result->desthost = talloc_strdup(result, cli->desthost);
2921 result->srv_name_slash = talloc_asprintf_strupper_m(
2922 result, "\\\\%s", result->desthost);
2924 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2925 *perr = NT_STATUS_NO_MEMORY;
2926 TALLOC_FREE(result);
2927 return NULL;
2930 if (pipe_idx == PI_NETLOGON) {
2931 /* Set up a netlogon credential chain for a netlogon pipe. */
2932 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2933 if (result->dc == NULL) {
2934 *perr = NT_STATUS_NO_MEMORY;
2935 TALLOC_FREE(result);
2936 return NULL;
2940 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2941 DESIRED_ACCESS_PIPE);
2942 if (fnum == -1) {
2943 DEBUG(1,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
2944 "to machine %s. Error was %s\n",
2945 result->trans.np.pipe_name, cli->desthost,
2946 cli_errstr(cli)));
2947 *perr = cli_get_nt_error(cli);
2948 talloc_destroy(result);
2949 return NULL;
2952 result->trans.np.fnum = fnum;
2954 DLIST_ADD(cli->pipe_list, result);
2955 talloc_set_destructor(result, rpc_pipe_destructor);
2957 *perr = NT_STATUS_OK;
2959 return result;
2962 /****************************************************************************
2963 Open a pipe to a remote server.
2964 ****************************************************************************/
2966 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli,
2967 int pipe_idx,
2968 NTSTATUS *perr)
2970 struct rpc_pipe_client *result = NULL;
2972 *perr = NT_STATUS_PIPE_NOT_AVAILABLE;
2974 switch (pipe_idx) {
2975 case PI_DRSUAPI:
2976 *perr = rpc_pipe_open_tcp(NULL, cli->desthost,
2977 &ndr_table_drsuapi.syntax_id,
2978 &result);
2979 if (!NT_STATUS_IS_OK(*perr)) {
2980 return NULL;
2982 break;
2983 default:
2984 result = rpc_pipe_open_np(cli, pipe_idx, perr);
2985 if (result == NULL) {
2986 return NULL;
2988 break;
2991 *perr = NT_STATUS_OK;
2993 return result;
2996 /****************************************************************************
2997 Open a named pipe to an SMB server and bind anonymously.
2998 ****************************************************************************/
3000 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
3002 struct rpc_pipe_client *result;
3003 struct cli_pipe_auth_data *auth;
3005 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3006 if (result == NULL) {
3007 return NULL;
3010 *perr = rpccli_anon_bind_data(result, &auth);
3011 if (!NT_STATUS_IS_OK(*perr)) {
3012 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3013 nt_errstr(*perr)));
3014 TALLOC_FREE(result);
3015 return NULL;
3019 * This is a bit of an abstraction violation due to the fact that an
3020 * anonymous bind on an authenticated SMB inherits the user/domain
3021 * from the enclosing SMB creds
3024 TALLOC_FREE(auth->user_name);
3025 TALLOC_FREE(auth->domain);
3027 auth->user_name = talloc_strdup(auth, cli->user_name);
3028 auth->domain = talloc_strdup(auth, cli->domain);
3030 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3031 *perr = NT_STATUS_NO_MEMORY;
3032 TALLOC_FREE(result);
3033 return NULL;
3036 *perr = rpc_pipe_bind(result, auth);
3037 if (!NT_STATUS_IS_OK(*perr)) {
3038 int lvl = 0;
3039 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
3040 /* non AD domains just don't have this pipe, avoid
3041 * level 0 statement in that case - gd */
3042 lvl = 3;
3044 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
3045 cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
3046 TALLOC_FREE(result);
3047 return NULL;
3050 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3051 "%s and bound anonymously.\n", result->trans.np.pipe_name,
3052 cli->desthost ));
3054 return result;
3057 /****************************************************************************
3058 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3059 ****************************************************************************/
3061 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3062 int pipe_idx,
3063 enum pipe_auth_type auth_type,
3064 enum pipe_auth_level auth_level,
3065 const char *domain,
3066 const char *username,
3067 const char *password,
3068 NTSTATUS *perr)
3070 struct rpc_pipe_client *result;
3071 struct cli_pipe_auth_data *auth;
3073 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3074 if (result == NULL) {
3075 return NULL;
3078 *perr = rpccli_ntlmssp_bind_data(
3079 result, auth_type, auth_level, domain, username,
3080 cli->pwd.null_pwd ? NULL : password, &auth);
3081 if (!NT_STATUS_IS_OK(*perr)) {
3082 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3083 nt_errstr(*perr)));
3084 TALLOC_FREE(result);
3085 return NULL;
3088 *perr = rpc_pipe_bind(result, auth);
3089 if (!NT_STATUS_IS_OK(*perr)) {
3090 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3091 nt_errstr(*perr) ));
3092 goto err;
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 ));
3100 return result;
3102 err:
3104 TALLOC_FREE(result);
3105 return NULL;
3108 /****************************************************************************
3109 External interface.
3110 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3111 ****************************************************************************/
3113 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3114 int pipe_idx,
3115 enum pipe_auth_level auth_level,
3116 const char *domain,
3117 const char *username,
3118 const char *password,
3119 NTSTATUS *perr)
3121 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3122 pipe_idx,
3123 PIPE_AUTH_TYPE_NTLMSSP,
3124 auth_level,
3125 domain,
3126 username,
3127 password,
3128 perr);
3131 /****************************************************************************
3132 External interface.
3133 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3134 ****************************************************************************/
3136 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3137 int pipe_idx,
3138 enum pipe_auth_level auth_level,
3139 const char *domain,
3140 const char *username,
3141 const char *password,
3142 NTSTATUS *perr)
3144 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3145 pipe_idx,
3146 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3147 auth_level,
3148 domain,
3149 username,
3150 password,
3151 perr);
3154 /****************************************************************************
3155 Get a the schannel session key out of an already opened netlogon pipe.
3156 ****************************************************************************/
3157 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3158 struct cli_state *cli,
3159 const char *domain,
3160 uint32 *pneg_flags,
3161 NTSTATUS *perr)
3163 uint32 sec_chan_type = 0;
3164 unsigned char machine_pwd[16];
3165 const char *machine_account;
3167 /* Get the machine account credentials from secrets.tdb. */
3168 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3169 &sec_chan_type))
3171 DEBUG(0, ("get_schannel_session_key: could not fetch "
3172 "trust account password for domain '%s'\n",
3173 domain));
3174 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3175 return false;
3178 *perr = 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 */
3183 machine_pwd,
3184 sec_chan_type,
3185 pneg_flags);
3187 if (!NT_STATUS_IS_OK(*perr)) {
3188 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
3189 "failed with result %s to server %s, domain %s, machine account %s.\n",
3190 nt_errstr(*perr), cli->desthost, domain, machine_account ));
3191 return false;
3194 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3195 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3196 cli->desthost));
3197 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
3198 return false;
3201 return true;
3204 /****************************************************************************
3205 Open a netlogon pipe and get the schannel session key.
3206 Now exposed to external callers.
3207 ****************************************************************************/
3210 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
3211 const char *domain,
3212 uint32 *pneg_flags,
3213 NTSTATUS *perr)
3215 struct rpc_pipe_client *netlogon_pipe = NULL;
3217 netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
3218 if (!netlogon_pipe) {
3219 return NULL;
3222 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
3223 pneg_flags, perr))
3225 TALLOC_FREE(netlogon_pipe);
3226 return NULL;
3229 return netlogon_pipe;
3232 /****************************************************************************
3233 External interface.
3234 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3235 using session_key. sign and seal.
3236 ****************************************************************************/
3238 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3239 int pipe_idx,
3240 enum pipe_auth_level auth_level,
3241 const char *domain,
3242 const struct dcinfo *pdc,
3243 NTSTATUS *perr)
3245 struct rpc_pipe_client *result;
3246 struct cli_pipe_auth_data *auth;
3248 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3249 if (result == NULL) {
3250 return NULL;
3253 *perr = rpccli_schannel_bind_data(result, domain, auth_level,
3254 pdc->sess_key, &auth);
3255 if (!NT_STATUS_IS_OK(*perr)) {
3256 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3257 nt_errstr(*perr)));
3258 TALLOC_FREE(result);
3259 return NULL;
3262 *perr = rpc_pipe_bind(result, auth);
3263 if (!NT_STATUS_IS_OK(*perr)) {
3264 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
3265 nt_errstr(*perr) ));
3266 TALLOC_FREE(result);
3267 return NULL;
3270 /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
3271 if (result->dc) {
3272 *result->dc = *pdc;
3275 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3276 "for domain %s "
3277 "and bound using schannel.\n",
3278 result->trans.np.pipe_name, cli->desthost, domain ));
3280 return result;
3283 /****************************************************************************
3284 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3285 Fetch the session key ourselves using a temporary netlogon pipe. This
3286 version uses an ntlmssp auth bound netlogon pipe to get the key.
3287 ****************************************************************************/
3289 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3290 const char *domain,
3291 const char *username,
3292 const char *password,
3293 uint32 *pneg_flags,
3294 NTSTATUS *perr)
3296 struct rpc_pipe_client *netlogon_pipe = NULL;
3298 netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
3299 if (!netlogon_pipe) {
3300 return NULL;
3303 if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
3304 pneg_flags, perr))
3306 TALLOC_FREE(netlogon_pipe);
3307 return NULL;
3310 return netlogon_pipe;
3313 /****************************************************************************
3314 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3315 Fetch the session key ourselves using a temporary netlogon pipe. This version
3316 uses an ntlmssp bind to get the session key.
3317 ****************************************************************************/
3319 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3320 int pipe_idx,
3321 enum pipe_auth_level auth_level,
3322 const char *domain,
3323 const char *username,
3324 const char *password,
3325 NTSTATUS *perr)
3327 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3328 struct rpc_pipe_client *netlogon_pipe = NULL;
3329 struct rpc_pipe_client *result = NULL;
3331 netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
3332 password, &neg_flags, perr);
3333 if (!netlogon_pipe) {
3334 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3335 "key from server %s for domain %s.\n",
3336 cli->desthost, domain ));
3337 return NULL;
3340 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
3341 auth_level,
3342 domain, netlogon_pipe->dc, perr);
3344 /* Now we've bound using the session key we can close the netlog pipe. */
3345 TALLOC_FREE(netlogon_pipe);
3347 return result;
3350 /****************************************************************************
3351 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3352 Fetch the session key ourselves using a temporary netlogon pipe.
3353 ****************************************************************************/
3355 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
3356 int pipe_idx,
3357 enum pipe_auth_level auth_level,
3358 const char *domain,
3359 NTSTATUS *perr)
3361 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3362 struct rpc_pipe_client *netlogon_pipe = NULL;
3363 struct rpc_pipe_client *result = NULL;
3365 netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
3366 if (!netlogon_pipe) {
3367 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3368 "key from server %s for domain %s.\n",
3369 cli->desthost, domain ));
3370 return NULL;
3373 result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
3374 auth_level,
3375 domain, netlogon_pipe->dc, perr);
3377 /* Now we've bound using the session key we can close the netlog pipe. */
3378 TALLOC_FREE(netlogon_pipe);
3380 return result;
3383 /****************************************************************************
3384 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3385 The idea is this can be called with service_princ, username and password all
3386 NULL so long as the caller has a TGT.
3387 ****************************************************************************/
3389 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
3390 int pipe_idx,
3391 enum pipe_auth_level auth_level,
3392 const char *service_princ,
3393 const char *username,
3394 const char *password,
3395 NTSTATUS *perr)
3397 #ifdef HAVE_KRB5
3398 struct rpc_pipe_client *result;
3399 struct cli_pipe_auth_data *auth;
3401 result = cli_rpc_pipe_open(cli, pipe_idx, perr);
3402 if (result == NULL) {
3403 return NULL;
3406 *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3407 username, password, &auth);
3408 if (!NT_STATUS_IS_OK(*perr)) {
3409 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3410 nt_errstr(*perr)));
3411 TALLOC_FREE(result);
3412 return NULL;
3415 *perr = rpc_pipe_bind(result, auth);
3416 if (!NT_STATUS_IS_OK(*perr)) {
3417 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
3418 nt_errstr(*perr) ));
3419 TALLOC_FREE(result);
3420 return NULL;
3423 return result;
3424 #else
3425 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3426 return NULL;
3427 #endif
3430 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3431 struct rpc_pipe_client *cli,
3432 DATA_BLOB *session_key)
3434 if (!session_key || !cli) {
3435 return NT_STATUS_INVALID_PARAMETER;
3438 if (!cli->auth) {
3439 return NT_STATUS_INVALID_PARAMETER;
3442 switch (cli->auth->auth_type) {
3443 case PIPE_AUTH_TYPE_SCHANNEL:
3444 *session_key = data_blob_talloc(mem_ctx,
3445 cli->auth->a_u.schannel_auth->sess_key, 16);
3446 break;
3447 case PIPE_AUTH_TYPE_NTLMSSP:
3448 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3449 *session_key = data_blob_talloc(mem_ctx,
3450 cli->auth->a_u.ntlmssp_state->session_key.data,
3451 cli->auth->a_u.ntlmssp_state->session_key.length);
3452 break;
3453 case PIPE_AUTH_TYPE_KRB5:
3454 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3455 *session_key = data_blob_talloc(mem_ctx,
3456 cli->auth->a_u.kerberos_auth->session_key.data,
3457 cli->auth->a_u.kerberos_auth->session_key.length);
3458 break;
3459 case PIPE_AUTH_TYPE_NONE:
3460 default:
3461 return NT_STATUS_NO_USER_SESSION_KEY;
3464 return NT_STATUS_OK;