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