s3-dcerpc: add dcerpc_push_dcerpc_auth().
[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  ********************************************************************/
1655
1656 static NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1657                                         enum dcerpc_AuthType auth_type,
1658                                         enum dcerpc_AuthLevel auth_level,
1659                                         uint8_t auth_pad_length,
1660                                         uint32_t auth_context_id,
1661                                         const DATA_BLOB *credentials,
1662                                         DATA_BLOB *blob)
1663 {
1664         struct dcerpc_auth r;
1665         enum ndr_err_code ndr_err;
1666
1667         r.auth_type             = auth_type;
1668         r.auth_level            = auth_level;
1669         r.auth_pad_length       = auth_pad_length;
1670         r.auth_reserved         = 0;
1671         r.auth_context_id       = auth_context_id;
1672         r.credentials           = *credentials;
1673
1674         ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1675                 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1676         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1677                 return ndr_map_error2ntstatus(ndr_err);
1678         }
1679
1680         if (DEBUGLEVEL >= 10) {
1681                 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1682         }
1683
1684         return NT_STATUS_OK;
1685 }
1686
1687 /*******************************************************************
1688  Creates krb5 auth bind.
1689  ********************************************************************/
1690
1691 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1692                                                 enum dcerpc_AuthLevel auth_level,
1693                                                 RPC_HDR_AUTH *pauth_out,
1694                                                 prs_struct *auth_data)
1695 {
1696 #ifdef HAVE_KRB5
1697         int ret;
1698         struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1699         DATA_BLOB tkt = data_blob_null;
1700         DATA_BLOB tkt_wrapped = data_blob_null;
1701
1702         /* We may change the pad length before marshalling. */
1703         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1704
1705         DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1706                 a->service_principal ));
1707
1708         /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1709
1710         ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1711                         &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1712
1713         if (ret) {
1714                 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1715                         "failed with %s\n",
1716                         a->service_principal,
1717                         error_message(ret) ));
1718
1719                 data_blob_free(&tkt);
1720                 return NT_STATUS_INVALID_PARAMETER;
1721         }
1722
1723         /* wrap that up in a nice GSS-API wrapping */
1724         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1725
1726         data_blob_free(&tkt);
1727
1728         /* Auth len in the rpc header doesn't include auth_header. */
1729         if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1730                 data_blob_free(&tkt_wrapped);
1731                 return NT_STATUS_NO_MEMORY;
1732         }
1733
1734         DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1735         dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1736
1737         data_blob_free(&tkt_wrapped);
1738         return NT_STATUS_OK;
1739 #else
1740         return NT_STATUS_INVALID_PARAMETER;
1741 #endif
1742 }
1743
1744 /*******************************************************************
1745  Creates SPNEGO NTLMSSP auth bind.
1746  ********************************************************************/
1747
1748 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1749                                                 enum dcerpc_AuthLevel auth_level,
1750                                                 RPC_HDR_AUTH *pauth_out,
1751                                                 prs_struct *auth_data)
1752 {
1753         NTSTATUS nt_status;
1754         DATA_BLOB null_blob = data_blob_null;
1755         DATA_BLOB request = data_blob_null;
1756         DATA_BLOB spnego_msg = data_blob_null;
1757
1758         /* We may change the pad length before marshalling. */
1759         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1760
1761         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1762         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1763                                         null_blob,
1764                                         &request);
1765
1766         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1767                 data_blob_free(&request);
1768                 return nt_status;
1769         }
1770
1771         /* Wrap this in SPNEGO. */
1772         spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1773
1774         data_blob_free(&request);
1775
1776         /* Auth len in the rpc header doesn't include auth_header. */
1777         if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1778                 data_blob_free(&spnego_msg);
1779                 return NT_STATUS_NO_MEMORY;
1780         }
1781
1782         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1783         dump_data(5, spnego_msg.data, spnego_msg.length);
1784
1785         data_blob_free(&spnego_msg);
1786         return NT_STATUS_OK;
1787 }
1788
1789 /*******************************************************************
1790  Creates NTLMSSP auth bind.
1791  ********************************************************************/
1792
1793 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1794                                                 enum dcerpc_AuthLevel auth_level,
1795                                                 RPC_HDR_AUTH *pauth_out,
1796                                                 prs_struct *auth_data)
1797 {
1798         NTSTATUS nt_status;
1799         DATA_BLOB null_blob = data_blob_null;
1800         DATA_BLOB request = data_blob_null;
1801
1802         /* We may change the pad length before marshalling. */
1803         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1804
1805         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1806         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1807                                         null_blob,
1808                                         &request);
1809
1810         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1811                 data_blob_free(&request);
1812                 return nt_status;
1813         }
1814
1815         /* Auth len in the rpc header doesn't include auth_header. */
1816         if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1817                 data_blob_free(&request);
1818                 return NT_STATUS_NO_MEMORY;
1819         }
1820
1821         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1822         dump_data(5, request.data, request.length);
1823
1824         data_blob_free(&request);
1825         return NT_STATUS_OK;
1826 }
1827
1828 /*******************************************************************
1829  Creates schannel auth bind.
1830  ********************************************************************/
1831
1832 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1833                                                 enum dcerpc_AuthLevel auth_level,
1834                                                 RPC_HDR_AUTH *pauth_out,
1835                                                 prs_struct *auth_data)
1836 {
1837         struct NL_AUTH_MESSAGE r;
1838         enum ndr_err_code ndr_err;
1839         DATA_BLOB blob;
1840
1841         /* We may change the pad length before marshalling. */
1842         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1843
1844         /* Use lp_workgroup() if domain not specified */
1845
1846         if (!cli->auth->domain || !cli->auth->domain[0]) {
1847                 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1848                 if (cli->auth->domain == NULL) {
1849                         return NT_STATUS_NO_MEMORY;
1850                 }
1851         }
1852
1853         /*
1854          * Now marshall the data into the auth parse_struct.
1855          */
1856
1857         r.MessageType                   = NL_NEGOTIATE_REQUEST;
1858         r.Flags                         = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1859                                           NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1860         r.oem_netbios_domain.a          = cli->auth->domain;
1861         r.oem_netbios_computer.a        = global_myname();
1862
1863         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &r,
1864                        (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1865         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1866                 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1867                 return ndr_map_error2ntstatus(ndr_err);
1868         }
1869
1870         if (DEBUGLEVEL >= 10) {
1871                 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1872         }
1873
1874         if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1875         {
1876                 return NT_STATUS_NO_MEMORY;
1877         }
1878
1879         return NT_STATUS_OK;
1880 }
1881
1882 /*******************************************************************
1883  ********************************************************************/
1884
1885 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1886                                      const struct ndr_syntax_id *abstract_syntax,
1887                                      const struct ndr_syntax_id *transfer_syntax,
1888                                      struct dcerpc_ctx_list **ctx_list_p)
1889 {
1890         struct dcerpc_ctx_list *ctx_list;
1891
1892         ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1893         NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1894
1895         ctx_list[0].context_id                  = 0;
1896         ctx_list[0].num_transfer_syntaxes       = 1;
1897         ctx_list[0].abstract_syntax             = *abstract_syntax;
1898         ctx_list[0].transfer_syntaxes           = talloc_array(ctx_list,
1899                                                                struct ndr_syntax_id,
1900                                                                ctx_list[0].num_transfer_syntaxes);
1901         NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
1902         ctx_list[0].transfer_syntaxes[0]        = *transfer_syntax;
1903
1904         *ctx_list_p = ctx_list;
1905
1906         return NT_STATUS_OK;
1907 }
1908
1909 /*******************************************************************
1910  Creates the internals of a DCE/RPC bind request or alter context PDU.
1911  ********************************************************************/
1912
1913 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
1914                                                 prs_struct *rpc_out, 
1915                                                 uint32 rpc_call_id,
1916                                                 const struct ndr_syntax_id *abstract,
1917                                                 const struct ndr_syntax_id *transfer,
1918                                                 RPC_HDR_AUTH *phdr_auth,
1919                                                 prs_struct *pauth_info)
1920 {
1921         uint16 auth_len = prs_offset(pauth_info);
1922         uint8 ss_padding_len = 0;
1923         uint16 frag_len = 0;
1924         NTSTATUS status;
1925         union dcerpc_payload u;
1926         DATA_BLOB blob;
1927         struct dcerpc_ctx_list *ctx_list;
1928
1929         status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
1930                                       &ctx_list);
1931         if (!NT_STATUS_IS_OK(status)) {
1932                 return status;
1933         }
1934
1935         u.bind.max_xmit_frag    = RPC_MAX_PDU_FRAG_LEN;
1936         u.bind.max_recv_frag    = RPC_MAX_PDU_FRAG_LEN;
1937         u.bind.assoc_group_id   = 0x0;
1938         u.bind.num_contexts     = 1;
1939         u.bind.ctx_list         = ctx_list;
1940         u.bind.auth_info        = data_blob_null;
1941
1942         /* Start building the frag length. */
1943         frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind);
1944
1945         /* Do we need to pad ? */
1946         if (auth_len) {
1947                 uint16_t data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind);
1948                 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1949                         ss_padding_len = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1950                         phdr_auth->auth_pad_len = ss_padding_len;
1951                 }
1952                 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1953         }
1954
1955         status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
1956                                           ptype,
1957                                           DCERPC_PFC_FLAG_FIRST |
1958                                           DCERPC_PFC_FLAG_LAST,
1959                                           frag_len,
1960                                           auth_len,
1961                                           rpc_call_id,
1962                                           u,
1963                                           &blob);
1964         if (!NT_STATUS_IS_OK(status)) {
1965                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1966                 return status;
1967         }
1968
1969         if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
1970                 return NT_STATUS_NO_MEMORY;
1971         }
1972
1973         /*
1974          * Grow the outgoing buffer to store any auth info.
1975          */
1976
1977         if(auth_len != 0) {
1978                 if (ss_padding_len) {
1979                         char pad[CLIENT_NDR_PADDING_SIZE];
1980                         memset(pad, '\0', CLIENT_NDR_PADDING_SIZE);
1981                         if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1982                                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1983                                 return NT_STATUS_NO_MEMORY;
1984                         }
1985                 }
1986
1987                 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1988                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1989                         return NT_STATUS_NO_MEMORY;
1990                 }
1991
1992
1993                 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1994                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1995                         return NT_STATUS_NO_MEMORY;
1996                 }
1997         }
1998
1999         return NT_STATUS_OK;
2000 }
2001
2002 /*******************************************************************
2003  Creates a DCE/RPC bind request.
2004  ********************************************************************/
2005
2006 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2007                                 prs_struct *rpc_out, 
2008                                 uint32 rpc_call_id,
2009                                 const struct ndr_syntax_id *abstract,
2010                                 const struct ndr_syntax_id *transfer,
2011                                 enum pipe_auth_type auth_type,
2012                                 enum dcerpc_AuthLevel auth_level)
2013 {
2014         RPC_HDR_AUTH hdr_auth;
2015         prs_struct auth_info;
2016         NTSTATUS ret = NT_STATUS_OK;
2017
2018         ZERO_STRUCT(hdr_auth);
2019         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2020                 return NT_STATUS_NO_MEMORY;
2021
2022         switch (auth_type) {
2023                 case PIPE_AUTH_TYPE_SCHANNEL:
2024                         ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2025                         if (!NT_STATUS_IS_OK(ret)) {
2026                                 return ret;
2027                         }
2028                         break;
2029
2030                 case PIPE_AUTH_TYPE_NTLMSSP:
2031                         ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2032                         if (!NT_STATUS_IS_OK(ret)) {
2033                                 return ret;
2034                         }
2035                         break;
2036
2037                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2038                         ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2039                         if (!NT_STATUS_IS_OK(ret)) {
2040                                 return ret;
2041                         }
2042                         break;
2043
2044                 case PIPE_AUTH_TYPE_KRB5:
2045                         ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2046                         if (!NT_STATUS_IS_OK(ret)) {
2047                                 return ret;
2048                         }
2049                         break;
2050
2051                 case PIPE_AUTH_TYPE_NONE:
2052                         break;
2053
2054                 default:
2055                         /* "Can't" happen. */
2056                         return NT_STATUS_INVALID_INFO_CLASS;
2057         }
2058
2059         ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2060                                                 rpc_out, 
2061                                                 rpc_call_id,
2062                                                 abstract,
2063                                                 transfer,
2064                                                 &hdr_auth,
2065                                                 &auth_info);
2066
2067         return ret;
2068 }
2069
2070 /*******************************************************************
2071  Create and add the NTLMSSP sign/seal auth header and data.
2072  ********************************************************************/
2073
2074 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2075                                         RPC_HDR *phdr,
2076                                         uint32 ss_padding_len,
2077                                         prs_struct *outgoing_pdu)
2078 {
2079         RPC_HDR_AUTH auth_info;
2080         NTSTATUS status;
2081         DATA_BLOB auth_blob = data_blob_null;
2082         uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2083         TALLOC_CTX *frame;
2084
2085         if (!cli->auth->a_u.ntlmssp_state) {
2086                 return NT_STATUS_INVALID_PARAMETER;
2087         }
2088
2089         frame = talloc_stackframe();
2090
2091         /* Init and marshall the auth header. */
2092         init_rpc_hdr_auth(&auth_info,
2093                         map_pipe_auth_type_to_rpc_auth_type(
2094                                 cli->auth->auth_type),
2095                         cli->auth->auth_level,
2096                         ss_padding_len,
2097                         1 /* context id. */);
2098
2099         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2100                 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2101                 talloc_free(frame);
2102                 return NT_STATUS_NO_MEMORY;
2103         }
2104
2105         switch (cli->auth->auth_level) {
2106                 case DCERPC_AUTH_LEVEL_PRIVACY:
2107                         /* Data portion is encrypted. */
2108                         status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2109                                                      frame,
2110                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2111                                         data_and_pad_len,
2112                                         (unsigned char *)prs_data_p(outgoing_pdu),
2113                                         (size_t)prs_offset(outgoing_pdu),
2114                                         &auth_blob);
2115                         if (!NT_STATUS_IS_OK(status)) {
2116                                 talloc_free(frame);
2117                                 return status;
2118                         }
2119                         break;
2120
2121                 case DCERPC_AUTH_LEVEL_INTEGRITY:
2122                         /* Data is signed. */
2123                         status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2124                                                      frame,
2125                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2126                                         data_and_pad_len,
2127                                         (unsigned char *)prs_data_p(outgoing_pdu),
2128                                         (size_t)prs_offset(outgoing_pdu),
2129                                         &auth_blob);
2130                         if (!NT_STATUS_IS_OK(status)) {
2131                                 talloc_free(frame);
2132                                 return status;
2133                         }
2134                         break;
2135
2136                 default:
2137                         /* Can't happen. */
2138                         smb_panic("bad auth level");
2139                         /* Notreached. */
2140                         return NT_STATUS_INVALID_PARAMETER;
2141         }
2142
2143         /* Finally marshall the blob. */
2144
2145         if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2146                 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2147                         (unsigned int)NTLMSSP_SIG_SIZE));
2148                 talloc_free(frame);
2149                 return NT_STATUS_NO_MEMORY;
2150         }
2151
2152         talloc_free(frame);
2153         return NT_STATUS_OK;
2154 }
2155
2156 /*******************************************************************
2157  Create and add the schannel sign/seal auth header and data.
2158  ********************************************************************/
2159
2160 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2161                                         RPC_HDR *phdr,
2162                                         uint32 ss_padding_len,
2163                                         prs_struct *outgoing_pdu)
2164 {
2165         RPC_HDR_AUTH auth_info;
2166         struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2167         char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2168         size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2169         DATA_BLOB blob;
2170         NTSTATUS status;
2171
2172         if (!sas) {
2173                 return NT_STATUS_INVALID_PARAMETER;
2174         }
2175
2176         /* Init and marshall the auth header. */
2177         init_rpc_hdr_auth(&auth_info,
2178                         map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2179                         cli->auth->auth_level,
2180                         ss_padding_len,
2181                         1 /* context id. */);
2182
2183         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2184                 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2185                 return NT_STATUS_NO_MEMORY;
2186         }
2187
2188         DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2189                         sas->seq_num));
2190
2191         switch (cli->auth->auth_level) {
2192         case DCERPC_AUTH_LEVEL_PRIVACY:
2193                 status = netsec_outgoing_packet(sas,
2194                                                 talloc_tos(),
2195                                                 true,
2196                                                 (uint8_t *)data_p,
2197                                                 data_and_pad_len,
2198                                                 &blob);
2199                 break;
2200         case DCERPC_AUTH_LEVEL_INTEGRITY:
2201                 status = netsec_outgoing_packet(sas,
2202                                                 talloc_tos(),
2203                                                 false,
2204                                                 (uint8_t *)data_p,
2205                                                 data_and_pad_len,
2206                                                 &blob);
2207                 break;
2208         default:
2209                 status = NT_STATUS_INTERNAL_ERROR;
2210                 break;
2211         }
2212
2213         if (!NT_STATUS_IS_OK(status)) {
2214                 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2215                         nt_errstr(status)));
2216                 return status;
2217         }
2218
2219         if (DEBUGLEVEL >= 10) {
2220                 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2221         }
2222
2223         /* Finally marshall the blob. */
2224         if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2225                 return NT_STATUS_NO_MEMORY;
2226         }
2227
2228         return NT_STATUS_OK;
2229 }
2230
2231 /*******************************************************************
2232  Calculate how much data we're going to send in this packet, also
2233  work out any sign/seal padding length.
2234  ********************************************************************/
2235
2236 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2237                                         uint32 data_left,
2238                                         uint16 *p_frag_len,
2239                                         uint16 *p_auth_len,
2240                                         uint32 *p_ss_padding)
2241 {
2242         uint32 data_space, data_len;
2243
2244 #if 0
2245         if ((data_left > 0) && (sys_random() % 2)) {
2246                 data_left = MAX(data_left/2, 1);
2247         }
2248 #endif
2249
2250         switch (cli->auth->auth_level) {
2251                 case DCERPC_AUTH_LEVEL_NONE:
2252                 case DCERPC_AUTH_LEVEL_CONNECT:
2253                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2254                         data_len = MIN(data_space, data_left);
2255                         *p_ss_padding = 0;
2256                         *p_auth_len = 0;
2257                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2258                         return data_len;
2259
2260                 case DCERPC_AUTH_LEVEL_INTEGRITY:
2261                 case DCERPC_AUTH_LEVEL_PRIVACY:
2262                         /* Treat the same for all authenticated rpc requests. */
2263                         switch(cli->auth->auth_type) {
2264                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2265                                 case PIPE_AUTH_TYPE_NTLMSSP:
2266                                         *p_auth_len = NTLMSSP_SIG_SIZE;
2267                                         break;
2268                                 case PIPE_AUTH_TYPE_SCHANNEL:
2269                                         *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2270                                         break;
2271                                 default:
2272                                         smb_panic("bad auth type");
2273                                         break;
2274                         }
2275
2276                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2277                                                 RPC_HDR_AUTH_LEN - *p_auth_len;
2278
2279                         data_len = MIN(data_space, data_left);
2280                         *p_ss_padding = 0;
2281                         if (data_len % CLIENT_NDR_PADDING_SIZE) {
2282                                 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2283                         }
2284                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN +                /* Normal headers. */
2285                                         data_len + *p_ss_padding +              /* data plus padding. */
2286                                         RPC_HDR_AUTH_LEN + *p_auth_len;         /* Auth header and auth data. */
2287                         return data_len;
2288
2289                 default:
2290                         smb_panic("bad auth level");
2291                         /* Notreached. */
2292                         return 0;
2293         }
2294 }
2295
2296 /*******************************************************************
2297  External interface.
2298  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2299  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2300  and deals with signing/sealing details.
2301  ********************************************************************/
2302
2303 struct rpc_api_pipe_req_state {
2304         struct event_context *ev;
2305         struct rpc_pipe_client *cli;
2306         uint8_t op_num;
2307         uint32_t call_id;
2308         prs_struct *req_data;
2309         uint32_t req_data_sent;
2310         prs_struct outgoing_frag;
2311         prs_struct reply_pdu;
2312 };
2313
2314 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2315 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2316 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2317                                   bool *is_last_frag);
2318
2319 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2320                                          struct event_context *ev,
2321                                          struct rpc_pipe_client *cli,
2322                                          uint8_t op_num,
2323                                          prs_struct *req_data)
2324 {
2325         struct tevent_req *req, *subreq;
2326         struct rpc_api_pipe_req_state *state;
2327         NTSTATUS status;
2328         bool is_last_frag;
2329
2330         req = tevent_req_create(mem_ctx, &state,
2331                                 struct rpc_api_pipe_req_state);
2332         if (req == NULL) {
2333                 return NULL;
2334         }
2335         state->ev = ev;
2336         state->cli = cli;
2337         state->op_num = op_num;
2338         state->req_data = req_data;
2339         state->req_data_sent = 0;
2340         state->call_id = get_rpc_call_id();
2341
2342         if (cli->max_xmit_frag
2343             < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2344                 /* Server is screwed up ! */
2345                 status = NT_STATUS_INVALID_PARAMETER;
2346                 goto post_status;
2347         }
2348
2349         prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2350
2351         if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2352                       state, MARSHALL)) {
2353                 goto fail;
2354         }
2355
2356         status = prepare_next_frag(state, &is_last_frag);
2357         if (!NT_STATUS_IS_OK(status)) {
2358                 goto post_status;
2359         }
2360
2361         if (is_last_frag) {
2362                 subreq = rpc_api_pipe_send(state, ev, state->cli,
2363                                            &state->outgoing_frag,
2364                                            DCERPC_PKT_RESPONSE);
2365                 if (subreq == NULL) {
2366                         goto fail;
2367                 }
2368                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2369         } else {
2370                 subreq = rpc_write_send(
2371                         state, ev, cli->transport,
2372                         (uint8_t *)prs_data_p(&state->outgoing_frag),
2373                         prs_offset(&state->outgoing_frag));
2374                 if (subreq == NULL) {
2375                         goto fail;
2376                 }
2377                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2378                                         req);
2379         }
2380         return req;
2381
2382  post_status:
2383         tevent_req_nterror(req, status);
2384         return tevent_req_post(req, ev);
2385  fail:
2386         TALLOC_FREE(req);
2387         return NULL;
2388 }
2389
2390 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2391                                   bool *is_last_frag)
2392 {
2393         RPC_HDR hdr;
2394         RPC_HDR_REQ hdr_req;
2395         uint32_t data_sent_thistime;
2396         uint16_t auth_len;
2397         uint16_t frag_len;
2398         uint8_t flags = 0;
2399         uint32_t ss_padding;
2400         uint32_t data_left;
2401         char pad[8] = { 0, };
2402         NTSTATUS status;
2403
2404         data_left = prs_offset(state->req_data) - state->req_data_sent;
2405
2406         data_sent_thistime = calculate_data_len_tosend(
2407                 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2408
2409         if (state->req_data_sent == 0) {
2410                 flags = DCERPC_PFC_FLAG_FIRST;
2411         }
2412
2413         if (data_sent_thistime == data_left) {
2414                 flags |= DCERPC_PFC_FLAG_LAST;
2415         }
2416
2417         if (!prs_set_offset(&state->outgoing_frag, 0)) {
2418                 return NT_STATUS_NO_MEMORY;
2419         }
2420
2421         /* Create and marshall the header and request header. */
2422         init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2423                      auth_len);
2424
2425         if (!smb_io_rpc_hdr("hdr    ", &hdr, &state->outgoing_frag, 0)) {
2426                 return NT_STATUS_NO_MEMORY;
2427         }
2428
2429         /* Create the rpc request RPC_HDR_REQ */
2430         init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2431                          state->op_num);
2432
2433         if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2434                                 &state->outgoing_frag, 0)) {
2435                 return NT_STATUS_NO_MEMORY;
2436         }
2437
2438         /* Copy in the data, plus any ss padding. */
2439         if (!prs_append_some_prs_data(&state->outgoing_frag,
2440                                       state->req_data, state->req_data_sent,
2441                                       data_sent_thistime)) {
2442                 return NT_STATUS_NO_MEMORY;
2443         }
2444
2445         /* Copy the sign/seal padding data. */
2446         if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2447                 return NT_STATUS_NO_MEMORY;
2448         }
2449
2450         /* Generate any auth sign/seal and add the auth footer. */
2451         switch (state->cli->auth->auth_type) {
2452         case PIPE_AUTH_TYPE_NONE:
2453                 status = NT_STATUS_OK;
2454                 break;
2455         case PIPE_AUTH_TYPE_NTLMSSP:
2456         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2457                 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2458                                                  &state->outgoing_frag);
2459                 break;
2460         case PIPE_AUTH_TYPE_SCHANNEL:
2461                 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2462                                                   &state->outgoing_frag);
2463                 break;
2464         default:
2465                 status = NT_STATUS_INVALID_PARAMETER;
2466                 break;
2467         }
2468
2469         state->req_data_sent += data_sent_thistime;
2470         *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2471
2472         return status;
2473 }
2474
2475 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2476 {
2477         struct tevent_req *req = tevent_req_callback_data(
2478                 subreq, struct tevent_req);
2479         struct rpc_api_pipe_req_state *state = tevent_req_data(
2480                 req, struct rpc_api_pipe_req_state);
2481         NTSTATUS status;
2482         bool is_last_frag;
2483
2484         status = rpc_write_recv(subreq);
2485         TALLOC_FREE(subreq);
2486         if (!NT_STATUS_IS_OK(status)) {
2487                 tevent_req_nterror(req, status);
2488                 return;
2489         }
2490
2491         status = prepare_next_frag(state, &is_last_frag);
2492         if (!NT_STATUS_IS_OK(status)) {
2493                 tevent_req_nterror(req, status);
2494                 return;
2495         }
2496
2497         if (is_last_frag) {
2498                 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2499                                            &state->outgoing_frag,
2500                                            DCERPC_PKT_RESPONSE);
2501                 if (tevent_req_nomem(subreq, req)) {
2502                         return;
2503                 }
2504                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2505         } else {
2506                 subreq = rpc_write_send(
2507                         state, state->ev,
2508                         state->cli->transport,
2509                         (uint8_t *)prs_data_p(&state->outgoing_frag),
2510                         prs_offset(&state->outgoing_frag));
2511                 if (tevent_req_nomem(subreq, req)) {
2512                         return;
2513                 }
2514                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2515                                         req);
2516         }
2517 }
2518
2519 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2520 {
2521         struct tevent_req *req = tevent_req_callback_data(
2522                 subreq, struct tevent_req);
2523         struct rpc_api_pipe_req_state *state = tevent_req_data(
2524                 req, struct rpc_api_pipe_req_state);
2525         NTSTATUS status;
2526
2527         status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2528         TALLOC_FREE(subreq);
2529         if (!NT_STATUS_IS_OK(status)) {
2530                 tevent_req_nterror(req, status);
2531                 return;
2532         }
2533         tevent_req_done(req);
2534 }
2535
2536 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2537                                prs_struct *reply_pdu)
2538 {
2539         struct rpc_api_pipe_req_state *state = tevent_req_data(
2540                 req, struct rpc_api_pipe_req_state);
2541         NTSTATUS status;
2542
2543         if (tevent_req_is_nterror(req, &status)) {
2544                 /*
2545                  * We always have to initialize to reply pdu, even if there is
2546                  * none. The rpccli_* caller routines expect this.
2547                  */
2548                 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2549                 return status;
2550         }
2551
2552         *reply_pdu = state->reply_pdu;
2553         reply_pdu->mem_ctx = mem_ctx;
2554
2555         /*
2556          * Prevent state->req_pdu from being freed
2557          * when state is freed.
2558          */
2559         talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2560         prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2561
2562         return NT_STATUS_OK;
2563 }
2564
2565 #if 0
2566 /****************************************************************************
2567  Set the handle state.
2568 ****************************************************************************/
2569
2570 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2571                                    const char *pipe_name, uint16 device_state)
2572 {
2573         bool state_set = False;
2574         char param[2];
2575         uint16 setup[2]; /* only need 2 uint16 setup parameters */
2576         char *rparam = NULL;
2577         char *rdata = NULL;
2578         uint32 rparam_len, rdata_len;
2579
2580         if (pipe_name == NULL)
2581                 return False;
2582
2583         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2584                  cli->fnum, pipe_name, device_state));
2585
2586         /* create parameters: device state */
2587         SSVAL(param, 0, device_state);
2588
2589         /* create setup parameters. */
2590         setup[0] = 0x0001; 
2591         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
2592
2593         /* send the data on \PIPE\ */
2594         if (cli_api_pipe(cli->cli, "\\PIPE\\",
2595                     setup, 2, 0,                /* setup, length, max */
2596                     param, 2, 0,                /* param, length, max */
2597                     NULL, 0, 1024,              /* data, length, max */
2598                     &rparam, &rparam_len,        /* return param, length */
2599                     &rdata, &rdata_len))         /* return data, length */
2600         {
2601                 DEBUG(5, ("Set Handle state: return OK\n"));
2602                 state_set = True;
2603         }
2604
2605         SAFE_FREE(rparam);
2606         SAFE_FREE(rdata);
2607
2608         return state_set;
2609 }
2610 #endif
2611
2612 /****************************************************************************
2613  Check the rpc bind acknowledge response.
2614 ****************************************************************************/
2615
2616 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2617                                 const struct ndr_syntax_id *transfer)
2618 {
2619         if ( hdr_ba->addr.len == 0) {
2620                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2621         }
2622
2623         /* check the transfer syntax */
2624         if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2625              (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2626                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2627                 return False;
2628         }
2629
2630         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2631                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2632                           hdr_ba->res.num_results, hdr_ba->res.reason));
2633         }
2634
2635         DEBUG(5,("check_bind_response: accepted!\n"));
2636         return True;
2637 }
2638
2639 /*******************************************************************
2640  Creates a DCE/RPC bind authentication response.
2641  This is the packet that is sent back to the server once we
2642  have received a BIND-ACK, to finish the third leg of
2643  the authentication handshake.
2644  ********************************************************************/
2645
2646 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2647                                 uint32 rpc_call_id,
2648                                 enum pipe_auth_type auth_type,
2649                                 enum dcerpc_AuthLevel auth_level,
2650                                 DATA_BLOB *pauth_blob,
2651                                 prs_struct *rpc_out)
2652 {
2653         RPC_HDR hdr;
2654         RPC_HDR_AUTH hdr_auth;
2655         uint32 pad = 0;
2656
2657         /* Create the request RPC_HDR */
2658         init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2659                      RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2660                      pauth_blob->length );
2661
2662         /* Marshall it. */
2663         if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2664                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2665                 return NT_STATUS_NO_MEMORY;
2666         }
2667
2668         /*
2669                 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2670                 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2671         */
2672
2673         /* 4 bytes padding. */
2674         if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2675                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2676                 return NT_STATUS_NO_MEMORY;
2677         }
2678
2679         /* Create the request RPC_HDR_AUTHA */
2680         init_rpc_hdr_auth(&hdr_auth,
2681                         map_pipe_auth_type_to_rpc_auth_type(auth_type),
2682                         auth_level, 0, 1);
2683
2684         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2685                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2686                 return NT_STATUS_NO_MEMORY;
2687         }
2688
2689         /*
2690          * Append the auth data to the outgoing buffer.
2691          */
2692
2693         if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2694                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2695                 return NT_STATUS_NO_MEMORY;
2696         }
2697
2698         return NT_STATUS_OK;
2699 }
2700
2701 /*******************************************************************
2702  Creates a DCE/RPC bind alter context authentication request which
2703  may contain a spnego auth blobl
2704  ********************************************************************/
2705
2706 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2707                                         const struct ndr_syntax_id *abstract,
2708                                         const struct ndr_syntax_id *transfer,
2709                                         enum dcerpc_AuthLevel auth_level,
2710                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2711                                         prs_struct *rpc_out)
2712 {
2713         RPC_HDR_AUTH hdr_auth;
2714         prs_struct auth_info;
2715         NTSTATUS ret = NT_STATUS_OK;
2716
2717         ZERO_STRUCT(hdr_auth);
2718         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2719                 return NT_STATUS_NO_MEMORY;
2720
2721         /* We may change the pad length before marshalling. */
2722         init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2723
2724         if (pauth_blob->length) {
2725                 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2726                         return NT_STATUS_NO_MEMORY;
2727                 }
2728         }
2729
2730         ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2731                                                 rpc_out, 
2732                                                 rpc_call_id,
2733                                                 abstract,
2734                                                 transfer,
2735                                                 &hdr_auth,
2736                                                 &auth_info);
2737         return ret;
2738 }
2739
2740 /****************************************************************************
2741  Do an rpc bind.
2742 ****************************************************************************/
2743
2744 struct rpc_pipe_bind_state {
2745         struct event_context *ev;
2746         struct rpc_pipe_client *cli;
2747         prs_struct rpc_out;
2748         uint32_t rpc_call_id;
2749 };
2750
2751 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2752 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2753                                            struct rpc_pipe_bind_state *state,
2754                                            struct rpc_hdr_info *phdr,
2755                                            prs_struct *reply_pdu);
2756 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2757 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2758                                                     struct rpc_pipe_bind_state *state,
2759                                                     struct rpc_hdr_info *phdr,
2760                                                     prs_struct *reply_pdu);
2761 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2762
2763 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2764                                       struct event_context *ev,
2765                                       struct rpc_pipe_client *cli,
2766                                       struct cli_pipe_auth_data *auth)
2767 {
2768         struct tevent_req *req, *subreq;
2769         struct rpc_pipe_bind_state *state;
2770         NTSTATUS status;
2771
2772         req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2773         if (req == NULL) {
2774                 return NULL;
2775         }
2776
2777         DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2778                 rpccli_pipe_txt(talloc_tos(), cli),
2779                 (unsigned int)auth->auth_type,
2780                 (unsigned int)auth->auth_level ));
2781
2782         state->ev = ev;
2783         state->cli = cli;
2784         state->rpc_call_id = get_rpc_call_id();
2785
2786         prs_init_empty(&state->rpc_out, state, MARSHALL);
2787
2788         cli->auth = talloc_move(cli, &auth);
2789
2790         /* Marshall the outgoing data. */
2791         status = create_rpc_bind_req(cli, &state->rpc_out,
2792                                      state->rpc_call_id,
2793                                      &cli->abstract_syntax,
2794                                      &cli->transfer_syntax,
2795                                      cli->auth->auth_type,
2796                                      cli->auth->auth_level);
2797
2798         if (!NT_STATUS_IS_OK(status)) {
2799                 goto post_status;
2800         }
2801
2802         subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2803                                    DCERPC_PKT_BIND_ACK);
2804         if (subreq == NULL) {
2805                 goto fail;
2806         }
2807         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2808         return req;
2809
2810  post_status:
2811         tevent_req_nterror(req, status);
2812         return tevent_req_post(req, ev);
2813  fail:
2814         TALLOC_FREE(req);
2815         return NULL;
2816 }
2817
2818 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2819 {
2820         struct tevent_req *req = tevent_req_callback_data(
2821                 subreq, struct tevent_req);
2822         struct rpc_pipe_bind_state *state = tevent_req_data(
2823                 req, struct rpc_pipe_bind_state);
2824         prs_struct reply_pdu;
2825         struct rpc_hdr_info hdr;
2826         struct rpc_hdr_ba_info hdr_ba;
2827         NTSTATUS status;
2828
2829         status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2830         TALLOC_FREE(subreq);
2831         if (!NT_STATUS_IS_OK(status)) {
2832                 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2833                           rpccli_pipe_txt(talloc_tos(), state->cli),
2834                           nt_errstr(status)));
2835                 tevent_req_nterror(req, status);
2836                 return;
2837         }
2838
2839         /* Unmarshall the RPC header */
2840         if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2841                 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2842                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2843                 return;
2844         }
2845
2846         if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2847                 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2848                           "RPC_HDR_BA.\n"));
2849                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2850                 return;
2851         }
2852
2853         if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2854                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2855                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2856                 return;
2857         }
2858
2859         state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2860         state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2861
2862         /*
2863          * For authenticated binds we may need to do 3 or 4 leg binds.
2864          */
2865
2866         switch(state->cli->auth->auth_type) {
2867
2868         case PIPE_AUTH_TYPE_NONE:
2869         case PIPE_AUTH_TYPE_SCHANNEL:
2870                 /* Bind complete. */
2871                 tevent_req_done(req);
2872                 break;
2873
2874         case PIPE_AUTH_TYPE_NTLMSSP:
2875                 /* Need to send AUTH3 packet - no reply. */
2876                 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2877                                                     &reply_pdu);
2878                 if (!NT_STATUS_IS_OK(status)) {
2879                         tevent_req_nterror(req, status);
2880                 }
2881                 break;
2882
2883         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2884                 /* Need to send alter context request and reply. */
2885                 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2886                                                              &reply_pdu);
2887                 if (!NT_STATUS_IS_OK(status)) {
2888                         tevent_req_nterror(req, status);
2889                 }
2890                 break;
2891
2892         case PIPE_AUTH_TYPE_KRB5:
2893                 /* */
2894
2895         default:
2896                 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2897                          (unsigned int)state->cli->auth->auth_type));
2898                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2899         }
2900 }
2901
2902 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2903                                            struct rpc_pipe_bind_state *state,
2904                                            struct rpc_hdr_info *phdr,
2905                                            prs_struct *reply_pdu)
2906 {
2907         DATA_BLOB server_response = data_blob_null;
2908         DATA_BLOB client_reply = data_blob_null;
2909         struct rpc_hdr_auth_info hdr_auth;
2910         struct tevent_req *subreq;
2911         NTSTATUS status;
2912
2913         if ((phdr->auth_len == 0)
2914             || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2915                 return NT_STATUS_INVALID_PARAMETER;
2916         }
2917
2918         if (!prs_set_offset(
2919                     reply_pdu,
2920                     phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2921                 return NT_STATUS_INVALID_PARAMETER;
2922         }
2923
2924         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2925                 return NT_STATUS_INVALID_PARAMETER;
2926         }
2927
2928         /* TODO - check auth_type/auth_level match. */
2929
2930         server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2931         prs_copy_data_out((char *)server_response.data, reply_pdu,
2932                           phdr->auth_len);
2933
2934         status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2935                                 server_response, &client_reply);
2936
2937         if (!NT_STATUS_IS_OK(status)) {
2938                 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2939                           "blob failed: %s.\n", nt_errstr(status)));
2940                 return status;
2941         }
2942
2943         prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2944
2945         status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2946                                        state->cli->auth->auth_type,
2947                                        state->cli->auth->auth_level,
2948                                        &client_reply, &state->rpc_out);
2949         data_blob_free(&client_reply);
2950
2951         if (!NT_STATUS_IS_OK(status)) {
2952                 return status;
2953         }
2954
2955         subreq = rpc_write_send(state, state->ev, state->cli->transport,
2956                                 (uint8_t *)prs_data_p(&state->rpc_out),
2957                                 prs_offset(&state->rpc_out));
2958         if (subreq == NULL) {
2959                 return NT_STATUS_NO_MEMORY;
2960         }
2961         tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2962         return NT_STATUS_OK;
2963 }
2964
2965 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2966 {
2967         struct tevent_req *req = tevent_req_callback_data(
2968                 subreq, struct tevent_req);
2969         NTSTATUS status;
2970
2971         status = rpc_write_recv(subreq);
2972         TALLOC_FREE(subreq);
2973         if (!NT_STATUS_IS_OK(status)) {
2974                 tevent_req_nterror(req, status);
2975                 return;
2976         }
2977         tevent_req_done(req);
2978 }
2979
2980 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2981                                                     struct rpc_pipe_bind_state *state,
2982                                                     struct rpc_hdr_info *phdr,
2983                                                     prs_struct *reply_pdu)
2984 {
2985         DATA_BLOB server_spnego_response = data_blob_null;
2986         DATA_BLOB server_ntlm_response = data_blob_null;
2987         DATA_BLOB client_reply = data_blob_null;
2988         DATA_BLOB tmp_blob = data_blob_null;
2989         RPC_HDR_AUTH hdr_auth;
2990         struct tevent_req *subreq;
2991         NTSTATUS status;
2992
2993         if ((phdr->auth_len == 0)
2994             || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2995                 return NT_STATUS_INVALID_PARAMETER;
2996         }
2997
2998         /* Process the returned NTLMSSP blob first. */
2999         if (!prs_set_offset(
3000                     reply_pdu,
3001                     phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
3002                 return NT_STATUS_INVALID_PARAMETER;
3003         }
3004
3005         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3006                 return NT_STATUS_INVALID_PARAMETER;
3007         }
3008
3009         server_spnego_response = data_blob(NULL, phdr->auth_len);
3010         prs_copy_data_out((char *)server_spnego_response.data,
3011                           reply_pdu, phdr->auth_len);
3012
3013         /*
3014          * The server might give us back two challenges - tmp_blob is for the
3015          * second.
3016          */
3017         if (!spnego_parse_challenge(server_spnego_response,
3018                                     &server_ntlm_response, &tmp_blob)) {
3019                 data_blob_free(&server_spnego_response);
3020                 data_blob_free(&server_ntlm_response);
3021                 data_blob_free(&tmp_blob);
3022                 return NT_STATUS_INVALID_PARAMETER;
3023         }
3024
3025         /* We're finished with the server spnego response and the tmp_blob. */
3026         data_blob_free(&server_spnego_response);
3027         data_blob_free(&tmp_blob);
3028
3029         status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3030                                 server_ntlm_response, &client_reply);
3031
3032         /* Finished with the server_ntlm response */
3033         data_blob_free(&server_ntlm_response);
3034
3035         if (!NT_STATUS_IS_OK(status)) {
3036                 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3037                           "using server blob failed.\n"));
3038                 data_blob_free(&client_reply);
3039                 return status;
3040         }
3041
3042         /* SPNEGO wrap the client reply. */
3043         tmp_blob = spnego_gen_auth(client_reply);
3044         data_blob_free(&client_reply);
3045         client_reply = tmp_blob;
3046         tmp_blob = data_blob_null;
3047
3048         /* Now prepare the alter context pdu. */
3049         prs_init_empty(&state->rpc_out, state, MARSHALL);
3050
3051         status = create_rpc_alter_context(state->rpc_call_id,
3052                                           &state->cli->abstract_syntax,
3053                                           &state->cli->transfer_syntax,
3054                                           state->cli->auth->auth_level,
3055                                           &client_reply,
3056                                           &state->rpc_out);
3057         data_blob_free(&client_reply);
3058
3059         if (!NT_STATUS_IS_OK(status)) {
3060                 return status;
3061         }
3062
3063         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3064                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3065         if (subreq == NULL) {
3066                 return NT_STATUS_NO_MEMORY;
3067         }
3068         tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3069         return NT_STATUS_OK;
3070 }
3071
3072 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3073 {
3074         struct tevent_req *req = tevent_req_callback_data(
3075                 subreq, struct tevent_req);
3076         struct rpc_pipe_bind_state *state = tevent_req_data(
3077                 req, struct rpc_pipe_bind_state);
3078         DATA_BLOB server_spnego_response = data_blob_null;
3079         DATA_BLOB tmp_blob = data_blob_null;
3080         prs_struct reply_pdu;
3081         struct rpc_hdr_info hdr;
3082         struct rpc_hdr_auth_info hdr_auth;
3083         NTSTATUS status;
3084
3085         status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3086         TALLOC_FREE(subreq);
3087         if (!NT_STATUS_IS_OK(status)) {
3088                 tevent_req_nterror(req, status);
3089                 return;
3090         }
3091
3092         /* Get the auth blob from the reply. */
3093         if (!smb_io_rpc_hdr("rpc_hdr   ", &hdr, &reply_pdu, 0)) {
3094                 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3095                           "unmarshall RPC_HDR.\n"));
3096                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3097                 return;
3098         }
3099
3100         if (!prs_set_offset(
3101                     &reply_pdu,
3102                     hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3103                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3104                 return;
3105         }
3106
3107         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3108                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3109                 return;
3110         }
3111
3112         server_spnego_response = data_blob(NULL, hdr.auth_len);
3113         prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3114                           hdr.auth_len);
3115
3116         /* Check we got a valid auth response. */
3117         if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3118                                         OID_NTLMSSP, &tmp_blob)) {
3119                 data_blob_free(&server_spnego_response);
3120                 data_blob_free(&tmp_blob);
3121                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3122                 return;
3123         }
3124
3125         data_blob_free(&server_spnego_response);
3126         data_blob_free(&tmp_blob);
3127
3128         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3129                  "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3130         tevent_req_done(req);
3131 }
3132
3133 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3134 {
3135         return tevent_req_simple_recv_ntstatus(req);
3136 }
3137
3138 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3139                        struct cli_pipe_auth_data *auth)
3140 {
3141         TALLOC_CTX *frame = talloc_stackframe();
3142         struct event_context *ev;
3143         struct tevent_req *req;
3144         NTSTATUS status = NT_STATUS_OK;
3145
3146         ev = event_context_init(frame);
3147         if (ev == NULL) {
3148                 status = NT_STATUS_NO_MEMORY;
3149                 goto fail;
3150         }
3151
3152         req = rpc_pipe_bind_send(frame, ev, cli, auth);
3153         if (req == NULL) {
3154                 status = NT_STATUS_NO_MEMORY;
3155                 goto fail;
3156         }
3157
3158         if (!tevent_req_poll(req, ev)) {
3159                 status = map_nt_error_from_unix(errno);
3160                 goto fail;
3161         }
3162
3163         status = rpc_pipe_bind_recv(req);
3164  fail:
3165         TALLOC_FREE(frame);
3166         return status;
3167 }
3168
3169 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3170
3171 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3172                                 unsigned int timeout)
3173 {
3174         unsigned int old;
3175
3176         if (rpc_cli->transport == NULL) {
3177                 return RPCCLI_DEFAULT_TIMEOUT;
3178         }
3179
3180         if (rpc_cli->transport->set_timeout == NULL) {
3181                 return RPCCLI_DEFAULT_TIMEOUT;
3182         }
3183
3184         old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3185         if (old == 0) {
3186                 return RPCCLI_DEFAULT_TIMEOUT;
3187         }
3188
3189         return old;
3190 }
3191
3192 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3193 {
3194         if (rpc_cli == NULL) {
3195                 return false;
3196         }
3197
3198         if (rpc_cli->transport == NULL) {
3199                 return false;
3200         }
3201
3202         return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3203 }
3204
3205 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3206 {
3207         struct cli_state *cli;
3208
3209         if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3210             || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3211                 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3212                 return true;
3213         }
3214
3215         cli = rpc_pipe_np_smb_conn(rpc_cli);
3216         if (cli == NULL) {
3217                 return false;
3218         }
3219         E_md4hash(cli->password ? cli->password : "", nt_hash);
3220         return true;
3221 }
3222
3223 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3224                                struct cli_pipe_auth_data **presult)
3225 {
3226         struct cli_pipe_auth_data *result;
3227
3228         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3229         if (result == NULL) {
3230                 return NT_STATUS_NO_MEMORY;
3231         }
3232
3233         result->auth_type = PIPE_AUTH_TYPE_NONE;
3234         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3235
3236         result->user_name = talloc_strdup(result, "");
3237         result->domain = talloc_strdup(result, "");
3238         if ((result->user_name == NULL) || (result->domain == NULL)) {
3239                 TALLOC_FREE(result);
3240                 return NT_STATUS_NO_MEMORY;
3241         }
3242
3243         *presult = result;
3244         return NT_STATUS_OK;
3245 }
3246
3247 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3248 {
3249         ntlmssp_end(&auth->a_u.ntlmssp_state);
3250         return 0;
3251 }
3252
3253 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3254                                   enum pipe_auth_type auth_type,
3255                                   enum dcerpc_AuthLevel auth_level,
3256                                   const char *domain,
3257                                   const char *username,
3258                                   const char *password,
3259                                   struct cli_pipe_auth_data **presult)
3260 {
3261         struct cli_pipe_auth_data *result;
3262         NTSTATUS status;
3263
3264         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3265         if (result == NULL) {
3266                 return NT_STATUS_NO_MEMORY;
3267         }
3268
3269         result->auth_type = auth_type;
3270         result->auth_level = auth_level;
3271
3272         result->user_name = talloc_strdup(result, username);
3273         result->domain = talloc_strdup(result, domain);
3274         if ((result->user_name == NULL) || (result->domain == NULL)) {
3275                 status = NT_STATUS_NO_MEMORY;
3276                 goto fail;
3277         }
3278
3279         status = ntlmssp_client_start(NULL,
3280                                       global_myname(),
3281                                       lp_workgroup(),
3282                                       lp_client_ntlmv2_auth(),
3283                                       &result->a_u.ntlmssp_state);
3284         if (!NT_STATUS_IS_OK(status)) {
3285                 goto fail;
3286         }
3287
3288         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3289
3290         status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3291         if (!NT_STATUS_IS_OK(status)) {
3292                 goto fail;
3293         }
3294
3295         status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3296         if (!NT_STATUS_IS_OK(status)) {
3297                 goto fail;
3298         }
3299
3300         status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3301         if (!NT_STATUS_IS_OK(status)) {
3302                 goto fail;
3303         }
3304
3305         /*
3306          * Turn off sign+seal to allow selected auth level to turn it back on.
3307          */
3308         result->a_u.ntlmssp_state->neg_flags &=
3309                 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3310
3311         if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3312                 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3313         } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3314                 result->a_u.ntlmssp_state->neg_flags
3315                         |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3316         }
3317
3318         *presult = result;
3319         return NT_STATUS_OK;
3320
3321  fail:
3322         TALLOC_FREE(result);
3323         return status;
3324 }
3325
3326 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3327                                    enum dcerpc_AuthLevel auth_level,
3328                                    struct netlogon_creds_CredentialState *creds,
3329                                    struct cli_pipe_auth_data **presult)
3330 {
3331         struct cli_pipe_auth_data *result;
3332
3333         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3334         if (result == NULL) {
3335                 return NT_STATUS_NO_MEMORY;
3336         }
3337
3338         result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3339         result->auth_level = auth_level;
3340
3341         result->user_name = talloc_strdup(result, "");
3342         result->domain = talloc_strdup(result, domain);
3343         if ((result->user_name == NULL) || (result->domain == NULL)) {
3344                 goto fail;
3345         }
3346
3347         result->a_u.schannel_auth = talloc(result, struct schannel_state);
3348         if (result->a_u.schannel_auth == NULL) {
3349                 goto fail;
3350         }
3351
3352         result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3353         result->a_u.schannel_auth->seq_num = 0;
3354         result->a_u.schannel_auth->initiator = true;
3355         result->a_u.schannel_auth->creds = creds;
3356
3357         *presult = result;
3358         return NT_STATUS_OK;
3359
3360  fail:
3361         TALLOC_FREE(result);
3362         return NT_STATUS_NO_MEMORY;
3363 }
3364
3365 #ifdef HAVE_KRB5
3366 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3367 {
3368         data_blob_free(&auth->session_key);
3369         return 0;
3370 }
3371 #endif
3372
3373 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3374                                    enum dcerpc_AuthLevel auth_level,
3375                                    const char *service_princ,
3376                                    const char *username,
3377                                    const char *password,
3378                                    struct cli_pipe_auth_data **presult)
3379 {
3380 #ifdef HAVE_KRB5
3381         struct cli_pipe_auth_data *result;
3382
3383         if ((username != NULL) && (password != NULL)) {
3384                 int ret = kerberos_kinit_password(username, password, 0, NULL);
3385                 if (ret != 0) {
3386                         return NT_STATUS_ACCESS_DENIED;
3387                 }
3388         }
3389
3390         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3391         if (result == NULL) {
3392                 return NT_STATUS_NO_MEMORY;
3393         }
3394
3395         result->auth_type = PIPE_AUTH_TYPE_KRB5;
3396         result->auth_level = auth_level;
3397
3398         /*
3399          * Username / domain need fixing!
3400          */
3401         result->user_name = talloc_strdup(result, "");
3402         result->domain = talloc_strdup(result, "");
3403         if ((result->user_name == NULL) || (result->domain == NULL)) {
3404                 goto fail;
3405         }
3406
3407         result->a_u.kerberos_auth = TALLOC_ZERO_P(
3408                 result, struct kerberos_auth_struct);
3409         if (result->a_u.kerberos_auth == NULL) {
3410                 goto fail;
3411         }
3412         talloc_set_destructor(result->a_u.kerberos_auth,
3413                               cli_auth_kerberos_data_destructor);
3414
3415         result->a_u.kerberos_auth->service_principal = talloc_strdup(
3416                 result, service_princ);
3417         if (result->a_u.kerberos_auth->service_principal == NULL) {
3418                 goto fail;
3419         }
3420
3421         *presult = result;
3422         return NT_STATUS_OK;
3423
3424  fail:
3425         TALLOC_FREE(result);
3426         return NT_STATUS_NO_MEMORY;
3427 #else
3428         return NT_STATUS_NOT_SUPPORTED;
3429 #endif
3430 }
3431
3432 /**
3433  * Create an rpc pipe client struct, connecting to a tcp port.
3434  */
3435 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3436                                        uint16_t port,
3437                                        const struct ndr_syntax_id *abstract_syntax,
3438                                        struct rpc_pipe_client **presult)
3439 {
3440         struct rpc_pipe_client *result;
3441         struct sockaddr_storage addr;
3442         NTSTATUS status;
3443         int fd;
3444
3445         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3446         if (result == NULL) {
3447                 return NT_STATUS_NO_MEMORY;
3448         }
3449
3450         result->abstract_syntax = *abstract_syntax;
3451         result->transfer_syntax = ndr_transfer_syntax;
3452         result->dispatch = cli_do_rpc_ndr;
3453         result->dispatch_send = cli_do_rpc_ndr_send;
3454         result->dispatch_recv = cli_do_rpc_ndr_recv;
3455
3456         result->desthost = talloc_strdup(result, host);
3457         result->srv_name_slash = talloc_asprintf_strupper_m(
3458                 result, "\\\\%s", result->desthost);
3459         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3460                 status = NT_STATUS_NO_MEMORY;
3461                 goto fail;
3462         }
3463
3464         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3465         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3466
3467         if (!resolve_name(host, &addr, 0, false)) {
3468                 status = NT_STATUS_NOT_FOUND;
3469                 goto fail;
3470         }
3471
3472         status = open_socket_out(&addr, port, 60, &fd);
3473         if (!NT_STATUS_IS_OK(status)) {
3474                 goto fail;
3475         }
3476         set_socket_options(fd, lp_socket_options());
3477
3478         status = rpc_transport_sock_init(result, fd, &result->transport);
3479         if (!NT_STATUS_IS_OK(status)) {
3480                 close(fd);
3481                 goto fail;
3482         }
3483
3484         result->transport->transport = NCACN_IP_TCP;
3485
3486         *presult = result;
3487         return NT_STATUS_OK;
3488
3489  fail:
3490         TALLOC_FREE(result);
3491         return status;
3492 }
3493
3494 /**
3495  * Determine the tcp port on which a dcerpc interface is listening
3496  * for the ncacn_ip_tcp transport via the endpoint mapper of the
3497  * target host.
3498  */
3499 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3500                                       const struct ndr_syntax_id *abstract_syntax,
3501                                       uint16_t *pport)
3502 {
3503         NTSTATUS status;
3504         struct rpc_pipe_client *epm_pipe = NULL;
3505         struct cli_pipe_auth_data *auth = NULL;
3506         struct dcerpc_binding *map_binding = NULL;
3507         struct dcerpc_binding *res_binding = NULL;
3508         struct epm_twr_t *map_tower = NULL;
3509         struct epm_twr_t *res_towers = NULL;
3510         struct policy_handle *entry_handle = NULL;
3511         uint32_t num_towers = 0;
3512         uint32_t max_towers = 1;
3513         struct epm_twr_p_t towers;
3514         TALLOC_CTX *tmp_ctx = talloc_stackframe();
3515
3516         if (pport == NULL) {
3517                 status = NT_STATUS_INVALID_PARAMETER;
3518                 goto done;
3519         }
3520
3521         /* open the connection to the endpoint mapper */
3522         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3523                                         &ndr_table_epmapper.syntax_id,
3524                                         &epm_pipe);
3525
3526         if (!NT_STATUS_IS_OK(status)) {
3527                 goto done;
3528         }
3529
3530         status = rpccli_anon_bind_data(tmp_ctx, &auth);
3531         if (!NT_STATUS_IS_OK(status)) {
3532                 goto done;
3533         }
3534
3535         status = rpc_pipe_bind(epm_pipe, auth);
3536         if (!NT_STATUS_IS_OK(status)) {
3537                 goto done;
3538         }
3539
3540         /* create tower for asking the epmapper */
3541
3542         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3543         if (map_binding == NULL) {
3544                 status = NT_STATUS_NO_MEMORY;
3545                 goto done;
3546         }
3547
3548         map_binding->transport = NCACN_IP_TCP;
3549         map_binding->object = *abstract_syntax;
3550         map_binding->host = host; /* needed? */
3551         map_binding->endpoint = "0"; /* correct? needed? */
3552
3553         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3554         if (map_tower == NULL) {
3555                 status = NT_STATUS_NO_MEMORY;
3556                 goto done;
3557         }
3558
3559         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3560                                             &(map_tower->tower));
3561         if (!NT_STATUS_IS_OK(status)) {
3562                 goto done;
3563         }
3564
3565         /* allocate further parameters for the epm_Map call */
3566
3567         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3568         if (res_towers == NULL) {
3569                 status = NT_STATUS_NO_MEMORY;
3570                 goto done;
3571         }
3572         towers.twr = res_towers;
3573
3574         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3575         if (entry_handle == NULL) {
3576                 status = NT_STATUS_NO_MEMORY;
3577                 goto done;
3578         }
3579
3580         /* ask the endpoint mapper for the port */
3581
3582         status = rpccli_epm_Map(epm_pipe,
3583                                 tmp_ctx,
3584                                 CONST_DISCARD(struct GUID *,
3585                                               &(abstract_syntax->uuid)),
3586                                 map_tower,
3587                                 entry_handle,
3588                                 max_towers,
3589                                 &num_towers,
3590                                 &towers);
3591
3592         if (!NT_STATUS_IS_OK(status)) {
3593                 goto done;
3594         }
3595
3596         if (num_towers != 1) {
3597                 status = NT_STATUS_UNSUCCESSFUL;
3598                 goto done;
3599         }
3600
3601         /* extract the port from the answer */
3602
3603         status = dcerpc_binding_from_tower(tmp_ctx,
3604                                            &(towers.twr->tower),
3605                                            &res_binding);
3606         if (!NT_STATUS_IS_OK(status)) {
3607                 goto done;
3608         }
3609
3610         /* are further checks here necessary? */
3611         if (res_binding->transport != NCACN_IP_TCP) {
3612                 status = NT_STATUS_UNSUCCESSFUL;
3613                 goto done;
3614         }
3615
3616         *pport = (uint16_t)atoi(res_binding->endpoint);
3617
3618 done:
3619         TALLOC_FREE(tmp_ctx);
3620         return status;
3621 }
3622
3623 /**
3624  * Create a rpc pipe client struct, connecting to a host via tcp.
3625  * The port is determined by asking the endpoint mapper on the given
3626  * host.
3627  */
3628 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3629                            const struct ndr_syntax_id *abstract_syntax,
3630                            struct rpc_pipe_client **presult)
3631 {
3632         NTSTATUS status;
3633         uint16_t port = 0;
3634
3635         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3636         if (!NT_STATUS_IS_OK(status)) {
3637                 return status;
3638         }
3639
3640         return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3641                                         abstract_syntax, presult);
3642 }
3643
3644 /********************************************************************
3645  Create a rpc pipe client struct, connecting to a unix domain socket
3646  ********************************************************************/
3647 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3648                                const struct ndr_syntax_id *abstract_syntax,
3649                                struct rpc_pipe_client **presult)
3650 {
3651         struct rpc_pipe_client *result;
3652         struct sockaddr_un addr;
3653         NTSTATUS status;
3654         int fd;
3655
3656         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3657         if (result == NULL) {
3658                 return NT_STATUS_NO_MEMORY;
3659         }
3660
3661         result->abstract_syntax = *abstract_syntax;
3662         result->transfer_syntax = ndr_transfer_syntax;
3663         result->dispatch = cli_do_rpc_ndr;
3664         result->dispatch_send = cli_do_rpc_ndr_send;
3665         result->dispatch_recv = cli_do_rpc_ndr_recv;
3666
3667         result->desthost = get_myname(result);
3668         result->srv_name_slash = talloc_asprintf_strupper_m(
3669                 result, "\\\\%s", result->desthost);
3670         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3671                 status = NT_STATUS_NO_MEMORY;
3672                 goto fail;
3673         }
3674
3675         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3676         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3677
3678         fd = socket(AF_UNIX, SOCK_STREAM, 0);
3679         if (fd == -1) {
3680                 status = map_nt_error_from_unix(errno);
3681                 goto fail;
3682         }
3683
3684         ZERO_STRUCT(addr);
3685         addr.sun_family = AF_UNIX;
3686         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3687
3688         if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3689                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3690                           strerror(errno)));
3691                 close(fd);
3692                 return map_nt_error_from_unix(errno);
3693         }
3694
3695         status = rpc_transport_sock_init(result, fd, &result->transport);
3696         if (!NT_STATUS_IS_OK(status)) {
3697                 close(fd);
3698                 goto fail;
3699         }
3700
3701         result->transport->transport = NCALRPC;
3702
3703         *presult = result;
3704         return NT_STATUS_OK;
3705
3706  fail:
3707         TALLOC_FREE(result);
3708         return status;
3709 }
3710
3711 struct rpc_pipe_client_np_ref {
3712         struct cli_state *cli;
3713         struct rpc_pipe_client *pipe;
3714 };
3715
3716 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3717 {
3718         DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3719         return 0;
3720 }
3721
3722 /****************************************************************************
3723  Open a named pipe over SMB to a remote server.
3724  *
3725  * CAVEAT CALLER OF THIS FUNCTION:
3726  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3727  *    so be sure that this function is called AFTER any structure (vs pointer)
3728  *    assignment of the cli.  In particular, libsmbclient does structure
3729  *    assignments of cli, which invalidates the data in the returned
3730  *    rpc_pipe_client if this function is called before the structure assignment
3731  *    of cli.
3732  * 
3733  ****************************************************************************/
3734
3735 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3736                                  const struct ndr_syntax_id *abstract_syntax,
3737                                  struct rpc_pipe_client **presult)
3738 {
3739         struct rpc_pipe_client *result;
3740         NTSTATUS status;
3741         struct rpc_pipe_client_np_ref *np_ref;
3742
3743         /* sanity check to protect against crashes */
3744
3745         if ( !cli ) {
3746                 return NT_STATUS_INVALID_HANDLE;
3747         }
3748
3749         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3750         if (result == NULL) {
3751                 return NT_STATUS_NO_MEMORY;
3752         }
3753
3754         result->abstract_syntax = *abstract_syntax;
3755         result->transfer_syntax = ndr_transfer_syntax;
3756         result->dispatch = cli_do_rpc_ndr;
3757         result->dispatch_send = cli_do_rpc_ndr_send;
3758         result->dispatch_recv = cli_do_rpc_ndr_recv;
3759         result->desthost = talloc_strdup(result, cli->desthost);
3760         result->srv_name_slash = talloc_asprintf_strupper_m(
3761                 result, "\\\\%s", result->desthost);
3762
3763         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3764         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3765
3766         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3767                 TALLOC_FREE(result);
3768                 return NT_STATUS_NO_MEMORY;
3769         }
3770
3771         status = rpc_transport_np_init(result, cli, abstract_syntax,
3772                                        &result->transport);
3773         if (!NT_STATUS_IS_OK(status)) {
3774                 TALLOC_FREE(result);
3775                 return status;
3776         }
3777
3778         result->transport->transport = NCACN_NP;
3779
3780         np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3781         if (np_ref == NULL) {
3782                 TALLOC_FREE(result);
3783                 return NT_STATUS_NO_MEMORY;
3784         }
3785         np_ref->cli = cli;
3786         np_ref->pipe = result;
3787
3788         DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3789         talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3790
3791         *presult = result;
3792         return NT_STATUS_OK;
3793 }
3794
3795 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3796                              struct rpc_cli_smbd_conn *conn,
3797                              const struct ndr_syntax_id *syntax,
3798                              struct rpc_pipe_client **presult)
3799 {
3800         struct rpc_pipe_client *result;
3801         struct cli_pipe_auth_data *auth;
3802         NTSTATUS status;
3803
3804         result = talloc(mem_ctx, struct rpc_pipe_client);
3805         if (result == NULL) {
3806                 return NT_STATUS_NO_MEMORY;
3807         }
3808         result->abstract_syntax = *syntax;
3809         result->transfer_syntax = ndr_transfer_syntax;
3810         result->dispatch = cli_do_rpc_ndr;
3811         result->dispatch_send = cli_do_rpc_ndr_send;
3812         result->dispatch_recv = cli_do_rpc_ndr_recv;
3813         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3814         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3815
3816         result->desthost = talloc_strdup(result, global_myname());
3817         result->srv_name_slash = talloc_asprintf_strupper_m(
3818                 result, "\\\\%s", global_myname());
3819         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3820                 TALLOC_FREE(result);
3821                 return NT_STATUS_NO_MEMORY;
3822         }
3823
3824         status = rpc_transport_smbd_init(result, conn, syntax,
3825                                          &result->transport);
3826         if (!NT_STATUS_IS_OK(status)) {
3827                 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3828                           nt_errstr(status)));
3829                 TALLOC_FREE(result);
3830                 return status;
3831         }
3832
3833         status = rpccli_anon_bind_data(result, &auth);
3834         if (!NT_STATUS_IS_OK(status)) {
3835                 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3836                           nt_errstr(status)));
3837                 TALLOC_FREE(result);
3838                 return status;
3839         }
3840
3841         status = rpc_pipe_bind(result, auth);
3842         if (!NT_STATUS_IS_OK(status)) {
3843                 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3844                 TALLOC_FREE(result);
3845                 return status;
3846         }
3847
3848         result->transport->transport = NCACN_INTERNAL;
3849
3850         *presult = result;
3851         return NT_STATUS_OK;
3852 }
3853
3854 /****************************************************************************
3855  Open a pipe to a remote server.
3856  ****************************************************************************/
3857
3858 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3859                                   enum dcerpc_transport_t transport,
3860                                   const struct ndr_syntax_id *interface,
3861                                   struct rpc_pipe_client **presult)
3862 {
3863         switch (transport) {
3864         case NCACN_IP_TCP:
3865                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3866                                          presult);
3867         case NCACN_NP:
3868                 return rpc_pipe_open_np(cli, interface, presult);
3869         default:
3870                 return NT_STATUS_NOT_IMPLEMENTED;
3871         }
3872 }
3873
3874 /****************************************************************************
3875  Open a named pipe to an SMB server and bind anonymously.
3876  ****************************************************************************/
3877
3878 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3879                                             enum dcerpc_transport_t transport,
3880                                             const struct ndr_syntax_id *interface,
3881                                             struct rpc_pipe_client **presult)
3882 {
3883         struct rpc_pipe_client *result;
3884         struct cli_pipe_auth_data *auth;
3885         NTSTATUS status;
3886
3887         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3888         if (!NT_STATUS_IS_OK(status)) {
3889                 return status;
3890         }
3891
3892         status = rpccli_anon_bind_data(result, &auth);
3893         if (!NT_STATUS_IS_OK(status)) {
3894                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3895                           nt_errstr(status)));
3896                 TALLOC_FREE(result);
3897                 return status;
3898         }
3899
3900         /*
3901          * This is a bit of an abstraction violation due to the fact that an
3902          * anonymous bind on an authenticated SMB inherits the user/domain
3903          * from the enclosing SMB creds
3904          */
3905
3906         TALLOC_FREE(auth->user_name);
3907         TALLOC_FREE(auth->domain);
3908
3909         auth->user_name = talloc_strdup(auth, cli->user_name);
3910         auth->domain = talloc_strdup(auth, cli->domain);
3911         auth->user_session_key = data_blob_talloc(auth,
3912                 cli->user_session_key.data,
3913                 cli->user_session_key.length);
3914
3915         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3916                 TALLOC_FREE(result);
3917                 return NT_STATUS_NO_MEMORY;
3918         }
3919
3920         status = rpc_pipe_bind(result, auth);
3921         if (!NT_STATUS_IS_OK(status)) {
3922                 int lvl = 0;
3923                 if (ndr_syntax_id_equal(interface,
3924                                         &ndr_table_dssetup.syntax_id)) {
3925                         /* non AD domains just don't have this pipe, avoid
3926                          * level 0 statement in that case - gd */
3927                         lvl = 3;
3928                 }
3929                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3930                             "%s failed with error %s\n",
3931                             get_pipe_name_from_syntax(talloc_tos(), interface),
3932                             nt_errstr(status) ));
3933                 TALLOC_FREE(result);
3934                 return status;
3935         }
3936
3937         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3938                   "%s and bound anonymously.\n",
3939                   get_pipe_name_from_syntax(talloc_tos(), interface),
3940                   cli->desthost));
3941
3942         *presult = result;
3943         return NT_STATUS_OK;
3944 }
3945
3946 /****************************************************************************
3947  ****************************************************************************/
3948
3949 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3950                                   const struct ndr_syntax_id *interface,
3951                                   struct rpc_pipe_client **presult)
3952 {
3953         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3954                                                   interface, presult);
3955 }
3956
3957 /****************************************************************************
3958  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3959  ****************************************************************************/
3960
3961 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3962                                                    const struct ndr_syntax_id *interface,
3963                                                    enum dcerpc_transport_t transport,
3964                                                    enum pipe_auth_type auth_type,
3965                                                    enum dcerpc_AuthLevel auth_level,
3966                                                    const char *domain,
3967                                                    const char *username,
3968                                                    const char *password,
3969                                                    struct rpc_pipe_client **presult)
3970 {
3971         struct rpc_pipe_client *result;
3972         struct cli_pipe_auth_data *auth;
3973         NTSTATUS status;
3974
3975         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3976         if (!NT_STATUS_IS_OK(status)) {
3977                 return status;
3978         }
3979
3980         status = rpccli_ntlmssp_bind_data(
3981                 result, auth_type, auth_level, domain, username,
3982                 password, &auth);
3983         if (!NT_STATUS_IS_OK(status)) {
3984                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3985                           nt_errstr(status)));
3986                 goto err;
3987         }
3988
3989         status = rpc_pipe_bind(result, auth);
3990         if (!NT_STATUS_IS_OK(status)) {
3991                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3992                         nt_errstr(status) ));
3993                 goto err;
3994         }
3995
3996         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3997                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3998                   get_pipe_name_from_syntax(talloc_tos(), interface),
3999                   cli->desthost, domain, username ));
4000
4001         *presult = result;
4002         return NT_STATUS_OK;
4003
4004   err:
4005
4006         TALLOC_FREE(result);
4007         return status;
4008 }
4009
4010 /****************************************************************************
4011  External interface.
4012  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4013  ****************************************************************************/
4014
4015 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4016                                    const struct ndr_syntax_id *interface,
4017                                    enum dcerpc_transport_t transport,
4018                                    enum dcerpc_AuthLevel auth_level,
4019                                    const char *domain,
4020                                    const char *username,
4021                                    const char *password,
4022                                    struct rpc_pipe_client **presult)
4023 {
4024         return cli_rpc_pipe_open_ntlmssp_internal(cli,
4025                                                 interface,
4026                                                 transport,
4027                                                 PIPE_AUTH_TYPE_NTLMSSP,
4028                                                 auth_level,
4029                                                 domain,
4030                                                 username,
4031                                                 password,
4032                                                 presult);
4033 }
4034
4035 /****************************************************************************
4036  External interface.
4037  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4038  ****************************************************************************/
4039
4040 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4041                                           const struct ndr_syntax_id *interface,
4042                                           enum dcerpc_transport_t transport,
4043                                           enum dcerpc_AuthLevel auth_level,
4044                                           const char *domain,
4045                                           const char *username,
4046                                           const char *password,
4047                                           struct rpc_pipe_client **presult)
4048 {
4049         return cli_rpc_pipe_open_ntlmssp_internal(cli,
4050                                                 interface,
4051                                                 transport,
4052                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4053                                                 auth_level,
4054                                                 domain,
4055                                                 username,
4056                                                 password,
4057                                                 presult);
4058 }
4059
4060 /****************************************************************************
4061   Get a the schannel session key out of an already opened netlogon pipe.
4062  ****************************************************************************/
4063 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4064                                                 struct cli_state *cli,
4065                                                 const char *domain,
4066                                                 uint32 *pneg_flags)
4067 {
4068         enum netr_SchannelType sec_chan_type = 0;
4069         unsigned char machine_pwd[16];
4070         const char *machine_account;
4071         NTSTATUS status;
4072
4073         /* Get the machine account credentials from secrets.tdb. */
4074         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4075                                &sec_chan_type))
4076         {
4077                 DEBUG(0, ("get_schannel_session_key: could not fetch "
4078                         "trust account password for domain '%s'\n",
4079                         domain));
4080                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4081         }
4082
4083         status = rpccli_netlogon_setup_creds(netlogon_pipe,
4084                                         cli->desthost, /* server name */
4085                                         domain,        /* domain */
4086                                         global_myname(), /* client name */
4087                                         machine_account, /* machine account name */
4088                                         machine_pwd,
4089                                         sec_chan_type,
4090                                         pneg_flags);
4091
4092         if (!NT_STATUS_IS_OK(status)) {
4093                 DEBUG(3, ("get_schannel_session_key_common: "
4094                           "rpccli_netlogon_setup_creds failed with result %s "
4095                           "to server %s, domain %s, machine account %s.\n",
4096                           nt_errstr(status), cli->desthost, domain,
4097                           machine_account ));
4098                 return status;
4099         }
4100
4101         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4102                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4103                         cli->desthost));
4104                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4105         }
4106
4107         return NT_STATUS_OK;;
4108 }
4109
4110 /****************************************************************************
4111  Open a netlogon pipe and get the schannel session key.
4112  Now exposed to external callers.
4113  ****************************************************************************/
4114
4115
4116 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4117                                   const char *domain,
4118                                   uint32 *pneg_flags,
4119                                   struct rpc_pipe_client **presult)
4120 {
4121         struct rpc_pipe_client *netlogon_pipe = NULL;
4122         NTSTATUS status;
4123
4124         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4125                                           &netlogon_pipe);
4126         if (!NT_STATUS_IS_OK(status)) {
4127                 return status;
4128         }
4129
4130         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4131                                                  pneg_flags);
4132         if (!NT_STATUS_IS_OK(status)) {
4133                 TALLOC_FREE(netlogon_pipe);
4134                 return status;
4135         }
4136
4137         *presult = netlogon_pipe;
4138         return NT_STATUS_OK;
4139 }
4140
4141 /****************************************************************************
4142  External interface.
4143  Open a named pipe to an SMB server and bind using schannel (bind type 68)
4144  using session_key. sign and seal.
4145
4146  The *pdc will be stolen onto this new pipe
4147  ****************************************************************************/
4148
4149 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4150                                              const struct ndr_syntax_id *interface,
4151                                              enum dcerpc_transport_t transport,
4152                                              enum dcerpc_AuthLevel auth_level,
4153                                              const char *domain,
4154                                              struct netlogon_creds_CredentialState **pdc,
4155                                              struct rpc_pipe_client **presult)
4156 {
4157         struct rpc_pipe_client *result;
4158         struct cli_pipe_auth_data *auth;
4159         NTSTATUS status;
4160
4161         status = cli_rpc_pipe_open(cli, transport, interface, &result);
4162         if (!NT_STATUS_IS_OK(status)) {
4163                 return status;
4164         }
4165
4166         status = rpccli_schannel_bind_data(result, domain, auth_level,
4167                                            *pdc, &auth);
4168         if (!NT_STATUS_IS_OK(status)) {
4169                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4170                           nt_errstr(status)));
4171                 TALLOC_FREE(result);
4172                 return status;
4173         }
4174
4175         status = rpc_pipe_bind(result, auth);
4176         if (!NT_STATUS_IS_OK(status)) {
4177                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4178                           "cli_rpc_pipe_bind failed with error %s\n",
4179                           nt_errstr(status) ));
4180                 TALLOC_FREE(result);
4181                 return status;
4182         }
4183
4184         /*
4185          * The credentials on a new netlogon pipe are the ones we are passed
4186          * in - reference them in
4187          */
4188         result->dc = talloc_move(result, pdc);
4189
4190         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4191                   "for domain %s and bound using schannel.\n",
4192                   get_pipe_name_from_syntax(talloc_tos(), interface),
4193                   cli->desthost, domain ));
4194
4195         *presult = result;
4196         return NT_STATUS_OK;
4197 }
4198
4199 /****************************************************************************
4200  Open a named pipe to an SMB server and bind using schannel (bind type 68).
4201  Fetch the session key ourselves using a temporary netlogon pipe. This
4202  version uses an ntlmssp auth bound netlogon pipe to get the key.
4203  ****************************************************************************/
4204
4205 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4206                                                       const char *domain,
4207                                                       const char *username,
4208                                                       const char *password,
4209                                                       uint32 *pneg_flags,
4210                                                       struct rpc_pipe_client **presult)
4211 {
4212         struct rpc_pipe_client *netlogon_pipe = NULL;
4213         NTSTATUS status;
4214
4215         status = cli_rpc_pipe_open_spnego_ntlmssp(
4216                 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4217                 DCERPC_AUTH_LEVEL_PRIVACY,
4218                 domain, username, password, &netlogon_pipe);
4219         if (!NT_STATUS_IS_OK(status)) {
4220                 return status;
4221         }
4222
4223         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4224                                                  pneg_flags);
4225         if (!NT_STATUS_IS_OK(status)) {
4226                 TALLOC_FREE(netlogon_pipe);
4227                 return status;
4228         }
4229
4230         *presult = netlogon_pipe;
4231         return NT_STATUS_OK;
4232 }
4233
4234 /****************************************************************************
4235  Open a named pipe to an SMB server and bind using schannel (bind type 68).
4236  Fetch the session key ourselves using a temporary netlogon pipe. This version
4237  uses an ntlmssp bind to get the session key.
4238  ****************************************************************************/
4239
4240 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4241                                                  const struct ndr_syntax_id *interface,
4242                                                  enum dcerpc_transport_t transport,
4243                                                  enum dcerpc_AuthLevel auth_level,
4244                                                  const char *domain,
4245                                                  const char *username,
4246                                                  const char *password,
4247                                                  struct rpc_pipe_client **presult)
4248 {
4249         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4250         struct rpc_pipe_client *netlogon_pipe = NULL;
4251         struct rpc_pipe_client *result = NULL;
4252         NTSTATUS status;
4253
4254         status = get_schannel_session_key_auth_ntlmssp(
4255                 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4256         if (!NT_STATUS_IS_OK(status)) {
4257                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4258                         "key from server %s for domain %s.\n",
4259                         cli->desthost, domain ));
4260                 return status;
4261         }
4262
4263         status = cli_rpc_pipe_open_schannel_with_key(
4264                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4265                 &result);
4266
4267         /* Now we've bound using the session key we can close the netlog pipe. */
4268         TALLOC_FREE(netlogon_pipe);
4269
4270         if (NT_STATUS_IS_OK(status)) {
4271                 *presult = result;
4272         }
4273         return status;
4274 }
4275
4276 /****************************************************************************
4277  Open a named pipe to an SMB server and bind using schannel (bind type 68).
4278  Fetch the session key ourselves using a temporary netlogon pipe.
4279  ****************************************************************************/
4280
4281 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4282                                     const struct ndr_syntax_id *interface,
4283                                     enum dcerpc_transport_t transport,
4284                                     enum dcerpc_AuthLevel auth_level,
4285                                     const char *domain,
4286                                     struct rpc_pipe_client **presult)
4287 {
4288         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4289         struct rpc_pipe_client *netlogon_pipe = NULL;
4290         struct rpc_pipe_client *result = NULL;
4291         NTSTATUS status;
4292
4293         status = get_schannel_session_key(cli, domain, &neg_flags,
4294                                           &netlogon_pipe);
4295         if (!NT_STATUS_IS_OK(status)) {
4296                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4297                         "key from server %s for domain %s.\n",
4298                         cli->desthost, domain ));
4299                 return status;
4300         }
4301
4302         status = cli_rpc_pipe_open_schannel_with_key(
4303                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4304                 &result);
4305
4306         /* Now we've bound using the session key we can close the netlog pipe. */
4307         TALLOC_FREE(netlogon_pipe);
4308
4309         if (NT_STATUS_IS_OK(status)) {
4310                 *presult = result;
4311         }
4312
4313         return status;
4314 }
4315
4316 /****************************************************************************
4317  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4318  The idea is this can be called with service_princ, username and password all
4319  NULL so long as the caller has a TGT.
4320  ****************************************************************************/
4321
4322 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4323                                 const struct ndr_syntax_id *interface,
4324                                 enum dcerpc_AuthLevel auth_level,
4325                                 const char *service_princ,
4326                                 const char *username,
4327                                 const char *password,
4328                                 struct rpc_pipe_client **presult)
4329 {
4330 #ifdef HAVE_KRB5
4331         struct rpc_pipe_client *result;
4332         struct cli_pipe_auth_data *auth;
4333         NTSTATUS status;
4334
4335         status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4336         if (!NT_STATUS_IS_OK(status)) {
4337                 return status;
4338         }
4339
4340         status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4341                                            username, password, &auth);
4342         if (!NT_STATUS_IS_OK(status)) {
4343                 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4344                           nt_errstr(status)));
4345                 TALLOC_FREE(result);
4346                 return status;
4347         }
4348
4349         status = rpc_pipe_bind(result, auth);
4350         if (!NT_STATUS_IS_OK(status)) {
4351                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4352                           "with error %s\n", nt_errstr(status)));
4353                 TALLOC_FREE(result);
4354                 return status;
4355         }
4356
4357         *presult = result;
4358         return NT_STATUS_OK;
4359 #else
4360         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4361         return NT_STATUS_NOT_IMPLEMENTED;
4362 #endif
4363 }
4364
4365 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4366                              struct rpc_pipe_client *cli,
4367                              DATA_BLOB *session_key)
4368 {
4369         if (!session_key || !cli) {
4370                 return NT_STATUS_INVALID_PARAMETER;
4371         }
4372
4373         if (!cli->auth) {
4374                 return NT_STATUS_INVALID_PARAMETER;
4375         }
4376
4377         switch (cli->auth->auth_type) {
4378                 case PIPE_AUTH_TYPE_SCHANNEL:
4379                         *session_key = data_blob_talloc(mem_ctx,
4380                                 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4381                         break;
4382                 case PIPE_AUTH_TYPE_NTLMSSP:
4383                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4384                         *session_key = data_blob_talloc(mem_ctx,
4385                                 cli->auth->a_u.ntlmssp_state->session_key.data,
4386                                 cli->auth->a_u.ntlmssp_state->session_key.length);
4387                         break;
4388                 case PIPE_AUTH_TYPE_KRB5:
4389                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4390                         *session_key = data_blob_talloc(mem_ctx,
4391                                 cli->auth->a_u.kerberos_auth->session_key.data,
4392                                 cli->auth->a_u.kerberos_auth->session_key.length);
4393                         break;
4394                 case PIPE_AUTH_TYPE_NONE:
4395                         *session_key = data_blob_talloc(mem_ctx,
4396                                 cli->auth->user_session_key.data,
4397                                 cli->auth->user_session_key.length);
4398                         break;
4399                 default:
4400                         return NT_STATUS_NO_USER_SESSION_KEY;
4401         }
4402
4403         return NT_STATUS_OK;
4404 }