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