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