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