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