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