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