• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source3/rpc_client/
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.
10 *
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.
15 *
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/>.
18 */
19
20#include "includes.h"
21#include "librpc/gen_ndr/cli_epmapper.h"
22#include "../librpc/gen_ndr/ndr_schannel.h"
23#include "../libcli/auth/schannel.h"
24#include "../libcli/auth/spnego.h"
25#include "smb_krb5.h"
26
27#undef DBGC_CLASS
28#define DBGC_CLASS DBGC_RPC_CLI
29
30static const char *get_pipe_name_from_iface(
31	TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
32{
33	int i;
34	const struct ndr_interface_string_array *ep = interface->endpoints;
35	char *p;
36
37	for (i=0; i<ep->count; i++) {
38		if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
39			break;
40		}
41	}
42	if (i == ep->count) {
43		return NULL;
44	}
45
46	/*
47	 * extract the pipe name without \\pipe from for example
48	 * ncacn_np:[\\pipe\\epmapper]
49	 */
50	p = strchr(ep->names[i]+15, ']');
51	if (p == NULL) {
52		return "PIPE";
53	}
54	return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
55}
56
57static const struct ndr_interface_table **interfaces;
58
59bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
60{
61	int num_interfaces = talloc_array_length(interfaces);
62	const struct ndr_interface_table **tmp;
63	int i;
64
65	for (i=0; i<num_interfaces; i++) {
66		if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
67					&interface->syntax_id)) {
68			return true;
69		}
70	}
71
72	tmp = talloc_realloc(NULL, interfaces,
73			     const struct ndr_interface_table *,
74			     num_interfaces + 1);
75	if (tmp == NULL) {
76		DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
77		return false;
78	}
79	interfaces = tmp;
80	interfaces[num_interfaces] = interface;
81	return true;
82}
83
84static bool initialize_interfaces(void)
85{
86	if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
87		return false;
88	}
89	if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
90		return false;
91	}
92	if (!smb_register_ndr_interface(&ndr_table_samr)) {
93		return false;
94	}
95	if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
96		return false;
97	}
98	if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
99		return false;
100	}
101	if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
102		return false;
103	}
104	if (!smb_register_ndr_interface(&ndr_table_winreg)) {
105		return false;
106	}
107	if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
108		return false;
109	}
110	if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
111		return false;
112	}
113	if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
114		return false;
115	}
116	if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
117		return false;
118	}
119	if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
120		return false;
121	}
122	if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
123		return false;
124	}
125	if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
126		return false;
127	}
128	if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
129		return false;
130	}
131	if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
132		return false;
133	}
134	return true;
135}
136
137const struct ndr_interface_table *get_iface_from_syntax(
138	const struct ndr_syntax_id *syntax)
139{
140	int num_interfaces;
141	int i;
142
143	if (interfaces == NULL) {
144		if (!initialize_interfaces()) {
145			return NULL;
146		}
147	}
148	num_interfaces = talloc_array_length(interfaces);
149
150	for (i=0; i<num_interfaces; i++) {
151		if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
152			return interfaces[i];
153		}
154	}
155
156	return NULL;
157}
158
159/****************************************************************************
160 Return the pipe name from the interface.
161 ****************************************************************************/
162
163const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
164				      const struct ndr_syntax_id *syntax)
165{
166	const struct ndr_interface_table *interface;
167	char *guid_str;
168	const char *result;
169
170	interface = get_iface_from_syntax(syntax);
171	if (interface != NULL) {
172		result = get_pipe_name_from_iface(mem_ctx, interface);
173		if (result != NULL) {
174			return result;
175		}
176	}
177
178	/*
179	 * Here we should ask \\epmapper, but for now our code is only
180	 * interested in the known pipes mentioned in pipe_names[]
181	 */
182
183	guid_str = GUID_string(talloc_tos(), &syntax->uuid);
184	if (guid_str == NULL) {
185		return NULL;
186	}
187	result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
188				 (int)syntax->if_version);
189	TALLOC_FREE(guid_str);
190
191	if (result == NULL) {
192		return "PIPE";
193	}
194	return result;
195}
196
197/********************************************************************
198 Map internal value to wire value.
199 ********************************************************************/
200
201static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
202{
203	switch (auth_type) {
204
205	case PIPE_AUTH_TYPE_NONE:
206		return DCERPC_AUTH_TYPE_NONE;
207
208	case PIPE_AUTH_TYPE_NTLMSSP:
209		return DCERPC_AUTH_TYPE_NTLMSSP;
210
211	case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
212	case PIPE_AUTH_TYPE_SPNEGO_KRB5:
213		return DCERPC_AUTH_TYPE_SPNEGO;
214
215	case PIPE_AUTH_TYPE_SCHANNEL:
216		return DCERPC_AUTH_TYPE_SCHANNEL;
217
218	case PIPE_AUTH_TYPE_KRB5:
219		return DCERPC_AUTH_TYPE_KRB5;
220
221	default:
222		DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
223			"auth type %u\n",
224			(unsigned int)auth_type ));
225		break;
226	}
227	return -1;
228}
229
230/********************************************************************
231 Pipe description for a DEBUG
232 ********************************************************************/
233static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
234				   struct rpc_pipe_client *cli)
235{
236	char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
237	if (result == NULL) {
238		return "pipe";
239	}
240	return result;
241}
242
243/********************************************************************
244 Rpc pipe call id.
245 ********************************************************************/
246
247static uint32 get_rpc_call_id(void)
248{
249	static uint32 call_id = 0;
250	return ++call_id;
251}
252
253/*
254 * Realloc pdu to have a least "size" bytes
255 */
256
257static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
258{
259	size_t extra_size;
260
261	if (prs_data_size(pdu) >= size) {
262		return true;
263	}
264
265	extra_size = size - prs_data_size(pdu);
266
267	if (!prs_force_grow(pdu, extra_size)) {
268		DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
269			  "%d bytes.\n", (int)extra_size));
270		return false;
271	}
272
273	DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
274		  (int)extra_size, prs_data_size(pdu)));
275	return true;
276}
277
278
279/*******************************************************************
280 Use SMBreadX to get rest of one fragment's worth of rpc data.
281 Reads the whole size or give an error message
282 ********************************************************************/
283
284struct rpc_read_state {
285	struct event_context *ev;
286	struct rpc_cli_transport *transport;
287	uint8_t *data;
288	size_t size;
289	size_t num_read;
290};
291
292static void rpc_read_done(struct tevent_req *subreq);
293
294static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
295					struct event_context *ev,
296					struct rpc_cli_transport *transport,
297					uint8_t *data, size_t size)
298{
299	struct tevent_req *req, *subreq;
300	struct rpc_read_state *state;
301
302	req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
303	if (req == NULL) {
304		return NULL;
305	}
306	state->ev = ev;
307	state->transport = transport;
308	state->data = data;
309	state->size = size;
310	state->num_read = 0;
311
312	DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
313
314	subreq = transport->read_send(state, ev, (uint8_t *)data, size,
315				      transport->priv);
316	if (subreq == NULL) {
317		goto fail;
318	}
319	tevent_req_set_callback(subreq, rpc_read_done, req);
320	return req;
321
322 fail:
323	TALLOC_FREE(req);
324	return NULL;
325}
326
327static void rpc_read_done(struct tevent_req *subreq)
328{
329	struct tevent_req *req = tevent_req_callback_data(
330		subreq, struct tevent_req);
331	struct rpc_read_state *state = tevent_req_data(
332		req, struct rpc_read_state);
333	NTSTATUS status;
334	ssize_t received;
335
336	status = state->transport->read_recv(subreq, &received);
337	TALLOC_FREE(subreq);
338	if (!NT_STATUS_IS_OK(status)) {
339		tevent_req_nterror(req, status);
340		return;
341	}
342
343	state->num_read += received;
344	if (state->num_read == state->size) {
345		tevent_req_done(req);
346		return;
347	}
348
349	subreq = state->transport->read_send(state, state->ev,
350					     state->data + state->num_read,
351					     state->size - state->num_read,
352					     state->transport->priv);
353	if (tevent_req_nomem(subreq, req)) {
354		return;
355	}
356	tevent_req_set_callback(subreq, rpc_read_done, req);
357}
358
359static NTSTATUS rpc_read_recv(struct tevent_req *req)
360{
361	return tevent_req_simple_recv_ntstatus(req);
362}
363
364struct rpc_write_state {
365	struct event_context *ev;
366	struct rpc_cli_transport *transport;
367	const uint8_t *data;
368	size_t size;
369	size_t num_written;
370};
371
372static void rpc_write_done(struct tevent_req *subreq);
373
374static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
375					 struct event_context *ev,
376					 struct rpc_cli_transport *transport,
377					 const uint8_t *data, size_t size)
378{
379	struct tevent_req *req, *subreq;
380	struct rpc_write_state *state;
381
382	req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
383	if (req == NULL) {
384		return NULL;
385	}
386	state->ev = ev;
387	state->transport = transport;
388	state->data = data;
389	state->size = size;
390	state->num_written = 0;
391
392	DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
393
394	subreq = transport->write_send(state, ev, data, size, transport->priv);
395	if (subreq == NULL) {
396		goto fail;
397	}
398	tevent_req_set_callback(subreq, rpc_write_done, req);
399	return req;
400 fail:
401	TALLOC_FREE(req);
402	return NULL;
403}
404
405static void rpc_write_done(struct tevent_req *subreq)
406{
407	struct tevent_req *req = tevent_req_callback_data(
408		subreq, struct tevent_req);
409	struct rpc_write_state *state = tevent_req_data(
410		req, struct rpc_write_state);
411	NTSTATUS status;
412	ssize_t written;
413
414	status = state->transport->write_recv(subreq, &written);
415	TALLOC_FREE(subreq);
416	if (!NT_STATUS_IS_OK(status)) {
417		tevent_req_nterror(req, status);
418		return;
419	}
420
421	state->num_written += written;
422
423	if (state->num_written == state->size) {
424		tevent_req_done(req);
425		return;
426	}
427
428	subreq = state->transport->write_send(state, state->ev,
429					      state->data + state->num_written,
430					      state->size - state->num_written,
431					      state->transport->priv);
432	if (tevent_req_nomem(subreq, req)) {
433		return;
434	}
435	tevent_req_set_callback(subreq, rpc_write_done, req);
436}
437
438static NTSTATUS rpc_write_recv(struct tevent_req *req)
439{
440	return tevent_req_simple_recv_ntstatus(req);
441}
442
443
444static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
445				 struct rpc_hdr_info *prhdr,
446				 prs_struct *pdu)
447{
448	/*
449	 * This next call sets the endian bit correctly in current_pdu. We
450	 * will propagate this to rbuf later.
451	 */
452
453	if(!smb_io_rpc_hdr("rpc_hdr   ", prhdr, pdu, 0)) {
454		DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
455		return NT_STATUS_BUFFER_TOO_SMALL;
456	}
457
458	if (prhdr->frag_len > cli->max_recv_frag) {
459		DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
460			  " we only allow %d\n", (int)prhdr->frag_len,
461			  (int)cli->max_recv_frag));
462		return NT_STATUS_BUFFER_TOO_SMALL;
463	}
464
465	return NT_STATUS_OK;
466}
467
468/****************************************************************************
469 Try and get a PDU's worth of data from current_pdu. If not, then read more
470 from the wire.
471 ****************************************************************************/
472
473struct get_complete_frag_state {
474	struct event_context *ev;
475	struct rpc_pipe_client *cli;
476	struct rpc_hdr_info *prhdr;
477	prs_struct *pdu;
478};
479
480static void get_complete_frag_got_header(struct tevent_req *subreq);
481static void get_complete_frag_got_rest(struct tevent_req *subreq);
482
483static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
484						 struct event_context *ev,
485						 struct rpc_pipe_client *cli,
486						 struct rpc_hdr_info *prhdr,
487						 prs_struct *pdu)
488{
489	struct tevent_req *req, *subreq;
490	struct get_complete_frag_state *state;
491	uint32_t pdu_len;
492	NTSTATUS status;
493
494	req = tevent_req_create(mem_ctx, &state,
495				struct get_complete_frag_state);
496	if (req == NULL) {
497		return NULL;
498	}
499	state->ev = ev;
500	state->cli = cli;
501	state->prhdr = prhdr;
502	state->pdu = pdu;
503
504	pdu_len = prs_data_size(pdu);
505	if (pdu_len < RPC_HEADER_LEN) {
506		if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
507			status = NT_STATUS_NO_MEMORY;
508			goto post_status;
509		}
510		subreq = rpc_read_send(
511			state, state->ev,
512			state->cli->transport,
513			(uint8_t *)(prs_data_p(state->pdu) + pdu_len),
514			RPC_HEADER_LEN - pdu_len);
515		if (subreq == NULL) {
516			status = NT_STATUS_NO_MEMORY;
517			goto post_status;
518		}
519		tevent_req_set_callback(subreq, get_complete_frag_got_header,
520					req);
521		return req;
522	}
523
524	status = parse_rpc_header(cli, prhdr, pdu);
525	if (!NT_STATUS_IS_OK(status)) {
526		goto post_status;
527	}
528
529	/*
530	 * Ensure we have frag_len bytes of data.
531	 */
532	if (pdu_len < prhdr->frag_len) {
533		if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
534			status = NT_STATUS_NO_MEMORY;
535			goto post_status;
536		}
537		subreq = rpc_read_send(state, state->ev,
538				       state->cli->transport,
539				       (uint8_t *)(prs_data_p(pdu) + pdu_len),
540				       prhdr->frag_len - pdu_len);
541		if (subreq == NULL) {
542			status = NT_STATUS_NO_MEMORY;
543			goto post_status;
544		}
545		tevent_req_set_callback(subreq, get_complete_frag_got_rest,
546					req);
547		return req;
548	}
549
550	status = NT_STATUS_OK;
551 post_status:
552	if (NT_STATUS_IS_OK(status)) {
553		tevent_req_done(req);
554	} else {
555		tevent_req_nterror(req, status);
556	}
557	return tevent_req_post(req, ev);
558}
559
560static void get_complete_frag_got_header(struct tevent_req *subreq)
561{
562	struct tevent_req *req = tevent_req_callback_data(
563		subreq, struct tevent_req);
564	struct get_complete_frag_state *state = tevent_req_data(
565		req, struct get_complete_frag_state);
566	NTSTATUS status;
567
568	status = rpc_read_recv(subreq);
569	TALLOC_FREE(subreq);
570	if (!NT_STATUS_IS_OK(status)) {
571		tevent_req_nterror(req, status);
572		return;
573	}
574
575	status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
576	if (!NT_STATUS_IS_OK(status)) {
577		tevent_req_nterror(req, status);
578		return;
579	}
580
581	if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
582		tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
583		return;
584	}
585
586	/*
587	 * We're here in this piece of code because we've read exactly
588	 * RPC_HEADER_LEN bytes into state->pdu.
589	 */
590
591	subreq = rpc_read_send(
592		state, state->ev, state->cli->transport,
593		(uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
594		state->prhdr->frag_len - RPC_HEADER_LEN);
595	if (tevent_req_nomem(subreq, req)) {
596		return;
597	}
598	tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
599}
600
601static void get_complete_frag_got_rest(struct tevent_req *subreq)
602{
603	struct tevent_req *req = tevent_req_callback_data(
604		subreq, struct tevent_req);
605	NTSTATUS status;
606
607	status = rpc_read_recv(subreq);
608	TALLOC_FREE(subreq);
609	if (!NT_STATUS_IS_OK(status)) {
610		tevent_req_nterror(req, status);
611		return;
612	}
613	tevent_req_done(req);
614}
615
616static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
617{
618	return tevent_req_simple_recv_ntstatus(req);
619}
620
621/****************************************************************************
622 NTLMSSP specific sign/seal.
623 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
624 In fact I should probably abstract these into identical pieces of code... JRA.
625 ****************************************************************************/
626
627static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
628				prs_struct *current_pdu,
629				uint8 *p_ss_padding_len)
630{
631	RPC_HDR_AUTH auth_info;
632	uint32 save_offset = prs_offset(current_pdu);
633	uint32 auth_len = prhdr->auth_len;
634	NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
635	unsigned char *data = NULL;
636	size_t data_len;
637	unsigned char *full_packet_data = NULL;
638	size_t full_packet_data_len;
639	DATA_BLOB auth_blob;
640	NTSTATUS status;
641
642	if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
643	    || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
644		return NT_STATUS_OK;
645	}
646
647	if (!ntlmssp_state) {
648		return NT_STATUS_INVALID_PARAMETER;
649	}
650
651	/* Ensure there's enough data for an authenticated response. */
652	if ((auth_len > RPC_MAX_SIGN_SIZE) ||
653			(RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
654		DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
655			(unsigned int)auth_len ));
656		return NT_STATUS_BUFFER_TOO_SMALL;
657	}
658
659	/*
660	 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
661	 * after the RPC header.
662	 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
663	 * functions as NTLMv2 checks the rpc headers also.
664	 */
665
666	data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
667	data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
668
669	full_packet_data = (unsigned char *)prs_data_p(current_pdu);
670	full_packet_data_len = prhdr->frag_len - auth_len;
671
672	/* Pull the auth header and the following data into a blob. */
673	if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
674		DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
675			(unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
676		return NT_STATUS_BUFFER_TOO_SMALL;
677	}
678
679	if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
680		DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
681		return NT_STATUS_BUFFER_TOO_SMALL;
682	}
683
684	auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
685	auth_blob.length = auth_len;
686
687	switch (cli->auth->auth_level) {
688		case DCERPC_AUTH_LEVEL_PRIVACY:
689			/* Data is encrypted. */
690			status = ntlmssp_unseal_packet(ntlmssp_state,
691							data, data_len,
692							full_packet_data,
693							full_packet_data_len,
694							&auth_blob);
695			if (!NT_STATUS_IS_OK(status)) {
696				DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
697					"packet from %s. Error was %s.\n",
698					rpccli_pipe_txt(talloc_tos(), cli),
699					nt_errstr(status) ));
700				return status;
701			}
702			break;
703		case DCERPC_AUTH_LEVEL_INTEGRITY:
704			/* Data is signed. */
705			status = ntlmssp_check_packet(ntlmssp_state,
706							data, data_len,
707							full_packet_data,
708							full_packet_data_len,
709							&auth_blob);
710			if (!NT_STATUS_IS_OK(status)) {
711				DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
712					"packet from %s. Error was %s.\n",
713					rpccli_pipe_txt(talloc_tos(), cli),
714					nt_errstr(status) ));
715				return status;
716			}
717			break;
718		default:
719			DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
720				  "auth level %d\n", cli->auth->auth_level));
721			return NT_STATUS_INVALID_INFO_CLASS;
722	}
723
724	/*
725	 * Return the current pointer to the data offset.
726	 */
727
728	if(!prs_set_offset(current_pdu, save_offset)) {
729		DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
730			(unsigned int)save_offset ));
731		return NT_STATUS_BUFFER_TOO_SMALL;
732	}
733
734	/*
735	 * Remember the padding length. We must remove it from the real data
736	 * stream once the sign/seal is done.
737	 */
738
739	*p_ss_padding_len = auth_info.auth_pad_len;
740
741	return NT_STATUS_OK;
742}
743
744/****************************************************************************
745 schannel specific sign/seal.
746 ****************************************************************************/
747
748static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
749				prs_struct *current_pdu,
750				uint8 *p_ss_padding_len)
751{
752	RPC_HDR_AUTH auth_info;
753	uint32 auth_len = prhdr->auth_len;
754	uint32 save_offset = prs_offset(current_pdu);
755	struct schannel_state *schannel_auth =
756		cli->auth->a_u.schannel_auth;
757	uint8_t *data;
758	uint32 data_len;
759	DATA_BLOB blob;
760	NTSTATUS status;
761
762	if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
763	    || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
764		return NT_STATUS_OK;
765	}
766
767	if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
768		DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
769		return NT_STATUS_INVALID_PARAMETER;
770	}
771
772	if (!schannel_auth) {
773		return NT_STATUS_INVALID_PARAMETER;
774	}
775
776	/* Ensure there's enough data for an authenticated response. */
777	if ((auth_len > RPC_MAX_SIGN_SIZE) ||
778			(RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
779		DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
780			(unsigned int)auth_len ));
781		return NT_STATUS_INVALID_PARAMETER;
782	}
783
784	data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
785
786	if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
787		DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
788			(unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
789		return NT_STATUS_BUFFER_TOO_SMALL;
790	}
791
792	if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
793		DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
794		return NT_STATUS_BUFFER_TOO_SMALL;
795	}
796
797	if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
798		DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
799			auth_info.auth_type));
800		return NT_STATUS_BUFFER_TOO_SMALL;
801	}
802
803	blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
804
805	if (DEBUGLEVEL >= 10) {
806		dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
807	}
808
809	data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
810
811	switch (cli->auth->auth_level) {
812	case DCERPC_AUTH_LEVEL_PRIVACY:
813		status = netsec_incoming_packet(schannel_auth,
814						talloc_tos(),
815						true,
816						data,
817						data_len,
818						&blob);
819		break;
820	case DCERPC_AUTH_LEVEL_INTEGRITY:
821		status = netsec_incoming_packet(schannel_auth,
822						talloc_tos(),
823						false,
824						data,
825						data_len,
826						&blob);
827		break;
828	default:
829		status = NT_STATUS_INTERNAL_ERROR;
830		break;
831	}
832
833	if (!NT_STATUS_IS_OK(status)) {
834		DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
835				"Connection to %s (%s).\n",
836				rpccli_pipe_txt(talloc_tos(), cli),
837				nt_errstr(status)));
838		return NT_STATUS_INVALID_PARAMETER;
839	}
840
841	/*
842	 * Return the current pointer to the data offset.
843	 */
844
845	if(!prs_set_offset(current_pdu, save_offset)) {
846		DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
847			(unsigned int)save_offset ));
848		return NT_STATUS_BUFFER_TOO_SMALL;
849	}
850
851	/*
852	 * Remember the padding length. We must remove it from the real data
853	 * stream once the sign/seal is done.
854	 */
855
856	*p_ss_padding_len = auth_info.auth_pad_len;
857
858	return NT_STATUS_OK;
859}
860
861/****************************************************************************
862 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
863 ****************************************************************************/
864
865static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
866				prs_struct *current_pdu,
867				uint8 *p_ss_padding_len)
868{
869	NTSTATUS ret = NT_STATUS_OK;
870
871	/* Paranioa checks for auth_len. */
872	if (prhdr->auth_len) {
873		if (prhdr->auth_len > prhdr->frag_len) {
874			return NT_STATUS_INVALID_PARAMETER;
875		}
876
877		if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
878				prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
879			/* Integer wrap attempt. */
880			return NT_STATUS_INVALID_PARAMETER;
881		}
882	}
883
884	/*
885	 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
886	 */
887
888	switch(cli->auth->auth_type) {
889		case PIPE_AUTH_TYPE_NONE:
890			if (prhdr->auth_len) {
891				DEBUG(3, ("cli_pipe_validate_rpc_response: "
892					  "Connection to %s - got non-zero "
893					  "auth len %u.\n",
894					rpccli_pipe_txt(talloc_tos(), cli),
895					(unsigned int)prhdr->auth_len ));
896				return NT_STATUS_INVALID_PARAMETER;
897			}
898			break;
899
900		case PIPE_AUTH_TYPE_NTLMSSP:
901		case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
902			ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
903			if (!NT_STATUS_IS_OK(ret)) {
904				return ret;
905			}
906			break;
907
908		case PIPE_AUTH_TYPE_SCHANNEL:
909			ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
910			if (!NT_STATUS_IS_OK(ret)) {
911				return ret;
912			}
913			break;
914
915		case PIPE_AUTH_TYPE_KRB5:
916		case PIPE_AUTH_TYPE_SPNEGO_KRB5:
917		default:
918			DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
919				  "to %s - unknown internal auth type %u.\n",
920				  rpccli_pipe_txt(talloc_tos(), cli),
921				  cli->auth->auth_type ));
922			return NT_STATUS_INVALID_INFO_CLASS;
923	}
924
925	return NT_STATUS_OK;
926}
927
928/****************************************************************************
929 Do basic authentication checks on an incoming pdu.
930 ****************************************************************************/
931
932static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
933			prs_struct *current_pdu,
934			uint8 expected_pkt_type,
935			char **ppdata,
936			uint32 *pdata_len,
937			prs_struct *return_data)
938{
939
940	NTSTATUS ret = NT_STATUS_OK;
941	uint32 current_pdu_len = prs_data_size(current_pdu);
942
943	if (current_pdu_len != prhdr->frag_len) {
944		DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
945			(unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
946		return NT_STATUS_INVALID_PARAMETER;
947	}
948
949	/*
950	 * Point the return values at the real data including the RPC
951	 * header. Just in case the caller wants it.
952	 */
953	*ppdata = prs_data_p(current_pdu);
954	*pdata_len = current_pdu_len;
955
956	/* Ensure we have the correct type. */
957	switch (prhdr->pkt_type) {
958		case DCERPC_PKT_ALTER_RESP:
959		case DCERPC_PKT_BIND_ACK:
960
961			/* Alter context and bind ack share the same packet definitions. */
962			break;
963
964
965		case DCERPC_PKT_RESPONSE:
966		{
967			RPC_HDR_RESP rhdr_resp;
968			uint8 ss_padding_len = 0;
969
970			if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
971				DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
972				return NT_STATUS_BUFFER_TOO_SMALL;
973			}
974
975			/* Here's where we deal with incoming sign/seal. */
976			ret = cli_pipe_validate_rpc_response(cli, prhdr,
977					current_pdu, &ss_padding_len);
978			if (!NT_STATUS_IS_OK(ret)) {
979				return ret;
980			}
981
982			/* Point the return values at the NDR data. Remember to remove any ss padding. */
983			*ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
984
985			if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
986				return NT_STATUS_BUFFER_TOO_SMALL;
987			}
988
989			*pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
990
991			/* Remember to remove the auth footer. */
992			if (prhdr->auth_len) {
993				/* We've already done integer wrap tests on auth_len in
994					cli_pipe_validate_rpc_response(). */
995				if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
996					return NT_STATUS_BUFFER_TOO_SMALL;
997				}
998				*pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
999			}
1000
1001			DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1002				current_pdu_len, *pdata_len, ss_padding_len ));
1003
1004			/*
1005			 * If this is the first reply, and the allocation hint is reasonably, try and
1006			 * set up the return_data parse_struct to the correct size.
1007			 */
1008
1009			if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1010				if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1011					DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1012						"too large to allocate\n",
1013						(unsigned int)rhdr_resp.alloc_hint ));
1014					return NT_STATUS_NO_MEMORY;
1015				}
1016			}
1017
1018			break;
1019		}
1020
1021		case DCERPC_PKT_BIND_NAK:
1022			DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1023				  "received from %s!\n",
1024				  rpccli_pipe_txt(talloc_tos(), cli)));
1025			/* Use this for now... */
1026			return NT_STATUS_NETWORK_ACCESS_DENIED;
1027
1028		case DCERPC_PKT_FAULT:
1029		{
1030			RPC_HDR_RESP rhdr_resp;
1031			RPC_HDR_FAULT fault_resp;
1032
1033			if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1034				DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1035				return NT_STATUS_BUFFER_TOO_SMALL;
1036			}
1037
1038			if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
1039				DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
1040				return NT_STATUS_BUFFER_TOO_SMALL;
1041			}
1042
1043			DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1044				  "code %s received from %s!\n",
1045				dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)),
1046				rpccli_pipe_txt(talloc_tos(), cli)));
1047			if (NT_STATUS_IS_OK(fault_resp.status)) {
1048				return NT_STATUS_UNSUCCESSFUL;
1049			} else {
1050				return fault_resp.status;
1051			}
1052		}
1053
1054		default:
1055			DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1056				"from %s!\n",
1057				(unsigned int)prhdr->pkt_type,
1058				rpccli_pipe_txt(talloc_tos(), cli)));
1059			return NT_STATUS_INVALID_INFO_CLASS;
1060	}
1061
1062	if (prhdr->pkt_type != expected_pkt_type) {
1063		DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1064			  "got an unexpected RPC packet type - %u, not %u\n",
1065			rpccli_pipe_txt(talloc_tos(), cli),
1066			prhdr->pkt_type,
1067			expected_pkt_type));
1068		return NT_STATUS_INVALID_INFO_CLASS;
1069	}
1070
1071	/* Do this just before return - we don't want to modify any rpc header
1072	   data before now as we may have needed to do cryptographic actions on
1073	   it before. */
1074
1075	if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
1076		DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1077			"setting fragment first/last ON.\n"));
1078		prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1079	}
1080
1081	return NT_STATUS_OK;
1082}
1083
1084/****************************************************************************
1085 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1086 Normally the frag_len and buffer size will match, but on the first trans
1087 reply there is a theoretical chance that buffer size > frag_len, so we must
1088 deal with that.
1089 ****************************************************************************/
1090
1091static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1092{
1093	uint32 current_pdu_len = prs_data_size(current_pdu);
1094
1095	if (current_pdu_len < prhdr->frag_len) {
1096		return NT_STATUS_BUFFER_TOO_SMALL;
1097	}
1098
1099	/* Common case. */
1100	if (current_pdu_len == (uint32)prhdr->frag_len) {
1101		prs_mem_free(current_pdu);
1102		prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1103		/* Make current_pdu dynamic with no memory. */
1104		prs_give_memory(current_pdu, 0, 0, True);
1105		return NT_STATUS_OK;
1106	}
1107
1108	/*
1109	 * Oh no ! More data in buffer than we processed in current pdu.
1110	 * Cheat. Move the data down and shrink the buffer.
1111	 */
1112
1113	memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1114			current_pdu_len - prhdr->frag_len);
1115
1116	/* Remember to set the read offset back to zero. */
1117	prs_set_offset(current_pdu, 0);
1118
1119	/* Shrink the buffer. */
1120	if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1121		return NT_STATUS_BUFFER_TOO_SMALL;
1122	}
1123
1124	return NT_STATUS_OK;
1125}
1126
1127/****************************************************************************
1128 Call a remote api on an arbitrary pipe.  takes param, data and setup buffers.
1129****************************************************************************/
1130
1131struct cli_api_pipe_state {
1132	struct event_context *ev;
1133	struct rpc_cli_transport *transport;
1134	uint8_t *rdata;
1135	uint32_t rdata_len;
1136};
1137
1138static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1139static void cli_api_pipe_write_done(struct tevent_req *subreq);
1140static void cli_api_pipe_read_done(struct tevent_req *subreq);
1141
1142static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1143					    struct event_context *ev,
1144					    struct rpc_cli_transport *transport,
1145					    uint8_t *data, size_t data_len,
1146					    uint32_t max_rdata_len)
1147{
1148	struct tevent_req *req, *subreq;
1149	struct cli_api_pipe_state *state;
1150	NTSTATUS status;
1151
1152	req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1153	if (req == NULL) {
1154		return NULL;
1155	}
1156	state->ev = ev;
1157	state->transport = transport;
1158
1159	if (max_rdata_len < RPC_HEADER_LEN) {
1160		/*
1161		 * For a RPC reply we always need at least RPC_HEADER_LEN
1162		 * bytes. We check this here because we will receive
1163		 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1164		 */
1165		status = NT_STATUS_INVALID_PARAMETER;
1166		goto post_status;
1167	}
1168
1169	if (transport->trans_send != NULL) {
1170		subreq = transport->trans_send(state, ev, data, data_len,
1171					       max_rdata_len, transport->priv);
1172		if (subreq == NULL) {
1173			goto fail;
1174		}
1175		tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1176		return req;
1177	}
1178
1179	/*
1180	 * If the transport does not provide a "trans" routine, i.e. for
1181	 * example the ncacn_ip_tcp transport, do the write/read step here.
1182	 */
1183
1184	subreq = rpc_write_send(state, ev, transport, data, data_len);
1185	if (subreq == NULL) {
1186		goto fail;
1187	}
1188	tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1189	return req;
1190
1191	status = NT_STATUS_INVALID_PARAMETER;
1192
1193 post_status:
1194	tevent_req_nterror(req, status);
1195	return tevent_req_post(req, ev);
1196 fail:
1197	TALLOC_FREE(req);
1198	return NULL;
1199}
1200
1201static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1202{
1203	struct tevent_req *req = tevent_req_callback_data(
1204		subreq, struct tevent_req);
1205	struct cli_api_pipe_state *state = tevent_req_data(
1206		req, struct cli_api_pipe_state);
1207	NTSTATUS status;
1208
1209	status = state->transport->trans_recv(subreq, state, &state->rdata,
1210					      &state->rdata_len);
1211	TALLOC_FREE(subreq);
1212	if (!NT_STATUS_IS_OK(status)) {
1213		tevent_req_nterror(req, status);
1214		return;
1215	}
1216	tevent_req_done(req);
1217}
1218
1219static void cli_api_pipe_write_done(struct tevent_req *subreq)
1220{
1221	struct tevent_req *req = tevent_req_callback_data(
1222		subreq, struct tevent_req);
1223	struct cli_api_pipe_state *state = tevent_req_data(
1224		req, struct cli_api_pipe_state);
1225	NTSTATUS status;
1226
1227	status = rpc_write_recv(subreq);
1228	TALLOC_FREE(subreq);
1229	if (!NT_STATUS_IS_OK(status)) {
1230		tevent_req_nterror(req, status);
1231		return;
1232	}
1233
1234	state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1235	if (tevent_req_nomem(state->rdata, req)) {
1236		return;
1237	}
1238
1239	/*
1240	 * We don't need to use rpc_read_send here, the upper layer will cope
1241	 * with a short read, transport->trans_send could also return less
1242	 * than state->max_rdata_len.
1243	 */
1244	subreq = state->transport->read_send(state, state->ev, state->rdata,
1245					     RPC_HEADER_LEN,
1246					     state->transport->priv);
1247	if (tevent_req_nomem(subreq, req)) {
1248		return;
1249	}
1250	tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1251}
1252
1253static void cli_api_pipe_read_done(struct tevent_req *subreq)
1254{
1255	struct tevent_req *req = tevent_req_callback_data(
1256		subreq, struct tevent_req);
1257	struct cli_api_pipe_state *state = tevent_req_data(
1258		req, struct cli_api_pipe_state);
1259	NTSTATUS status;
1260	ssize_t received;
1261
1262	status = state->transport->read_recv(subreq, &received);
1263	TALLOC_FREE(subreq);
1264	if (!NT_STATUS_IS_OK(status)) {
1265		tevent_req_nterror(req, status);
1266		return;
1267	}
1268	state->rdata_len = received;
1269	tevent_req_done(req);
1270}
1271
1272static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1273				  uint8_t **prdata, uint32_t *prdata_len)
1274{
1275	struct cli_api_pipe_state *state = tevent_req_data(
1276		req, struct cli_api_pipe_state);
1277	NTSTATUS status;
1278
1279	if (tevent_req_is_nterror(req, &status)) {
1280		return status;
1281	}
1282
1283	*prdata = talloc_move(mem_ctx, &state->rdata);
1284	*prdata_len = state->rdata_len;
1285	return NT_STATUS_OK;
1286}
1287
1288/****************************************************************************
1289 Send data on an rpc pipe via trans. The prs_struct data must be the last
1290 pdu fragment of an NDR data stream.
1291
1292 Receive response data from an rpc pipe, which may be large...
1293
1294 Read the first fragment: unfortunately have to use SMBtrans for the first
1295 bit, then SMBreadX for subsequent bits.
1296
1297 If first fragment received also wasn't the last fragment, continue
1298 getting fragments until we _do_ receive the last fragment.
1299
1300 Request/Response PDU's look like the following...
1301
1302 |<------------------PDU len----------------------------------------------->|
1303 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1304
1305 +------------+-----------------+-------------+---------------+-------------+
1306 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
1307 +------------+-----------------+-------------+---------------+-------------+
1308
1309 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1310 signing & sealing being negotiated.
1311
1312 ****************************************************************************/
1313
1314struct rpc_api_pipe_state {
1315	struct event_context *ev;
1316	struct rpc_pipe_client *cli;
1317	uint8_t expected_pkt_type;
1318
1319	prs_struct incoming_frag;
1320	struct rpc_hdr_info rhdr;
1321
1322	prs_struct incoming_pdu;	/* Incoming reply */
1323	uint32_t incoming_pdu_offset;
1324};
1325
1326static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1327{
1328	prs_mem_free(&state->incoming_frag);
1329	prs_mem_free(&state->incoming_pdu);
1330	return 0;
1331}
1332
1333static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1334static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1335
1336static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1337					    struct event_context *ev,
1338					    struct rpc_pipe_client *cli,
1339					    prs_struct *data, /* Outgoing PDU */
1340					    uint8_t expected_pkt_type)
1341{
1342	struct tevent_req *req, *subreq;
1343	struct rpc_api_pipe_state *state;
1344	uint16_t max_recv_frag;
1345	NTSTATUS status;
1346
1347	req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1348	if (req == NULL) {
1349		return NULL;
1350	}
1351	state->ev = ev;
1352	state->cli = cli;
1353	state->expected_pkt_type = expected_pkt_type;
1354	state->incoming_pdu_offset = 0;
1355
1356	prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1357
1358	prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1359	/* Make incoming_pdu dynamic with no memory. */
1360	prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1361
1362	talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1363
1364	/*
1365	 * Ensure we're not sending too much.
1366	 */
1367	if (prs_offset(data) > cli->max_xmit_frag) {
1368		status = NT_STATUS_INVALID_PARAMETER;
1369		goto post_status;
1370	}
1371
1372	DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1373
1374	max_recv_frag = cli->max_recv_frag;
1375
1376#if 0
1377	max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1378#endif
1379
1380	subreq = cli_api_pipe_send(state, ev, cli->transport,
1381				   (uint8_t *)prs_data_p(data),
1382				   prs_offset(data), max_recv_frag);
1383	if (subreq == NULL) {
1384		goto fail;
1385	}
1386	tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1387	return req;
1388
1389 post_status:
1390	tevent_req_nterror(req, status);
1391	return tevent_req_post(req, ev);
1392 fail:
1393	TALLOC_FREE(req);
1394	return NULL;
1395}
1396
1397static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1398{
1399	struct tevent_req *req = tevent_req_callback_data(
1400		subreq, struct tevent_req);
1401	struct rpc_api_pipe_state *state = tevent_req_data(
1402		req, struct rpc_api_pipe_state);
1403	NTSTATUS status;
1404	uint8_t *rdata = NULL;
1405	uint32_t rdata_len = 0;
1406	char *rdata_copy;
1407
1408	status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1409	TALLOC_FREE(subreq);
1410	if (!NT_STATUS_IS_OK(status)) {
1411		DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1412		tevent_req_nterror(req, status);
1413		return;
1414	}
1415
1416	if (rdata == NULL) {
1417		DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1418			 rpccli_pipe_txt(talloc_tos(), state->cli)));
1419		tevent_req_done(req);
1420		return;
1421	}
1422
1423	/*
1424	 * Give the memory received from cli_trans as dynamic to the current
1425	 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1426	 * :-(
1427	 */
1428	rdata_copy = (char *)memdup(rdata, rdata_len);
1429	TALLOC_FREE(rdata);
1430	if (tevent_req_nomem(rdata_copy, req)) {
1431		return;
1432	}
1433	prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1434
1435	/* Ensure we have enough data for a pdu. */
1436	subreq = get_complete_frag_send(state, state->ev, state->cli,
1437					&state->rhdr, &state->incoming_frag);
1438	if (tevent_req_nomem(subreq, req)) {
1439		return;
1440	}
1441	tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1442}
1443
1444static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1445{
1446	struct tevent_req *req = tevent_req_callback_data(
1447		subreq, struct tevent_req);
1448	struct rpc_api_pipe_state *state = tevent_req_data(
1449		req, struct rpc_api_pipe_state);
1450	NTSTATUS status;
1451	char *rdata = NULL;
1452	uint32_t rdata_len = 0;
1453
1454	status = get_complete_frag_recv(subreq);
1455	TALLOC_FREE(subreq);
1456	if (!NT_STATUS_IS_OK(status)) {
1457		DEBUG(5, ("get_complete_frag failed: %s\n",
1458			  nt_errstr(status)));
1459		tevent_req_nterror(req, status);
1460		return;
1461	}
1462
1463	status = cli_pipe_validate_current_pdu(
1464		state->cli, &state->rhdr, &state->incoming_frag,
1465		state->expected_pkt_type, &rdata, &rdata_len,
1466		&state->incoming_pdu);
1467
1468	DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1469		  (unsigned)prs_data_size(&state->incoming_frag),
1470		  (unsigned)state->incoming_pdu_offset,
1471		  nt_errstr(status)));
1472
1473	if (!NT_STATUS_IS_OK(status)) {
1474		tevent_req_nterror(req, status);
1475		return;
1476	}
1477
1478	if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1479	    && (state->rhdr.pack_type[0] == 0)) {
1480		/*
1481		 * Set the data type correctly for big-endian data on the
1482		 * first packet.
1483		 */
1484		DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1485			  "big-endian.\n",
1486			  rpccli_pipe_txt(talloc_tos(), state->cli)));
1487		prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1488	}
1489	/*
1490	 * Check endianness on subsequent packets.
1491	 */
1492	if (state->incoming_frag.bigendian_data
1493	    != state->incoming_pdu.bigendian_data) {
1494		DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1495			 "%s\n",
1496			 state->incoming_pdu.bigendian_data?"big":"little",
1497			 state->incoming_frag.bigendian_data?"big":"little"));
1498		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1499		return;
1500	}
1501
1502	/* Now copy the data portion out of the pdu into rbuf. */
1503	if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1504		tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1505		return;
1506	}
1507
1508	memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1509	       rdata, (size_t)rdata_len);
1510	state->incoming_pdu_offset += rdata_len;
1511
1512	status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1513					    &state->incoming_frag);
1514	if (!NT_STATUS_IS_OK(status)) {
1515		tevent_req_nterror(req, status);
1516		return;
1517	}
1518
1519	if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1520		DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1521			  rpccli_pipe_txt(talloc_tos(), state->cli),
1522			  (unsigned)prs_data_size(&state->incoming_pdu)));
1523		tevent_req_done(req);
1524		return;
1525	}
1526
1527	subreq = get_complete_frag_send(state, state->ev, state->cli,
1528					&state->rhdr, &state->incoming_frag);
1529	if (tevent_req_nomem(subreq, req)) {
1530		return;
1531	}
1532	tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1533}
1534
1535static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1536				  prs_struct *reply_pdu)
1537{
1538	struct rpc_api_pipe_state *state = tevent_req_data(
1539		req, struct rpc_api_pipe_state);
1540	NTSTATUS status;
1541
1542	if (tevent_req_is_nterror(req, &status)) {
1543		return status;
1544	}
1545
1546	*reply_pdu = state->incoming_pdu;
1547	reply_pdu->mem_ctx = mem_ctx;
1548
1549	/*
1550	 * Prevent state->incoming_pdu from being freed in
1551	 * rpc_api_pipe_state_destructor()
1552	 */
1553	prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1554
1555	return NT_STATUS_OK;
1556}
1557
1558/*******************************************************************
1559 Creates krb5 auth bind.
1560 ********************************************************************/
1561
1562static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1563						enum dcerpc_AuthLevel auth_level,
1564						RPC_HDR_AUTH *pauth_out,
1565						prs_struct *auth_data)
1566{
1567#ifdef HAVE_KRB5
1568	int ret;
1569	struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1570	DATA_BLOB tkt = data_blob_null;
1571	DATA_BLOB tkt_wrapped = data_blob_null;
1572
1573	/* We may change the pad length before marshalling. */
1574	init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1575
1576	DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1577		a->service_principal ));
1578
1579	/* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1580
1581	ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1582			&a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1583
1584	if (ret) {
1585		DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1586			"failed with %s\n",
1587			a->service_principal,
1588			error_message(ret) ));
1589
1590		data_blob_free(&tkt);
1591		prs_mem_free(auth_data);
1592		return NT_STATUS_INVALID_PARAMETER;
1593	}
1594
1595	/* wrap that up in a nice GSS-API wrapping */
1596	tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1597
1598	data_blob_free(&tkt);
1599
1600	/* Auth len in the rpc header doesn't include auth_header. */
1601	if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1602		data_blob_free(&tkt_wrapped);
1603		prs_mem_free(auth_data);
1604		return NT_STATUS_NO_MEMORY;
1605	}
1606
1607	DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1608	dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1609
1610	data_blob_free(&tkt_wrapped);
1611	return NT_STATUS_OK;
1612#else
1613	return NT_STATUS_INVALID_PARAMETER;
1614#endif
1615}
1616
1617/*******************************************************************
1618 Creates SPNEGO NTLMSSP auth bind.
1619 ********************************************************************/
1620
1621static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1622						enum dcerpc_AuthLevel auth_level,
1623						RPC_HDR_AUTH *pauth_out,
1624						prs_struct *auth_data)
1625{
1626	NTSTATUS nt_status;
1627	DATA_BLOB null_blob = data_blob_null;
1628	DATA_BLOB request = data_blob_null;
1629	DATA_BLOB spnego_msg = data_blob_null;
1630
1631	/* We may change the pad length before marshalling. */
1632	init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1633
1634	DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1635	nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1636					null_blob,
1637					&request);
1638
1639	if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1640		data_blob_free(&request);
1641		prs_mem_free(auth_data);
1642		return nt_status;
1643	}
1644
1645	/* Wrap this in SPNEGO. */
1646	spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1647
1648	data_blob_free(&request);
1649
1650	/* Auth len in the rpc header doesn't include auth_header. */
1651	if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1652		data_blob_free(&spnego_msg);
1653		prs_mem_free(auth_data);
1654		return NT_STATUS_NO_MEMORY;
1655	}
1656
1657	DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1658	dump_data(5, spnego_msg.data, spnego_msg.length);
1659
1660	data_blob_free(&spnego_msg);
1661	return NT_STATUS_OK;
1662}
1663
1664/*******************************************************************
1665 Creates NTLMSSP auth bind.
1666 ********************************************************************/
1667
1668static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1669						enum dcerpc_AuthLevel auth_level,
1670						RPC_HDR_AUTH *pauth_out,
1671						prs_struct *auth_data)
1672{
1673	NTSTATUS nt_status;
1674	DATA_BLOB null_blob = data_blob_null;
1675	DATA_BLOB request = data_blob_null;
1676
1677	/* We may change the pad length before marshalling. */
1678	init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1679
1680	DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1681	nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1682					null_blob,
1683					&request);
1684
1685	if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1686		data_blob_free(&request);
1687		prs_mem_free(auth_data);
1688		return nt_status;
1689	}
1690
1691	/* Auth len in the rpc header doesn't include auth_header. */
1692	if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1693		data_blob_free(&request);
1694		prs_mem_free(auth_data);
1695		return NT_STATUS_NO_MEMORY;
1696	}
1697
1698	DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1699	dump_data(5, request.data, request.length);
1700
1701	data_blob_free(&request);
1702	return NT_STATUS_OK;
1703}
1704
1705/*******************************************************************
1706 Creates schannel auth bind.
1707 ********************************************************************/
1708
1709static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1710						enum dcerpc_AuthLevel auth_level,
1711						RPC_HDR_AUTH *pauth_out,
1712						prs_struct *auth_data)
1713{
1714	struct NL_AUTH_MESSAGE r;
1715	enum ndr_err_code ndr_err;
1716	DATA_BLOB blob;
1717
1718	/* We may change the pad length before marshalling. */
1719	init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1720
1721	/* Use lp_workgroup() if domain not specified */
1722
1723	if (!cli->auth->domain || !cli->auth->domain[0]) {
1724		cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1725		if (cli->auth->domain == NULL) {
1726			return NT_STATUS_NO_MEMORY;
1727		}
1728	}
1729
1730	/*
1731	 * Now marshall the data into the auth parse_struct.
1732	 */
1733
1734	r.MessageType			= NL_NEGOTIATE_REQUEST;
1735	r.Flags				= NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1736					  NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1737	r.oem_netbios_domain.a		= cli->auth->domain;
1738	r.oem_netbios_computer.a	= global_myname();
1739
1740	ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
1741		       (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1742	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1743		DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1744		prs_mem_free(auth_data);
1745		return ndr_map_error2ntstatus(ndr_err);
1746	}
1747
1748	if (DEBUGLEVEL >= 10) {
1749		NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1750	}
1751
1752	if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1753	{
1754		prs_mem_free(auth_data);
1755		return NT_STATUS_NO_MEMORY;
1756	}
1757
1758	return NT_STATUS_OK;
1759}
1760
1761/*******************************************************************
1762 Creates the internals of a DCE/RPC bind request or alter context PDU.
1763 ********************************************************************/
1764
1765static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1766						prs_struct *rpc_out,
1767						uint32 rpc_call_id,
1768						const struct ndr_syntax_id *abstract,
1769						const struct ndr_syntax_id *transfer,
1770						RPC_HDR_AUTH *phdr_auth,
1771						prs_struct *pauth_info)
1772{
1773	RPC_HDR hdr;
1774	RPC_HDR_RB hdr_rb;
1775	RPC_CONTEXT rpc_ctx;
1776	uint16 auth_len = prs_offset(pauth_info);
1777	uint8 ss_padding_len = 0;
1778	uint16 frag_len = 0;
1779
1780	/* create the RPC context. */
1781	init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1782
1783	/* create the bind request RPC_HDR_RB */
1784	init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1785
1786	/* Start building the frag length. */
1787	frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1788
1789	/* Do we need to pad ? */
1790	if (auth_len) {
1791		uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1792		if (data_len % 8) {
1793			ss_padding_len = 8 - (data_len % 8);
1794			phdr_auth->auth_pad_len = ss_padding_len;
1795		}
1796		frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1797	}
1798
1799	/* Create the request RPC_HDR */
1800	init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1801
1802	/* Marshall the RPC header */
1803	if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
1804		DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1805		return NT_STATUS_NO_MEMORY;
1806	}
1807
1808	/* Marshall the bind request data */
1809	if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1810		DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1811		return NT_STATUS_NO_MEMORY;
1812	}
1813
1814	/*
1815	 * Grow the outgoing buffer to store any auth info.
1816	 */
1817
1818	if(auth_len != 0) {
1819		if (ss_padding_len) {
1820			char pad[8];
1821			memset(pad, '\0', 8);
1822			if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1823				DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1824				return NT_STATUS_NO_MEMORY;
1825			}
1826		}
1827
1828		if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1829			DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1830			return NT_STATUS_NO_MEMORY;
1831		}
1832
1833
1834		if(!prs_append_prs_data( rpc_out, pauth_info)) {
1835			DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1836			return NT_STATUS_NO_MEMORY;
1837		}
1838	}
1839
1840	return NT_STATUS_OK;
1841}
1842
1843/*******************************************************************
1844 Creates a DCE/RPC bind request.
1845 ********************************************************************/
1846
1847static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1848				prs_struct *rpc_out,
1849				uint32 rpc_call_id,
1850				const struct ndr_syntax_id *abstract,
1851				const struct ndr_syntax_id *transfer,
1852				enum pipe_auth_type auth_type,
1853				enum dcerpc_AuthLevel auth_level)
1854{
1855	RPC_HDR_AUTH hdr_auth;
1856	prs_struct auth_info;
1857	NTSTATUS ret = NT_STATUS_OK;
1858
1859	ZERO_STRUCT(hdr_auth);
1860	if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1861		return NT_STATUS_NO_MEMORY;
1862
1863	switch (auth_type) {
1864		case PIPE_AUTH_TYPE_SCHANNEL:
1865			ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1866			if (!NT_STATUS_IS_OK(ret)) {
1867				prs_mem_free(&auth_info);
1868				return ret;
1869			}
1870			break;
1871
1872		case PIPE_AUTH_TYPE_NTLMSSP:
1873			ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1874			if (!NT_STATUS_IS_OK(ret)) {
1875				prs_mem_free(&auth_info);
1876				return ret;
1877			}
1878			break;
1879
1880		case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1881			ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1882			if (!NT_STATUS_IS_OK(ret)) {
1883				prs_mem_free(&auth_info);
1884				return ret;
1885			}
1886			break;
1887
1888		case PIPE_AUTH_TYPE_KRB5:
1889			ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1890			if (!NT_STATUS_IS_OK(ret)) {
1891				prs_mem_free(&auth_info);
1892				return ret;
1893			}
1894			break;
1895
1896		case PIPE_AUTH_TYPE_NONE:
1897			break;
1898
1899		default:
1900			/* "Can't" happen. */
1901			return NT_STATUS_INVALID_INFO_CLASS;
1902	}
1903
1904	ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1905						rpc_out,
1906						rpc_call_id,
1907						abstract,
1908						transfer,
1909						&hdr_auth,
1910						&auth_info);
1911
1912	prs_mem_free(&auth_info);
1913	return ret;
1914}
1915
1916/*******************************************************************
1917 Create and add the NTLMSSP sign/seal auth header and data.
1918 ********************************************************************/
1919
1920static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1921					RPC_HDR *phdr,
1922					uint32 ss_padding_len,
1923					prs_struct *outgoing_pdu)
1924{
1925	RPC_HDR_AUTH auth_info;
1926	NTSTATUS status;
1927	DATA_BLOB auth_blob = data_blob_null;
1928	uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1929
1930	if (!cli->auth->a_u.ntlmssp_state) {
1931		return NT_STATUS_INVALID_PARAMETER;
1932	}
1933
1934	/* Init and marshall the auth header. */
1935	init_rpc_hdr_auth(&auth_info,
1936			map_pipe_auth_type_to_rpc_auth_type(
1937				cli->auth->auth_type),
1938			cli->auth->auth_level,
1939			ss_padding_len,
1940			1 /* context id. */);
1941
1942	if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1943		DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1944		data_blob_free(&auth_blob);
1945		return NT_STATUS_NO_MEMORY;
1946	}
1947
1948	switch (cli->auth->auth_level) {
1949		case DCERPC_AUTH_LEVEL_PRIVACY:
1950			/* Data portion is encrypted. */
1951			status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1952					(unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1953					data_and_pad_len,
1954					(unsigned char *)prs_data_p(outgoing_pdu),
1955					(size_t)prs_offset(outgoing_pdu),
1956					&auth_blob);
1957			if (!NT_STATUS_IS_OK(status)) {
1958				data_blob_free(&auth_blob);
1959				return status;
1960			}
1961			break;
1962
1963		case DCERPC_AUTH_LEVEL_INTEGRITY:
1964			/* Data is signed. */
1965			status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1966					(unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1967					data_and_pad_len,
1968					(unsigned char *)prs_data_p(outgoing_pdu),
1969					(size_t)prs_offset(outgoing_pdu),
1970					&auth_blob);
1971			if (!NT_STATUS_IS_OK(status)) {
1972				data_blob_free(&auth_blob);
1973				return status;
1974			}
1975			break;
1976
1977		default:
1978			/* Can't happen. */
1979			smb_panic("bad auth level");
1980			/* Notreached. */
1981			return NT_STATUS_INVALID_PARAMETER;
1982	}
1983
1984	/* Finally marshall the blob. */
1985
1986	if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1987		DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1988			(unsigned int)NTLMSSP_SIG_SIZE));
1989		data_blob_free(&auth_blob);
1990		return NT_STATUS_NO_MEMORY;
1991	}
1992
1993	data_blob_free(&auth_blob);
1994	return NT_STATUS_OK;
1995}
1996
1997/*******************************************************************
1998 Create and add the schannel sign/seal auth header and data.
1999 ********************************************************************/
2000
2001static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2002					RPC_HDR *phdr,
2003					uint32 ss_padding_len,
2004					prs_struct *outgoing_pdu)
2005{
2006	RPC_HDR_AUTH auth_info;
2007	struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2008	char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2009	size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2010	DATA_BLOB blob;
2011	NTSTATUS status;
2012
2013	if (!sas) {
2014		return NT_STATUS_INVALID_PARAMETER;
2015	}
2016
2017	/* Init and marshall the auth header. */
2018	init_rpc_hdr_auth(&auth_info,
2019			map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2020			cli->auth->auth_level,
2021			ss_padding_len,
2022			1 /* context id. */);
2023
2024	if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2025		DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2026		return NT_STATUS_NO_MEMORY;
2027	}
2028
2029	DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2030			sas->seq_num));
2031
2032	switch (cli->auth->auth_level) {
2033	case DCERPC_AUTH_LEVEL_PRIVACY:
2034		status = netsec_outgoing_packet(sas,
2035						talloc_tos(),
2036						true,
2037						(uint8_t *)data_p,
2038						data_and_pad_len,
2039						&blob);
2040		break;
2041	case DCERPC_AUTH_LEVEL_INTEGRITY:
2042		status = netsec_outgoing_packet(sas,
2043						talloc_tos(),
2044						false,
2045						(uint8_t *)data_p,
2046						data_and_pad_len,
2047						&blob);
2048		break;
2049	default:
2050		status = NT_STATUS_INTERNAL_ERROR;
2051		break;
2052	}
2053
2054	if (!NT_STATUS_IS_OK(status)) {
2055		DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2056			nt_errstr(status)));
2057		return status;
2058	}
2059
2060	if (DEBUGLEVEL >= 10) {
2061		dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2062	}
2063
2064	/* Finally marshall the blob. */
2065	if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2066		return NT_STATUS_NO_MEMORY;
2067	}
2068
2069	return NT_STATUS_OK;
2070}
2071
2072/*******************************************************************
2073 Calculate how much data we're going to send in this packet, also
2074 work out any sign/seal padding length.
2075 ********************************************************************/
2076
2077static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2078					uint32 data_left,
2079					uint16 *p_frag_len,
2080					uint16 *p_auth_len,
2081					uint32 *p_ss_padding)
2082{
2083	uint32 data_space, data_len;
2084
2085#if 0
2086	if ((data_left > 0) && (sys_random() % 2)) {
2087		data_left = MAX(data_left/2, 1);
2088	}
2089#endif
2090
2091	switch (cli->auth->auth_level) {
2092		case DCERPC_AUTH_LEVEL_NONE:
2093		case DCERPC_AUTH_LEVEL_CONNECT:
2094			data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2095			data_len = MIN(data_space, data_left);
2096			*p_ss_padding = 0;
2097			*p_auth_len = 0;
2098			*p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2099			return data_len;
2100
2101		case DCERPC_AUTH_LEVEL_INTEGRITY:
2102		case DCERPC_AUTH_LEVEL_PRIVACY:
2103			/* Treat the same for all authenticated rpc requests. */
2104			switch(cli->auth->auth_type) {
2105				case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2106				case PIPE_AUTH_TYPE_NTLMSSP:
2107					*p_auth_len = NTLMSSP_SIG_SIZE;
2108					break;
2109				case PIPE_AUTH_TYPE_SCHANNEL:
2110					*p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2111					break;
2112				default:
2113					smb_panic("bad auth type");
2114					break;
2115			}
2116
2117			data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2118						RPC_HDR_AUTH_LEN - *p_auth_len;
2119
2120			data_len = MIN(data_space, data_left);
2121			*p_ss_padding = 0;
2122			if (data_len % 8) {
2123				*p_ss_padding = 8 - (data_len % 8);
2124			}
2125			*p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + 		/* Normal headers. */
2126					data_len + *p_ss_padding + 		/* data plus padding. */
2127					RPC_HDR_AUTH_LEN + *p_auth_len;		/* Auth header and auth data. */
2128			return data_len;
2129
2130		default:
2131			smb_panic("bad auth level");
2132			/* Notreached. */
2133			return 0;
2134	}
2135}
2136
2137/*******************************************************************
2138 External interface.
2139 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2140 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2141 and deals with signing/sealing details.
2142 ********************************************************************/
2143
2144struct rpc_api_pipe_req_state {
2145	struct event_context *ev;
2146	struct rpc_pipe_client *cli;
2147	uint8_t op_num;
2148	uint32_t call_id;
2149	prs_struct *req_data;
2150	uint32_t req_data_sent;
2151	prs_struct outgoing_frag;
2152	prs_struct reply_pdu;
2153};
2154
2155static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2156{
2157	prs_mem_free(&s->outgoing_frag);
2158	prs_mem_free(&s->reply_pdu);
2159	return 0;
2160}
2161
2162static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2163static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2164static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2165				  bool *is_last_frag);
2166
2167struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2168					 struct event_context *ev,
2169					 struct rpc_pipe_client *cli,
2170					 uint8_t op_num,
2171					 prs_struct *req_data)
2172{
2173	struct tevent_req *req, *subreq;
2174	struct rpc_api_pipe_req_state *state;
2175	NTSTATUS status;
2176	bool is_last_frag;
2177
2178	req = tevent_req_create(mem_ctx, &state,
2179				struct rpc_api_pipe_req_state);
2180	if (req == NULL) {
2181		return NULL;
2182	}
2183	state->ev = ev;
2184	state->cli = cli;
2185	state->op_num = op_num;
2186	state->req_data = req_data;
2187	state->req_data_sent = 0;
2188	state->call_id = get_rpc_call_id();
2189
2190	if (cli->max_xmit_frag
2191	    < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2192		/* Server is screwed up ! */
2193		status = NT_STATUS_INVALID_PARAMETER;
2194		goto post_status;
2195	}
2196
2197	prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2198
2199	if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2200		      state, MARSHALL)) {
2201		goto fail;
2202	}
2203
2204	talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2205
2206	status = prepare_next_frag(state, &is_last_frag);
2207	if (!NT_STATUS_IS_OK(status)) {
2208		goto post_status;
2209	}
2210
2211	if (is_last_frag) {
2212		subreq = rpc_api_pipe_send(state, ev, state->cli,
2213					   &state->outgoing_frag,
2214					   DCERPC_PKT_RESPONSE);
2215		if (subreq == NULL) {
2216			goto fail;
2217		}
2218		tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2219	} else {
2220		subreq = rpc_write_send(
2221			state, ev, cli->transport,
2222			(uint8_t *)prs_data_p(&state->outgoing_frag),
2223			prs_offset(&state->outgoing_frag));
2224		if (subreq == NULL) {
2225			goto fail;
2226		}
2227		tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2228					req);
2229	}
2230	return req;
2231
2232 post_status:
2233	tevent_req_nterror(req, status);
2234	return tevent_req_post(req, ev);
2235 fail:
2236	TALLOC_FREE(req);
2237	return NULL;
2238}
2239
2240static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2241				  bool *is_last_frag)
2242{
2243	RPC_HDR hdr;
2244	RPC_HDR_REQ hdr_req;
2245	uint32_t data_sent_thistime;
2246	uint16_t auth_len;
2247	uint16_t frag_len;
2248	uint8_t flags = 0;
2249	uint32_t ss_padding;
2250	uint32_t data_left;
2251	char pad[8] = { 0, };
2252	NTSTATUS status;
2253
2254	data_left = prs_offset(state->req_data) - state->req_data_sent;
2255
2256	data_sent_thistime = calculate_data_len_tosend(
2257		state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2258
2259	if (state->req_data_sent == 0) {
2260		flags = DCERPC_PFC_FLAG_FIRST;
2261	}
2262
2263	if (data_sent_thistime == data_left) {
2264		flags |= DCERPC_PFC_FLAG_LAST;
2265	}
2266
2267	if (!prs_set_offset(&state->outgoing_frag, 0)) {
2268		return NT_STATUS_NO_MEMORY;
2269	}
2270
2271	/* Create and marshall the header and request header. */
2272	init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2273		     auth_len);
2274
2275	if (!smb_io_rpc_hdr("hdr    ", &hdr, &state->outgoing_frag, 0)) {
2276		return NT_STATUS_NO_MEMORY;
2277	}
2278
2279	/* Create the rpc request RPC_HDR_REQ */
2280	init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2281			 state->op_num);
2282
2283	if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2284				&state->outgoing_frag, 0)) {
2285		return NT_STATUS_NO_MEMORY;
2286	}
2287
2288	/* Copy in the data, plus any ss padding. */
2289	if (!prs_append_some_prs_data(&state->outgoing_frag,
2290				      state->req_data, state->req_data_sent,
2291				      data_sent_thistime)) {
2292		return NT_STATUS_NO_MEMORY;
2293	}
2294
2295	/* Copy the sign/seal padding data. */
2296	if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2297		return NT_STATUS_NO_MEMORY;
2298	}
2299
2300	/* Generate any auth sign/seal and add the auth footer. */
2301	switch (state->cli->auth->auth_type) {
2302	case PIPE_AUTH_TYPE_NONE:
2303		status = NT_STATUS_OK;
2304		break;
2305	case PIPE_AUTH_TYPE_NTLMSSP:
2306	case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2307		status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2308						 &state->outgoing_frag);
2309		break;
2310	case PIPE_AUTH_TYPE_SCHANNEL:
2311		status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2312						  &state->outgoing_frag);
2313		break;
2314	default:
2315		status = NT_STATUS_INVALID_PARAMETER;
2316		break;
2317	}
2318
2319	state->req_data_sent += data_sent_thistime;
2320	*is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2321
2322	return status;
2323}
2324
2325static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2326{
2327	struct tevent_req *req = tevent_req_callback_data(
2328		subreq, struct tevent_req);
2329	struct rpc_api_pipe_req_state *state = tevent_req_data(
2330		req, struct rpc_api_pipe_req_state);
2331	NTSTATUS status;
2332	bool is_last_frag;
2333
2334	status = rpc_write_recv(subreq);
2335	TALLOC_FREE(subreq);
2336	if (!NT_STATUS_IS_OK(status)) {
2337		tevent_req_nterror(req, status);
2338		return;
2339	}
2340
2341	status = prepare_next_frag(state, &is_last_frag);
2342	if (!NT_STATUS_IS_OK(status)) {
2343		tevent_req_nterror(req, status);
2344		return;
2345	}
2346
2347	if (is_last_frag) {
2348		subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2349					   &state->outgoing_frag,
2350					   DCERPC_PKT_RESPONSE);
2351		if (tevent_req_nomem(subreq, req)) {
2352			return;
2353		}
2354		tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2355	} else {
2356		subreq = rpc_write_send(
2357			state, state->ev,
2358			state->cli->transport,
2359			(uint8_t *)prs_data_p(&state->outgoing_frag),
2360			prs_offset(&state->outgoing_frag));
2361		if (tevent_req_nomem(subreq, req)) {
2362			return;
2363		}
2364		tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2365					req);
2366	}
2367}
2368
2369static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2370{
2371	struct tevent_req *req = tevent_req_callback_data(
2372		subreq, struct tevent_req);
2373	struct rpc_api_pipe_req_state *state = tevent_req_data(
2374		req, struct rpc_api_pipe_req_state);
2375	NTSTATUS status;
2376
2377	status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2378	TALLOC_FREE(subreq);
2379	if (!NT_STATUS_IS_OK(status)) {
2380		tevent_req_nterror(req, status);
2381		return;
2382	}
2383	tevent_req_done(req);
2384}
2385
2386NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2387			       prs_struct *reply_pdu)
2388{
2389	struct rpc_api_pipe_req_state *state = tevent_req_data(
2390		req, struct rpc_api_pipe_req_state);
2391	NTSTATUS status;
2392
2393	if (tevent_req_is_nterror(req, &status)) {
2394		/*
2395		 * We always have to initialize to reply pdu, even if there is
2396		 * none. The rpccli_* caller routines expect this.
2397		 */
2398		prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2399		return status;
2400	}
2401
2402	*reply_pdu = state->reply_pdu;
2403	reply_pdu->mem_ctx = mem_ctx;
2404
2405	/*
2406	 * Prevent state->req_pdu from being freed in
2407	 * rpc_api_pipe_req_state_destructor()
2408	 */
2409	prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2410
2411	return NT_STATUS_OK;
2412}
2413
2414#if 0
2415/****************************************************************************
2416 Set the handle state.
2417****************************************************************************/
2418
2419static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2420				   const char *pipe_name, uint16 device_state)
2421{
2422	bool state_set = False;
2423	char param[2];
2424	uint16 setup[2]; /* only need 2 uint16 setup parameters */
2425	char *rparam = NULL;
2426	char *rdata = NULL;
2427	uint32 rparam_len, rdata_len;
2428
2429	if (pipe_name == NULL)
2430		return False;
2431
2432	DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2433		 cli->fnum, pipe_name, device_state));
2434
2435	/* create parameters: device state */
2436	SSVAL(param, 0, device_state);
2437
2438	/* create setup parameters. */
2439	setup[0] = 0x0001;
2440	setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
2441
2442	/* send the data on \PIPE\ */
2443	if (cli_api_pipe(cli->cli, "\\PIPE\\",
2444	            setup, 2, 0,                /* setup, length, max */
2445	            param, 2, 0,                /* param, length, max */
2446	            NULL, 0, 1024,              /* data, length, max */
2447	            &rparam, &rparam_len,        /* return param, length */
2448	            &rdata, &rdata_len))         /* return data, length */
2449	{
2450		DEBUG(5, ("Set Handle state: return OK\n"));
2451		state_set = True;
2452	}
2453
2454	SAFE_FREE(rparam);
2455	SAFE_FREE(rdata);
2456
2457	return state_set;
2458}
2459#endif
2460
2461/****************************************************************************
2462 Check the rpc bind acknowledge response.
2463****************************************************************************/
2464
2465static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2466				const struct ndr_syntax_id *transfer)
2467{
2468	if ( hdr_ba->addr.len == 0) {
2469		DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2470	}
2471
2472	/* check the transfer syntax */
2473	if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2474	     (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2475		DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2476		return False;
2477	}
2478
2479	if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2480		DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2481		          hdr_ba->res.num_results, hdr_ba->res.reason));
2482	}
2483
2484	DEBUG(5,("check_bind_response: accepted!\n"));
2485	return True;
2486}
2487
2488/*******************************************************************
2489 Creates a DCE/RPC bind authentication response.
2490 This is the packet that is sent back to the server once we
2491 have received a BIND-ACK, to finish the third leg of
2492 the authentication handshake.
2493 ********************************************************************/
2494
2495static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2496				uint32 rpc_call_id,
2497				enum pipe_auth_type auth_type,
2498				enum dcerpc_AuthLevel auth_level,
2499				DATA_BLOB *pauth_blob,
2500				prs_struct *rpc_out)
2501{
2502	RPC_HDR hdr;
2503	RPC_HDR_AUTH hdr_auth;
2504	uint32 pad = 0;
2505
2506	/* Create the request RPC_HDR */
2507	init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2508		     RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2509		     pauth_blob->length );
2510
2511	/* Marshall it. */
2512	if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2513		DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2514		return NT_STATUS_NO_MEMORY;
2515	}
2516
2517	/*
2518		I'm puzzled about this - seems to violate the DCE RPC auth rules,
2519		about padding - shouldn't this pad to length 8 ? JRA.
2520	*/
2521
2522	/* 4 bytes padding. */
2523	if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2524		DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2525		return NT_STATUS_NO_MEMORY;
2526	}
2527
2528	/* Create the request RPC_HDR_AUTHA */
2529	init_rpc_hdr_auth(&hdr_auth,
2530			map_pipe_auth_type_to_rpc_auth_type(auth_type),
2531			auth_level, 0, 1);
2532
2533	if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2534		DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2535		return NT_STATUS_NO_MEMORY;
2536	}
2537
2538	/*
2539	 * Append the auth data to the outgoing buffer.
2540	 */
2541
2542	if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2543		DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2544		return NT_STATUS_NO_MEMORY;
2545	}
2546
2547	return NT_STATUS_OK;
2548}
2549
2550/*******************************************************************
2551 Creates a DCE/RPC bind alter context authentication request which
2552 may contain a spnego auth blobl
2553 ********************************************************************/
2554
2555static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2556					const struct ndr_syntax_id *abstract,
2557					const struct ndr_syntax_id *transfer,
2558					enum dcerpc_AuthLevel auth_level,
2559					const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2560					prs_struct *rpc_out)
2561{
2562	RPC_HDR_AUTH hdr_auth;
2563	prs_struct auth_info;
2564	NTSTATUS ret = NT_STATUS_OK;
2565
2566	ZERO_STRUCT(hdr_auth);
2567	if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2568		return NT_STATUS_NO_MEMORY;
2569
2570	/* We may change the pad length before marshalling. */
2571	init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2572
2573	if (pauth_blob->length) {
2574		if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2575			prs_mem_free(&auth_info);
2576			return NT_STATUS_NO_MEMORY;
2577		}
2578	}
2579
2580	ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2581						rpc_out,
2582						rpc_call_id,
2583						abstract,
2584						transfer,
2585						&hdr_auth,
2586						&auth_info);
2587	prs_mem_free(&auth_info);
2588	return ret;
2589}
2590
2591/****************************************************************************
2592 Do an rpc bind.
2593****************************************************************************/
2594
2595struct rpc_pipe_bind_state {
2596	struct event_context *ev;
2597	struct rpc_pipe_client *cli;
2598	prs_struct rpc_out;
2599	uint32_t rpc_call_id;
2600};
2601
2602static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2603{
2604	prs_mem_free(&state->rpc_out);
2605	return 0;
2606}
2607
2608static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2609static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2610					   struct rpc_pipe_bind_state *state,
2611					   struct rpc_hdr_info *phdr,
2612					   prs_struct *reply_pdu);
2613static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2614static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2615						    struct rpc_pipe_bind_state *state,
2616						    struct rpc_hdr_info *phdr,
2617						    prs_struct *reply_pdu);
2618static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2619
2620struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2621				      struct event_context *ev,
2622				      struct rpc_pipe_client *cli,
2623				      struct cli_pipe_auth_data *auth)
2624{
2625	struct tevent_req *req, *subreq;
2626	struct rpc_pipe_bind_state *state;
2627	NTSTATUS status;
2628
2629	req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2630	if (req == NULL) {
2631		return NULL;
2632	}
2633
2634	DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2635		rpccli_pipe_txt(talloc_tos(), cli),
2636		(unsigned int)auth->auth_type,
2637		(unsigned int)auth->auth_level ));
2638
2639	state->ev = ev;
2640	state->cli = cli;
2641	state->rpc_call_id = get_rpc_call_id();
2642
2643	prs_init_empty(&state->rpc_out, state, MARSHALL);
2644	talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2645
2646	cli->auth = talloc_move(cli, &auth);
2647
2648	/* Marshall the outgoing data. */
2649	status = create_rpc_bind_req(cli, &state->rpc_out,
2650				     state->rpc_call_id,
2651				     &cli->abstract_syntax,
2652				     &cli->transfer_syntax,
2653				     cli->auth->auth_type,
2654				     cli->auth->auth_level);
2655
2656	if (!NT_STATUS_IS_OK(status)) {
2657		goto post_status;
2658	}
2659
2660	subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2661				   DCERPC_PKT_BIND_ACK);
2662	if (subreq == NULL) {
2663		goto fail;
2664	}
2665	tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2666	return req;
2667
2668 post_status:
2669	tevent_req_nterror(req, status);
2670	return tevent_req_post(req, ev);
2671 fail:
2672	TALLOC_FREE(req);
2673	return NULL;
2674}
2675
2676static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2677{
2678	struct tevent_req *req = tevent_req_callback_data(
2679		subreq, struct tevent_req);
2680	struct rpc_pipe_bind_state *state = tevent_req_data(
2681		req, struct rpc_pipe_bind_state);
2682	prs_struct reply_pdu;
2683	struct rpc_hdr_info hdr;
2684	struct rpc_hdr_ba_info hdr_ba;
2685	NTSTATUS status;
2686
2687	status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2688	TALLOC_FREE(subreq);
2689	if (!NT_STATUS_IS_OK(status)) {
2690		DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2691			  rpccli_pipe_txt(talloc_tos(), state->cli),
2692			  nt_errstr(status)));
2693		tevent_req_nterror(req, status);
2694		return;
2695	}
2696
2697	/* Unmarshall the RPC header */
2698	if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2699		DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2700		prs_mem_free(&reply_pdu);
2701		tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2702		return;
2703	}
2704
2705	if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2706		DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2707			  "RPC_HDR_BA.\n"));
2708		prs_mem_free(&reply_pdu);
2709		tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2710		return;
2711	}
2712
2713	if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2714		DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2715		prs_mem_free(&reply_pdu);
2716		tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2717		return;
2718	}
2719
2720	state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2721	state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2722
2723	/*
2724	 * For authenticated binds we may need to do 3 or 4 leg binds.
2725	 */
2726
2727	switch(state->cli->auth->auth_type) {
2728
2729	case PIPE_AUTH_TYPE_NONE:
2730	case PIPE_AUTH_TYPE_SCHANNEL:
2731		/* Bind complete. */
2732		prs_mem_free(&reply_pdu);
2733		tevent_req_done(req);
2734		break;
2735
2736	case PIPE_AUTH_TYPE_NTLMSSP:
2737		/* Need to send AUTH3 packet - no reply. */
2738		status = rpc_finish_auth3_bind_send(req, state, &hdr,
2739						    &reply_pdu);
2740		prs_mem_free(&reply_pdu);
2741		if (!NT_STATUS_IS_OK(status)) {
2742			tevent_req_nterror(req, status);
2743		}
2744		break;
2745
2746	case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2747		/* Need to send alter context request and reply. */
2748		status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2749							     &reply_pdu);
2750		prs_mem_free(&reply_pdu);
2751		if (!NT_STATUS_IS_OK(status)) {
2752			tevent_req_nterror(req, status);
2753		}
2754		break;
2755
2756	case PIPE_AUTH_TYPE_KRB5:
2757		/* */
2758
2759	default:
2760		DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2761			 (unsigned int)state->cli->auth->auth_type));
2762		prs_mem_free(&reply_pdu);
2763		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2764	}
2765}
2766
2767static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2768					   struct rpc_pipe_bind_state *state,
2769					   struct rpc_hdr_info *phdr,
2770					   prs_struct *reply_pdu)
2771{
2772	DATA_BLOB server_response = data_blob_null;
2773	DATA_BLOB client_reply = data_blob_null;
2774	struct rpc_hdr_auth_info hdr_auth;
2775	struct tevent_req *subreq;
2776	NTSTATUS status;
2777
2778	if ((phdr->auth_len == 0)
2779	    || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2780		return NT_STATUS_INVALID_PARAMETER;
2781	}
2782
2783	if (!prs_set_offset(
2784		    reply_pdu,
2785		    phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2786		return NT_STATUS_INVALID_PARAMETER;
2787	}
2788
2789	if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2790		return NT_STATUS_INVALID_PARAMETER;
2791	}
2792
2793	/* TODO - check auth_type/auth_level match. */
2794
2795	server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2796	prs_copy_data_out((char *)server_response.data, reply_pdu,
2797			  phdr->auth_len);
2798
2799	status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2800				server_response, &client_reply);
2801
2802	if (!NT_STATUS_IS_OK(status)) {
2803		DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2804			  "blob failed: %s.\n", nt_errstr(status)));
2805		return status;
2806	}
2807
2808	prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2809
2810	status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2811				       state->cli->auth->auth_type,
2812				       state->cli->auth->auth_level,
2813				       &client_reply, &state->rpc_out);
2814	data_blob_free(&client_reply);
2815
2816	if (!NT_STATUS_IS_OK(status)) {
2817		return status;
2818	}
2819
2820	subreq = rpc_write_send(state, state->ev, state->cli->transport,
2821				(uint8_t *)prs_data_p(&state->rpc_out),
2822				prs_offset(&state->rpc_out));
2823	if (subreq == NULL) {
2824		return NT_STATUS_NO_MEMORY;
2825	}
2826	tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2827	return NT_STATUS_OK;
2828}
2829
2830static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2831{
2832	struct tevent_req *req = tevent_req_callback_data(
2833		subreq, struct tevent_req);
2834	NTSTATUS status;
2835
2836	status = rpc_write_recv(subreq);
2837	TALLOC_FREE(subreq);
2838	if (!NT_STATUS_IS_OK(status)) {
2839		tevent_req_nterror(req, status);
2840		return;
2841	}
2842	tevent_req_done(req);
2843}
2844
2845static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2846						    struct rpc_pipe_bind_state *state,
2847						    struct rpc_hdr_info *phdr,
2848						    prs_struct *reply_pdu)
2849{
2850	DATA_BLOB server_spnego_response = data_blob_null;
2851	DATA_BLOB server_ntlm_response = data_blob_null;
2852	DATA_BLOB client_reply = data_blob_null;
2853	DATA_BLOB tmp_blob = data_blob_null;
2854	RPC_HDR_AUTH hdr_auth;
2855	struct tevent_req *subreq;
2856	NTSTATUS status;
2857
2858	if ((phdr->auth_len == 0)
2859	    || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2860		return NT_STATUS_INVALID_PARAMETER;
2861	}
2862
2863	/* Process the returned NTLMSSP blob first. */
2864	if (!prs_set_offset(
2865		    reply_pdu,
2866		    phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2867		return NT_STATUS_INVALID_PARAMETER;
2868	}
2869
2870	if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2871		return NT_STATUS_INVALID_PARAMETER;
2872	}
2873
2874	server_spnego_response = data_blob(NULL, phdr->auth_len);
2875	prs_copy_data_out((char *)server_spnego_response.data,
2876			  reply_pdu, phdr->auth_len);
2877
2878	/*
2879	 * The server might give us back two challenges - tmp_blob is for the
2880	 * second.
2881	 */
2882	if (!spnego_parse_challenge(server_spnego_response,
2883				    &server_ntlm_response, &tmp_blob)) {
2884		data_blob_free(&server_spnego_response);
2885		data_blob_free(&server_ntlm_response);
2886		data_blob_free(&tmp_blob);
2887		return NT_STATUS_INVALID_PARAMETER;
2888	}
2889
2890	/* We're finished with the server spnego response and the tmp_blob. */
2891	data_blob_free(&server_spnego_response);
2892	data_blob_free(&tmp_blob);
2893
2894	status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2895				server_ntlm_response, &client_reply);
2896
2897	/* Finished with the server_ntlm response */
2898	data_blob_free(&server_ntlm_response);
2899
2900	if (!NT_STATUS_IS_OK(status)) {
2901		DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2902			  "using server blob failed.\n"));
2903		data_blob_free(&client_reply);
2904		return status;
2905	}
2906
2907	/* SPNEGO wrap the client reply. */
2908	tmp_blob = spnego_gen_auth(client_reply);
2909	data_blob_free(&client_reply);
2910	client_reply = tmp_blob;
2911	tmp_blob = data_blob_null;
2912
2913	/* Now prepare the alter context pdu. */
2914	prs_init_empty(&state->rpc_out, state, MARSHALL);
2915
2916	status = create_rpc_alter_context(state->rpc_call_id,
2917					  &state->cli->abstract_syntax,
2918					  &state->cli->transfer_syntax,
2919					  state->cli->auth->auth_level,
2920					  &client_reply,
2921					  &state->rpc_out);
2922	data_blob_free(&client_reply);
2923
2924	if (!NT_STATUS_IS_OK(status)) {
2925		return status;
2926	}
2927
2928	subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2929				   &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2930	if (subreq == NULL) {
2931		return NT_STATUS_NO_MEMORY;
2932	}
2933	tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2934	return NT_STATUS_OK;
2935}
2936
2937static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2938{
2939	struct tevent_req *req = tevent_req_callback_data(
2940		subreq, struct tevent_req);
2941	struct rpc_pipe_bind_state *state = tevent_req_data(
2942		req, struct rpc_pipe_bind_state);
2943	DATA_BLOB server_spnego_response = data_blob_null;
2944	DATA_BLOB tmp_blob = data_blob_null;
2945	prs_struct reply_pdu;
2946	struct rpc_hdr_info hdr;
2947	struct rpc_hdr_auth_info hdr_auth;
2948	NTSTATUS status;
2949
2950	status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2951	TALLOC_FREE(subreq);
2952	if (!NT_STATUS_IS_OK(status)) {
2953		tevent_req_nterror(req, status);
2954		return;
2955	}
2956
2957	/* Get the auth blob from the reply. */
2958	if (!smb_io_rpc_hdr("rpc_hdr   ", &hdr, &reply_pdu, 0)) {
2959		DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2960			  "unmarshall RPC_HDR.\n"));
2961		tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2962		return;
2963	}
2964
2965	if (!prs_set_offset(
2966		    &reply_pdu,
2967		    hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2968		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2969		return;
2970	}
2971
2972	if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2973		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2974		return;
2975	}
2976
2977	server_spnego_response = data_blob(NULL, hdr.auth_len);
2978	prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2979			  hdr.auth_len);
2980
2981	/* Check we got a valid auth response. */
2982	if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2983					OID_NTLMSSP, &tmp_blob)) {
2984		data_blob_free(&server_spnego_response);
2985		data_blob_free(&tmp_blob);
2986		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2987		return;
2988	}
2989
2990	data_blob_free(&server_spnego_response);
2991	data_blob_free(&tmp_blob);
2992
2993	DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2994		 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2995	tevent_req_done(req);
2996}
2997
2998NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2999{
3000	return tevent_req_simple_recv_ntstatus(req);
3001}
3002
3003NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3004		       struct cli_pipe_auth_data *auth)
3005{
3006	TALLOC_CTX *frame = talloc_stackframe();
3007	struct event_context *ev;
3008	struct tevent_req *req;
3009	NTSTATUS status = NT_STATUS_OK;
3010
3011	ev = event_context_init(frame);
3012	if (ev == NULL) {
3013		status = NT_STATUS_NO_MEMORY;
3014		goto fail;
3015	}
3016
3017	req = rpc_pipe_bind_send(frame, ev, cli, auth);
3018	if (req == NULL) {
3019		status = NT_STATUS_NO_MEMORY;
3020		goto fail;
3021	}
3022
3023	if (!tevent_req_poll(req, ev)) {
3024		status = map_nt_error_from_unix(errno);
3025		goto fail;
3026	}
3027
3028	status = rpc_pipe_bind_recv(req);
3029 fail:
3030	TALLOC_FREE(frame);
3031	return status;
3032}
3033
3034#define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3035
3036unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3037				unsigned int timeout)
3038{
3039	unsigned int old;
3040
3041	if (rpc_cli->transport == NULL) {
3042		return RPCCLI_DEFAULT_TIMEOUT;
3043	}
3044
3045	if (rpc_cli->transport->set_timeout == NULL) {
3046		return RPCCLI_DEFAULT_TIMEOUT;
3047	}
3048
3049	old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3050	if (old == 0) {
3051		return RPCCLI_DEFAULT_TIMEOUT;
3052	}
3053
3054	return old;
3055}
3056
3057bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3058{
3059	if (rpc_cli == NULL) {
3060		return false;
3061	}
3062
3063	if (rpc_cli->transport == NULL) {
3064		return false;
3065	}
3066
3067	return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3068}
3069
3070bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3071{
3072	struct cli_state *cli;
3073
3074	if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3075	    || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3076		memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3077		return true;
3078	}
3079
3080	cli = rpc_pipe_np_smb_conn(rpc_cli);
3081	if (cli == NULL) {
3082		return false;
3083	}
3084	E_md4hash(cli->password ? cli->password : "", nt_hash);
3085	return true;
3086}
3087
3088NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3089			       struct cli_pipe_auth_data **presult)
3090{
3091	struct cli_pipe_auth_data *result;
3092
3093	result = talloc(mem_ctx, struct cli_pipe_auth_data);
3094	if (result == NULL) {
3095		return NT_STATUS_NO_MEMORY;
3096	}
3097
3098	result->auth_type = PIPE_AUTH_TYPE_NONE;
3099	result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3100
3101	result->user_name = talloc_strdup(result, "");
3102	result->domain = talloc_strdup(result, "");
3103	if ((result->user_name == NULL) || (result->domain == NULL)) {
3104		TALLOC_FREE(result);
3105		return NT_STATUS_NO_MEMORY;
3106	}
3107
3108	*presult = result;
3109	return NT_STATUS_OK;
3110}
3111
3112static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3113{
3114	ntlmssp_end(&auth->a_u.ntlmssp_state);
3115	return 0;
3116}
3117
3118static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3119				  enum pipe_auth_type auth_type,
3120				  enum dcerpc_AuthLevel auth_level,
3121				  const char *domain,
3122				  const char *username,
3123				  const char *password,
3124				  struct cli_pipe_auth_data **presult)
3125{
3126	struct cli_pipe_auth_data *result;
3127	NTSTATUS status;
3128
3129	result = talloc(mem_ctx, struct cli_pipe_auth_data);
3130	if (result == NULL) {
3131		return NT_STATUS_NO_MEMORY;
3132	}
3133
3134	result->auth_type = auth_type;
3135	result->auth_level = auth_level;
3136
3137	result->user_name = talloc_strdup(result, username);
3138	result->domain = talloc_strdup(result, domain);
3139	if ((result->user_name == NULL) || (result->domain == NULL)) {
3140		status = NT_STATUS_NO_MEMORY;
3141		goto fail;
3142	}
3143
3144	status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3145	if (!NT_STATUS_IS_OK(status)) {
3146		goto fail;
3147	}
3148
3149	talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3150
3151	status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3152	if (!NT_STATUS_IS_OK(status)) {
3153		goto fail;
3154	}
3155
3156	status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3157	if (!NT_STATUS_IS_OK(status)) {
3158		goto fail;
3159	}
3160
3161	status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3162	if (!NT_STATUS_IS_OK(status)) {
3163		goto fail;
3164	}
3165
3166	/*
3167	 * Turn off sign+seal to allow selected auth level to turn it back on.
3168	 */
3169	result->a_u.ntlmssp_state->neg_flags &=
3170		~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3171
3172	if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3173		result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3174	} else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3175		result->a_u.ntlmssp_state->neg_flags
3176			|= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3177	}
3178
3179	*presult = result;
3180	return NT_STATUS_OK;
3181
3182 fail:
3183	TALLOC_FREE(result);
3184	return status;
3185}
3186
3187NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3188				   enum dcerpc_AuthLevel auth_level,
3189				   struct netlogon_creds_CredentialState *creds,
3190				   struct cli_pipe_auth_data **presult)
3191{
3192	struct cli_pipe_auth_data *result;
3193
3194	result = talloc(mem_ctx, struct cli_pipe_auth_data);
3195	if (result == NULL) {
3196		return NT_STATUS_NO_MEMORY;
3197	}
3198
3199	result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3200	result->auth_level = auth_level;
3201
3202	result->user_name = talloc_strdup(result, "");
3203	result->domain = talloc_strdup(result, domain);
3204	if ((result->user_name == NULL) || (result->domain == NULL)) {
3205		goto fail;
3206	}
3207
3208	result->a_u.schannel_auth = talloc(result, struct schannel_state);
3209	if (result->a_u.schannel_auth == NULL) {
3210		goto fail;
3211	}
3212
3213	result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3214	result->a_u.schannel_auth->seq_num = 0;
3215	result->a_u.schannel_auth->initiator = true;
3216	result->a_u.schannel_auth->creds = netlogon_creds_copy(result, creds);
3217
3218	*presult = result;
3219	return NT_STATUS_OK;
3220
3221 fail:
3222	TALLOC_FREE(result);
3223	return NT_STATUS_NO_MEMORY;
3224}
3225
3226#ifdef HAVE_KRB5
3227static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3228{
3229	data_blob_free(&auth->session_key);
3230	return 0;
3231}
3232#endif
3233
3234static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3235				   enum dcerpc_AuthLevel auth_level,
3236				   const char *service_princ,
3237				   const char *username,
3238				   const char *password,
3239				   struct cli_pipe_auth_data **presult)
3240{
3241#ifdef HAVE_KRB5
3242	struct cli_pipe_auth_data *result;
3243
3244	if ((username != NULL) && (password != NULL)) {
3245		int ret = kerberos_kinit_password(username, password, 0, NULL);
3246		if (ret != 0) {
3247			return NT_STATUS_ACCESS_DENIED;
3248		}
3249	}
3250
3251	result = talloc(mem_ctx, struct cli_pipe_auth_data);
3252	if (result == NULL) {
3253		return NT_STATUS_NO_MEMORY;
3254	}
3255
3256	result->auth_type = PIPE_AUTH_TYPE_KRB5;
3257	result->auth_level = auth_level;
3258
3259	/*
3260	 * Username / domain need fixing!
3261	 */
3262	result->user_name = talloc_strdup(result, "");
3263	result->domain = talloc_strdup(result, "");
3264	if ((result->user_name == NULL) || (result->domain == NULL)) {
3265		goto fail;
3266	}
3267
3268	result->a_u.kerberos_auth = TALLOC_ZERO_P(
3269		result, struct kerberos_auth_struct);
3270	if (result->a_u.kerberos_auth == NULL) {
3271		goto fail;
3272	}
3273	talloc_set_destructor(result->a_u.kerberos_auth,
3274			      cli_auth_kerberos_data_destructor);
3275
3276	result->a_u.kerberos_auth->service_principal = talloc_strdup(
3277		result, service_princ);
3278	if (result->a_u.kerberos_auth->service_principal == NULL) {
3279		goto fail;
3280	}
3281
3282	*presult = result;
3283	return NT_STATUS_OK;
3284
3285 fail:
3286	TALLOC_FREE(result);
3287	return NT_STATUS_NO_MEMORY;
3288#else
3289	return NT_STATUS_NOT_SUPPORTED;
3290#endif
3291}
3292
3293/**
3294 * Create an rpc pipe client struct, connecting to a tcp port.
3295 */
3296static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3297				       uint16_t port,
3298				       const struct ndr_syntax_id *abstract_syntax,
3299				       struct rpc_pipe_client **presult)
3300{
3301	struct rpc_pipe_client *result;
3302	struct sockaddr_storage addr;
3303	NTSTATUS status;
3304	int fd;
3305
3306	result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3307	if (result == NULL) {
3308		return NT_STATUS_NO_MEMORY;
3309	}
3310
3311	result->abstract_syntax = *abstract_syntax;
3312	result->transfer_syntax = ndr_transfer_syntax;
3313	result->dispatch = cli_do_rpc_ndr;
3314	result->dispatch_send = cli_do_rpc_ndr_send;
3315	result->dispatch_recv = cli_do_rpc_ndr_recv;
3316
3317	result->desthost = talloc_strdup(result, host);
3318	result->srv_name_slash = talloc_asprintf_strupper_m(
3319		result, "\\\\%s", result->desthost);
3320	if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3321		status = NT_STATUS_NO_MEMORY;
3322		goto fail;
3323	}
3324
3325	result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3326	result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3327
3328	if (!resolve_name(host, &addr, 0, false)) {
3329		status = NT_STATUS_NOT_FOUND;
3330		goto fail;
3331	}
3332
3333	status = open_socket_out(&addr, port, 60, &fd);
3334	if (!NT_STATUS_IS_OK(status)) {
3335		goto fail;
3336	}
3337	set_socket_options(fd, lp_socket_options());
3338
3339	status = rpc_transport_sock_init(result, fd, &result->transport);
3340	if (!NT_STATUS_IS_OK(status)) {
3341		close(fd);
3342		goto fail;
3343	}
3344
3345	result->transport->transport = NCACN_IP_TCP;
3346
3347	*presult = result;
3348	return NT_STATUS_OK;
3349
3350 fail:
3351	TALLOC_FREE(result);
3352	return status;
3353}
3354
3355/**
3356 * Determine the tcp port on which a dcerpc interface is listening
3357 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3358 * target host.
3359 */
3360static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3361				      const struct ndr_syntax_id *abstract_syntax,
3362				      uint16_t *pport)
3363{
3364	NTSTATUS status;
3365	struct rpc_pipe_client *epm_pipe = NULL;
3366	struct cli_pipe_auth_data *auth = NULL;
3367	struct dcerpc_binding *map_binding = NULL;
3368	struct dcerpc_binding *res_binding = NULL;
3369	struct epm_twr_t *map_tower = NULL;
3370	struct epm_twr_t *res_towers = NULL;
3371	struct policy_handle *entry_handle = NULL;
3372	uint32_t num_towers = 0;
3373	uint32_t max_towers = 1;
3374	struct epm_twr_p_t towers;
3375	TALLOC_CTX *tmp_ctx = talloc_stackframe();
3376
3377	if (pport == NULL) {
3378		status = NT_STATUS_INVALID_PARAMETER;
3379		goto done;
3380	}
3381
3382	/* open the connection to the endpoint mapper */
3383	status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3384					&ndr_table_epmapper.syntax_id,
3385					&epm_pipe);
3386
3387	if (!NT_STATUS_IS_OK(status)) {
3388		goto done;
3389	}
3390
3391	status = rpccli_anon_bind_data(tmp_ctx, &auth);
3392	if (!NT_STATUS_IS_OK(status)) {
3393		goto done;
3394	}
3395
3396	status = rpc_pipe_bind(epm_pipe, auth);
3397	if (!NT_STATUS_IS_OK(status)) {
3398		goto done;
3399	}
3400
3401	/* create tower for asking the epmapper */
3402
3403	map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3404	if (map_binding == NULL) {
3405		status = NT_STATUS_NO_MEMORY;
3406		goto done;
3407	}
3408
3409	map_binding->transport = NCACN_IP_TCP;
3410	map_binding->object = *abstract_syntax;
3411	map_binding->host = host; /* needed? */
3412	map_binding->endpoint = "0"; /* correct? needed? */
3413
3414	map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3415	if (map_tower == NULL) {
3416		status = NT_STATUS_NO_MEMORY;
3417		goto done;
3418	}
3419
3420	status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3421					    &(map_tower->tower));
3422	if (!NT_STATUS_IS_OK(status)) {
3423		goto done;
3424	}
3425
3426	/* allocate further parameters for the epm_Map call */
3427
3428	res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3429	if (res_towers == NULL) {
3430		status = NT_STATUS_NO_MEMORY;
3431		goto done;
3432	}
3433	towers.twr = res_towers;
3434
3435	entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3436	if (entry_handle == NULL) {
3437		status = NT_STATUS_NO_MEMORY;
3438		goto done;
3439	}
3440
3441	/* ask the endpoint mapper for the port */
3442
3443	status = rpccli_epm_Map(epm_pipe,
3444				tmp_ctx,
3445				CONST_DISCARD(struct GUID *,
3446					      &(abstract_syntax->uuid)),
3447				map_tower,
3448				entry_handle,
3449				max_towers,
3450				&num_towers,
3451				&towers);
3452
3453	if (!NT_STATUS_IS_OK(status)) {
3454		goto done;
3455	}
3456
3457	if (num_towers != 1) {
3458		status = NT_STATUS_UNSUCCESSFUL;
3459		goto done;
3460	}
3461
3462	/* extract the port from the answer */
3463
3464	status = dcerpc_binding_from_tower(tmp_ctx,
3465					   &(towers.twr->tower),
3466					   &res_binding);
3467	if (!NT_STATUS_IS_OK(status)) {
3468		goto done;
3469	}
3470
3471	/* are further checks here necessary? */
3472	if (res_binding->transport != NCACN_IP_TCP) {
3473		status = NT_STATUS_UNSUCCESSFUL;
3474		goto done;
3475	}
3476
3477	*pport = (uint16_t)atoi(res_binding->endpoint);
3478
3479done:
3480	TALLOC_FREE(tmp_ctx);
3481	return status;
3482}
3483
3484/**
3485 * Create a rpc pipe client struct, connecting to a host via tcp.
3486 * The port is determined by asking the endpoint mapper on the given
3487 * host.
3488 */
3489NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3490			   const struct ndr_syntax_id *abstract_syntax,
3491			   struct rpc_pipe_client **presult)
3492{
3493	NTSTATUS status;
3494	uint16_t port = 0;
3495
3496	status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3497	if (!NT_STATUS_IS_OK(status)) {
3498		return status;
3499	}
3500
3501	return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3502					abstract_syntax, presult);
3503}
3504
3505/********************************************************************
3506 Create a rpc pipe client struct, connecting to a unix domain socket
3507 ********************************************************************/
3508NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3509			       const struct ndr_syntax_id *abstract_syntax,
3510			       struct rpc_pipe_client **presult)
3511{
3512	struct rpc_pipe_client *result;
3513	struct sockaddr_un addr;
3514	NTSTATUS status;
3515	int fd;
3516
3517	result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3518	if (result == NULL) {
3519		return NT_STATUS_NO_MEMORY;
3520	}
3521
3522	result->abstract_syntax = *abstract_syntax;
3523	result->transfer_syntax = ndr_transfer_syntax;
3524	result->dispatch = cli_do_rpc_ndr;
3525	result->dispatch_send = cli_do_rpc_ndr_send;
3526	result->dispatch_recv = cli_do_rpc_ndr_recv;
3527
3528	result->desthost = get_myname(result);
3529	result->srv_name_slash = talloc_asprintf_strupper_m(
3530		result, "\\\\%s", result->desthost);
3531	if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3532		status = NT_STATUS_NO_MEMORY;
3533		goto fail;
3534	}
3535
3536	result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3537	result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3538
3539	fd = socket(AF_UNIX, SOCK_STREAM, 0);
3540	if (fd == -1) {
3541		status = map_nt_error_from_unix(errno);
3542		goto fail;
3543	}
3544
3545	ZERO_STRUCT(addr);
3546	addr.sun_family = AF_UNIX;
3547	strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3548
3549	if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3550		DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3551			  strerror(errno)));
3552		close(fd);
3553		return map_nt_error_from_unix(errno);
3554	}
3555
3556	status = rpc_transport_sock_init(result, fd, &result->transport);
3557	if (!NT_STATUS_IS_OK(status)) {
3558		close(fd);
3559		goto fail;
3560	}
3561
3562	result->transport->transport = NCALRPC;
3563
3564	*presult = result;
3565	return NT_STATUS_OK;
3566
3567 fail:
3568	TALLOC_FREE(result);
3569	return status;
3570}
3571
3572struct rpc_pipe_client_np_ref {
3573	struct cli_state *cli;
3574	struct rpc_pipe_client *pipe;
3575};
3576
3577static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3578{
3579	DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3580	return 0;
3581}
3582
3583/****************************************************************************
3584 Open a named pipe over SMB to a remote server.
3585 *
3586 * CAVEAT CALLER OF THIS FUNCTION:
3587 *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3588 *    so be sure that this function is called AFTER any structure (vs pointer)
3589 *    assignment of the cli.  In particular, libsmbclient does structure
3590 *    assignments of cli, which invalidates the data in the returned
3591 *    rpc_pipe_client if this function is called before the structure assignment
3592 *    of cli.
3593 *
3594 ****************************************************************************/
3595
3596static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3597				 const struct ndr_syntax_id *abstract_syntax,
3598				 struct rpc_pipe_client **presult)
3599{
3600	struct rpc_pipe_client *result;
3601	NTSTATUS status;
3602	struct rpc_pipe_client_np_ref *np_ref;
3603
3604	/* sanity check to protect against crashes */
3605
3606	if ( !cli ) {
3607		return NT_STATUS_INVALID_HANDLE;
3608	}
3609
3610	result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3611	if (result == NULL) {
3612		return NT_STATUS_NO_MEMORY;
3613	}
3614
3615	result->abstract_syntax = *abstract_syntax;
3616	result->transfer_syntax = ndr_transfer_syntax;
3617	result->dispatch = cli_do_rpc_ndr;
3618	result->dispatch_send = cli_do_rpc_ndr_send;
3619	result->dispatch_recv = cli_do_rpc_ndr_recv;
3620	result->desthost = talloc_strdup(result, cli->desthost);
3621	result->srv_name_slash = talloc_asprintf_strupper_m(
3622		result, "\\\\%s", result->desthost);
3623
3624	result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3625	result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3626
3627	if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3628		TALLOC_FREE(result);
3629		return NT_STATUS_NO_MEMORY;
3630	}
3631
3632	status = rpc_transport_np_init(result, cli, abstract_syntax,
3633				       &result->transport);
3634	if (!NT_STATUS_IS_OK(status)) {
3635		TALLOC_FREE(result);
3636		return status;
3637	}
3638
3639	result->transport->transport = NCACN_NP;
3640
3641	np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3642	if (np_ref == NULL) {
3643		TALLOC_FREE(result);
3644		return NT_STATUS_NO_MEMORY;
3645	}
3646	np_ref->cli = cli;
3647	np_ref->pipe = result;
3648
3649	DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3650	talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3651
3652	*presult = result;
3653	return NT_STATUS_OK;
3654}
3655
3656NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3657			     struct rpc_cli_smbd_conn *conn,
3658			     const struct ndr_syntax_id *syntax,
3659			     struct rpc_pipe_client **presult)
3660{
3661	struct rpc_pipe_client *result;
3662	struct cli_pipe_auth_data *auth;
3663	NTSTATUS status;
3664
3665	result = talloc(mem_ctx, struct rpc_pipe_client);
3666	if (result == NULL) {
3667		return NT_STATUS_NO_MEMORY;
3668	}
3669	result->abstract_syntax = *syntax;
3670	result->transfer_syntax = ndr_transfer_syntax;
3671	result->dispatch = cli_do_rpc_ndr;
3672	result->dispatch_send = cli_do_rpc_ndr_send;
3673	result->dispatch_recv = cli_do_rpc_ndr_recv;
3674	result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3675	result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3676
3677	result->desthost = talloc_strdup(result, global_myname());
3678	result->srv_name_slash = talloc_asprintf_strupper_m(
3679		result, "\\\\%s", global_myname());
3680	if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3681		TALLOC_FREE(result);
3682		return NT_STATUS_NO_MEMORY;
3683	}
3684
3685	status = rpc_transport_smbd_init(result, conn, syntax,
3686					 &result->transport);
3687	if (!NT_STATUS_IS_OK(status)) {
3688		DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3689			  nt_errstr(status)));
3690		TALLOC_FREE(result);
3691		return status;
3692	}
3693
3694	status = rpccli_anon_bind_data(result, &auth);
3695	if (!NT_STATUS_IS_OK(status)) {
3696		DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3697			  nt_errstr(status)));
3698		TALLOC_FREE(result);
3699		return status;
3700	}
3701
3702	status = rpc_pipe_bind(result, auth);
3703	if (!NT_STATUS_IS_OK(status)) {
3704		DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3705		TALLOC_FREE(result);
3706		return status;
3707	}
3708
3709	result->transport->transport = NCACN_INTERNAL;
3710
3711	*presult = result;
3712	return NT_STATUS_OK;
3713}
3714
3715/****************************************************************************
3716 Open a pipe to a remote server.
3717 ****************************************************************************/
3718
3719static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3720				  enum dcerpc_transport_t transport,
3721				  const struct ndr_syntax_id *interface,
3722				  struct rpc_pipe_client **presult)
3723{
3724	switch (transport) {
3725	case NCACN_IP_TCP:
3726		return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3727					 presult);
3728	case NCACN_NP:
3729		return rpc_pipe_open_np(cli, interface, presult);
3730	default:
3731		return NT_STATUS_NOT_IMPLEMENTED;
3732	}
3733}
3734
3735/****************************************************************************
3736 Open a named pipe to an SMB server and bind anonymously.
3737 ****************************************************************************/
3738
3739NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3740					    enum dcerpc_transport_t transport,
3741					    const struct ndr_syntax_id *interface,
3742					    struct rpc_pipe_client **presult)
3743{
3744	struct rpc_pipe_client *result;
3745	struct cli_pipe_auth_data *auth;
3746	NTSTATUS status;
3747
3748	status = cli_rpc_pipe_open(cli, transport, interface, &result);
3749	if (!NT_STATUS_IS_OK(status)) {
3750		return status;
3751	}
3752
3753	status = rpccli_anon_bind_data(result, &auth);
3754	if (!NT_STATUS_IS_OK(status)) {
3755		DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3756			  nt_errstr(status)));
3757		TALLOC_FREE(result);
3758		return status;
3759	}
3760
3761	/*
3762	 * This is a bit of an abstraction violation due to the fact that an
3763	 * anonymous bind on an authenticated SMB inherits the user/domain
3764	 * from the enclosing SMB creds
3765	 */
3766
3767	TALLOC_FREE(auth->user_name);
3768	TALLOC_FREE(auth->domain);
3769
3770	auth->user_name = talloc_strdup(auth, cli->user_name);
3771	auth->domain = talloc_strdup(auth, cli->domain);
3772	auth->user_session_key = data_blob_talloc(auth,
3773		cli->user_session_key.data,
3774		cli->user_session_key.length);
3775
3776	if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3777		TALLOC_FREE(result);
3778		return NT_STATUS_NO_MEMORY;
3779	}
3780
3781	status = rpc_pipe_bind(result, auth);
3782	if (!NT_STATUS_IS_OK(status)) {
3783		int lvl = 0;
3784		if (ndr_syntax_id_equal(interface,
3785					&ndr_table_dssetup.syntax_id)) {
3786			/* non AD domains just don't have this pipe, avoid
3787			 * level 0 statement in that case - gd */
3788			lvl = 3;
3789		}
3790		DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3791			    "%s failed with error %s\n",
3792			    get_pipe_name_from_syntax(talloc_tos(), interface),
3793			    nt_errstr(status) ));
3794		TALLOC_FREE(result);
3795		return status;
3796	}
3797
3798	DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3799		  "%s and bound anonymously.\n",
3800		  get_pipe_name_from_syntax(talloc_tos(), interface),
3801		  cli->desthost));
3802
3803	*presult = result;
3804	return NT_STATUS_OK;
3805}
3806
3807/****************************************************************************
3808 ****************************************************************************/
3809
3810NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3811				  const struct ndr_syntax_id *interface,
3812				  struct rpc_pipe_client **presult)
3813{
3814	return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3815						  interface, presult);
3816}
3817
3818/****************************************************************************
3819 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3820 ****************************************************************************/
3821
3822static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3823						   const struct ndr_syntax_id *interface,
3824						   enum dcerpc_transport_t transport,
3825						   enum pipe_auth_type auth_type,
3826						   enum dcerpc_AuthLevel auth_level,
3827						   const char *domain,
3828						   const char *username,
3829						   const char *password,
3830						   struct rpc_pipe_client **presult)
3831{
3832	struct rpc_pipe_client *result;
3833	struct cli_pipe_auth_data *auth;
3834	NTSTATUS status;
3835
3836	status = cli_rpc_pipe_open(cli, transport, interface, &result);
3837	if (!NT_STATUS_IS_OK(status)) {
3838		return status;
3839	}
3840
3841	status = rpccli_ntlmssp_bind_data(
3842		result, auth_type, auth_level, domain, username,
3843		password, &auth);
3844	if (!NT_STATUS_IS_OK(status)) {
3845		DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3846			  nt_errstr(status)));
3847		goto err;
3848	}
3849
3850	status = rpc_pipe_bind(result, auth);
3851	if (!NT_STATUS_IS_OK(status)) {
3852		DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3853			nt_errstr(status) ));
3854		goto err;
3855	}
3856
3857	DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3858		"machine %s and bound NTLMSSP as user %s\\%s.\n",
3859		  get_pipe_name_from_syntax(talloc_tos(), interface),
3860		  cli->desthost, domain, username ));
3861
3862	*presult = result;
3863	return NT_STATUS_OK;
3864
3865  err:
3866
3867	TALLOC_FREE(result);
3868	return status;
3869}
3870
3871/****************************************************************************
3872 External interface.
3873 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3874 ****************************************************************************/
3875
3876NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3877				   const struct ndr_syntax_id *interface,
3878				   enum dcerpc_transport_t transport,
3879				   enum dcerpc_AuthLevel auth_level,
3880				   const char *domain,
3881				   const char *username,
3882				   const char *password,
3883				   struct rpc_pipe_client **presult)
3884{
3885	return cli_rpc_pipe_open_ntlmssp_internal(cli,
3886						interface,
3887						transport,
3888						PIPE_AUTH_TYPE_NTLMSSP,
3889						auth_level,
3890						domain,
3891						username,
3892						password,
3893						presult);
3894}
3895
3896/****************************************************************************
3897 External interface.
3898 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3899 ****************************************************************************/
3900
3901NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3902					  const struct ndr_syntax_id *interface,
3903					  enum dcerpc_transport_t transport,
3904					  enum dcerpc_AuthLevel auth_level,
3905					  const char *domain,
3906					  const char *username,
3907					  const char *password,
3908					  struct rpc_pipe_client **presult)
3909{
3910	return cli_rpc_pipe_open_ntlmssp_internal(cli,
3911						interface,
3912						transport,
3913						PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3914						auth_level,
3915						domain,
3916						username,
3917						password,
3918						presult);
3919}
3920
3921/****************************************************************************
3922  Get a the schannel session key out of an already opened netlogon pipe.
3923 ****************************************************************************/
3924static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3925						struct cli_state *cli,
3926						const char *domain,
3927						uint32 *pneg_flags)
3928{
3929	enum netr_SchannelType sec_chan_type = 0;
3930	unsigned char machine_pwd[16];
3931	const char *machine_account;
3932	NTSTATUS status;
3933
3934	/* Get the machine account credentials from secrets.tdb. */
3935	if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3936			       &sec_chan_type))
3937	{
3938		DEBUG(0, ("get_schannel_session_key: could not fetch "
3939			"trust account password for domain '%s'\n",
3940			domain));
3941		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3942	}
3943
3944	status = rpccli_netlogon_setup_creds(netlogon_pipe,
3945					cli->desthost, /* server name */
3946					domain,	       /* domain */
3947					global_myname(), /* client name */
3948					machine_account, /* machine account name */
3949					machine_pwd,
3950					sec_chan_type,
3951					pneg_flags);
3952
3953	if (!NT_STATUS_IS_OK(status)) {
3954		DEBUG(3, ("get_schannel_session_key_common: "
3955			  "rpccli_netlogon_setup_creds failed with result %s "
3956			  "to server %s, domain %s, machine account %s.\n",
3957			  nt_errstr(status), cli->desthost, domain,
3958			  machine_account ));
3959		return status;
3960	}
3961
3962	if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3963		DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3964			cli->desthost));
3965		return NT_STATUS_INVALID_NETWORK_RESPONSE;
3966	}
3967
3968	return NT_STATUS_OK;;
3969}
3970
3971/****************************************************************************
3972 Open a netlogon pipe and get the schannel session key.
3973 Now exposed to external callers.
3974 ****************************************************************************/
3975
3976
3977NTSTATUS get_schannel_session_key(struct cli_state *cli,
3978				  const char *domain,
3979				  uint32 *pneg_flags,
3980				  struct rpc_pipe_client **presult)
3981{
3982	struct rpc_pipe_client *netlogon_pipe = NULL;
3983	NTSTATUS status;
3984
3985	status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3986					  &netlogon_pipe);
3987	if (!NT_STATUS_IS_OK(status)) {
3988		return status;
3989	}
3990
3991	status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3992						 pneg_flags);
3993	if (!NT_STATUS_IS_OK(status)) {
3994		TALLOC_FREE(netlogon_pipe);
3995		return status;
3996	}
3997
3998	*presult = netlogon_pipe;
3999	return NT_STATUS_OK;
4000}
4001
4002/****************************************************************************
4003 External interface.
4004 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4005 using session_key. sign and seal.
4006
4007 The *pdc will be stolen onto this new pipe
4008 ****************************************************************************/
4009
4010NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4011					     const struct ndr_syntax_id *interface,
4012					     enum dcerpc_transport_t transport,
4013					     enum dcerpc_AuthLevel auth_level,
4014					     const char *domain,
4015					     struct netlogon_creds_CredentialState **pdc,
4016					     struct rpc_pipe_client **presult)
4017{
4018	struct rpc_pipe_client *result;
4019	struct cli_pipe_auth_data *auth;
4020	NTSTATUS status;
4021
4022	status = cli_rpc_pipe_open(cli, transport, interface, &result);
4023	if (!NT_STATUS_IS_OK(status)) {
4024		return status;
4025	}
4026
4027	status = rpccli_schannel_bind_data(result, domain, auth_level,
4028					   *pdc, &auth);
4029	if (!NT_STATUS_IS_OK(status)) {
4030		DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4031			  nt_errstr(status)));
4032		TALLOC_FREE(result);
4033		return status;
4034	}
4035
4036	status = rpc_pipe_bind(result, auth);
4037	if (!NT_STATUS_IS_OK(status)) {
4038		DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4039			  "cli_rpc_pipe_bind failed with error %s\n",
4040			  nt_errstr(status) ));
4041		TALLOC_FREE(result);
4042		return status;
4043	}
4044
4045	/*
4046	 * The credentials on a new netlogon pipe are the ones we are passed
4047	 * in - copy them over
4048	 */
4049	result->dc = netlogon_creds_copy(result, *pdc);
4050	if (result->dc == NULL) {
4051		TALLOC_FREE(result);
4052		return NT_STATUS_NO_MEMORY;
4053	}
4054
4055	DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4056		  "for domain %s and bound using schannel.\n",
4057		  get_pipe_name_from_syntax(talloc_tos(), interface),
4058		  cli->desthost, domain ));
4059
4060	*presult = result;
4061	return NT_STATUS_OK;
4062}
4063
4064/****************************************************************************
4065 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4066 Fetch the session key ourselves using a temporary netlogon pipe. This
4067 version uses an ntlmssp auth bound netlogon pipe to get the key.
4068 ****************************************************************************/
4069
4070static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4071						      const char *domain,
4072						      const char *username,
4073						      const char *password,
4074						      uint32 *pneg_flags,
4075						      struct rpc_pipe_client **presult)
4076{
4077	struct rpc_pipe_client *netlogon_pipe = NULL;
4078	NTSTATUS status;
4079
4080	status = cli_rpc_pipe_open_spnego_ntlmssp(
4081		cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4082		DCERPC_AUTH_LEVEL_PRIVACY,
4083		domain, username, password, &netlogon_pipe);
4084	if (!NT_STATUS_IS_OK(status)) {
4085		return status;
4086	}
4087
4088	status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4089						 pneg_flags);
4090	if (!NT_STATUS_IS_OK(status)) {
4091		TALLOC_FREE(netlogon_pipe);
4092		return status;
4093	}
4094
4095	*presult = netlogon_pipe;
4096	return NT_STATUS_OK;
4097}
4098
4099/****************************************************************************
4100 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4101 Fetch the session key ourselves using a temporary netlogon pipe. This version
4102 uses an ntlmssp bind to get the session key.
4103 ****************************************************************************/
4104
4105NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4106						 const struct ndr_syntax_id *interface,
4107						 enum dcerpc_transport_t transport,
4108						 enum dcerpc_AuthLevel auth_level,
4109						 const char *domain,
4110						 const char *username,
4111						 const char *password,
4112						 struct rpc_pipe_client **presult)
4113{
4114	uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4115	struct rpc_pipe_client *netlogon_pipe = NULL;
4116	struct rpc_pipe_client *result = NULL;
4117	NTSTATUS status;
4118
4119	status = get_schannel_session_key_auth_ntlmssp(
4120		cli, domain, username, password, &neg_flags, &netlogon_pipe);
4121	if (!NT_STATUS_IS_OK(status)) {
4122		DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4123			"key from server %s for domain %s.\n",
4124			cli->desthost, domain ));
4125		return status;
4126	}
4127
4128	status = cli_rpc_pipe_open_schannel_with_key(
4129		cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4130		&result);
4131
4132	/* Now we've bound using the session key we can close the netlog pipe. */
4133	TALLOC_FREE(netlogon_pipe);
4134
4135	if (NT_STATUS_IS_OK(status)) {
4136		*presult = result;
4137	}
4138	return status;
4139}
4140
4141/****************************************************************************
4142 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4143 Fetch the session key ourselves using a temporary netlogon pipe.
4144 ****************************************************************************/
4145
4146NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4147				    const struct ndr_syntax_id *interface,
4148				    enum dcerpc_transport_t transport,
4149				    enum dcerpc_AuthLevel auth_level,
4150				    const char *domain,
4151				    struct rpc_pipe_client **presult)
4152{
4153	uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4154	struct rpc_pipe_client *netlogon_pipe = NULL;
4155	struct rpc_pipe_client *result = NULL;
4156	NTSTATUS status;
4157
4158	status = get_schannel_session_key(cli, domain, &neg_flags,
4159					  &netlogon_pipe);
4160	if (!NT_STATUS_IS_OK(status)) {
4161		DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4162			"key from server %s for domain %s.\n",
4163			cli->desthost, domain ));
4164		return status;
4165	}
4166
4167	status = cli_rpc_pipe_open_schannel_with_key(
4168		cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4169		&result);
4170
4171	/* Now we've bound using the session key we can close the netlog pipe. */
4172	TALLOC_FREE(netlogon_pipe);
4173
4174	if (NT_STATUS_IS_OK(status)) {
4175		*presult = result;
4176	}
4177
4178	return status;
4179}
4180
4181/****************************************************************************
4182 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4183 The idea is this can be called with service_princ, username and password all
4184 NULL so long as the caller has a TGT.
4185 ****************************************************************************/
4186
4187NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4188				const struct ndr_syntax_id *interface,
4189				enum dcerpc_AuthLevel auth_level,
4190				const char *service_princ,
4191				const char *username,
4192				const char *password,
4193				struct rpc_pipe_client **presult)
4194{
4195#ifdef HAVE_KRB5
4196	struct rpc_pipe_client *result;
4197	struct cli_pipe_auth_data *auth;
4198	NTSTATUS status;
4199
4200	status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4201	if (!NT_STATUS_IS_OK(status)) {
4202		return status;
4203	}
4204
4205	status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4206					   username, password, &auth);
4207	if (!NT_STATUS_IS_OK(status)) {
4208		DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4209			  nt_errstr(status)));
4210		TALLOC_FREE(result);
4211		return status;
4212	}
4213
4214	status = rpc_pipe_bind(result, auth);
4215	if (!NT_STATUS_IS_OK(status)) {
4216		DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4217			  "with error %s\n", nt_errstr(status)));
4218		TALLOC_FREE(result);
4219		return status;
4220	}
4221
4222	*presult = result;
4223	return NT_STATUS_OK;
4224#else
4225	DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4226	return NT_STATUS_NOT_IMPLEMENTED;
4227#endif
4228}
4229
4230NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4231			     struct rpc_pipe_client *cli,
4232			     DATA_BLOB *session_key)
4233{
4234	if (!session_key || !cli) {
4235		return NT_STATUS_INVALID_PARAMETER;
4236	}
4237
4238	if (!cli->auth) {
4239		return NT_STATUS_INVALID_PARAMETER;
4240	}
4241
4242	switch (cli->auth->auth_type) {
4243		case PIPE_AUTH_TYPE_SCHANNEL:
4244			*session_key = data_blob_talloc(mem_ctx,
4245				cli->auth->a_u.schannel_auth->creds->session_key, 16);
4246			break;
4247		case PIPE_AUTH_TYPE_NTLMSSP:
4248		case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4249			*session_key = data_blob_talloc(mem_ctx,
4250				cli->auth->a_u.ntlmssp_state->session_key.data,
4251				cli->auth->a_u.ntlmssp_state->session_key.length);
4252			break;
4253		case PIPE_AUTH_TYPE_KRB5:
4254		case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4255			*session_key = data_blob_talloc(mem_ctx,
4256				cli->auth->a_u.kerberos_auth->session_key.data,
4257				cli->auth->a_u.kerberos_auth->session_key.length);
4258			break;
4259		case PIPE_AUTH_TYPE_NONE:
4260			*session_key = data_blob_talloc(mem_ctx,
4261				cli->auth->user_session_key.data,
4262				cli->auth->user_session_key.length);
4263			break;
4264		default:
4265			return NT_STATUS_NO_USER_SESSION_KEY;
4266	}
4267
4268	return NT_STATUS_OK;
4269}
4270