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