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