Make rpc_read look like a real read call
[Samba.git] / source3 / rpc_client / cli_pipe.c
blob99bd85af5d110986b02d4615288149d9281c1b91
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 #define PIPE_SRVSVC "\\PIPE\\srvsvc"
31 #define PIPE_SAMR "\\PIPE\\samr"
32 #define PIPE_WINREG "\\PIPE\\winreg"
33 #define PIPE_WKSSVC "\\PIPE\\wkssvc"
34 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
35 #define PIPE_NTLSA "\\PIPE\\ntlsa"
36 #define PIPE_NTSVCS "\\PIPE\\ntsvcs"
37 #define PIPE_LSASS "\\PIPE\\lsass"
38 #define PIPE_LSARPC "\\PIPE\\lsarpc"
39 #define PIPE_SPOOLSS "\\PIPE\\spoolss"
40 #define PIPE_NETDFS "\\PIPE\\netdfs"
41 #define PIPE_ECHO "\\PIPE\\rpcecho"
42 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
43 #define PIPE_EPM "\\PIPE\\epmapper"
44 #define PIPE_SVCCTL "\\PIPE\\svcctl"
45 #define PIPE_EVENTLOG "\\PIPE\\eventlog"
46 #define PIPE_EPMAPPER "\\PIPE\\epmapper"
47 #define PIPE_DRSUAPI "\\PIPE\\drsuapi"
50 * IMPORTANT!! If you update this structure, make sure to
51 * update the index #defines in smb.h.
54 static const struct pipe_id_info {
55 /* the names appear not to matter: the syntaxes _do_ matter */
57 const char *client_pipe;
58 const RPC_IFACE *abstr_syntax; /* this one is the abstract syntax id */
59 } pipe_names [] =
61 { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
62 { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
63 { PIPE_SAMR, &ndr_table_samr.syntax_id },
64 { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
65 { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
66 { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
67 { PIPE_WINREG, &ndr_table_winreg.syntax_id },
68 { PIPE_SPOOLSS, &syntax_spoolss },
69 { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
70 { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
71 { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
72 { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
73 { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
74 { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
75 { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
76 { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
77 { NULL, NULL }
80 /****************************************************************************
81 Return the pipe name from the interface.
82 ****************************************************************************/
84 const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx,
85 struct cli_state *cli,
86 const struct ndr_syntax_id *interface)
88 int i;
89 for (i = 0; pipe_names[i].client_pipe; i++) {
90 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
91 interface)) {
92 return &pipe_names[i].client_pipe[5];
97 * Here we should ask \\epmapper, but for now our code is only
98 * interested in the known pipes mentioned in pipe_names[]
101 return NULL;
104 /********************************************************************
105 Map internal value to wire value.
106 ********************************************************************/
108 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
110 switch (auth_type) {
112 case PIPE_AUTH_TYPE_NONE:
113 return RPC_ANONYMOUS_AUTH_TYPE;
115 case PIPE_AUTH_TYPE_NTLMSSP:
116 return RPC_NTLMSSP_AUTH_TYPE;
118 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
119 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
120 return RPC_SPNEGO_AUTH_TYPE;
122 case PIPE_AUTH_TYPE_SCHANNEL:
123 return RPC_SCHANNEL_AUTH_TYPE;
125 case PIPE_AUTH_TYPE_KRB5:
126 return RPC_KRB5_AUTH_TYPE;
128 default:
129 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
130 "auth type %u\n",
131 (unsigned int)auth_type ));
132 break;
134 return -1;
137 /********************************************************************
138 Pipe description for a DEBUG
139 ********************************************************************/
140 static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli)
142 char *result;
144 switch (cli->transport_type) {
145 case NCACN_NP:
146 result = talloc_asprintf(mem_ctx, "host %s, pipe %s, "
147 "fnum 0x%x",
148 cli->desthost,
149 cli->trans.np.pipe_name,
150 (unsigned int)(cli->trans.np.fnum));
151 break;
152 case NCACN_IP_TCP:
153 case NCACN_UNIX_STREAM:
154 result = talloc_asprintf(mem_ctx, "host %s, fd %d",
155 cli->desthost, cli->trans.sock.fd);
156 break;
157 default:
158 result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
159 break;
161 SMB_ASSERT(result != NULL);
162 return result;
165 /********************************************************************
166 Rpc pipe call id.
167 ********************************************************************/
169 static uint32 get_rpc_call_id(void)
171 static uint32 call_id = 0;
172 return ++call_id;
175 /*******************************************************************
176 Read from a RPC named pipe
177 ********************************************************************/
178 static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name,
179 int fnum, char *buf, size_t size,
180 ssize_t *pnum_read)
182 ssize_t num_read;
184 num_read = cli_read(cli, fnum, buf, 0, size);
186 DEBUG(5,("rpc_read_np: num_read = %d, to read: %u\n", (int)num_read,
187 (unsigned int)size));
190 * A dos error of ERRDOS/ERRmoredata is not an error.
192 if (cli_is_dos_error(cli)) {
193 uint32 ecode;
194 uint8 eclass;
195 cli_dos_error(cli, &eclass, &ecode);
196 if (eclass != ERRDOS && ecode != ERRmoredata) {
197 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read "
198 "on fnum 0x%x\n", eclass, (unsigned int)ecode,
199 cli_errstr(cli), fnum));
200 return dos_to_ntstatus(eclass, ecode);
205 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
207 if (cli_is_nt_error(cli)) {
208 if (!NT_STATUS_EQUAL(cli_nt_error(cli),
209 NT_STATUS_BUFFER_TOO_SMALL)) {
210 DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum "
211 "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum));
212 return cli_nt_error(cli);
216 if (num_read == -1) {
217 DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned "
218 "-1\n", fnum));
219 return cli_get_nt_error(cli);
222 *pnum_read = num_read;
223 return NT_STATUS_OK;
227 * Realloc pdu to have a least "size" bytes
230 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
232 size_t extra_size;
234 if (prs_data_size(pdu) >= size) {
235 return true;
238 extra_size = size - prs_data_size(pdu);
240 if (!prs_force_grow(pdu, extra_size)) {
241 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
242 "%d bytes.\n", (int)extra_size));
243 return false;
246 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
247 (int)extra_size, prs_data_size(pdu)));
248 return true;
252 /*******************************************************************
253 Use SMBreadX to get rest of one fragment's worth of rpc data.
254 Reads the whole size or give an error message
255 ********************************************************************/
257 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
258 char *pdata, size_t size)
260 ssize_t num_read = 0;
262 DEBUG(5, ("rpc_read: data_to_read: %u\n", (unsigned int)size));
264 while (num_read < size) {
265 ssize_t thistime = 0;
266 NTSTATUS status;
268 switch (cli->transport_type) {
269 case NCACN_NP:
270 status = rpc_read_np(cli->trans.np.cli,
271 cli->trans.np.pipe_name,
272 cli->trans.np.fnum,
273 pdata + num_read,
274 size - num_read, &thistime);
275 break;
276 case NCACN_IP_TCP:
277 case NCACN_UNIX_STREAM:
278 status = NT_STATUS_OK;
279 thistime = sys_read(cli->trans.sock.fd,
280 pdata + num_read,
281 size - num_read);
282 if (thistime == -1) {
283 status = map_nt_error_from_unix(errno);
285 break;
286 default:
287 DEBUG(0, ("unknown transport type %d\n",
288 cli->transport_type));
289 return NT_STATUS_INTERNAL_ERROR;
292 if (!NT_STATUS_IS_OK(status)) {
293 return status;
295 if (thistime == 0) {
296 return NT_STATUS_END_OF_FILE;
299 num_read += thistime;
303 return NT_STATUS_OK;
306 /****************************************************************************
307 Try and get a PDU's worth of data from current_pdu. If not, then read more
308 from the wire.
309 ****************************************************************************/
311 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
313 NTSTATUS ret = NT_STATUS_OK;
314 uint32 current_pdu_len = prs_data_size(current_pdu);
316 /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
317 if (current_pdu_len < RPC_HEADER_LEN) {
318 if (!rpc_grow_buffer(current_pdu, RPC_HEADER_LEN)) {
319 return NT_STATUS_NO_MEMORY;
321 ret = rpc_read(cli,
322 prs_data_p(current_pdu) + current_pdu_len,
323 RPC_HEADER_LEN - current_pdu_len);
324 if (!NT_STATUS_IS_OK(ret)) {
325 return ret;
327 current_pdu_len = RPC_HEADER_LEN;
330 /* This next call sets the endian bit correctly in current_pdu. */
331 /* We will propagate this to rbuf later. */
332 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
333 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
334 return NT_STATUS_BUFFER_TOO_SMALL;
337 if (prhdr->frag_len > cli->max_recv_frag) {
338 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
339 " we only allow %d\n", (int)prhdr->frag_len,
340 (int)cli->max_recv_frag));
341 return NT_STATUS_BUFFER_TOO_SMALL;
344 /* Ensure we have frag_len bytes of data. */
345 if (current_pdu_len < prhdr->frag_len) {
346 if (!rpc_grow_buffer(current_pdu, prhdr->frag_len)) {
347 return NT_STATUS_NO_MEMORY;
349 ret = rpc_read(cli,
350 prs_data_p(current_pdu) + current_pdu_len,
351 prhdr->frag_len - current_pdu_len);
352 if (!NT_STATUS_IS_OK(ret)) {
353 return ret;
357 return NT_STATUS_OK;
360 /****************************************************************************
361 NTLMSSP specific sign/seal.
362 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
363 In fact I should probably abstract these into identical pieces of code... JRA.
364 ****************************************************************************/
366 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
367 prs_struct *current_pdu,
368 uint8 *p_ss_padding_len)
370 RPC_HDR_AUTH auth_info;
371 uint32 save_offset = prs_offset(current_pdu);
372 uint32 auth_len = prhdr->auth_len;
373 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
374 unsigned char *data = NULL;
375 size_t data_len;
376 unsigned char *full_packet_data = NULL;
377 size_t full_packet_data_len;
378 DATA_BLOB auth_blob;
379 NTSTATUS status;
381 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
382 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
383 return NT_STATUS_OK;
386 if (!ntlmssp_state) {
387 return NT_STATUS_INVALID_PARAMETER;
390 /* Ensure there's enough data for an authenticated response. */
391 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
392 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
393 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
394 (unsigned int)auth_len ));
395 return NT_STATUS_BUFFER_TOO_SMALL;
399 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
400 * after the RPC header.
401 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
402 * functions as NTLMv2 checks the rpc headers also.
405 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
406 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
408 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
409 full_packet_data_len = prhdr->frag_len - auth_len;
411 /* Pull the auth header and the following data into a blob. */
412 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
413 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
414 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
415 return NT_STATUS_BUFFER_TOO_SMALL;
418 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
419 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
420 return NT_STATUS_BUFFER_TOO_SMALL;
423 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
424 auth_blob.length = auth_len;
426 switch (cli->auth->auth_level) {
427 case PIPE_AUTH_LEVEL_PRIVACY:
428 /* Data is encrypted. */
429 status = ntlmssp_unseal_packet(ntlmssp_state,
430 data, data_len,
431 full_packet_data,
432 full_packet_data_len,
433 &auth_blob);
434 if (!NT_STATUS_IS_OK(status)) {
435 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
436 "packet from %s. Error was %s.\n",
437 rpccli_pipe_txt(debug_ctx(), cli),
438 nt_errstr(status) ));
439 return status;
441 break;
442 case PIPE_AUTH_LEVEL_INTEGRITY:
443 /* Data is signed. */
444 status = ntlmssp_check_packet(ntlmssp_state,
445 data, data_len,
446 full_packet_data,
447 full_packet_data_len,
448 &auth_blob);
449 if (!NT_STATUS_IS_OK(status)) {
450 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
451 "packet from %s. Error was %s.\n",
452 rpccli_pipe_txt(debug_ctx(), cli),
453 nt_errstr(status) ));
454 return status;
456 break;
457 default:
458 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
459 "auth level %d\n", cli->auth->auth_level));
460 return NT_STATUS_INVALID_INFO_CLASS;
464 * Return the current pointer to the data offset.
467 if(!prs_set_offset(current_pdu, save_offset)) {
468 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
469 (unsigned int)save_offset ));
470 return NT_STATUS_BUFFER_TOO_SMALL;
474 * Remember the padding length. We must remove it from the real data
475 * stream once the sign/seal is done.
478 *p_ss_padding_len = auth_info.auth_pad_len;
480 return NT_STATUS_OK;
483 /****************************************************************************
484 schannel specific sign/seal.
485 ****************************************************************************/
487 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
488 prs_struct *current_pdu,
489 uint8 *p_ss_padding_len)
491 RPC_HDR_AUTH auth_info;
492 RPC_AUTH_SCHANNEL_CHK schannel_chk;
493 uint32 auth_len = prhdr->auth_len;
494 uint32 save_offset = prs_offset(current_pdu);
495 struct schannel_auth_struct *schannel_auth =
496 cli->auth->a_u.schannel_auth;
497 uint32 data_len;
499 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
500 || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
501 return NT_STATUS_OK;
504 if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
505 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
506 return NT_STATUS_INVALID_PARAMETER;
509 if (!schannel_auth) {
510 return NT_STATUS_INVALID_PARAMETER;
513 /* Ensure there's enough data for an authenticated response. */
514 if ((auth_len > RPC_MAX_SIGN_SIZE) ||
515 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
516 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
517 (unsigned int)auth_len ));
518 return NT_STATUS_INVALID_PARAMETER;
521 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
523 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
524 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
525 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
526 return NT_STATUS_BUFFER_TOO_SMALL;
529 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
530 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
531 return NT_STATUS_BUFFER_TOO_SMALL;
534 if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
535 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
536 auth_info.auth_type));
537 return NT_STATUS_BUFFER_TOO_SMALL;
540 if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
541 &schannel_chk, current_pdu, 0)) {
542 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
543 return NT_STATUS_BUFFER_TOO_SMALL;
546 if (!schannel_decode(schannel_auth,
547 cli->auth->auth_level,
548 SENDER_IS_ACCEPTOR,
549 &schannel_chk,
550 prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
551 data_len)) {
552 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
553 "Connection to %s.\n",
554 rpccli_pipe_txt(debug_ctx(), cli)));
555 return NT_STATUS_INVALID_PARAMETER;
558 /* The sequence number gets incremented on both send and receive. */
559 schannel_auth->seq_num++;
562 * Return the current pointer to the data offset.
565 if(!prs_set_offset(current_pdu, save_offset)) {
566 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
567 (unsigned int)save_offset ));
568 return NT_STATUS_BUFFER_TOO_SMALL;
572 * Remember the padding length. We must remove it from the real data
573 * stream once the sign/seal is done.
576 *p_ss_padding_len = auth_info.auth_pad_len;
578 return NT_STATUS_OK;
581 /****************************************************************************
582 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
583 ****************************************************************************/
585 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
586 prs_struct *current_pdu,
587 uint8 *p_ss_padding_len)
589 NTSTATUS ret = NT_STATUS_OK;
591 /* Paranioa checks for auth_len. */
592 if (prhdr->auth_len) {
593 if (prhdr->auth_len > prhdr->frag_len) {
594 return NT_STATUS_INVALID_PARAMETER;
597 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
598 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
599 /* Integer wrap attempt. */
600 return NT_STATUS_INVALID_PARAMETER;
605 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
608 switch(cli->auth->auth_type) {
609 case PIPE_AUTH_TYPE_NONE:
610 if (prhdr->auth_len) {
611 DEBUG(3, ("cli_pipe_validate_rpc_response: "
612 "Connection to %s - got non-zero "
613 "auth len %u.\n",
614 rpccli_pipe_txt(debug_ctx(), cli),
615 (unsigned int)prhdr->auth_len ));
616 return NT_STATUS_INVALID_PARAMETER;
618 break;
620 case PIPE_AUTH_TYPE_NTLMSSP:
621 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
622 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
623 if (!NT_STATUS_IS_OK(ret)) {
624 return ret;
626 break;
628 case PIPE_AUTH_TYPE_SCHANNEL:
629 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
630 if (!NT_STATUS_IS_OK(ret)) {
631 return ret;
633 break;
635 case PIPE_AUTH_TYPE_KRB5:
636 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
637 default:
638 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
639 "to %s - unknown internal auth type %u.\n",
640 rpccli_pipe_txt(debug_ctx(), cli),
641 cli->auth->auth_type ));
642 return NT_STATUS_INVALID_INFO_CLASS;
645 return NT_STATUS_OK;
648 /****************************************************************************
649 Do basic authentication checks on an incoming pdu.
650 ****************************************************************************/
652 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
653 prs_struct *current_pdu,
654 uint8 expected_pkt_type,
655 char **ppdata,
656 uint32 *pdata_len,
657 prs_struct *return_data)
660 NTSTATUS ret = NT_STATUS_OK;
661 uint32 current_pdu_len = prs_data_size(current_pdu);
663 if (current_pdu_len != prhdr->frag_len) {
664 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
665 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
666 return NT_STATUS_INVALID_PARAMETER;
670 * Point the return values at the real data including the RPC
671 * header. Just in case the caller wants it.
673 *ppdata = prs_data_p(current_pdu);
674 *pdata_len = current_pdu_len;
676 /* Ensure we have the correct type. */
677 switch (prhdr->pkt_type) {
678 case RPC_ALTCONTRESP:
679 case RPC_BINDACK:
681 /* Alter context and bind ack share the same packet definitions. */
682 break;
685 case RPC_RESPONSE:
687 RPC_HDR_RESP rhdr_resp;
688 uint8 ss_padding_len = 0;
690 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
691 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
692 return NT_STATUS_BUFFER_TOO_SMALL;
695 /* Here's where we deal with incoming sign/seal. */
696 ret = cli_pipe_validate_rpc_response(cli, prhdr,
697 current_pdu, &ss_padding_len);
698 if (!NT_STATUS_IS_OK(ret)) {
699 return ret;
702 /* Point the return values at the NDR data. Remember to remove any ss padding. */
703 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
705 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
706 return NT_STATUS_BUFFER_TOO_SMALL;
709 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
711 /* Remember to remove the auth footer. */
712 if (prhdr->auth_len) {
713 /* We've already done integer wrap tests on auth_len in
714 cli_pipe_validate_rpc_response(). */
715 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
716 return NT_STATUS_BUFFER_TOO_SMALL;
718 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
721 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
722 current_pdu_len, *pdata_len, ss_padding_len ));
725 * If this is the first reply, and the allocation hint is reasonably, try and
726 * set up the return_data parse_struct to the correct size.
729 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
730 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
731 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
732 "too large to allocate\n",
733 (unsigned int)rhdr_resp.alloc_hint ));
734 return NT_STATUS_NO_MEMORY;
738 break;
741 case RPC_BINDNACK:
742 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
743 "received from %s!\n",
744 rpccli_pipe_txt(debug_ctx(), cli)));
745 /* Use this for now... */
746 return NT_STATUS_NETWORK_ACCESS_DENIED;
748 case RPC_FAULT:
750 RPC_HDR_RESP rhdr_resp;
751 RPC_HDR_FAULT fault_resp;
753 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
754 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
755 return NT_STATUS_BUFFER_TOO_SMALL;
758 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
759 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
760 return NT_STATUS_BUFFER_TOO_SMALL;
763 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
764 "code %s received from %s!\n",
765 dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
766 rpccli_pipe_txt(debug_ctx(), cli)));
767 if (NT_STATUS_IS_OK(fault_resp.status)) {
768 return NT_STATUS_UNSUCCESSFUL;
769 } else {
770 return fault_resp.status;
774 default:
775 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
776 "from %s!\n",
777 (unsigned int)prhdr->pkt_type,
778 rpccli_pipe_txt(debug_ctx(), cli)));
779 return NT_STATUS_INVALID_INFO_CLASS;
782 if (prhdr->pkt_type != expected_pkt_type) {
783 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
784 "got an unexpected RPC packet type - %u, not %u\n",
785 rpccli_pipe_txt(debug_ctx(), cli),
786 prhdr->pkt_type,
787 expected_pkt_type));
788 return NT_STATUS_INVALID_INFO_CLASS;
791 /* Do this just before return - we don't want to modify any rpc header
792 data before now as we may have needed to do cryptographic actions on
793 it before. */
795 if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
796 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
797 "setting fragment first/last ON.\n"));
798 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
801 return NT_STATUS_OK;
804 /****************************************************************************
805 Ensure we eat the just processed pdu from the current_pdu prs_struct.
806 Normally the frag_len and buffer size will match, but on the first trans
807 reply there is a theoretical chance that buffer size > frag_len, so we must
808 deal with that.
809 ****************************************************************************/
811 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
813 uint32 current_pdu_len = prs_data_size(current_pdu);
815 if (current_pdu_len < prhdr->frag_len) {
816 return NT_STATUS_BUFFER_TOO_SMALL;
819 /* Common case. */
820 if (current_pdu_len == (uint32)prhdr->frag_len) {
821 prs_mem_free(current_pdu);
822 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
823 /* Make current_pdu dynamic with no memory. */
824 prs_give_memory(current_pdu, 0, 0, True);
825 return NT_STATUS_OK;
829 * Oh no ! More data in buffer than we processed in current pdu.
830 * Cheat. Move the data down and shrink the buffer.
833 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
834 current_pdu_len - prhdr->frag_len);
836 /* Remember to set the read offset back to zero. */
837 prs_set_offset(current_pdu, 0);
839 /* Shrink the buffer. */
840 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
841 return NT_STATUS_BUFFER_TOO_SMALL;
844 return NT_STATUS_OK;
847 /****************************************************************************
848 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
849 ****************************************************************************/
851 static bool cli_api_pipe(struct cli_state *cli, const char *pipe_name,
852 uint16 *setup, uint32 setup_count,
853 uint32 max_setup_count,
854 char *params, uint32 param_count,
855 uint32 max_param_count,
856 char *data, uint32 data_count,
857 uint32 max_data_count,
858 char **rparam, uint32 *rparam_count,
859 char **rdata, uint32 *rdata_count)
861 cli_send_trans(cli, SMBtrans,
862 pipe_name,
863 0,0, /* fid, flags */
864 setup, setup_count, max_setup_count,
865 params, param_count, max_param_count,
866 data, data_count, max_data_count);
868 return (cli_receive_trans(cli, SMBtrans,
869 rparam, (unsigned int *)rparam_count,
870 rdata, (unsigned int *)rdata_count));
873 /****************************************************************************
874 Send data on an rpc pipe via trans. The prs_struct data must be the last
875 pdu fragment of an NDR data stream.
877 Receive response data from an rpc pipe, which may be large...
879 Read the first fragment: unfortunately have to use SMBtrans for the first
880 bit, then SMBreadX for subsequent bits.
882 If first fragment received also wasn't the last fragment, continue
883 getting fragments until we _do_ receive the last fragment.
885 Request/Response PDU's look like the following...
887 |<------------------PDU len----------------------------------------------->|
888 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
890 +------------+-----------------+-------------+---------------+-------------+
891 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
892 +------------+-----------------+-------------+---------------+-------------+
894 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
895 signing & sealing being negotiated.
897 ****************************************************************************/
899 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
900 prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
901 prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
902 uint8 expected_pkt_type)
904 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
905 char *rparam = NULL;
906 uint32 rparam_len = 0;
907 char *pdata = prs_data_p(data);
908 uint32 data_len = prs_offset(data);
909 char *prdata = NULL;
910 uint32 rdata_len = 0;
911 uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
912 uint32 current_rbuf_offset = 0;
913 prs_struct current_pdu;
915 #ifdef DEVELOPER
916 /* Ensure we're not sending too much. */
917 SMB_ASSERT(data_len <= max_data);
918 #endif
920 /* Set up the current pdu parse struct. */
921 prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
923 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
925 switch (cli->transport_type) {
926 case NCACN_NP: {
927 uint16 setup[2];
928 /* Create setup parameters - must be in native byte order. */
929 setup[0] = TRANSACT_DCERPCCMD;
930 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
933 * Send the last (or only) fragment of an RPC request. For
934 * small amounts of data (about 1024 bytes or so) the RPC
935 * request and response appears in a SMBtrans request and
936 * response.
939 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
940 setup, 2, 0, /* Setup, length, max */
941 NULL, 0, 0, /* Params, length, max */
942 pdata, data_len, max_data, /* data, length,
943 * max */
944 &rparam, &rparam_len, /* return params,
945 * len */
946 &prdata, &rdata_len)) /* return data, len */
948 DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
949 "Error was %s\n",
950 rpccli_pipe_txt(debug_ctx(), cli),
951 cli_errstr(cli->trans.np.cli)));
952 ret = cli_get_nt_error(cli->trans.np.cli);
953 SAFE_FREE(rparam);
954 SAFE_FREE(prdata);
955 goto err;
957 break;
959 case NCACN_IP_TCP:
960 case NCACN_UNIX_STREAM:
962 ssize_t nwritten, nread;
963 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
964 if (nwritten == -1) {
965 ret = map_nt_error_from_unix(errno);
966 DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
967 strerror(errno)));
968 goto err;
970 rparam = NULL;
971 prdata = SMB_MALLOC_ARRAY(char, 1);
972 if (prdata == NULL) {
973 return NT_STATUS_NO_MEMORY;
975 nread = sys_read(cli->trans.sock.fd, prdata, 1);
976 if (nread == 0) {
977 SAFE_FREE(prdata);
979 if (nread == -1) {
980 ret = NT_STATUS_END_OF_FILE;
981 goto err;
983 rdata_len = nread;
984 break;
986 default:
987 DEBUG(0, ("unknown transport type %d\n",
988 cli->transport_type));
989 return NT_STATUS_INTERNAL_ERROR;
992 /* Throw away returned params - we know we won't use them. */
994 SAFE_FREE(rparam);
996 if (prdata == NULL) {
997 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
998 rpccli_pipe_txt(debug_ctx(), cli)));
999 /* Yes - some calls can truely return no data... */
1000 prs_mem_free(&current_pdu);
1001 return NT_STATUS_OK;
1005 * Give this memory as dynamic to the current pdu.
1008 prs_give_memory(&current_pdu, prdata, rdata_len, True);
1010 /* Ensure we can mess with the return prs_struct. */
1011 SMB_ASSERT(UNMARSHALLING(rbuf));
1012 SMB_ASSERT(prs_data_size(rbuf) == 0);
1014 /* Make rbuf dynamic with no memory. */
1015 prs_give_memory(rbuf, 0, 0, True);
1017 while(1) {
1018 RPC_HDR rhdr;
1019 char *ret_data = NULL;
1020 uint32 ret_data_len = 0;
1022 /* Ensure we have enough data for a pdu. */
1023 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
1024 if (!NT_STATUS_IS_OK(ret)) {
1025 goto err;
1028 /* We pass in rbuf here so if the alloc hint is set correctly
1029 we can set the output size and avoid reallocs. */
1031 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
1032 &ret_data, &ret_data_len, rbuf);
1034 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
1035 prs_data_size(&current_pdu), current_rbuf_offset ));
1037 if (!NT_STATUS_IS_OK(ret)) {
1038 goto err;
1041 if ((rhdr.flags & RPC_FLG_FIRST)) {
1042 if (rhdr.pack_type[0] == 0) {
1043 /* Set the data type correctly for big-endian data on the first packet. */
1044 DEBUG(10,("rpc_api_pipe: On %s "
1045 "PDU data format is big-endian.\n",
1046 rpccli_pipe_txt(debug_ctx(), cli)));
1048 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
1049 } else {
1050 /* Check endianness on subsequent packets. */
1051 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
1052 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1053 rbuf->bigendian_data ? "big" : "little",
1054 current_pdu.bigendian_data ? "big" : "little" ));
1055 ret = NT_STATUS_INVALID_PARAMETER;
1056 goto err;
1061 /* Now copy the data portion out of the pdu into rbuf. */
1062 if (!prs_force_grow(rbuf, ret_data_len)) {
1063 ret = NT_STATUS_NO_MEMORY;
1064 goto err;
1066 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
1067 current_rbuf_offset += ret_data_len;
1069 /* See if we've finished with all the data in current_pdu yet ? */
1070 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
1071 if (!NT_STATUS_IS_OK(ret)) {
1072 goto err;
1075 if (rhdr.flags & RPC_FLG_LAST) {
1076 break; /* We're done. */
1080 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1081 rpccli_pipe_txt(debug_ctx(), cli),
1082 (unsigned int)prs_data_size(rbuf) ));
1084 prs_mem_free(&current_pdu);
1085 return NT_STATUS_OK;
1087 err:
1089 prs_mem_free(&current_pdu);
1090 prs_mem_free(rbuf);
1091 return ret;
1094 /*******************************************************************
1095 Creates krb5 auth bind.
1096 ********************************************************************/
1098 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1099 enum pipe_auth_level auth_level,
1100 RPC_HDR_AUTH *pauth_out,
1101 prs_struct *auth_data)
1103 #ifdef HAVE_KRB5
1104 int ret;
1105 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1106 DATA_BLOB tkt = data_blob_null;
1107 DATA_BLOB tkt_wrapped = data_blob_null;
1109 /* We may change the pad length before marshalling. */
1110 init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1112 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1113 a->service_principal ));
1115 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1117 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1118 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1120 if (ret) {
1121 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1122 "failed with %s\n",
1123 a->service_principal,
1124 error_message(ret) ));
1126 data_blob_free(&tkt);
1127 prs_mem_free(auth_data);
1128 return NT_STATUS_INVALID_PARAMETER;
1131 /* wrap that up in a nice GSS-API wrapping */
1132 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1134 data_blob_free(&tkt);
1136 /* Auth len in the rpc header doesn't include auth_header. */
1137 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1138 data_blob_free(&tkt_wrapped);
1139 prs_mem_free(auth_data);
1140 return NT_STATUS_NO_MEMORY;
1143 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1144 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1146 data_blob_free(&tkt_wrapped);
1147 return NT_STATUS_OK;
1148 #else
1149 return NT_STATUS_INVALID_PARAMETER;
1150 #endif
1153 /*******************************************************************
1154 Creates SPNEGO NTLMSSP auth bind.
1155 ********************************************************************/
1157 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1158 enum pipe_auth_level auth_level,
1159 RPC_HDR_AUTH *pauth_out,
1160 prs_struct *auth_data)
1162 NTSTATUS nt_status;
1163 DATA_BLOB null_blob = data_blob_null;
1164 DATA_BLOB request = data_blob_null;
1165 DATA_BLOB spnego_msg = data_blob_null;
1167 /* We may change the pad length before marshalling. */
1168 init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1170 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1171 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1172 null_blob,
1173 &request);
1175 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1176 data_blob_free(&request);
1177 prs_mem_free(auth_data);
1178 return nt_status;
1181 /* Wrap this in SPNEGO. */
1182 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1184 data_blob_free(&request);
1186 /* Auth len in the rpc header doesn't include auth_header. */
1187 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1188 data_blob_free(&spnego_msg);
1189 prs_mem_free(auth_data);
1190 return NT_STATUS_NO_MEMORY;
1193 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1194 dump_data(5, spnego_msg.data, spnego_msg.length);
1196 data_blob_free(&spnego_msg);
1197 return NT_STATUS_OK;
1200 /*******************************************************************
1201 Creates NTLMSSP auth bind.
1202 ********************************************************************/
1204 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1205 enum pipe_auth_level auth_level,
1206 RPC_HDR_AUTH *pauth_out,
1207 prs_struct *auth_data)
1209 NTSTATUS nt_status;
1210 DATA_BLOB null_blob = data_blob_null;
1211 DATA_BLOB request = data_blob_null;
1213 /* We may change the pad length before marshalling. */
1214 init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1216 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1217 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1218 null_blob,
1219 &request);
1221 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1222 data_blob_free(&request);
1223 prs_mem_free(auth_data);
1224 return nt_status;
1227 /* Auth len in the rpc header doesn't include auth_header. */
1228 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1229 data_blob_free(&request);
1230 prs_mem_free(auth_data);
1231 return NT_STATUS_NO_MEMORY;
1234 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1235 dump_data(5, request.data, request.length);
1237 data_blob_free(&request);
1238 return NT_STATUS_OK;
1241 /*******************************************************************
1242 Creates schannel auth bind.
1243 ********************************************************************/
1245 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1246 enum pipe_auth_level auth_level,
1247 RPC_HDR_AUTH *pauth_out,
1248 prs_struct *auth_data)
1250 RPC_AUTH_SCHANNEL_NEG schannel_neg;
1252 /* We may change the pad length before marshalling. */
1253 init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1255 /* Use lp_workgroup() if domain not specified */
1257 if (!cli->auth->domain || !cli->auth->domain[0]) {
1258 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1259 if (cli->auth->domain == NULL) {
1260 return NT_STATUS_NO_MEMORY;
1264 init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1265 global_myname());
1268 * Now marshall the data into the auth parse_struct.
1271 if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1272 &schannel_neg, auth_data, 0)) {
1273 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1274 prs_mem_free(auth_data);
1275 return NT_STATUS_NO_MEMORY;
1278 return NT_STATUS_OK;
1281 /*******************************************************************
1282 Creates the internals of a DCE/RPC bind request or alter context PDU.
1283 ********************************************************************/
1285 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1286 prs_struct *rpc_out,
1287 uint32 rpc_call_id,
1288 const RPC_IFACE *abstract,
1289 const RPC_IFACE *transfer,
1290 RPC_HDR_AUTH *phdr_auth,
1291 prs_struct *pauth_info)
1293 RPC_HDR hdr;
1294 RPC_HDR_RB hdr_rb;
1295 RPC_CONTEXT rpc_ctx;
1296 uint16 auth_len = prs_offset(pauth_info);
1297 uint8 ss_padding_len = 0;
1298 uint16 frag_len = 0;
1300 /* create the RPC context. */
1301 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1303 /* create the bind request RPC_HDR_RB */
1304 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1306 /* Start building the frag length. */
1307 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1309 /* Do we need to pad ? */
1310 if (auth_len) {
1311 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1312 if (data_len % 8) {
1313 ss_padding_len = 8 - (data_len % 8);
1314 phdr_auth->auth_pad_len = ss_padding_len;
1316 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1319 /* Create the request RPC_HDR */
1320 init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1322 /* Marshall the RPC header */
1323 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1324 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1325 return NT_STATUS_NO_MEMORY;
1328 /* Marshall the bind request data */
1329 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1330 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1331 return NT_STATUS_NO_MEMORY;
1335 * Grow the outgoing buffer to store any auth info.
1338 if(auth_len != 0) {
1339 if (ss_padding_len) {
1340 char pad[8];
1341 memset(pad, '\0', 8);
1342 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1343 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1344 return NT_STATUS_NO_MEMORY;
1348 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1349 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1350 return NT_STATUS_NO_MEMORY;
1354 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1355 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1356 return NT_STATUS_NO_MEMORY;
1360 return NT_STATUS_OK;
1363 /*******************************************************************
1364 Creates a DCE/RPC bind request.
1365 ********************************************************************/
1367 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1368 prs_struct *rpc_out,
1369 uint32 rpc_call_id,
1370 const RPC_IFACE *abstract,
1371 const RPC_IFACE *transfer,
1372 enum pipe_auth_type auth_type,
1373 enum pipe_auth_level auth_level)
1375 RPC_HDR_AUTH hdr_auth;
1376 prs_struct auth_info;
1377 NTSTATUS ret = NT_STATUS_OK;
1379 ZERO_STRUCT(hdr_auth);
1380 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1381 return NT_STATUS_NO_MEMORY;
1383 switch (auth_type) {
1384 case PIPE_AUTH_TYPE_SCHANNEL:
1385 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1386 if (!NT_STATUS_IS_OK(ret)) {
1387 prs_mem_free(&auth_info);
1388 return ret;
1390 break;
1392 case PIPE_AUTH_TYPE_NTLMSSP:
1393 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1394 if (!NT_STATUS_IS_OK(ret)) {
1395 prs_mem_free(&auth_info);
1396 return ret;
1398 break;
1400 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1401 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1402 if (!NT_STATUS_IS_OK(ret)) {
1403 prs_mem_free(&auth_info);
1404 return ret;
1406 break;
1408 case PIPE_AUTH_TYPE_KRB5:
1409 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1410 if (!NT_STATUS_IS_OK(ret)) {
1411 prs_mem_free(&auth_info);
1412 return ret;
1414 break;
1416 case PIPE_AUTH_TYPE_NONE:
1417 break;
1419 default:
1420 /* "Can't" happen. */
1421 return NT_STATUS_INVALID_INFO_CLASS;
1424 ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1425 rpc_out,
1426 rpc_call_id,
1427 abstract,
1428 transfer,
1429 &hdr_auth,
1430 &auth_info);
1432 prs_mem_free(&auth_info);
1433 return ret;
1436 /*******************************************************************
1437 Create and add the NTLMSSP sign/seal auth header and data.
1438 ********************************************************************/
1440 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1441 RPC_HDR *phdr,
1442 uint32 ss_padding_len,
1443 prs_struct *outgoing_pdu)
1445 RPC_HDR_AUTH auth_info;
1446 NTSTATUS status;
1447 DATA_BLOB auth_blob = data_blob_null;
1448 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1450 if (!cli->auth->a_u.ntlmssp_state) {
1451 return NT_STATUS_INVALID_PARAMETER;
1454 /* Init and marshall the auth header. */
1455 init_rpc_hdr_auth(&auth_info,
1456 map_pipe_auth_type_to_rpc_auth_type(
1457 cli->auth->auth_type),
1458 cli->auth->auth_level,
1459 ss_padding_len,
1460 1 /* context id. */);
1462 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1463 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1464 data_blob_free(&auth_blob);
1465 return NT_STATUS_NO_MEMORY;
1468 switch (cli->auth->auth_level) {
1469 case PIPE_AUTH_LEVEL_PRIVACY:
1470 /* Data portion is encrypted. */
1471 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1472 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1473 data_and_pad_len,
1474 (unsigned char *)prs_data_p(outgoing_pdu),
1475 (size_t)prs_offset(outgoing_pdu),
1476 &auth_blob);
1477 if (!NT_STATUS_IS_OK(status)) {
1478 data_blob_free(&auth_blob);
1479 return status;
1481 break;
1483 case PIPE_AUTH_LEVEL_INTEGRITY:
1484 /* Data is signed. */
1485 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1486 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1487 data_and_pad_len,
1488 (unsigned char *)prs_data_p(outgoing_pdu),
1489 (size_t)prs_offset(outgoing_pdu),
1490 &auth_blob);
1491 if (!NT_STATUS_IS_OK(status)) {
1492 data_blob_free(&auth_blob);
1493 return status;
1495 break;
1497 default:
1498 /* Can't happen. */
1499 smb_panic("bad auth level");
1500 /* Notreached. */
1501 return NT_STATUS_INVALID_PARAMETER;
1504 /* Finally marshall the blob. */
1506 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1507 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1508 (unsigned int)NTLMSSP_SIG_SIZE));
1509 data_blob_free(&auth_blob);
1510 return NT_STATUS_NO_MEMORY;
1513 data_blob_free(&auth_blob);
1514 return NT_STATUS_OK;
1517 /*******************************************************************
1518 Create and add the schannel sign/seal auth header and data.
1519 ********************************************************************/
1521 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1522 RPC_HDR *phdr,
1523 uint32 ss_padding_len,
1524 prs_struct *outgoing_pdu)
1526 RPC_HDR_AUTH auth_info;
1527 RPC_AUTH_SCHANNEL_CHK verf;
1528 struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1529 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1530 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1532 if (!sas) {
1533 return NT_STATUS_INVALID_PARAMETER;
1536 /* Init and marshall the auth header. */
1537 init_rpc_hdr_auth(&auth_info,
1538 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1539 cli->auth->auth_level,
1540 ss_padding_len,
1541 1 /* context id. */);
1543 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1544 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1545 return NT_STATUS_NO_MEMORY;
1548 switch (cli->auth->auth_level) {
1549 case PIPE_AUTH_LEVEL_PRIVACY:
1550 case PIPE_AUTH_LEVEL_INTEGRITY:
1551 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1552 sas->seq_num));
1554 schannel_encode(sas,
1555 cli->auth->auth_level,
1556 SENDER_IS_INITIATOR,
1557 &verf,
1558 data_p,
1559 data_and_pad_len);
1561 sas->seq_num++;
1562 break;
1564 default:
1565 /* Can't happen. */
1566 smb_panic("bad auth level");
1567 /* Notreached. */
1568 return NT_STATUS_INVALID_PARAMETER;
1571 /* Finally marshall the blob. */
1572 smb_io_rpc_auth_schannel_chk("",
1573 RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1574 &verf,
1575 outgoing_pdu,
1578 return NT_STATUS_OK;
1581 /*******************************************************************
1582 Calculate how much data we're going to send in this packet, also
1583 work out any sign/seal padding length.
1584 ********************************************************************/
1586 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1587 uint32 data_left,
1588 uint16 *p_frag_len,
1589 uint16 *p_auth_len,
1590 uint32 *p_ss_padding)
1592 uint32 data_space, data_len;
1594 switch (cli->auth->auth_level) {
1595 case PIPE_AUTH_LEVEL_NONE:
1596 case PIPE_AUTH_LEVEL_CONNECT:
1597 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1598 data_len = MIN(data_space, data_left);
1599 *p_ss_padding = 0;
1600 *p_auth_len = 0;
1601 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1602 return data_len;
1604 case PIPE_AUTH_LEVEL_INTEGRITY:
1605 case PIPE_AUTH_LEVEL_PRIVACY:
1606 /* Treat the same for all authenticated rpc requests. */
1607 switch(cli->auth->auth_type) {
1608 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1609 case PIPE_AUTH_TYPE_NTLMSSP:
1610 *p_auth_len = NTLMSSP_SIG_SIZE;
1611 break;
1612 case PIPE_AUTH_TYPE_SCHANNEL:
1613 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1614 break;
1615 default:
1616 smb_panic("bad auth type");
1617 break;
1620 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1621 RPC_HDR_AUTH_LEN - *p_auth_len;
1623 data_len = MIN(data_space, data_left);
1624 if (data_len % 8) {
1625 *p_ss_padding = 8 - (data_len % 8);
1627 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
1628 data_len + *p_ss_padding + /* data plus padding. */
1629 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
1630 return data_len;
1632 default:
1633 smb_panic("bad auth level");
1634 /* Notreached. */
1635 return 0;
1639 /*******************************************************************
1640 External interface.
1641 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1642 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1643 and deals with signing/sealing details.
1644 ********************************************************************/
1646 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1647 uint8 op_num,
1648 prs_struct *in_data,
1649 prs_struct *out_data)
1651 NTSTATUS ret;
1652 uint32 data_left = prs_offset(in_data);
1653 uint32 alloc_hint = prs_offset(in_data);
1654 uint32 data_sent_thistime = 0;
1655 uint32 current_data_offset = 0;
1656 uint32 call_id = get_rpc_call_id();
1657 char pad[8];
1658 prs_struct outgoing_pdu;
1660 memset(pad, '\0', 8);
1662 if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1663 /* Server is screwed up ! */
1664 return NT_STATUS_INVALID_PARAMETER;
1667 if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1668 return NT_STATUS_NO_MEMORY;
1670 while (1) {
1671 RPC_HDR hdr;
1672 RPC_HDR_REQ hdr_req;
1673 uint16 auth_len = 0;
1674 uint16 frag_len = 0;
1675 uint8 flags = 0;
1676 uint32 ss_padding = 0;
1677 ssize_t num_written;
1679 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1680 &frag_len, &auth_len, &ss_padding);
1682 if (current_data_offset == 0) {
1683 flags = RPC_FLG_FIRST;
1686 if (data_sent_thistime == data_left) {
1687 flags |= RPC_FLG_LAST;
1690 /* Create and marshall the header and request header. */
1691 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1693 if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
1694 prs_mem_free(&outgoing_pdu);
1695 return NT_STATUS_NO_MEMORY;
1698 /* Create the rpc request RPC_HDR_REQ */
1699 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1701 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1702 prs_mem_free(&outgoing_pdu);
1703 return NT_STATUS_NO_MEMORY;
1706 /* Copy in the data, plus any ss padding. */
1707 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1708 prs_mem_free(&outgoing_pdu);
1709 return NT_STATUS_NO_MEMORY;
1712 /* Copy the sign/seal padding data. */
1713 if (ss_padding) {
1714 if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1715 prs_mem_free(&outgoing_pdu);
1716 return NT_STATUS_NO_MEMORY;
1720 /* Generate any auth sign/seal and add the auth footer. */
1721 if (auth_len) {
1722 switch (cli->auth->auth_type) {
1723 case PIPE_AUTH_TYPE_NONE:
1724 break;
1725 case PIPE_AUTH_TYPE_NTLMSSP:
1726 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1727 ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1728 if (!NT_STATUS_IS_OK(ret)) {
1729 prs_mem_free(&outgoing_pdu);
1730 return ret;
1732 break;
1733 case PIPE_AUTH_TYPE_SCHANNEL:
1734 ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1735 if (!NT_STATUS_IS_OK(ret)) {
1736 prs_mem_free(&outgoing_pdu);
1737 return ret;
1739 break;
1740 default:
1741 smb_panic("bad auth type");
1742 break; /* notreached */
1746 /* Actually send the packet. */
1747 if (flags & RPC_FLG_LAST) {
1748 /* Last packet - send the data, get the reply and return. */
1749 ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1750 prs_mem_free(&outgoing_pdu);
1752 if ((DEBUGLEVEL >= 50)
1753 && (cli->transport_type == NCACN_NP)) {
1754 char *dump_name = NULL;
1755 /* Also capture received data */
1756 if (asprintf(&dump_name, "%s/reply_%s_%d",
1757 get_dyn_LOGFILEBASE(),
1758 cli->trans.np.pipe_name, op_num) > 0) {
1759 prs_dump(dump_name, op_num, out_data);
1760 SAFE_FREE(dump_name);
1764 return ret;
1767 switch (cli->transport_type) {
1768 case NCACN_NP:
1769 num_written = cli_write(cli->trans.np.cli,
1770 cli->trans.np.fnum,
1771 8, /* 8 means message mode. */
1772 prs_data_p(&outgoing_pdu),
1773 (off_t)0,
1774 (size_t)hdr.frag_len);
1776 if (num_written != hdr.frag_len) {
1777 prs_mem_free(&outgoing_pdu);
1778 return cli_get_nt_error(cli->trans.np.cli);
1780 break;
1781 case NCACN_IP_TCP:
1782 case NCACN_UNIX_STREAM:
1783 num_written = write_data(
1784 cli->trans.sock.fd,
1785 prs_data_p(&outgoing_pdu),
1786 (size_t)hdr.frag_len);
1787 if (num_written != hdr.frag_len) {
1788 NTSTATUS status;
1789 status = map_nt_error_from_unix(errno);
1790 prs_mem_free(&outgoing_pdu);
1791 return status;
1793 break;
1794 default:
1795 DEBUG(0, ("unknown transport type %d\n",
1796 cli->transport_type));
1797 return NT_STATUS_INTERNAL_ERROR;
1800 current_data_offset += data_sent_thistime;
1801 data_left -= data_sent_thistime;
1803 /* Reset the marshalling position back to zero. */
1804 if (!prs_set_offset(&outgoing_pdu, 0)) {
1805 prs_mem_free(&outgoing_pdu);
1806 return NT_STATUS_NO_MEMORY;
1810 #if 0
1811 /****************************************************************************
1812 Set the handle state.
1813 ****************************************************************************/
1815 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1816 const char *pipe_name, uint16 device_state)
1818 bool state_set = False;
1819 char param[2];
1820 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1821 char *rparam = NULL;
1822 char *rdata = NULL;
1823 uint32 rparam_len, rdata_len;
1825 if (pipe_name == NULL)
1826 return False;
1828 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1829 cli->fnum, pipe_name, device_state));
1831 /* create parameters: device state */
1832 SSVAL(param, 0, device_state);
1834 /* create setup parameters. */
1835 setup[0] = 0x0001;
1836 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1838 /* send the data on \PIPE\ */
1839 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1840 setup, 2, 0, /* setup, length, max */
1841 param, 2, 0, /* param, length, max */
1842 NULL, 0, 1024, /* data, length, max */
1843 &rparam, &rparam_len, /* return param, length */
1844 &rdata, &rdata_len)) /* return data, length */
1846 DEBUG(5, ("Set Handle state: return OK\n"));
1847 state_set = True;
1850 SAFE_FREE(rparam);
1851 SAFE_FREE(rdata);
1853 return state_set;
1855 #endif
1857 /****************************************************************************
1858 Check the rpc bind acknowledge response.
1859 ****************************************************************************/
1861 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1863 if ( hdr_ba->addr.len == 0) {
1864 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1867 /* check the transfer syntax */
1868 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1869 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1870 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1871 return False;
1874 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1875 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1876 hdr_ba->res.num_results, hdr_ba->res.reason));
1879 DEBUG(5,("check_bind_response: accepted!\n"));
1880 return True;
1883 /*******************************************************************
1884 Creates a DCE/RPC bind authentication response.
1885 This is the packet that is sent back to the server once we
1886 have received a BIND-ACK, to finish the third leg of
1887 the authentication handshake.
1888 ********************************************************************/
1890 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1891 uint32 rpc_call_id,
1892 enum pipe_auth_type auth_type,
1893 enum pipe_auth_level auth_level,
1894 DATA_BLOB *pauth_blob,
1895 prs_struct *rpc_out)
1897 RPC_HDR hdr;
1898 RPC_HDR_AUTH hdr_auth;
1899 uint32 pad = 0;
1901 /* Create the request RPC_HDR */
1902 init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1903 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1904 pauth_blob->length );
1906 /* Marshall it. */
1907 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1908 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1909 return NT_STATUS_NO_MEMORY;
1913 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1914 about padding - shouldn't this pad to length 8 ? JRA.
1917 /* 4 bytes padding. */
1918 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1919 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1920 return NT_STATUS_NO_MEMORY;
1923 /* Create the request RPC_HDR_AUTHA */
1924 init_rpc_hdr_auth(&hdr_auth,
1925 map_pipe_auth_type_to_rpc_auth_type(auth_type),
1926 auth_level, 0, 1);
1928 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1929 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1930 return NT_STATUS_NO_MEMORY;
1934 * Append the auth data to the outgoing buffer.
1937 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1938 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1939 return NT_STATUS_NO_MEMORY;
1942 return NT_STATUS_OK;
1945 /****************************************************************************
1946 Create and send the third packet in an RPC auth.
1947 ****************************************************************************/
1949 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1950 RPC_HDR *phdr,
1951 prs_struct *rbuf,
1952 uint32 rpc_call_id,
1953 enum pipe_auth_type auth_type,
1954 enum pipe_auth_level auth_level)
1956 DATA_BLOB server_response = data_blob_null;
1957 DATA_BLOB client_reply = data_blob_null;
1958 RPC_HDR_AUTH hdr_auth;
1959 NTSTATUS nt_status;
1960 prs_struct rpc_out;
1961 ssize_t ret;
1963 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1964 return NT_STATUS_INVALID_PARAMETER;
1967 /* Process the returned NTLMSSP blob first. */
1968 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1969 return NT_STATUS_INVALID_PARAMETER;
1972 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1973 return NT_STATUS_INVALID_PARAMETER;
1976 /* TODO - check auth_type/auth_level match. */
1978 server_response = data_blob(NULL, phdr->auth_len);
1979 prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1981 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1982 server_response,
1983 &client_reply);
1985 if (!NT_STATUS_IS_OK(nt_status)) {
1986 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1987 data_blob_free(&server_response);
1988 return nt_status;
1991 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1993 nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1994 auth_type, auth_level,
1995 &client_reply, &rpc_out);
1997 if (!NT_STATUS_IS_OK(nt_status)) {
1998 prs_mem_free(&rpc_out);
1999 data_blob_free(&client_reply);
2000 data_blob_free(&server_response);
2001 return nt_status;
2004 switch (cli->transport_type) {
2005 case NCACN_NP:
2006 /* 8 here is named pipe message mode. */
2007 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
2008 0x8, prs_data_p(&rpc_out), 0,
2009 (size_t)prs_offset(&rpc_out));
2010 break;
2012 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2013 nt_status = cli_get_nt_error(cli->trans.np.cli);
2015 case NCACN_IP_TCP:
2016 case NCACN_UNIX_STREAM:
2017 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
2018 (size_t)prs_offset(&rpc_out));
2019 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2020 nt_status = map_nt_error_from_unix(errno);
2022 break;
2023 default:
2024 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
2025 return NT_STATUS_INTERNAL_ERROR;
2028 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2029 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
2030 nt_errstr(nt_status)));
2031 prs_mem_free(&rpc_out);
2032 data_blob_free(&client_reply);
2033 data_blob_free(&server_response);
2034 return nt_status;
2037 DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2038 rpccli_pipe_txt(debug_ctx(), cli)));
2040 prs_mem_free(&rpc_out);
2041 data_blob_free(&client_reply);
2042 data_blob_free(&server_response);
2043 return NT_STATUS_OK;
2046 /*******************************************************************
2047 Creates a DCE/RPC bind alter context authentication request which
2048 may contain a spnego auth blobl
2049 ********************************************************************/
2051 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2052 const RPC_IFACE *abstract,
2053 const RPC_IFACE *transfer,
2054 enum pipe_auth_level auth_level,
2055 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2056 prs_struct *rpc_out)
2058 RPC_HDR_AUTH hdr_auth;
2059 prs_struct auth_info;
2060 NTSTATUS ret = NT_STATUS_OK;
2062 ZERO_STRUCT(hdr_auth);
2063 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2064 return NT_STATUS_NO_MEMORY;
2066 /* We may change the pad length before marshalling. */
2067 init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2069 if (pauth_blob->length) {
2070 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2071 prs_mem_free(&auth_info);
2072 return NT_STATUS_NO_MEMORY;
2076 ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2077 rpc_out,
2078 rpc_call_id,
2079 abstract,
2080 transfer,
2081 &hdr_auth,
2082 &auth_info);
2083 prs_mem_free(&auth_info);
2084 return ret;
2087 /*******************************************************************
2088 Third leg of the SPNEGO bind mechanism - sends alter context PDU
2089 and gets a response.
2090 ********************************************************************/
2092 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
2093 RPC_HDR *phdr,
2094 prs_struct *rbuf,
2095 uint32 rpc_call_id,
2096 const RPC_IFACE *abstract,
2097 const RPC_IFACE *transfer,
2098 enum pipe_auth_type auth_type,
2099 enum pipe_auth_level auth_level)
2101 DATA_BLOB server_spnego_response = data_blob_null;
2102 DATA_BLOB server_ntlm_response = data_blob_null;
2103 DATA_BLOB client_reply = data_blob_null;
2104 DATA_BLOB tmp_blob = data_blob_null;
2105 RPC_HDR_AUTH hdr_auth;
2106 NTSTATUS nt_status;
2107 prs_struct rpc_out;
2109 if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2110 return NT_STATUS_INVALID_PARAMETER;
2113 /* Process the returned NTLMSSP blob first. */
2114 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2115 return NT_STATUS_INVALID_PARAMETER;
2118 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2119 return NT_STATUS_INVALID_PARAMETER;
2122 server_spnego_response = data_blob(NULL, phdr->auth_len);
2123 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2125 /* The server might give us back two challenges - tmp_blob is for the second. */
2126 if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2127 data_blob_free(&server_spnego_response);
2128 data_blob_free(&server_ntlm_response);
2129 data_blob_free(&tmp_blob);
2130 return NT_STATUS_INVALID_PARAMETER;
2133 /* We're finished with the server spnego response and the tmp_blob. */
2134 data_blob_free(&server_spnego_response);
2135 data_blob_free(&tmp_blob);
2137 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2138 server_ntlm_response,
2139 &client_reply);
2141 /* Finished with the server_ntlm response */
2142 data_blob_free(&server_ntlm_response);
2144 if (!NT_STATUS_IS_OK(nt_status)) {
2145 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2146 data_blob_free(&client_reply);
2147 return nt_status;
2150 /* SPNEGO wrap the client reply. */
2151 tmp_blob = spnego_gen_auth(client_reply);
2152 data_blob_free(&client_reply);
2153 client_reply = tmp_blob;
2154 tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2156 /* Now prepare the alter context pdu. */
2157 prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2159 nt_status = create_rpc_alter_context(rpc_call_id,
2160 abstract,
2161 transfer,
2162 auth_level,
2163 &client_reply,
2164 &rpc_out);
2166 data_blob_free(&client_reply);
2168 if (!NT_STATUS_IS_OK(nt_status)) {
2169 prs_mem_free(&rpc_out);
2170 return nt_status;
2173 /* Initialize the returning data struct. */
2174 prs_mem_free(rbuf);
2175 prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2177 nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2178 if (!NT_STATUS_IS_OK(nt_status)) {
2179 prs_mem_free(&rpc_out);
2180 return nt_status;
2183 prs_mem_free(&rpc_out);
2185 /* Get the auth blob from the reply. */
2186 if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
2187 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2188 return NT_STATUS_BUFFER_TOO_SMALL;
2191 if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2192 return NT_STATUS_INVALID_PARAMETER;
2195 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2196 return NT_STATUS_INVALID_PARAMETER;
2199 server_spnego_response = data_blob(NULL, phdr->auth_len);
2200 prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2202 /* Check we got a valid auth response. */
2203 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2204 data_blob_free(&server_spnego_response);
2205 data_blob_free(&tmp_blob);
2206 return NT_STATUS_INVALID_PARAMETER;
2209 data_blob_free(&server_spnego_response);
2210 data_blob_free(&tmp_blob);
2212 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2213 "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2215 return NT_STATUS_OK;
2218 /****************************************************************************
2219 Do an rpc bind.
2220 ****************************************************************************/
2222 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2223 struct cli_pipe_auth_data *auth)
2225 RPC_HDR hdr;
2226 RPC_HDR_BA hdr_ba;
2227 prs_struct rpc_out;
2228 prs_struct rbuf;
2229 uint32 rpc_call_id;
2230 NTSTATUS status;
2232 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2233 rpccli_pipe_txt(debug_ctx(), cli),
2234 (unsigned int)auth->auth_type,
2235 (unsigned int)auth->auth_level ));
2237 cli->auth = talloc_move(cli, &auth);
2239 prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2241 rpc_call_id = get_rpc_call_id();
2243 /* Marshall the outgoing data. */
2244 status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2245 &cli->abstract_syntax,
2246 &cli->transfer_syntax,
2247 cli->auth->auth_type,
2248 cli->auth->auth_level);
2250 if (!NT_STATUS_IS_OK(status)) {
2251 prs_mem_free(&rpc_out);
2252 return status;
2255 /* Initialize the incoming data struct. */
2256 prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2258 /* send data on \PIPE\. receive a response */
2259 status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2260 if (!NT_STATUS_IS_OK(status)) {
2261 prs_mem_free(&rpc_out);
2262 return status;
2265 prs_mem_free(&rpc_out);
2267 DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2268 rpccli_pipe_txt(debug_ctx(), cli)));
2270 /* Unmarshall the RPC header */
2271 if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
2272 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2273 prs_mem_free(&rbuf);
2274 return NT_STATUS_BUFFER_TOO_SMALL;
2277 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2278 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2279 prs_mem_free(&rbuf);
2280 return NT_STATUS_BUFFER_TOO_SMALL;
2283 if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) {
2284 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2285 prs_mem_free(&rbuf);
2286 return NT_STATUS_BUFFER_TOO_SMALL;
2289 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2290 cli->max_recv_frag = hdr_ba.bba.max_rsize;
2292 /* For authenticated binds we may need to do 3 or 4 leg binds. */
2293 switch(cli->auth->auth_type) {
2295 case PIPE_AUTH_TYPE_NONE:
2296 case PIPE_AUTH_TYPE_SCHANNEL:
2297 /* Bind complete. */
2298 break;
2300 case PIPE_AUTH_TYPE_NTLMSSP:
2301 /* Need to send AUTH3 packet - no reply. */
2302 status = rpc_finish_auth3_bind(
2303 cli, &hdr, &rbuf, rpc_call_id,
2304 cli->auth->auth_type,
2305 cli->auth->auth_level);
2306 if (!NT_STATUS_IS_OK(status)) {
2307 prs_mem_free(&rbuf);
2308 return status;
2310 break;
2312 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2313 /* Need to send alter context request and reply. */
2314 status = rpc_finish_spnego_ntlmssp_bind(
2315 cli, &hdr, &rbuf, rpc_call_id,
2316 &cli->abstract_syntax, &cli->transfer_syntax,
2317 cli->auth->auth_type, cli->auth->auth_level);
2318 if (!NT_STATUS_IS_OK(status)) {
2319 prs_mem_free(&rbuf);
2320 return status;
2322 break;
2324 case PIPE_AUTH_TYPE_KRB5:
2325 /* */
2327 default:
2328 DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2329 "%u\n", (unsigned int)cli->auth->auth_type));
2330 prs_mem_free(&rbuf);
2331 return NT_STATUS_INVALID_INFO_CLASS;
2334 /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2335 if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2336 || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2337 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2338 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2339 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2340 prs_mem_free(&rbuf);
2341 return NT_STATUS_INVALID_PARAMETER;
2344 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2345 if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2346 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2347 prs_mem_free(&rbuf);
2348 return NT_STATUS_INVALID_PARAMETER;
2353 prs_mem_free(&rbuf);
2354 return NT_STATUS_OK;
2357 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2358 unsigned int timeout)
2360 return cli_set_timeout(cli->trans.np.cli, timeout);
2363 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2365 if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2366 || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2367 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2368 return true;
2371 if (cli->transport_type == NCACN_NP) {
2372 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2373 return true;
2376 return false;
2379 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2381 if (p->transport_type == NCACN_NP) {
2382 return p->trans.np.cli;
2384 return NULL;
2387 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2389 if (p->transport_type == NCACN_NP) {
2390 bool ret;
2391 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2392 if (!ret) {
2393 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2394 "pipe %s. Error was %s\n",
2395 rpccli_pipe_txt(debug_ctx(), p),
2396 cli_errstr(p->trans.np.cli)));
2399 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2400 rpccli_pipe_txt(debug_ctx(), p)));
2402 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2403 return ret ? -1 : 0;
2406 return -1;
2409 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2410 struct cli_pipe_auth_data **presult)
2412 struct cli_pipe_auth_data *result;
2414 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2415 if (result == NULL) {
2416 return NT_STATUS_NO_MEMORY;
2419 result->auth_type = PIPE_AUTH_TYPE_NONE;
2420 result->auth_level = PIPE_AUTH_LEVEL_NONE;
2422 result->user_name = talloc_strdup(result, "");
2423 result->domain = talloc_strdup(result, "");
2424 if ((result->user_name == NULL) || (result->domain == NULL)) {
2425 TALLOC_FREE(result);
2426 return NT_STATUS_NO_MEMORY;
2429 *presult = result;
2430 return NT_STATUS_OK;
2433 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2435 ntlmssp_end(&auth->a_u.ntlmssp_state);
2436 return 0;
2439 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2440 enum pipe_auth_type auth_type,
2441 enum pipe_auth_level auth_level,
2442 const char *domain,
2443 const char *username,
2444 const char *password,
2445 struct cli_pipe_auth_data **presult)
2447 struct cli_pipe_auth_data *result;
2448 NTSTATUS status;
2450 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2451 if (result == NULL) {
2452 return NT_STATUS_NO_MEMORY;
2455 result->auth_type = auth_type;
2456 result->auth_level = auth_level;
2458 result->user_name = talloc_strdup(result, username);
2459 result->domain = talloc_strdup(result, domain);
2460 if ((result->user_name == NULL) || (result->domain == NULL)) {
2461 status = NT_STATUS_NO_MEMORY;
2462 goto fail;
2465 status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2466 if (!NT_STATUS_IS_OK(status)) {
2467 goto fail;
2470 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2472 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2473 if (!NT_STATUS_IS_OK(status)) {
2474 goto fail;
2477 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2478 if (!NT_STATUS_IS_OK(status)) {
2479 goto fail;
2482 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2483 if (!NT_STATUS_IS_OK(status)) {
2484 goto fail;
2488 * Turn off sign+seal to allow selected auth level to turn it back on.
2490 result->a_u.ntlmssp_state->neg_flags &=
2491 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2493 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2494 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2495 } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2496 result->a_u.ntlmssp_state->neg_flags
2497 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2500 *presult = result;
2501 return NT_STATUS_OK;
2503 fail:
2504 TALLOC_FREE(result);
2505 return status;
2508 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2509 enum pipe_auth_level auth_level,
2510 const uint8_t sess_key[16],
2511 struct cli_pipe_auth_data **presult)
2513 struct cli_pipe_auth_data *result;
2515 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2516 if (result == NULL) {
2517 return NT_STATUS_NO_MEMORY;
2520 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2521 result->auth_level = auth_level;
2523 result->user_name = talloc_strdup(result, "");
2524 result->domain = talloc_strdup(result, domain);
2525 if ((result->user_name == NULL) || (result->domain == NULL)) {
2526 goto fail;
2529 result->a_u.schannel_auth = talloc(result,
2530 struct schannel_auth_struct);
2531 if (result->a_u.schannel_auth == NULL) {
2532 goto fail;
2535 memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2536 sizeof(result->a_u.schannel_auth->sess_key));
2537 result->a_u.schannel_auth->seq_num = 0;
2539 *presult = result;
2540 return NT_STATUS_OK;
2542 fail:
2543 TALLOC_FREE(result);
2544 return NT_STATUS_NO_MEMORY;
2547 #ifdef HAVE_KRB5
2548 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2550 data_blob_free(&auth->session_key);
2551 return 0;
2553 #endif
2555 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2556 enum pipe_auth_level auth_level,
2557 const char *service_princ,
2558 const char *username,
2559 const char *password,
2560 struct cli_pipe_auth_data **presult)
2562 #ifdef HAVE_KRB5
2563 struct cli_pipe_auth_data *result;
2565 if ((username != NULL) && (password != NULL)) {
2566 int ret = kerberos_kinit_password(username, password, 0, NULL);
2567 if (ret != 0) {
2568 return NT_STATUS_ACCESS_DENIED;
2572 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2573 if (result == NULL) {
2574 return NT_STATUS_NO_MEMORY;
2577 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2578 result->auth_level = auth_level;
2581 * Username / domain need fixing!
2583 result->user_name = talloc_strdup(result, "");
2584 result->domain = talloc_strdup(result, "");
2585 if ((result->user_name == NULL) || (result->domain == NULL)) {
2586 goto fail;
2589 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2590 result, struct kerberos_auth_struct);
2591 if (result->a_u.kerberos_auth == NULL) {
2592 goto fail;
2594 talloc_set_destructor(result->a_u.kerberos_auth,
2595 cli_auth_kerberos_data_destructor);
2597 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2598 result, service_princ);
2599 if (result->a_u.kerberos_auth->service_principal == NULL) {
2600 goto fail;
2603 *presult = result;
2604 return NT_STATUS_OK;
2606 fail:
2607 TALLOC_FREE(result);
2608 return NT_STATUS_NO_MEMORY;
2609 #else
2610 return NT_STATUS_NOT_SUPPORTED;
2611 #endif
2614 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2616 close(p->trans.sock.fd);
2617 return 0;
2621 * Create an rpc pipe client struct, connecting to a tcp port.
2623 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2624 uint16_t port,
2625 const struct ndr_syntax_id *abstract_syntax,
2626 struct rpc_pipe_client **presult)
2628 struct rpc_pipe_client *result;
2629 struct sockaddr_storage addr;
2630 NTSTATUS status;
2632 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2633 if (result == NULL) {
2634 return NT_STATUS_NO_MEMORY;
2637 result->transport_type = NCACN_IP_TCP;
2639 result->abstract_syntax = *abstract_syntax;
2640 result->transfer_syntax = ndr_transfer_syntax;
2642 result->desthost = talloc_strdup(result, host);
2643 result->srv_name_slash = talloc_asprintf_strupper_m(
2644 result, "\\\\%s", result->desthost);
2645 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2646 status = NT_STATUS_NO_MEMORY;
2647 goto fail;
2650 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2651 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2653 if (!resolve_name(host, &addr, 0)) {
2654 status = NT_STATUS_NOT_FOUND;
2655 goto fail;
2658 status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
2659 if (!NT_STATUS_IS_OK(status)) {
2660 goto fail;
2663 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2665 *presult = result;
2666 return NT_STATUS_OK;
2668 fail:
2669 TALLOC_FREE(result);
2670 return status;
2674 * Determine the tcp port on which a dcerpc interface is listening
2675 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2676 * target host.
2678 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2679 const struct ndr_syntax_id *abstract_syntax,
2680 uint16_t *pport)
2682 NTSTATUS status;
2683 struct rpc_pipe_client *epm_pipe = NULL;
2684 struct cli_pipe_auth_data *auth = NULL;
2685 struct dcerpc_binding *map_binding = NULL;
2686 struct dcerpc_binding *res_binding = NULL;
2687 struct epm_twr_t *map_tower = NULL;
2688 struct epm_twr_t *res_towers = NULL;
2689 struct policy_handle *entry_handle = NULL;
2690 uint32_t num_towers = 0;
2691 uint32_t max_towers = 1;
2692 struct epm_twr_p_t towers;
2693 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2695 if (pport == NULL) {
2696 status = NT_STATUS_INVALID_PARAMETER;
2697 goto done;
2700 /* open the connection to the endpoint mapper */
2701 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2702 &ndr_table_epmapper.syntax_id,
2703 &epm_pipe);
2705 if (!NT_STATUS_IS_OK(status)) {
2706 goto done;
2709 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2710 if (!NT_STATUS_IS_OK(status)) {
2711 goto done;
2714 status = rpc_pipe_bind(epm_pipe, auth);
2715 if (!NT_STATUS_IS_OK(status)) {
2716 goto done;
2719 /* create tower for asking the epmapper */
2721 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2722 if (map_binding == NULL) {
2723 status = NT_STATUS_NO_MEMORY;
2724 goto done;
2727 map_binding->transport = NCACN_IP_TCP;
2728 map_binding->object = *abstract_syntax;
2729 map_binding->host = host; /* needed? */
2730 map_binding->endpoint = "0"; /* correct? needed? */
2732 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2733 if (map_tower == NULL) {
2734 status = NT_STATUS_NO_MEMORY;
2735 goto done;
2738 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2739 &(map_tower->tower));
2740 if (!NT_STATUS_IS_OK(status)) {
2741 goto done;
2744 /* allocate further parameters for the epm_Map call */
2746 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2747 if (res_towers == NULL) {
2748 status = NT_STATUS_NO_MEMORY;
2749 goto done;
2751 towers.twr = res_towers;
2753 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2754 if (entry_handle == NULL) {
2755 status = NT_STATUS_NO_MEMORY;
2756 goto done;
2759 /* ask the endpoint mapper for the port */
2761 status = rpccli_epm_Map(epm_pipe,
2762 tmp_ctx,
2763 CONST_DISCARD(struct GUID *,
2764 &(abstract_syntax->uuid)),
2765 map_tower,
2766 entry_handle,
2767 max_towers,
2768 &num_towers,
2769 &towers);
2771 if (!NT_STATUS_IS_OK(status)) {
2772 goto done;
2775 if (num_towers != 1) {
2776 status = NT_STATUS_UNSUCCESSFUL;
2777 goto done;
2780 /* extract the port from the answer */
2782 status = dcerpc_binding_from_tower(tmp_ctx,
2783 &(towers.twr->tower),
2784 &res_binding);
2785 if (!NT_STATUS_IS_OK(status)) {
2786 goto done;
2789 /* are further checks here necessary? */
2790 if (res_binding->transport != NCACN_IP_TCP) {
2791 status = NT_STATUS_UNSUCCESSFUL;
2792 goto done;
2795 *pport = (uint16_t)atoi(res_binding->endpoint);
2797 done:
2798 TALLOC_FREE(tmp_ctx);
2799 return status;
2803 * Create a rpc pipe client struct, connecting to a host via tcp.
2804 * The port is determined by asking the endpoint mapper on the given
2805 * host.
2807 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2808 const struct ndr_syntax_id *abstract_syntax,
2809 struct rpc_pipe_client **presult)
2811 NTSTATUS status;
2812 uint16_t port = 0;
2814 *presult = NULL;
2816 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2817 if (!NT_STATUS_IS_OK(status)) {
2818 goto done;
2821 status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2822 abstract_syntax, presult);
2824 done:
2825 return status;
2828 /********************************************************************
2829 Create a rpc pipe client struct, connecting to a unix domain socket
2830 ********************************************************************/
2831 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2832 const struct ndr_syntax_id *abstract_syntax,
2833 struct rpc_pipe_client **presult)
2835 struct rpc_pipe_client *result;
2836 struct sockaddr_un addr;
2837 NTSTATUS status;
2839 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2840 if (result == NULL) {
2841 return NT_STATUS_NO_MEMORY;
2844 result->transport_type = NCACN_UNIX_STREAM;
2846 result->abstract_syntax = *abstract_syntax;
2847 result->transfer_syntax = ndr_transfer_syntax;
2849 result->desthost = talloc_get_myname(result);
2850 result->srv_name_slash = talloc_asprintf_strupper_m(
2851 result, "\\\\%s", result->desthost);
2852 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2853 status = NT_STATUS_NO_MEMORY;
2854 goto fail;
2857 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2858 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2860 result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2861 if (result->trans.sock.fd == -1) {
2862 status = map_nt_error_from_unix(errno);
2863 goto fail;
2866 talloc_set_destructor(result, rpc_pipe_sock_destructor);
2868 ZERO_STRUCT(addr);
2869 addr.sun_family = AF_UNIX;
2870 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2872 if (sys_connect(result->trans.sock.fd,
2873 (struct sockaddr *)&addr) == -1) {
2874 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2875 strerror(errno)));
2876 close(result->trans.sock.fd);
2877 return map_nt_error_from_unix(errno);
2880 *presult = result;
2881 return NT_STATUS_OK;
2883 fail:
2884 TALLOC_FREE(result);
2885 return status;
2889 /****************************************************************************
2890 Open a named pipe over SMB to a remote server.
2892 * CAVEAT CALLER OF THIS FUNCTION:
2893 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2894 * so be sure that this function is called AFTER any structure (vs pointer)
2895 * assignment of the cli. In particular, libsmbclient does structure
2896 * assignments of cli, which invalidates the data in the returned
2897 * rpc_pipe_client if this function is called before the structure assignment
2898 * of cli.
2900 ****************************************************************************/
2902 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2903 const struct ndr_syntax_id *abstract_syntax,
2904 struct rpc_pipe_client **presult)
2906 struct rpc_pipe_client *result;
2907 int fnum;
2909 /* sanity check to protect against crashes */
2911 if ( !cli ) {
2912 return NT_STATUS_INVALID_HANDLE;
2915 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2916 if (result == NULL) {
2917 return NT_STATUS_NO_MEMORY;
2920 result->transport_type = NCACN_NP;
2922 result->trans.np.pipe_name = cli_get_pipe_name_from_iface(
2923 result, cli, abstract_syntax);
2924 if (result->trans.np.pipe_name == NULL) {
2925 DEBUG(1, ("Could not find pipe for interface\n"));
2926 TALLOC_FREE(result);
2927 return NT_STATUS_INVALID_PARAMETER;
2930 result->trans.np.cli = cli;
2931 result->abstract_syntax = *abstract_syntax;
2932 result->transfer_syntax = ndr_transfer_syntax;
2933 result->desthost = talloc_strdup(result, cli->desthost);
2934 result->srv_name_slash = talloc_asprintf_strupper_m(
2935 result, "\\\\%s", result->desthost);
2937 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2938 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2940 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2941 TALLOC_FREE(result);
2942 return NT_STATUS_NO_MEMORY;
2945 fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2946 DESIRED_ACCESS_PIPE);
2947 if (fnum == -1) {
2948 DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
2949 "to machine %s. Error was %s\n",
2950 result->trans.np.pipe_name, cli->desthost,
2951 cli_errstr(cli)));
2952 TALLOC_FREE(result);
2953 return cli_get_nt_error(cli);
2956 result->trans.np.fnum = fnum;
2958 DLIST_ADD(cli->pipe_list, result);
2959 talloc_set_destructor(result, rpc_pipe_destructor);
2961 *presult = result;
2962 return NT_STATUS_OK;
2965 /****************************************************************************
2966 Open a pipe to a remote server.
2967 ****************************************************************************/
2969 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2970 const struct ndr_syntax_id *interface,
2971 struct rpc_pipe_client **presult)
2973 if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
2975 * We should have a better way to figure out this drsuapi
2976 * speciality...
2978 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2979 presult);
2982 return rpc_pipe_open_np(cli, interface, presult);
2985 /****************************************************************************
2986 Open a named pipe to an SMB server and bind anonymously.
2987 ****************************************************************************/
2989 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2990 const struct ndr_syntax_id *interface,
2991 struct rpc_pipe_client **presult)
2993 struct rpc_pipe_client *result;
2994 struct cli_pipe_auth_data *auth;
2995 NTSTATUS status;
2997 status = cli_rpc_pipe_open(cli, interface, &result);
2998 if (!NT_STATUS_IS_OK(status)) {
2999 return status;
3002 status = rpccli_anon_bind_data(result, &auth);
3003 if (!NT_STATUS_IS_OK(status)) {
3004 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3005 nt_errstr(status)));
3006 TALLOC_FREE(result);
3007 return status;
3011 * This is a bit of an abstraction violation due to the fact that an
3012 * anonymous bind on an authenticated SMB inherits the user/domain
3013 * from the enclosing SMB creds
3016 TALLOC_FREE(auth->user_name);
3017 TALLOC_FREE(auth->domain);
3019 auth->user_name = talloc_strdup(auth, cli->user_name);
3020 auth->domain = talloc_strdup(auth, cli->domain);
3021 auth->user_session_key = data_blob_talloc(auth,
3022 cli->user_session_key.data,
3023 cli->user_session_key.length);
3025 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3026 TALLOC_FREE(result);
3027 return NT_STATUS_NO_MEMORY;
3030 status = rpc_pipe_bind(result, auth);
3031 if (!NT_STATUS_IS_OK(status)) {
3032 int lvl = 0;
3033 if (ndr_syntax_id_equal(interface,
3034 &ndr_table_dssetup.syntax_id)) {
3035 /* non AD domains just don't have this pipe, avoid
3036 * level 0 statement in that case - gd */
3037 lvl = 3;
3039 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3040 "%s failed with error %s\n",
3041 cli_get_pipe_name_from_iface(debug_ctx(), cli,
3042 interface),
3043 nt_errstr(status) ));
3044 TALLOC_FREE(result);
3045 return status;
3048 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3049 "%s and bound anonymously.\n", result->trans.np.pipe_name,
3050 cli->desthost ));
3052 *presult = result;
3053 return NT_STATUS_OK;
3056 /****************************************************************************
3057 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3058 ****************************************************************************/
3060 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3061 const struct ndr_syntax_id *interface,
3062 enum pipe_auth_type auth_type,
3063 enum pipe_auth_level auth_level,
3064 const char *domain,
3065 const char *username,
3066 const char *password,
3067 struct rpc_pipe_client **presult)
3069 struct rpc_pipe_client *result;
3070 struct cli_pipe_auth_data *auth;
3071 NTSTATUS status;
3073 status = cli_rpc_pipe_open(cli, interface, &result);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 return status;
3078 status = 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(status)) {
3082 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3083 nt_errstr(status)));
3084 goto err;
3087 status = rpc_pipe_bind(result, auth);
3088 if (!NT_STATUS_IS_OK(status)) {
3089 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3090 nt_errstr(status) ));
3091 goto err;
3094 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3095 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3096 result->trans.np.pipe_name, cli->desthost,
3097 domain, username ));
3099 *presult = result;
3100 return NT_STATUS_OK;
3102 err:
3104 TALLOC_FREE(result);
3105 return status;
3108 /****************************************************************************
3109 External interface.
3110 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3111 ****************************************************************************/
3113 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3114 const struct ndr_syntax_id *interface,
3115 enum pipe_auth_level auth_level,
3116 const char *domain,
3117 const char *username,
3118 const char *password,
3119 struct rpc_pipe_client **presult)
3121 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3122 interface,
3123 PIPE_AUTH_TYPE_NTLMSSP,
3124 auth_level,
3125 domain,
3126 username,
3127 password,
3128 presult);
3131 /****************************************************************************
3132 External interface.
3133 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3134 ****************************************************************************/
3136 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3137 const struct ndr_syntax_id *interface,
3138 enum pipe_auth_level auth_level,
3139 const char *domain,
3140 const char *username,
3141 const char *password,
3142 struct rpc_pipe_client **presult)
3144 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3145 interface,
3146 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3147 auth_level,
3148 domain,
3149 username,
3150 password,
3151 presult);
3154 /****************************************************************************
3155 Get a the schannel session key out of an already opened netlogon pipe.
3156 ****************************************************************************/
3157 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3158 struct cli_state *cli,
3159 const char *domain,
3160 uint32 *pneg_flags)
3162 uint32 sec_chan_type = 0;
3163 unsigned char machine_pwd[16];
3164 const char *machine_account;
3165 NTSTATUS status;
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 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3177 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3178 cli->desthost, /* server name */
3179 domain, /* domain */
3180 global_myname(), /* client name */
3181 machine_account, /* machine account name */
3182 machine_pwd,
3183 sec_chan_type,
3184 pneg_flags);
3186 if (!NT_STATUS_IS_OK(status)) {
3187 DEBUG(3, ("get_schannel_session_key_common: "
3188 "rpccli_netlogon_setup_creds failed with result %s "
3189 "to server %s, domain %s, machine account %s.\n",
3190 nt_errstr(status), cli->desthost, domain,
3191 machine_account ));
3192 return status;
3195 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3196 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3197 cli->desthost));
3198 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3201 return NT_STATUS_OK;;
3204 /****************************************************************************
3205 Open a netlogon pipe and get the schannel session key.
3206 Now exposed to external callers.
3207 ****************************************************************************/
3210 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3211 const char *domain,
3212 uint32 *pneg_flags,
3213 struct rpc_pipe_client **presult)
3215 struct rpc_pipe_client *netlogon_pipe = NULL;
3216 NTSTATUS status;
3218 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3219 &netlogon_pipe);
3220 if (!NT_STATUS_IS_OK(status)) {
3221 return status;
3224 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3225 pneg_flags);
3226 if (!NT_STATUS_IS_OK(status)) {
3227 TALLOC_FREE(netlogon_pipe);
3228 return status;
3231 *presult = netlogon_pipe;
3232 return NT_STATUS_OK;
3235 /****************************************************************************
3236 External interface.
3237 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3238 using session_key. sign and seal.
3239 ****************************************************************************/
3241 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3242 const struct ndr_syntax_id *interface,
3243 enum pipe_auth_level auth_level,
3244 const char *domain,
3245 const struct dcinfo *pdc,
3246 struct rpc_pipe_client **presult)
3248 struct rpc_pipe_client *result;
3249 struct cli_pipe_auth_data *auth;
3250 NTSTATUS status;
3252 status = cli_rpc_pipe_open(cli, interface, &result);
3253 if (!NT_STATUS_IS_OK(status)) {
3254 return status;
3257 status = rpccli_schannel_bind_data(result, domain, auth_level,
3258 pdc->sess_key, &auth);
3259 if (!NT_STATUS_IS_OK(status)) {
3260 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3261 nt_errstr(status)));
3262 TALLOC_FREE(result);
3263 return status;
3266 status = rpc_pipe_bind(result, auth);
3267 if (!NT_STATUS_IS_OK(status)) {
3268 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3269 "cli_rpc_pipe_bind failed with error %s\n",
3270 nt_errstr(status) ));
3271 TALLOC_FREE(result);
3272 return status;
3276 * The credentials on a new netlogon pipe are the ones we are passed
3277 * in - copy them over.
3279 result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3280 if (result->dc == NULL) {
3281 DEBUG(0, ("talloc failed\n"));
3282 TALLOC_FREE(result);
3283 return NT_STATUS_NO_MEMORY;
3286 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3287 "for domain %s "
3288 "and bound using schannel.\n",
3289 result->trans.np.pipe_name, cli->desthost, domain ));
3291 *presult = result;
3292 return NT_STATUS_OK;
3295 /****************************************************************************
3296 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3297 Fetch the session key ourselves using a temporary netlogon pipe. This
3298 version uses an ntlmssp auth bound netlogon pipe to get the key.
3299 ****************************************************************************/
3301 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3302 const char *domain,
3303 const char *username,
3304 const char *password,
3305 uint32 *pneg_flags,
3306 struct rpc_pipe_client **presult)
3308 struct rpc_pipe_client *netlogon_pipe = NULL;
3309 NTSTATUS status;
3311 status = cli_rpc_pipe_open_spnego_ntlmssp(
3312 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3313 domain, username, password, &netlogon_pipe);
3314 if (!NT_STATUS_IS_OK(status)) {
3315 return status;
3318 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3319 pneg_flags);
3320 if (!NT_STATUS_IS_OK(status)) {
3321 TALLOC_FREE(netlogon_pipe);
3322 return status;
3325 *presult = netlogon_pipe;
3326 return NT_STATUS_OK;
3329 /****************************************************************************
3330 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3331 Fetch the session key ourselves using a temporary netlogon pipe. This version
3332 uses an ntlmssp bind to get the session key.
3333 ****************************************************************************/
3335 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3336 const struct ndr_syntax_id *interface,
3337 enum pipe_auth_level auth_level,
3338 const char *domain,
3339 const char *username,
3340 const char *password,
3341 struct rpc_pipe_client **presult)
3343 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3344 struct rpc_pipe_client *netlogon_pipe = NULL;
3345 struct rpc_pipe_client *result = NULL;
3346 NTSTATUS status;
3348 status = get_schannel_session_key_auth_ntlmssp(
3349 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3350 if (!NT_STATUS_IS_OK(status)) {
3351 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3352 "key from server %s for domain %s.\n",
3353 cli->desthost, domain ));
3354 return status;
3357 status = cli_rpc_pipe_open_schannel_with_key(
3358 cli, interface, auth_level, domain, netlogon_pipe->dc,
3359 &result);
3361 /* Now we've bound using the session key we can close the netlog pipe. */
3362 TALLOC_FREE(netlogon_pipe);
3364 if (NT_STATUS_IS_OK(status)) {
3365 *presult = result;
3367 return status;
3370 /****************************************************************************
3371 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3372 Fetch the session key ourselves using a temporary netlogon pipe.
3373 ****************************************************************************/
3375 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3376 const struct ndr_syntax_id *interface,
3377 enum pipe_auth_level auth_level,
3378 const char *domain,
3379 struct rpc_pipe_client **presult)
3381 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3382 struct rpc_pipe_client *netlogon_pipe = NULL;
3383 struct rpc_pipe_client *result = NULL;
3384 NTSTATUS status;
3386 status = get_schannel_session_key(cli, domain, &neg_flags,
3387 &netlogon_pipe);
3388 if (!NT_STATUS_IS_OK(status)) {
3389 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3390 "key from server %s for domain %s.\n",
3391 cli->desthost, domain ));
3392 return status;
3395 status = cli_rpc_pipe_open_schannel_with_key(
3396 cli, interface, auth_level, domain, netlogon_pipe->dc,
3397 &result);
3399 /* Now we've bound using the session key we can close the netlog pipe. */
3400 TALLOC_FREE(netlogon_pipe);
3402 if (NT_STATUS_IS_OK(status)) {
3403 *presult = result;
3406 return NT_STATUS_OK;
3409 /****************************************************************************
3410 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3411 The idea is this can be called with service_princ, username and password all
3412 NULL so long as the caller has a TGT.
3413 ****************************************************************************/
3415 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3416 const struct ndr_syntax_id *interface,
3417 enum pipe_auth_level auth_level,
3418 const char *service_princ,
3419 const char *username,
3420 const char *password,
3421 struct rpc_pipe_client **presult)
3423 #ifdef HAVE_KRB5
3424 struct rpc_pipe_client *result;
3425 struct cli_pipe_auth_data *auth;
3426 NTSTATUS status;
3428 status = cli_rpc_pipe_open(cli, interface, &result);
3429 if (!NT_STATUS_IS_OK(status)) {
3430 return status;
3433 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3434 username, password, &auth);
3435 if (!NT_STATUS_IS_OK(status)) {
3436 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3437 nt_errstr(status)));
3438 TALLOC_FREE(result);
3439 return status;
3442 status = rpc_pipe_bind(result, auth);
3443 if (!NT_STATUS_IS_OK(status)) {
3444 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3445 "with error %s\n", nt_errstr(status)));
3446 TALLOC_FREE(result);
3447 return status;
3450 *presult = result;
3451 return NT_STATUS_OK;
3452 #else
3453 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3454 return NT_STATUS_NOT_IMPLEMENTED;
3455 #endif
3458 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3459 struct rpc_pipe_client *cli,
3460 DATA_BLOB *session_key)
3462 if (!session_key || !cli) {
3463 return NT_STATUS_INVALID_PARAMETER;
3466 if (!cli->auth) {
3467 return NT_STATUS_INVALID_PARAMETER;
3470 switch (cli->auth->auth_type) {
3471 case PIPE_AUTH_TYPE_SCHANNEL:
3472 *session_key = data_blob_talloc(mem_ctx,
3473 cli->auth->a_u.schannel_auth->sess_key, 16);
3474 break;
3475 case PIPE_AUTH_TYPE_NTLMSSP:
3476 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3477 *session_key = data_blob_talloc(mem_ctx,
3478 cli->auth->a_u.ntlmssp_state->session_key.data,
3479 cli->auth->a_u.ntlmssp_state->session_key.length);
3480 break;
3481 case PIPE_AUTH_TYPE_KRB5:
3482 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3483 *session_key = data_blob_talloc(mem_ctx,
3484 cli->auth->a_u.kerberos_auth->session_key.data,
3485 cli->auth->a_u.kerberos_auth->session_key.length);
3486 break;
3487 case PIPE_AUTH_TYPE_NONE:
3488 *session_key = data_blob_talloc(mem_ctx,
3489 cli->auth->user_session_key.data,
3490 cli->auth->user_session_key.length);
3491 break;
3492 default:
3493 return NT_STATUS_NO_USER_SESSION_KEY;
3496 return NT_STATUS_OK;