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