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