s3:rpc_client: use netlogon_creds_copy before rpc_pipe_bind
[obnox/samba/samba-obnox.git] / source3 / rpc_client / cli_pipe.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client routines
4  *  Largely rewritten by Jeremy Allison             2005.
5  *  Heavily modified by Simo Sorce                  2010.
6  *  Copyright Andrew Bartlett                       2011.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "includes.h"
23 #include "../lib/util/tevent_ntstatus.h"
24 #include "librpc/gen_ndr/ndr_epmapper_c.h"
25 #include "../librpc/gen_ndr/ndr_schannel.h"
26 #include "../librpc/gen_ndr/ndr_dssetup.h"
27 #include "../libcli/auth/schannel.h"
28 #include "../libcli/auth/spnego.h"
29 #include "../auth/ntlmssp/ntlmssp.h"
30 #include "auth_generic.h"
31 #include "librpc/gen_ndr/ndr_dcerpc.h"
32 #include "librpc/gen_ndr/ndr_netlogon_c.h"
33 #include "librpc/rpc/dcerpc.h"
34 #include "rpc_dce.h"
35 #include "cli_pipe.h"
36 #include "libsmb/libsmb.h"
37 #include "auth/gensec/gensec.h"
38 #include "auth/credentials/credentials.h"
39 #include "../libcli/smb/smbXcli_base.h"
40
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_RPC_CLI
43
44 /********************************************************************
45  Pipe description for a DEBUG
46  ********************************************************************/
47 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
48                                    struct rpc_pipe_client *cli)
49 {
50         char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
51         if (result == NULL) {
52                 return "pipe";
53         }
54         return result;
55 }
56
57 /********************************************************************
58  Rpc pipe call id.
59  ********************************************************************/
60
61 static uint32 get_rpc_call_id(void)
62 {
63         static uint32 call_id = 0;
64         return ++call_id;
65 }
66
67 /*******************************************************************
68  Use SMBreadX to get rest of one fragment's worth of rpc data.
69  Reads the whole size or give an error message
70  ********************************************************************/
71
72 struct rpc_read_state {
73         struct tevent_context *ev;
74         struct rpc_cli_transport *transport;
75         uint8_t *data;
76         size_t size;
77         size_t num_read;
78 };
79
80 static void rpc_read_done(struct tevent_req *subreq);
81
82 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
83                                         struct tevent_context *ev,
84                                         struct rpc_cli_transport *transport,
85                                         uint8_t *data, size_t size)
86 {
87         struct tevent_req *req, *subreq;
88         struct rpc_read_state *state;
89
90         req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
91         if (req == NULL) {
92                 return NULL;
93         }
94         state->ev = ev;
95         state->transport = transport;
96         state->data = data;
97         state->size = size;
98         state->num_read = 0;
99
100         DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
101
102         subreq = transport->read_send(state, ev, (uint8_t *)data, size,
103                                       transport->priv);
104         if (subreq == NULL) {
105                 goto fail;
106         }
107         tevent_req_set_callback(subreq, rpc_read_done, req);
108         return req;
109
110  fail:
111         TALLOC_FREE(req);
112         return NULL;
113 }
114
115 static void rpc_read_done(struct tevent_req *subreq)
116 {
117         struct tevent_req *req = tevent_req_callback_data(
118                 subreq, struct tevent_req);
119         struct rpc_read_state *state = tevent_req_data(
120                 req, struct rpc_read_state);
121         NTSTATUS status;
122         ssize_t received;
123
124         status = state->transport->read_recv(subreq, &received);
125         TALLOC_FREE(subreq);
126         if (!NT_STATUS_IS_OK(status)) {
127                 tevent_req_nterror(req, status);
128                 return;
129         }
130
131         state->num_read += received;
132         if (state->num_read == state->size) {
133                 tevent_req_done(req);
134                 return;
135         }
136
137         subreq = state->transport->read_send(state, state->ev,
138                                              state->data + state->num_read,
139                                              state->size - state->num_read,
140                                              state->transport->priv);
141         if (tevent_req_nomem(subreq, req)) {
142                 return;
143         }
144         tevent_req_set_callback(subreq, rpc_read_done, req);
145 }
146
147 static NTSTATUS rpc_read_recv(struct tevent_req *req)
148 {
149         return tevent_req_simple_recv_ntstatus(req);
150 }
151
152 struct rpc_write_state {
153         struct tevent_context *ev;
154         struct rpc_cli_transport *transport;
155         const uint8_t *data;
156         size_t size;
157         size_t num_written;
158 };
159
160 static void rpc_write_done(struct tevent_req *subreq);
161
162 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
163                                          struct tevent_context *ev,
164                                          struct rpc_cli_transport *transport,
165                                          const uint8_t *data, size_t size)
166 {
167         struct tevent_req *req, *subreq;
168         struct rpc_write_state *state;
169
170         req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
171         if (req == NULL) {
172                 return NULL;
173         }
174         state->ev = ev;
175         state->transport = transport;
176         state->data = data;
177         state->size = size;
178         state->num_written = 0;
179
180         DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
181
182         subreq = transport->write_send(state, ev, data, size, transport->priv);
183         if (subreq == NULL) {
184                 goto fail;
185         }
186         tevent_req_set_callback(subreq, rpc_write_done, req);
187         return req;
188  fail:
189         TALLOC_FREE(req);
190         return NULL;
191 }
192
193 static void rpc_write_done(struct tevent_req *subreq)
194 {
195         struct tevent_req *req = tevent_req_callback_data(
196                 subreq, struct tevent_req);
197         struct rpc_write_state *state = tevent_req_data(
198                 req, struct rpc_write_state);
199         NTSTATUS status;
200         ssize_t written;
201
202         status = state->transport->write_recv(subreq, &written);
203         TALLOC_FREE(subreq);
204         if (!NT_STATUS_IS_OK(status)) {
205                 tevent_req_nterror(req, status);
206                 return;
207         }
208
209         state->num_written += written;
210
211         if (state->num_written == state->size) {
212                 tevent_req_done(req);
213                 return;
214         }
215
216         subreq = state->transport->write_send(state, state->ev,
217                                               state->data + state->num_written,
218                                               state->size - state->num_written,
219                                               state->transport->priv);
220         if (tevent_req_nomem(subreq, req)) {
221                 return;
222         }
223         tevent_req_set_callback(subreq, rpc_write_done, req);
224 }
225
226 static NTSTATUS rpc_write_recv(struct tevent_req *req)
227 {
228         return tevent_req_simple_recv_ntstatus(req);
229 }
230
231
232 /****************************************************************************
233  Try and get a PDU's worth of data from current_pdu. If not, then read more
234  from the wire.
235  ****************************************************************************/
236
237 struct get_complete_frag_state {
238         struct tevent_context *ev;
239         struct rpc_pipe_client *cli;
240         uint16_t frag_len;
241         DATA_BLOB *pdu;
242 };
243
244 static void get_complete_frag_got_header(struct tevent_req *subreq);
245 static void get_complete_frag_got_rest(struct tevent_req *subreq);
246
247 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
248                                                  struct tevent_context *ev,
249                                                  struct rpc_pipe_client *cli,
250                                                  DATA_BLOB *pdu)
251 {
252         struct tevent_req *req, *subreq;
253         struct get_complete_frag_state *state;
254         size_t received;
255         NTSTATUS status;
256
257         req = tevent_req_create(mem_ctx, &state,
258                                 struct get_complete_frag_state);
259         if (req == NULL) {
260                 return NULL;
261         }
262         state->ev = ev;
263         state->cli = cli;
264         state->frag_len = RPC_HEADER_LEN;
265         state->pdu = pdu;
266
267         received = pdu->length;
268         if (received < RPC_HEADER_LEN) {
269                 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
270                         status = NT_STATUS_NO_MEMORY;
271                         goto post_status;
272                 }
273                 subreq = rpc_read_send(state, state->ev,
274                                         state->cli->transport,
275                                         pdu->data + received,
276                                         RPC_HEADER_LEN - received);
277                 if (subreq == NULL) {
278                         status = NT_STATUS_NO_MEMORY;
279                         goto post_status;
280                 }
281                 tevent_req_set_callback(subreq, get_complete_frag_got_header,
282                                         req);
283                 return req;
284         }
285
286         state->frag_len = dcerpc_get_frag_length(pdu);
287
288         /*
289          * Ensure we have frag_len bytes of data.
290          */
291         if (received < state->frag_len) {
292                 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
293                         status = NT_STATUS_NO_MEMORY;
294                         goto post_status;
295                 }
296                 subreq = rpc_read_send(state, state->ev,
297                                         state->cli->transport,
298                                         pdu->data + received,
299                                         state->frag_len - received);
300                 if (subreq == NULL) {
301                         status = NT_STATUS_NO_MEMORY;
302                         goto post_status;
303                 }
304                 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
305                                         req);
306                 return req;
307         }
308
309         status = NT_STATUS_OK;
310  post_status:
311         if (NT_STATUS_IS_OK(status)) {
312                 tevent_req_done(req);
313         } else {
314                 tevent_req_nterror(req, status);
315         }
316         return tevent_req_post(req, ev);
317 }
318
319 static void get_complete_frag_got_header(struct tevent_req *subreq)
320 {
321         struct tevent_req *req = tevent_req_callback_data(
322                 subreq, struct tevent_req);
323         struct get_complete_frag_state *state = tevent_req_data(
324                 req, struct get_complete_frag_state);
325         NTSTATUS status;
326
327         status = rpc_read_recv(subreq);
328         TALLOC_FREE(subreq);
329         if (!NT_STATUS_IS_OK(status)) {
330                 tevent_req_nterror(req, status);
331                 return;
332         }
333
334         state->frag_len = dcerpc_get_frag_length(state->pdu);
335
336         if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
337                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
338                 return;
339         }
340
341         /*
342          * We're here in this piece of code because we've read exactly
343          * RPC_HEADER_LEN bytes into state->pdu.
344          */
345
346         subreq = rpc_read_send(state, state->ev, state->cli->transport,
347                                 state->pdu->data + RPC_HEADER_LEN,
348                                 state->frag_len - RPC_HEADER_LEN);
349         if (tevent_req_nomem(subreq, req)) {
350                 return;
351         }
352         tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
353 }
354
355 static void get_complete_frag_got_rest(struct tevent_req *subreq)
356 {
357         struct tevent_req *req = tevent_req_callback_data(
358                 subreq, struct tevent_req);
359         NTSTATUS status;
360
361         status = rpc_read_recv(subreq);
362         TALLOC_FREE(subreq);
363         if (!NT_STATUS_IS_OK(status)) {
364                 tevent_req_nterror(req, status);
365                 return;
366         }
367         tevent_req_done(req);
368 }
369
370 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
371 {
372         return tevent_req_simple_recv_ntstatus(req);
373 }
374
375 /****************************************************************************
376  Do basic authentication checks on an incoming pdu.
377  ****************************************************************************/
378
379 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
380                                                 struct rpc_pipe_client *cli,
381                                                 struct ncacn_packet *pkt,
382                                                 DATA_BLOB *pdu,
383                                                 uint8_t expected_pkt_type,
384                                                 DATA_BLOB *rdata,
385                                                 DATA_BLOB *reply_pdu)
386 {
387         struct dcerpc_response *r;
388         NTSTATUS ret = NT_STATUS_OK;
389         size_t pad_len = 0;
390
391         /*
392          * Point the return values at the real data including the RPC
393          * header. Just in case the caller wants it.
394          */
395         *rdata = *pdu;
396
397         /* Ensure we have the correct type. */
398         switch (pkt->ptype) {
399         case DCERPC_PKT_ALTER_RESP:
400         case DCERPC_PKT_BIND_ACK:
401
402                 /* Client code never receives this kind of packets */
403                 break;
404
405
406         case DCERPC_PKT_RESPONSE:
407
408                 r = &pkt->u.response;
409
410                 /* Here's where we deal with incoming sign/seal. */
411                 ret = dcerpc_check_auth(cli->auth, pkt,
412                                         &r->stub_and_verifier,
413                                         DCERPC_RESPONSE_LENGTH,
414                                         pdu, &pad_len);
415                 if (!NT_STATUS_IS_OK(ret)) {
416                         return ret;
417                 }
418
419                 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
420                         return NT_STATUS_BUFFER_TOO_SMALL;
421                 }
422
423                 /* Point the return values at the NDR data. */
424                 rdata->data = r->stub_and_verifier.data;
425
426                 if (pkt->auth_length) {
427                         /* We've already done integer wrap tests in
428                          * dcerpc_check_auth(). */
429                         rdata->length = r->stub_and_verifier.length
430                                          - pad_len
431                                          - DCERPC_AUTH_TRAILER_LENGTH
432                                          - pkt->auth_length;
433                 } else {
434                         rdata->length = r->stub_and_verifier.length;
435                 }
436
437                 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
438                            (long unsigned int)pdu->length,
439                            (long unsigned int)rdata->length,
440                            (unsigned int)pad_len));
441
442                 /*
443                  * If this is the first reply, and the allocation hint is
444                  * reasonable, try and set up the reply_pdu DATA_BLOB to the
445                  * correct size.
446                  */
447
448                 if ((reply_pdu->length == 0) &&
449                     r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
450                         if (!data_blob_realloc(mem_ctx, reply_pdu,
451                                                         r->alloc_hint)) {
452                                 DEBUG(0, ("reply alloc hint %d too "
453                                           "large to allocate\n",
454                                           (int)r->alloc_hint));
455                                 return NT_STATUS_NO_MEMORY;
456                         }
457                 }
458
459                 break;
460
461         case DCERPC_PKT_BIND_NAK:
462                 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
463                           rpccli_pipe_txt(talloc_tos(), cli)));
464                 /* Use this for now... */
465                 return NT_STATUS_NETWORK_ACCESS_DENIED;
466
467         case DCERPC_PKT_FAULT:
468
469                 DEBUG(1, (__location__ ": RPC fault code %s received "
470                           "from %s!\n",
471                           dcerpc_errstr(talloc_tos(),
472                           pkt->u.fault.status),
473                           rpccli_pipe_txt(talloc_tos(), cli)));
474
475                 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
476
477         default:
478                 DEBUG(0, (__location__ "Unknown packet type %u received "
479                           "from %s!\n",
480                           (unsigned int)pkt->ptype,
481                           rpccli_pipe_txt(talloc_tos(), cli)));
482                 return NT_STATUS_INVALID_INFO_CLASS;
483         }
484
485         if (pkt->ptype != expected_pkt_type) {
486                 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
487                           "RPC packet type - %u, not %u\n",
488                           rpccli_pipe_txt(talloc_tos(), cli),
489                           pkt->ptype, expected_pkt_type));
490                 return NT_STATUS_INVALID_INFO_CLASS;
491         }
492
493         /* Do this just before return - we don't want to modify any rpc header
494            data before now as we may have needed to do cryptographic actions on
495            it before. */
496
497         if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
498             !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
499                 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
500                           "fragment first/last ON.\n"));
501                 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
502         }
503
504         return NT_STATUS_OK;
505 }
506
507 /****************************************************************************
508  Call a remote api on an arbitrary pipe.  takes param, data and setup buffers.
509 ****************************************************************************/
510
511 struct cli_api_pipe_state {
512         struct tevent_context *ev;
513         struct rpc_cli_transport *transport;
514         uint8_t *rdata;
515         uint32_t rdata_len;
516 };
517
518 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
519 static void cli_api_pipe_write_done(struct tevent_req *subreq);
520 static void cli_api_pipe_read_done(struct tevent_req *subreq);
521
522 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
523                                             struct tevent_context *ev,
524                                             struct rpc_cli_transport *transport,
525                                             uint8_t *data, size_t data_len,
526                                             uint32_t max_rdata_len)
527 {
528         struct tevent_req *req, *subreq;
529         struct cli_api_pipe_state *state;
530         NTSTATUS status;
531
532         req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
533         if (req == NULL) {
534                 return NULL;
535         }
536         state->ev = ev;
537         state->transport = transport;
538
539         if (max_rdata_len < RPC_HEADER_LEN) {
540                 /*
541                  * For a RPC reply we always need at least RPC_HEADER_LEN
542                  * bytes. We check this here because we will receive
543                  * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
544                  */
545                 status = NT_STATUS_INVALID_PARAMETER;
546                 goto post_status;
547         }
548
549         if (transport->trans_send != NULL) {
550                 subreq = transport->trans_send(state, ev, data, data_len,
551                                                max_rdata_len, transport->priv);
552                 if (subreq == NULL) {
553                         goto fail;
554                 }
555                 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
556                 return req;
557         }
558
559         /*
560          * If the transport does not provide a "trans" routine, i.e. for
561          * example the ncacn_ip_tcp transport, do the write/read step here.
562          */
563
564         subreq = rpc_write_send(state, ev, transport, data, data_len);
565         if (subreq == NULL) {
566                 goto fail;
567         }
568         tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
569         return req;
570
571  post_status:
572         tevent_req_nterror(req, status);
573         return tevent_req_post(req, ev);
574  fail:
575         TALLOC_FREE(req);
576         return NULL;
577 }
578
579 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
580 {
581         struct tevent_req *req = tevent_req_callback_data(
582                 subreq, struct tevent_req);
583         struct cli_api_pipe_state *state = tevent_req_data(
584                 req, struct cli_api_pipe_state);
585         NTSTATUS status;
586
587         status = state->transport->trans_recv(subreq, state, &state->rdata,
588                                               &state->rdata_len);
589         TALLOC_FREE(subreq);
590         if (!NT_STATUS_IS_OK(status)) {
591                 tevent_req_nterror(req, status);
592                 return;
593         }
594         tevent_req_done(req);
595 }
596
597 static void cli_api_pipe_write_done(struct tevent_req *subreq)
598 {
599         struct tevent_req *req = tevent_req_callback_data(
600                 subreq, struct tevent_req);
601         struct cli_api_pipe_state *state = tevent_req_data(
602                 req, struct cli_api_pipe_state);
603         NTSTATUS status;
604
605         status = rpc_write_recv(subreq);
606         TALLOC_FREE(subreq);
607         if (!NT_STATUS_IS_OK(status)) {
608                 tevent_req_nterror(req, status);
609                 return;
610         }
611
612         state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
613         if (tevent_req_nomem(state->rdata, req)) {
614                 return;
615         }
616
617         /*
618          * We don't need to use rpc_read_send here, the upper layer will cope
619          * with a short read, transport->trans_send could also return less
620          * than state->max_rdata_len.
621          */
622         subreq = state->transport->read_send(state, state->ev, state->rdata,
623                                              RPC_HEADER_LEN,
624                                              state->transport->priv);
625         if (tevent_req_nomem(subreq, req)) {
626                 return;
627         }
628         tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
629 }
630
631 static void cli_api_pipe_read_done(struct tevent_req *subreq)
632 {
633         struct tevent_req *req = tevent_req_callback_data(
634                 subreq, struct tevent_req);
635         struct cli_api_pipe_state *state = tevent_req_data(
636                 req, struct cli_api_pipe_state);
637         NTSTATUS status;
638         ssize_t received;
639
640         status = state->transport->read_recv(subreq, &received);
641         TALLOC_FREE(subreq);
642         if (!NT_STATUS_IS_OK(status)) {
643                 tevent_req_nterror(req, status);
644                 return;
645         }
646         state->rdata_len = received;
647         tevent_req_done(req);
648 }
649
650 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
651                                   uint8_t **prdata, uint32_t *prdata_len)
652 {
653         struct cli_api_pipe_state *state = tevent_req_data(
654                 req, struct cli_api_pipe_state);
655         NTSTATUS status;
656
657         if (tevent_req_is_nterror(req, &status)) {
658                 return status;
659         }
660
661         *prdata = talloc_move(mem_ctx, &state->rdata);
662         *prdata_len = state->rdata_len;
663         return NT_STATUS_OK;
664 }
665
666 /****************************************************************************
667  Send data on an rpc pipe via trans. The data must be the last
668  pdu fragment of an NDR data stream.
669
670  Receive response data from an rpc pipe, which may be large...
671
672  Read the first fragment: unfortunately have to use SMBtrans for the first
673  bit, then SMBreadX for subsequent bits.
674
675  If first fragment received also wasn't the last fragment, continue
676  getting fragments until we _do_ receive the last fragment.
677
678  Request/Response PDU's look like the following...
679
680  |<------------------PDU len----------------------------------------------->|
681  |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
682
683  +------------+-----------------+-------------+---------------+-------------+
684  | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
685  +------------+-----------------+-------------+---------------+-------------+
686
687  Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
688  signing & sealing being negotiated.
689
690  ****************************************************************************/
691
692 struct rpc_api_pipe_state {
693         struct tevent_context *ev;
694         struct rpc_pipe_client *cli;
695         uint8_t expected_pkt_type;
696
697         DATA_BLOB incoming_frag;
698         struct ncacn_packet *pkt;
699
700         /* Incoming reply */
701         DATA_BLOB reply_pdu;
702         size_t reply_pdu_offset;
703         uint8_t endianess;
704 };
705
706 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
707 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
708 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
709
710 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
711                                             struct tevent_context *ev,
712                                             struct rpc_pipe_client *cli,
713                                             DATA_BLOB *data, /* Outgoing PDU */
714                                             uint8_t expected_pkt_type)
715 {
716         struct tevent_req *req, *subreq;
717         struct rpc_api_pipe_state *state;
718         uint16_t max_recv_frag;
719         NTSTATUS status;
720
721         req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
722         if (req == NULL) {
723                 return NULL;
724         }
725         state->ev = ev;
726         state->cli = cli;
727         state->expected_pkt_type = expected_pkt_type;
728         state->endianess = DCERPC_DREP_LE;
729
730         /*
731          * Ensure we're not sending too much.
732          */
733         if (data->length > cli->max_xmit_frag) {
734                 status = NT_STATUS_INVALID_PARAMETER;
735                 goto post_status;
736         }
737
738         DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
739
740         if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
741                 subreq = rpc_write_send(state, ev, cli->transport,
742                                         data->data, data->length);
743                 if (subreq == NULL) {
744                         goto fail;
745                 }
746                 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
747                 return req;
748         }
749
750         /* get the header first, then fetch the rest once we have
751          * the frag_length available */
752         max_recv_frag = RPC_HEADER_LEN;
753
754         subreq = cli_api_pipe_send(state, ev, cli->transport,
755                                    data->data, data->length, max_recv_frag);
756         if (subreq == NULL) {
757                 goto fail;
758         }
759         tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
760         return req;
761
762  post_status:
763         tevent_req_nterror(req, status);
764         return tevent_req_post(req, ev);
765  fail:
766         TALLOC_FREE(req);
767         return NULL;
768 }
769
770 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
771 {
772         struct tevent_req *req =
773                 tevent_req_callback_data(subreq,
774                 struct tevent_req);
775         NTSTATUS status;
776
777         status = rpc_write_recv(subreq);
778         TALLOC_FREE(subreq);
779         if (!NT_STATUS_IS_OK(status)) {
780                 tevent_req_nterror(req, status);
781                 return;
782         }
783
784         tevent_req_done(req);
785 }
786
787 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
788 {
789         struct tevent_req *req = tevent_req_callback_data(
790                 subreq, struct tevent_req);
791         struct rpc_api_pipe_state *state = tevent_req_data(
792                 req, struct rpc_api_pipe_state);
793         NTSTATUS status;
794         uint8_t *rdata = NULL;
795         uint32_t rdata_len = 0;
796
797         status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
798         TALLOC_FREE(subreq);
799         if (!NT_STATUS_IS_OK(status)) {
800                 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
801                 tevent_req_nterror(req, status);
802                 return;
803         }
804
805         if (rdata == NULL) {
806                 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
807                          rpccli_pipe_txt(talloc_tos(), state->cli)));
808                 tevent_req_done(req);
809                 return;
810         }
811
812         /*
813          * Move data on state->incoming_frag.
814          */
815         state->incoming_frag.data = talloc_move(state, &rdata);
816         state->incoming_frag.length = rdata_len;
817         if (!state->incoming_frag.data) {
818                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
819                 return;
820         }
821
822         /* Ensure we have enough data for a pdu. */
823         subreq = get_complete_frag_send(state, state->ev, state->cli,
824                                         &state->incoming_frag);
825         if (tevent_req_nomem(subreq, req)) {
826                 return;
827         }
828         tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
829 }
830
831 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
832 {
833         struct tevent_req *req = tevent_req_callback_data(
834                 subreq, struct tevent_req);
835         struct rpc_api_pipe_state *state = tevent_req_data(
836                 req, struct rpc_api_pipe_state);
837         NTSTATUS status;
838         DATA_BLOB rdata = data_blob_null;
839
840         status = get_complete_frag_recv(subreq);
841         TALLOC_FREE(subreq);
842         if (!NT_STATUS_IS_OK(status)) {
843                 DEBUG(5, ("get_complete_frag failed: %s\n",
844                           nt_errstr(status)));
845                 tevent_req_nterror(req, status);
846                 return;
847         }
848
849         state->pkt = talloc(state, struct ncacn_packet);
850         if (!state->pkt) {
851                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
852                 return;
853         }
854
855         status = dcerpc_pull_ncacn_packet(state->pkt,
856                                           &state->incoming_frag,
857                                           state->pkt,
858                                           !state->endianess);
859         if (!NT_STATUS_IS_OK(status)) {
860                 tevent_req_nterror(req, status);
861                 return;
862         }
863
864         if (state->incoming_frag.length != state->pkt->frag_length) {
865                 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
866                           (unsigned int)state->incoming_frag.length,
867                           (unsigned int)state->pkt->frag_length));
868                 tevent_req_nterror(req,  NT_STATUS_INVALID_PARAMETER);
869                 return;
870         }
871
872         status = cli_pipe_validate_current_pdu(state,
873                                                 state->cli, state->pkt,
874                                                 &state->incoming_frag,
875                                                 state->expected_pkt_type,
876                                                 &rdata,
877                                                 &state->reply_pdu);
878
879         DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
880                   (unsigned)state->incoming_frag.length,
881                   (unsigned)state->reply_pdu_offset,
882                   nt_errstr(status)));
883
884         if (!NT_STATUS_IS_OK(status)) {
885                 tevent_req_nterror(req, status);
886                 return;
887         }
888
889         if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
890             && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
891                 /*
892                  * Set the data type correctly for big-endian data on the
893                  * first packet.
894                  */
895                 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
896                           "big-endian.\n",
897                           rpccli_pipe_txt(talloc_tos(), state->cli)));
898                 state->endianess = 0x00; /* BIG ENDIAN */
899         }
900         /*
901          * Check endianness on subsequent packets.
902          */
903         if (state->endianess != state->pkt->drep[0]) {
904                 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
905                          "%s\n",
906                          state->endianess?"little":"big",
907                          state->pkt->drep[0]?"little":"big"));
908                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
909                 return;
910         }
911
912         /* Now copy the data portion out of the pdu into rbuf. */
913         if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
914                 if (!data_blob_realloc(NULL, &state->reply_pdu,
915                                 state->reply_pdu_offset + rdata.length)) {
916                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
917                         return;
918                 }
919         }
920
921         memcpy(state->reply_pdu.data + state->reply_pdu_offset,
922                 rdata.data, rdata.length);
923         state->reply_pdu_offset += rdata.length;
924
925         /* reset state->incoming_frag, there is no need to free it,
926          * it will be reallocated to the right size the next time
927          * it is used */
928         state->incoming_frag.length = 0;
929
930         if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
931                 /* make sure the pdu length is right now that we
932                  * have all the data available (alloc hint may
933                  * have allocated more than was actually used) */
934                 state->reply_pdu.length = state->reply_pdu_offset;
935                 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
936                           rpccli_pipe_txt(talloc_tos(), state->cli),
937                           (unsigned)state->reply_pdu.length));
938                 tevent_req_done(req);
939                 return;
940         }
941
942         subreq = get_complete_frag_send(state, state->ev, state->cli,
943                                         &state->incoming_frag);
944         if (tevent_req_nomem(subreq, req)) {
945                 return;
946         }
947         tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
948 }
949
950 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
951                                   struct ncacn_packet **pkt,
952                                   DATA_BLOB *reply_pdu)
953 {
954         struct rpc_api_pipe_state *state = tevent_req_data(
955                 req, struct rpc_api_pipe_state);
956         NTSTATUS status;
957
958         if (tevent_req_is_nterror(req, &status)) {
959                 return status;
960         }
961
962         /* return data to caller and assign it ownership of memory */
963         if (reply_pdu) {
964                 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
965                 reply_pdu->length = state->reply_pdu.length;
966                 state->reply_pdu.length = 0;
967         } else {
968                 data_blob_free(&state->reply_pdu);
969         }
970
971         if (pkt) {
972                 *pkt = talloc_steal(mem_ctx, state->pkt);
973         }
974
975         return NT_STATUS_OK;
976 }
977
978 /*******************************************************************
979  Creates NTLMSSP auth bind.
980  ********************************************************************/
981
982 static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
983                                                  TALLOC_CTX *mem_ctx,
984                                                  DATA_BLOB *auth_token)
985 {
986         struct gensec_security *gensec_security;
987         DATA_BLOB null_blob = data_blob_null;
988
989         gensec_security = talloc_get_type_abort(cli->auth->auth_ctx,
990                                         struct gensec_security);
991
992         DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
993         return gensec_update(gensec_security, mem_ctx, NULL, null_blob, auth_token);
994 }
995
996 /*******************************************************************
997  Creates schannel auth bind.
998  ********************************************************************/
999
1000 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1001                                                   DATA_BLOB *auth_token)
1002 {
1003         NTSTATUS status;
1004         struct NL_AUTH_MESSAGE r;
1005
1006         /* Use lp_workgroup() if domain not specified */
1007
1008         if (!cli->auth->domain || !cli->auth->domain[0]) {
1009                 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1010                 if (cli->auth->domain == NULL) {
1011                         return NT_STATUS_NO_MEMORY;
1012                 }
1013         }
1014
1015         /*
1016          * Now marshall the data into the auth parse_struct.
1017          */
1018
1019         r.MessageType                   = NL_NEGOTIATE_REQUEST;
1020         r.Flags                         = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1021                                           NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1022         r.oem_netbios_domain.a          = cli->auth->domain;
1023         r.oem_netbios_computer.a        = lp_netbios_name();
1024
1025         status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1026         if (!NT_STATUS_IS_OK(status)) {
1027                 return status;
1028         }
1029
1030         return NT_STATUS_OK;
1031 }
1032
1033 /*******************************************************************
1034  Creates the internals of a DCE/RPC bind request or alter context PDU.
1035  ********************************************************************/
1036
1037 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1038                                                 enum dcerpc_pkt_type ptype,
1039                                                 uint32 rpc_call_id,
1040                                                 const struct ndr_syntax_id *abstract,
1041                                                 const struct ndr_syntax_id *transfer,
1042                                                 const DATA_BLOB *auth_info,
1043                                                 DATA_BLOB *blob)
1044 {
1045         uint16 auth_len = auth_info->length;
1046         NTSTATUS status;
1047         union dcerpc_payload u;
1048         struct dcerpc_ctx_list ctx_list;
1049
1050         if (auth_len) {
1051                 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1052         }
1053
1054         ctx_list.context_id = 0;
1055         ctx_list.num_transfer_syntaxes = 1;
1056         ctx_list.abstract_syntax = *abstract;
1057         ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1058
1059         u.bind.max_xmit_frag    = RPC_MAX_PDU_FRAG_LEN;
1060         u.bind.max_recv_frag    = RPC_MAX_PDU_FRAG_LEN;
1061         u.bind.assoc_group_id   = 0x0;
1062         u.bind.num_contexts     = 1;
1063         u.bind.ctx_list         = &ctx_list;
1064         u.bind.auth_info        = *auth_info;
1065
1066         status = dcerpc_push_ncacn_packet(mem_ctx,
1067                                           ptype,
1068                                           DCERPC_PFC_FLAG_FIRST |
1069                                           DCERPC_PFC_FLAG_LAST,
1070                                           auth_len,
1071                                           rpc_call_id,
1072                                           &u,
1073                                           blob);
1074         if (!NT_STATUS_IS_OK(status)) {
1075                 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1076                 return status;
1077         }
1078
1079         return NT_STATUS_OK;
1080 }
1081
1082 /*******************************************************************
1083  Creates a DCE/RPC bind request.
1084  ********************************************************************/
1085
1086 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1087                                     struct rpc_pipe_client *cli,
1088                                     struct pipe_auth_data *auth,
1089                                     uint32 rpc_call_id,
1090                                     const struct ndr_syntax_id *abstract,
1091                                     const struct ndr_syntax_id *transfer,
1092                                     DATA_BLOB *rpc_out)
1093 {
1094         DATA_BLOB auth_token = data_blob_null;
1095         DATA_BLOB auth_info = data_blob_null;
1096         NTSTATUS ret = NT_STATUS_OK;
1097
1098         switch (auth->auth_type) {
1099         case DCERPC_AUTH_TYPE_SCHANNEL:
1100                 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1101                 if (!NT_STATUS_IS_OK(ret)) {
1102                         return ret;
1103                 }
1104                 break;
1105
1106         case DCERPC_AUTH_TYPE_NTLMSSP:
1107         case DCERPC_AUTH_TYPE_KRB5:
1108         case DCERPC_AUTH_TYPE_SPNEGO:
1109                 ret = create_generic_auth_rpc_bind_req(cli, mem_ctx, &auth_token);
1110
1111                 if (!NT_STATUS_IS_OK(ret) &&
1112                     !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1113                         return ret;
1114                 }
1115                 break;
1116
1117         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1118                 auth_token = data_blob_talloc(mem_ctx,
1119                                               "NCALRPC_AUTH_TOKEN",
1120                                               18);
1121                 break;
1122
1123         case DCERPC_AUTH_TYPE_NONE:
1124                 break;
1125
1126         default:
1127                 /* "Can't" happen. */
1128                 return NT_STATUS_INVALID_INFO_CLASS;
1129         }
1130
1131         if (auth_token.length != 0) {
1132                 ret = dcerpc_push_dcerpc_auth(cli,
1133                                                 auth->auth_type,
1134                                                 auth->auth_level,
1135                                                 0, /* auth_pad_length */
1136                                                 1, /* auth_context_id */
1137                                                 &auth_token,
1138                                                 &auth_info);
1139                 if (!NT_STATUS_IS_OK(ret)) {
1140                         return ret;
1141                 }
1142                 data_blob_free(&auth_token);
1143         }
1144
1145         ret = create_bind_or_alt_ctx_internal(mem_ctx,
1146                                               DCERPC_PKT_BIND,
1147                                               rpc_call_id,
1148                                               abstract,
1149                                               transfer,
1150                                               &auth_info,
1151                                               rpc_out);
1152         return ret;
1153 }
1154
1155 /*******************************************************************
1156  External interface.
1157  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1158  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1159  and deals with signing/sealing details.
1160  ********************************************************************/
1161
1162 struct rpc_api_pipe_req_state {
1163         struct tevent_context *ev;
1164         struct rpc_pipe_client *cli;
1165         uint8_t op_num;
1166         uint32_t call_id;
1167         DATA_BLOB *req_data;
1168         uint32_t req_data_sent;
1169         DATA_BLOB rpc_out;
1170         DATA_BLOB reply_pdu;
1171 };
1172
1173 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1174 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1175 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1176                                   bool *is_last_frag);
1177
1178 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1179                                          struct tevent_context *ev,
1180                                          struct rpc_pipe_client *cli,
1181                                          uint8_t op_num,
1182                                          DATA_BLOB *req_data)
1183 {
1184         struct tevent_req *req, *subreq;
1185         struct rpc_api_pipe_req_state *state;
1186         NTSTATUS status;
1187         bool is_last_frag;
1188
1189         req = tevent_req_create(mem_ctx, &state,
1190                                 struct rpc_api_pipe_req_state);
1191         if (req == NULL) {
1192                 return NULL;
1193         }
1194         state->ev = ev;
1195         state->cli = cli;
1196         state->op_num = op_num;
1197         state->req_data = req_data;
1198         state->req_data_sent = 0;
1199         state->call_id = get_rpc_call_id();
1200         state->reply_pdu = data_blob_null;
1201         state->rpc_out = data_blob_null;
1202
1203         if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1204                                         + RPC_MAX_SIGN_SIZE) {
1205                 /* Server is screwed up ! */
1206                 status = NT_STATUS_INVALID_PARAMETER;
1207                 goto post_status;
1208         }
1209
1210         status = prepare_next_frag(state, &is_last_frag);
1211         if (!NT_STATUS_IS_OK(status)) {
1212                 goto post_status;
1213         }
1214
1215         if (is_last_frag) {
1216                 subreq = rpc_api_pipe_send(state, ev, state->cli,
1217                                            &state->rpc_out,
1218                                            DCERPC_PKT_RESPONSE);
1219                 if (subreq == NULL) {
1220                         goto fail;
1221                 }
1222                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1223         } else {
1224                 subreq = rpc_write_send(state, ev, cli->transport,
1225                                         state->rpc_out.data,
1226                                         state->rpc_out.length);
1227                 if (subreq == NULL) {
1228                         goto fail;
1229                 }
1230                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1231                                         req);
1232         }
1233         return req;
1234
1235  post_status:
1236         tevent_req_nterror(req, status);
1237         return tevent_req_post(req, ev);
1238  fail:
1239         TALLOC_FREE(req);
1240         return NULL;
1241 }
1242
1243 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1244                                   bool *is_last_frag)
1245 {
1246         size_t data_sent_thistime;
1247         size_t auth_len;
1248         size_t frag_len;
1249         uint8_t flags = 0;
1250         size_t pad_len;
1251         size_t data_left;
1252         NTSTATUS status;
1253         union dcerpc_payload u;
1254
1255         data_left = state->req_data->length - state->req_data_sent;
1256
1257         status = dcerpc_guess_sizes(state->cli->auth,
1258                                     DCERPC_REQUEST_LENGTH, data_left,
1259                                     state->cli->max_xmit_frag,
1260                                     CLIENT_NDR_PADDING_SIZE,
1261                                     &data_sent_thistime,
1262                                     &frag_len, &auth_len, &pad_len);
1263         if (!NT_STATUS_IS_OK(status)) {
1264                 return status;
1265         }
1266
1267         if (state->req_data_sent == 0) {
1268                 flags = DCERPC_PFC_FLAG_FIRST;
1269         }
1270
1271         if (data_sent_thistime == data_left) {
1272                 flags |= DCERPC_PFC_FLAG_LAST;
1273         }
1274
1275         data_blob_free(&state->rpc_out);
1276
1277         ZERO_STRUCT(u.request);
1278
1279         u.request.alloc_hint    = state->req_data->length;
1280         u.request.context_id    = 0;
1281         u.request.opnum         = state->op_num;
1282
1283         status = dcerpc_push_ncacn_packet(state,
1284                                           DCERPC_PKT_REQUEST,
1285                                           flags,
1286                                           auth_len,
1287                                           state->call_id,
1288                                           &u,
1289                                           &state->rpc_out);
1290         if (!NT_STATUS_IS_OK(status)) {
1291                 return status;
1292         }
1293
1294         /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1295          * compute it right for requests because the auth trailer is missing
1296          * at this stage */
1297         dcerpc_set_frag_length(&state->rpc_out, frag_len);
1298
1299         /* Copy in the data. */
1300         if (!data_blob_append(NULL, &state->rpc_out,
1301                                 state->req_data->data + state->req_data_sent,
1302                                 data_sent_thistime)) {
1303                 return NT_STATUS_NO_MEMORY;
1304         }
1305
1306         switch (state->cli->auth->auth_level) {
1307         case DCERPC_AUTH_LEVEL_NONE:
1308         case DCERPC_AUTH_LEVEL_CONNECT:
1309         case DCERPC_AUTH_LEVEL_PACKET:
1310                 break;
1311         case DCERPC_AUTH_LEVEL_INTEGRITY:
1312         case DCERPC_AUTH_LEVEL_PRIVACY:
1313                 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1314                                                 &state->rpc_out);
1315                 if (!NT_STATUS_IS_OK(status)) {
1316                         return status;
1317                 }
1318                 break;
1319         default:
1320                 return NT_STATUS_INVALID_PARAMETER;
1321         }
1322
1323         state->req_data_sent += data_sent_thistime;
1324         *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1325
1326         return status;
1327 }
1328
1329 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1330 {
1331         struct tevent_req *req = tevent_req_callback_data(
1332                 subreq, struct tevent_req);
1333         struct rpc_api_pipe_req_state *state = tevent_req_data(
1334                 req, struct rpc_api_pipe_req_state);
1335         NTSTATUS status;
1336         bool is_last_frag;
1337
1338         status = rpc_write_recv(subreq);
1339         TALLOC_FREE(subreq);
1340         if (!NT_STATUS_IS_OK(status)) {
1341                 tevent_req_nterror(req, status);
1342                 return;
1343         }
1344
1345         status = prepare_next_frag(state, &is_last_frag);
1346         if (!NT_STATUS_IS_OK(status)) {
1347                 tevent_req_nterror(req, status);
1348                 return;
1349         }
1350
1351         if (is_last_frag) {
1352                 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1353                                            &state->rpc_out,
1354                                            DCERPC_PKT_RESPONSE);
1355                 if (tevent_req_nomem(subreq, req)) {
1356                         return;
1357                 }
1358                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1359         } else {
1360                 subreq = rpc_write_send(state, state->ev,
1361                                         state->cli->transport,
1362                                         state->rpc_out.data,
1363                                         state->rpc_out.length);
1364                 if (tevent_req_nomem(subreq, req)) {
1365                         return;
1366                 }
1367                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1368                                         req);
1369         }
1370 }
1371
1372 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1373 {
1374         struct tevent_req *req = tevent_req_callback_data(
1375                 subreq, struct tevent_req);
1376         struct rpc_api_pipe_req_state *state = tevent_req_data(
1377                 req, struct rpc_api_pipe_req_state);
1378         NTSTATUS status;
1379
1380         status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1381         TALLOC_FREE(subreq);
1382         if (!NT_STATUS_IS_OK(status)) {
1383                 tevent_req_nterror(req, status);
1384                 return;
1385         }
1386         tevent_req_done(req);
1387 }
1388
1389 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1390                                DATA_BLOB *reply_pdu)
1391 {
1392         struct rpc_api_pipe_req_state *state = tevent_req_data(
1393                 req, struct rpc_api_pipe_req_state);
1394         NTSTATUS status;
1395
1396         if (tevent_req_is_nterror(req, &status)) {
1397                 /*
1398                  * We always have to initialize to reply pdu, even if there is
1399                  * none. The rpccli_* caller routines expect this.
1400                  */
1401                 *reply_pdu = data_blob_null;
1402                 return status;
1403         }
1404
1405         /* return data to caller and assign it ownership of memory */
1406         reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1407         reply_pdu->length = state->reply_pdu.length;
1408         state->reply_pdu.length = 0;
1409
1410         return NT_STATUS_OK;
1411 }
1412
1413 /****************************************************************************
1414  Check the rpc bind acknowledge response.
1415 ****************************************************************************/
1416
1417 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1418                                 const struct ndr_syntax_id *transfer)
1419 {
1420         struct dcerpc_ack_ctx ctx;
1421
1422         if (r->secondary_address_size == 0) {
1423                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1424         }
1425
1426         if (r->num_results < 1 || !r->ctx_list) {
1427                 return false;
1428         }
1429
1430         ctx = r->ctx_list[0];
1431
1432         /* check the transfer syntax */
1433         if ((ctx.syntax.if_version != transfer->if_version) ||
1434              (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1435                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1436                 return False;
1437         }
1438
1439         if (r->num_results != 0x1 || ctx.result != 0) {
1440                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1441                           r->num_results, ctx.reason));
1442         }
1443
1444         DEBUG(5,("check_bind_response: accepted!\n"));
1445         return True;
1446 }
1447
1448 /*******************************************************************
1449  Creates a DCE/RPC bind authentication response.
1450  This is the packet that is sent back to the server once we
1451  have received a BIND-ACK, to finish the third leg of
1452  the authentication handshake.
1453  ********************************************************************/
1454
1455 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1456                                 struct rpc_pipe_client *cli,
1457                                 uint32 rpc_call_id,
1458                                 enum dcerpc_AuthType auth_type,
1459                                 enum dcerpc_AuthLevel auth_level,
1460                                 DATA_BLOB *pauth_blob,
1461                                 DATA_BLOB *rpc_out)
1462 {
1463         NTSTATUS status;
1464         union dcerpc_payload u;
1465
1466         u.auth3._pad = 0;
1467
1468         status = dcerpc_push_dcerpc_auth(mem_ctx,
1469                                          auth_type,
1470                                          auth_level,
1471                                          0, /* auth_pad_length */
1472                                          1, /* auth_context_id */
1473                                          pauth_blob,
1474                                          &u.auth3.auth_info);
1475         if (!NT_STATUS_IS_OK(status)) {
1476                 return status;
1477         }
1478
1479         status = dcerpc_push_ncacn_packet(mem_ctx,
1480                                           DCERPC_PKT_AUTH3,
1481                                           DCERPC_PFC_FLAG_FIRST |
1482                                           DCERPC_PFC_FLAG_LAST,
1483                                           pauth_blob->length,
1484                                           rpc_call_id,
1485                                           &u,
1486                                           rpc_out);
1487         data_blob_free(&u.auth3.auth_info);
1488         if (!NT_STATUS_IS_OK(status)) {
1489                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1490                 return status;
1491         }
1492
1493         return NT_STATUS_OK;
1494 }
1495
1496 /*******************************************************************
1497  Creates a DCE/RPC bind alter context authentication request which
1498  may contain a spnego auth blobl
1499  ********************************************************************/
1500
1501 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1502                                         enum dcerpc_AuthType auth_type,
1503                                         enum dcerpc_AuthLevel auth_level,
1504                                         uint32 rpc_call_id,
1505                                         const struct ndr_syntax_id *abstract,
1506                                         const struct ndr_syntax_id *transfer,
1507                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1508                                         DATA_BLOB *rpc_out)
1509 {
1510         DATA_BLOB auth_info;
1511         NTSTATUS status;
1512
1513         status = dcerpc_push_dcerpc_auth(mem_ctx,
1514                                          auth_type,
1515                                          auth_level,
1516                                          0, /* auth_pad_length */
1517                                          1, /* auth_context_id */
1518                                          pauth_blob,
1519                                          &auth_info);
1520         if (!NT_STATUS_IS_OK(status)) {
1521                 return status;
1522         }
1523
1524         status = create_bind_or_alt_ctx_internal(mem_ctx,
1525                                                  DCERPC_PKT_ALTER,
1526                                                  rpc_call_id,
1527                                                  abstract,
1528                                                  transfer,
1529                                                  &auth_info,
1530                                                  rpc_out);
1531         data_blob_free(&auth_info);
1532         return status;
1533 }
1534
1535 /****************************************************************************
1536  Do an rpc bind.
1537 ****************************************************************************/
1538
1539 struct rpc_pipe_bind_state {
1540         struct tevent_context *ev;
1541         struct rpc_pipe_client *cli;
1542         DATA_BLOB rpc_out;
1543         bool auth3;
1544         uint32_t rpc_call_id;
1545         struct netr_Authenticator auth;
1546         struct netr_Authenticator return_auth;
1547         struct netlogon_creds_CredentialState *creds;
1548         union netr_Capabilities capabilities;
1549         struct netr_LogonGetCapabilities r;
1550 };
1551
1552 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1553 static void rpc_pipe_bind_step_two_trigger(struct tevent_req *req);
1554 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1555                                    struct rpc_pipe_bind_state *state,
1556                                    DATA_BLOB *credentials);
1557 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1558                                      struct rpc_pipe_bind_state *state,
1559                                      DATA_BLOB *credentials);
1560
1561 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1562                                       struct tevent_context *ev,
1563                                       struct rpc_pipe_client *cli,
1564                                       struct pipe_auth_data *auth)
1565 {
1566         struct tevent_req *req, *subreq;
1567         struct rpc_pipe_bind_state *state;
1568         NTSTATUS status;
1569
1570         req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1571         if (req == NULL) {
1572                 return NULL;
1573         }
1574
1575         DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1576                 rpccli_pipe_txt(talloc_tos(), cli),
1577                 (unsigned int)auth->auth_type,
1578                 (unsigned int)auth->auth_level ));
1579
1580         state->ev = ev;
1581         state->cli = cli;
1582         state->rpc_call_id = get_rpc_call_id();
1583
1584         cli->auth = talloc_move(cli, &auth);
1585
1586         /* Marshall the outgoing data. */
1587         status = create_rpc_bind_req(state, cli,
1588                                      cli->auth,
1589                                      state->rpc_call_id,
1590                                      &cli->abstract_syntax,
1591                                      &cli->transfer_syntax,
1592                                      &state->rpc_out);
1593
1594         if (!NT_STATUS_IS_OK(status) &&
1595             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1596                 goto post_status;
1597         }
1598
1599         subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1600                                    DCERPC_PKT_BIND_ACK);
1601         if (subreq == NULL) {
1602                 goto fail;
1603         }
1604         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1605         return req;
1606
1607  post_status:
1608         tevent_req_nterror(req, status);
1609         return tevent_req_post(req, ev);
1610  fail:
1611         TALLOC_FREE(req);
1612         return NULL;
1613 }
1614
1615 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1616 {
1617         struct tevent_req *req = tevent_req_callback_data(
1618                 subreq, struct tevent_req);
1619         struct rpc_pipe_bind_state *state = tevent_req_data(
1620                 req, struct rpc_pipe_bind_state);
1621         struct pipe_auth_data *pauth = state->cli->auth;
1622         struct gensec_security *gensec_security;
1623         struct ncacn_packet *pkt = NULL;
1624         struct dcerpc_auth auth;
1625         DATA_BLOB auth_token = data_blob_null;
1626         NTSTATUS status;
1627
1628         status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1629         TALLOC_FREE(subreq);
1630         if (!NT_STATUS_IS_OK(status)) {
1631                 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1632                           rpccli_pipe_txt(talloc_tos(), state->cli),
1633                           nt_errstr(status)));
1634                 tevent_req_nterror(req, status);
1635                 return;
1636         }
1637
1638         if (state->auth3) {
1639                 tevent_req_done(req);
1640                 return;
1641         }
1642
1643         if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1644                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1645                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1646                 return;
1647         }
1648
1649         state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1650         state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1651
1652         switch(pauth->auth_type) {
1653
1654         case DCERPC_AUTH_TYPE_NONE:
1655         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1656                 /* Bind complete. */
1657                 tevent_req_done(req);
1658                 return;
1659
1660         case DCERPC_AUTH_TYPE_SCHANNEL:
1661                 rpc_pipe_bind_step_two_trigger(req);
1662                 return;
1663
1664         case DCERPC_AUTH_TYPE_NTLMSSP:
1665         case DCERPC_AUTH_TYPE_SPNEGO:
1666         case DCERPC_AUTH_TYPE_KRB5:
1667                 /* Paranoid lenght checks */
1668                 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1669                                                 + pkt->auth_length) {
1670                         tevent_req_nterror(req,
1671                                         NT_STATUS_INFO_LENGTH_MISMATCH);
1672                         return;
1673                 }
1674                 /* get auth credentials */
1675                 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1676                                                  &pkt->u.bind_ack.auth_info,
1677                                                  &auth, false);
1678                 if (!NT_STATUS_IS_OK(status)) {
1679                         DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1680                                   nt_errstr(status)));
1681                         tevent_req_nterror(req, status);
1682                         return;
1683                 }
1684                 break;
1685
1686         default:
1687                 goto err_out;
1688         }
1689
1690         /*
1691          * For authenticated binds we may need to do 3 or 4 leg binds.
1692          */
1693
1694         switch(pauth->auth_type) {
1695
1696         case DCERPC_AUTH_TYPE_NONE:
1697         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1698         case DCERPC_AUTH_TYPE_SCHANNEL:
1699                 /* Bind complete. */
1700                 tevent_req_done(req);
1701                 return;
1702
1703         case DCERPC_AUTH_TYPE_NTLMSSP:
1704         case DCERPC_AUTH_TYPE_KRB5:
1705         case DCERPC_AUTH_TYPE_SPNEGO:
1706                 gensec_security = talloc_get_type_abort(pauth->auth_ctx,
1707                                                 struct gensec_security);
1708                 status = gensec_update(gensec_security, state, NULL,
1709                                        auth.credentials, &auth_token);
1710                 if (NT_STATUS_EQUAL(status,
1711                                     NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1712                         status = rpc_bind_next_send(req, state,
1713                                                         &auth_token);
1714                 } else if (NT_STATUS_IS_OK(status)) {
1715                         if (auth_token.length == 0) {
1716                                 /* Bind complete. */
1717                                 tevent_req_done(req);
1718                                 return;
1719                         }
1720                         status = rpc_bind_finish_send(req, state,
1721                                                         &auth_token);
1722                 }
1723                 break;
1724
1725         default:
1726                 goto err_out;
1727         }
1728
1729         if (!NT_STATUS_IS_OK(status)) {
1730                 tevent_req_nterror(req, status);
1731         }
1732         return;
1733
1734 err_out:
1735         DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1736                  (unsigned int)state->cli->auth->auth_type));
1737         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1738 }
1739
1740 static void rpc_pipe_bind_step_two_done(struct tevent_req *subreq);
1741
1742 static void rpc_pipe_bind_step_two_trigger(struct tevent_req *req)
1743 {
1744         struct rpc_pipe_bind_state *state =
1745                 tevent_req_data(req,
1746                                 struct rpc_pipe_bind_state);
1747         struct dcerpc_binding_handle *b = state->cli->binding_handle;
1748         struct schannel_state *schannel_auth =
1749                 talloc_get_type_abort(state->cli->auth->auth_ctx,
1750                                       struct schannel_state);
1751         struct tevent_req *subreq;
1752
1753         if (schannel_auth == NULL ||
1754             !ndr_syntax_id_equal(&state->cli->abstract_syntax,
1755                                  &ndr_table_netlogon.syntax_id)) {
1756                 tevent_req_done(req);
1757                 return;
1758         }
1759
1760         ZERO_STRUCT(state->return_auth);
1761
1762         state->creds = netlogon_creds_copy(state, schannel_auth->creds);
1763         if (state->creds == NULL) {
1764                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1765                 return;
1766         }
1767
1768         netlogon_creds_client_authenticator(state->creds, &state->auth);
1769
1770         state->r.in.server_name = state->cli->srv_name_slash;
1771         state->r.in.computer_name = state->creds->computer_name;
1772         state->r.in.credential = &state->auth;
1773         state->r.in.query_level = 1;
1774         state->r.in.return_authenticator = &state->return_auth;
1775
1776         state->r.out.capabilities = &state->capabilities;
1777         state->r.out.return_authenticator = &state->return_auth;
1778
1779         subreq = dcerpc_netr_LogonGetCapabilities_r_send(talloc_tos(),
1780                                                          state->ev,
1781                                                          b,
1782                                                          &state->r);
1783         if (subreq == NULL) {
1784                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1785                 return;
1786         }
1787
1788         tevent_req_set_callback(subreq, rpc_pipe_bind_step_two_done, req);
1789         return;
1790 }
1791
1792 static void rpc_pipe_bind_step_two_done(struct tevent_req *subreq)
1793 {
1794         struct tevent_req *req =
1795                 tevent_req_callback_data(subreq,
1796                                          struct tevent_req);
1797         struct rpc_pipe_bind_state *state =
1798                 tevent_req_data(req,
1799                                 struct rpc_pipe_bind_state);
1800         NTSTATUS status;
1801
1802         status = dcerpc_netr_LogonGetCapabilities_r_recv(subreq, talloc_tos());
1803         TALLOC_FREE(subreq);
1804         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
1805                 if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1806                         DEBUG(5, ("AES is not supported and the error was %s\n",
1807                                   nt_errstr(status)));
1808                         tevent_req_nterror(req,
1809                                            NT_STATUS_INVALID_NETWORK_RESPONSE);
1810                         return;
1811                 }
1812
1813                 /* This is probably NT */
1814                 DEBUG(5, ("We are checking against an NT - %s\n",
1815                           nt_errstr(status)));
1816                 tevent_req_done(req);
1817                 return;
1818         } else if (!NT_STATUS_IS_OK(status)) {
1819                 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
1820                           nt_errstr(status)));
1821                 tevent_req_nterror(req, status);
1822                 return;
1823         }
1824
1825         if (NT_STATUS_EQUAL(state->r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1826                 if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1827                         /* This means AES isn't supported. */
1828                         DEBUG(5, ("AES is not supported and the error was %s\n",
1829                                   nt_errstr(state->r.out.result)));
1830                         tevent_req_nterror(req,
1831                                            NT_STATUS_INVALID_NETWORK_RESPONSE);
1832                         return;
1833                 }
1834
1835                 /* This is probably an old Samba version */
1836                 DEBUG(5, ("We are checking against an old Samba version - %s\n",
1837                           nt_errstr(state->r.out.result)));
1838                 tevent_req_done(req);
1839                 return;
1840         }
1841
1842         /* We need to check the credential state here, cause win2k3 and earlier
1843          * returns NT_STATUS_NOT_IMPLEMENTED */
1844         if (!netlogon_creds_client_check(state->creds,
1845                                          &state->r.out.return_authenticator->cred)) {
1846                 /*
1847                  * Server replied with bad credential. Fail.
1848                  */
1849                 DEBUG(0,("rpc_pipe_bind_step_two_done: server %s "
1850                          "replied with bad credential\n",
1851                          state->cli->desthost));
1852                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1853                 return;
1854         }
1855
1856         if (!NT_STATUS_IS_OK(state->r.out.result)) {
1857                 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
1858                           nt_errstr(state->r.out.result)));
1859                 tevent_req_nterror(req, state->r.out.result);
1860                 return;
1861         }
1862
1863         if (!(state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1864                 DEBUG(0, ("netr_LogonGetCapabilities is supported by %s, "
1865                           "but AES was not negotiated - downgrade detected",
1866                          state->cli->desthost));
1867                 tevent_req_nterror(req,
1868                                    NT_STATUS_INVALID_NETWORK_RESPONSE);
1869                 return;
1870         }
1871
1872         TALLOC_FREE(state->cli->dc);
1873         state->cli->dc = talloc_move(state->cli, &state->creds);
1874
1875         tevent_req_done(req);
1876         return;
1877 }
1878
1879 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1880                                    struct rpc_pipe_bind_state *state,
1881                                    DATA_BLOB *auth_token)
1882 {
1883         struct pipe_auth_data *auth = state->cli->auth;
1884         struct tevent_req *subreq;
1885         NTSTATUS status;
1886
1887         /* Now prepare the alter context pdu. */
1888         data_blob_free(&state->rpc_out);
1889
1890         status = create_rpc_alter_context(state,
1891                                           auth->auth_type,
1892                                           auth->auth_level,
1893                                           state->rpc_call_id,
1894                                           &state->cli->abstract_syntax,
1895                                           &state->cli->transfer_syntax,
1896                                           auth_token,
1897                                           &state->rpc_out);
1898         if (!NT_STATUS_IS_OK(status)) {
1899                 return status;
1900         }
1901
1902         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1903                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1904         if (subreq == NULL) {
1905                 return NT_STATUS_NO_MEMORY;
1906         }
1907         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1908         return NT_STATUS_OK;
1909 }
1910
1911 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1912                                      struct rpc_pipe_bind_state *state,
1913                                      DATA_BLOB *auth_token)
1914 {
1915         struct pipe_auth_data *auth = state->cli->auth;
1916         struct tevent_req *subreq;
1917         NTSTATUS status;
1918
1919         state->auth3 = true;
1920
1921         /* Now prepare the auth3 context pdu. */
1922         data_blob_free(&state->rpc_out);
1923
1924         status = create_rpc_bind_auth3(state, state->cli,
1925                                         state->rpc_call_id,
1926                                         auth->auth_type,
1927                                         auth->auth_level,
1928                                         auth_token,
1929                                         &state->rpc_out);
1930         if (!NT_STATUS_IS_OK(status)) {
1931                 return status;
1932         }
1933
1934         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1935                                    &state->rpc_out, DCERPC_PKT_AUTH3);
1936         if (subreq == NULL) {
1937                 return NT_STATUS_NO_MEMORY;
1938         }
1939         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1940         return NT_STATUS_OK;
1941 }
1942
1943 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1944 {
1945         return tevent_req_simple_recv_ntstatus(req);
1946 }
1947
1948 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1949                        struct pipe_auth_data *auth)
1950 {
1951         TALLOC_CTX *frame = talloc_stackframe();
1952         struct tevent_context *ev;
1953         struct tevent_req *req;
1954         NTSTATUS status = NT_STATUS_OK;
1955
1956         ev = samba_tevent_context_init(frame);
1957         if (ev == NULL) {
1958                 status = NT_STATUS_NO_MEMORY;
1959                 goto fail;
1960         }
1961
1962         req = rpc_pipe_bind_send(frame, ev, cli, auth);
1963         if (req == NULL) {
1964                 status = NT_STATUS_NO_MEMORY;
1965                 goto fail;
1966         }
1967
1968         if (!tevent_req_poll(req, ev)) {
1969                 status = map_nt_error_from_unix(errno);
1970                 goto fail;
1971         }
1972
1973         status = rpc_pipe_bind_recv(req);
1974  fail:
1975         TALLOC_FREE(frame);
1976         return status;
1977 }
1978
1979 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1980
1981 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1982                                 unsigned int timeout)
1983 {
1984         unsigned int old;
1985
1986         if (rpc_cli->transport == NULL) {
1987                 return RPCCLI_DEFAULT_TIMEOUT;
1988         }
1989
1990         if (rpc_cli->transport->set_timeout == NULL) {
1991                 return RPCCLI_DEFAULT_TIMEOUT;
1992         }
1993
1994         old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1995         if (old == 0) {
1996                 return RPCCLI_DEFAULT_TIMEOUT;
1997         }
1998
1999         return old;
2000 }
2001
2002 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2003 {
2004         if (rpc_cli == NULL) {
2005                 return false;
2006         }
2007
2008         if (rpc_cli->transport == NULL) {
2009                 return false;
2010         }
2011
2012         return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2013 }
2014
2015 struct rpccli_bh_state {
2016         struct rpc_pipe_client *rpc_cli;
2017 };
2018
2019 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2020 {
2021         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2022                                      struct rpccli_bh_state);
2023
2024         return rpccli_is_connected(hs->rpc_cli);
2025 }
2026
2027 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2028                                       uint32_t timeout)
2029 {
2030         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2031                                      struct rpccli_bh_state);
2032
2033         return rpccli_set_timeout(hs->rpc_cli, timeout);
2034 }
2035
2036 struct rpccli_bh_raw_call_state {
2037         DATA_BLOB in_data;
2038         DATA_BLOB out_data;
2039         uint32_t out_flags;
2040 };
2041
2042 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2043
2044 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2045                                                   struct tevent_context *ev,
2046                                                   struct dcerpc_binding_handle *h,
2047                                                   const struct GUID *object,
2048                                                   uint32_t opnum,
2049                                                   uint32_t in_flags,
2050                                                   const uint8_t *in_data,
2051                                                   size_t in_length)
2052 {
2053         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2054                                      struct rpccli_bh_state);
2055         struct tevent_req *req;
2056         struct rpccli_bh_raw_call_state *state;
2057         bool ok;
2058         struct tevent_req *subreq;
2059
2060         req = tevent_req_create(mem_ctx, &state,
2061                                 struct rpccli_bh_raw_call_state);
2062         if (req == NULL) {
2063                 return NULL;
2064         }
2065         state->in_data.data = discard_const_p(uint8_t, in_data);
2066         state->in_data.length = in_length;
2067
2068         ok = rpccli_bh_is_connected(h);
2069         if (!ok) {
2070                 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2071                 return tevent_req_post(req, ev);
2072         }
2073
2074         subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2075                                        opnum, &state->in_data);
2076         if (tevent_req_nomem(subreq, req)) {
2077                 return tevent_req_post(req, ev);
2078         }
2079         tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2080
2081         return req;
2082 }
2083
2084 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2085 {
2086         struct tevent_req *req =
2087                 tevent_req_callback_data(subreq,
2088                 struct tevent_req);
2089         struct rpccli_bh_raw_call_state *state =
2090                 tevent_req_data(req,
2091                 struct rpccli_bh_raw_call_state);
2092         NTSTATUS status;
2093
2094         state->out_flags = 0;
2095
2096         /* TODO: support bigendian responses */
2097
2098         status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2099         TALLOC_FREE(subreq);
2100         if (!NT_STATUS_IS_OK(status)) {
2101                 tevent_req_nterror(req, status);
2102                 return;
2103         }
2104
2105         tevent_req_done(req);
2106 }
2107
2108 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2109                                         TALLOC_CTX *mem_ctx,
2110                                         uint8_t **out_data,
2111                                         size_t *out_length,
2112                                         uint32_t *out_flags)
2113 {
2114         struct rpccli_bh_raw_call_state *state =
2115                 tevent_req_data(req,
2116                 struct rpccli_bh_raw_call_state);
2117         NTSTATUS status;
2118
2119         if (tevent_req_is_nterror(req, &status)) {
2120                 tevent_req_received(req);
2121                 return status;
2122         }
2123
2124         *out_data = talloc_move(mem_ctx, &state->out_data.data);
2125         *out_length = state->out_data.length;
2126         *out_flags = state->out_flags;
2127         tevent_req_received(req);
2128         return NT_STATUS_OK;
2129 }
2130
2131 struct rpccli_bh_disconnect_state {
2132         uint8_t _dummy;
2133 };
2134
2135 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2136                                                 struct tevent_context *ev,
2137                                                 struct dcerpc_binding_handle *h)
2138 {
2139         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2140                                      struct rpccli_bh_state);
2141         struct tevent_req *req;
2142         struct rpccli_bh_disconnect_state *state;
2143         bool ok;
2144
2145         req = tevent_req_create(mem_ctx, &state,
2146                                 struct rpccli_bh_disconnect_state);
2147         if (req == NULL) {
2148                 return NULL;
2149         }
2150
2151         ok = rpccli_bh_is_connected(h);
2152         if (!ok) {
2153                 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2154                 return tevent_req_post(req, ev);
2155         }
2156
2157         /*
2158          * TODO: do a real async disconnect ...
2159          *
2160          * For now the caller needs to free rpc_cli
2161          */
2162         hs->rpc_cli = NULL;
2163
2164         tevent_req_done(req);
2165         return tevent_req_post(req, ev);
2166 }
2167
2168 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2169 {
2170         NTSTATUS status;
2171
2172         if (tevent_req_is_nterror(req, &status)) {
2173                 tevent_req_received(req);
2174                 return status;
2175         }
2176
2177         tevent_req_received(req);
2178         return NT_STATUS_OK;
2179 }
2180
2181 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2182 {
2183         return true;
2184 }
2185
2186 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2187                                    int ndr_flags,
2188                                    const void *_struct_ptr,
2189                                    const struct ndr_interface_call *call)
2190 {
2191         void *struct_ptr = discard_const(_struct_ptr);
2192
2193         if (DEBUGLEVEL < 10) {
2194                 return;
2195         }
2196
2197         if (ndr_flags & NDR_IN) {
2198                 ndr_print_function_debug(call->ndr_print,
2199                                          call->name,
2200                                          ndr_flags,
2201                                          struct_ptr);
2202         }
2203         if (ndr_flags & NDR_OUT) {
2204                 ndr_print_function_debug(call->ndr_print,
2205                                          call->name,
2206                                          ndr_flags,
2207                                          struct_ptr);
2208         }
2209 }
2210
2211 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2212         .name                   = "rpccli",
2213         .is_connected           = rpccli_bh_is_connected,
2214         .set_timeout            = rpccli_bh_set_timeout,
2215         .raw_call_send          = rpccli_bh_raw_call_send,
2216         .raw_call_recv          = rpccli_bh_raw_call_recv,
2217         .disconnect_send        = rpccli_bh_disconnect_send,
2218         .disconnect_recv        = rpccli_bh_disconnect_recv,
2219
2220         .ref_alloc              = rpccli_bh_ref_alloc,
2221         .do_ndr_print           = rpccli_bh_do_ndr_print,
2222 };
2223
2224 /* initialise a rpc_pipe_client binding handle */
2225 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2226 {
2227         struct dcerpc_binding_handle *h;
2228         struct rpccli_bh_state *hs;
2229
2230         h = dcerpc_binding_handle_create(c,
2231                                          &rpccli_bh_ops,
2232                                          NULL,
2233                                          NULL, /* TODO */
2234                                          &hs,
2235                                          struct rpccli_bh_state,
2236                                          __location__);
2237         if (h == NULL) {
2238                 return NULL;
2239         }
2240         hs->rpc_cli = c;
2241
2242         return h;
2243 }
2244
2245 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2246                                   struct pipe_auth_data **presult)
2247 {
2248         struct pipe_auth_data *result;
2249
2250         result = talloc(mem_ctx, struct pipe_auth_data);
2251         if (result == NULL) {
2252                 return NT_STATUS_NO_MEMORY;
2253         }
2254
2255         result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2256         result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2257
2258         result->user_name = talloc_strdup(result, "");
2259         result->domain = talloc_strdup(result, "");
2260         if ((result->user_name == NULL) || (result->domain == NULL)) {
2261                 TALLOC_FREE(result);
2262                 return NT_STATUS_NO_MEMORY;
2263         }
2264
2265         *presult = result;
2266         return NT_STATUS_OK;
2267 }
2268
2269 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2270                                struct pipe_auth_data **presult)
2271 {
2272         struct pipe_auth_data *result;
2273
2274         result = talloc(mem_ctx, struct pipe_auth_data);
2275         if (result == NULL) {
2276                 return NT_STATUS_NO_MEMORY;
2277         }
2278
2279         result->auth_type = DCERPC_AUTH_TYPE_NONE;
2280         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2281
2282         result->user_name = talloc_strdup(result, "");
2283         result->domain = talloc_strdup(result, "");
2284         if ((result->user_name == NULL) || (result->domain == NULL)) {
2285                 TALLOC_FREE(result);
2286                 return NT_STATUS_NO_MEMORY;
2287         }
2288
2289         *presult = result;
2290         return NT_STATUS_OK;
2291 }
2292
2293 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2294                                          enum dcerpc_AuthType auth_type,
2295                                          enum dcerpc_AuthLevel auth_level,
2296                                          const char *server,
2297                                          const char *target_service,
2298                                          const char *domain,
2299                                          const char *username,
2300                                          const char *password,
2301                                          enum credentials_use_kerberos use_kerberos,
2302                                          struct pipe_auth_data **presult)
2303 {
2304         struct auth_generic_state *auth_generic_ctx;
2305         struct pipe_auth_data *result;
2306         NTSTATUS status;
2307
2308         result = talloc(mem_ctx, struct pipe_auth_data);
2309         if (result == NULL) {
2310                 return NT_STATUS_NO_MEMORY;
2311         }
2312
2313         result->auth_type = auth_type;
2314         result->auth_level = auth_level;
2315
2316         result->user_name = talloc_strdup(result, username);
2317         result->domain = talloc_strdup(result, domain);
2318         if ((result->user_name == NULL) || (result->domain == NULL)) {
2319                 status = NT_STATUS_NO_MEMORY;
2320                 goto fail;
2321         }
2322
2323         status = auth_generic_client_prepare(result,
2324                                              &auth_generic_ctx);
2325         if (!NT_STATUS_IS_OK(status)) {
2326                 goto fail;
2327         }
2328
2329         status = auth_generic_set_username(auth_generic_ctx, username);
2330         if (!NT_STATUS_IS_OK(status)) {
2331                 goto fail;
2332         }
2333
2334         status = auth_generic_set_domain(auth_generic_ctx, domain);
2335         if (!NT_STATUS_IS_OK(status)) {
2336                 goto fail;
2337         }
2338
2339         status = auth_generic_set_password(auth_generic_ctx, password);
2340         if (!NT_STATUS_IS_OK(status)) {
2341                 goto fail;
2342         }
2343
2344         status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2345         if (!NT_STATUS_IS_OK(status)) {
2346                 goto fail;
2347         }
2348
2349         status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2350         if (!NT_STATUS_IS_OK(status)) {
2351                 goto fail;
2352         }
2353
2354         cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
2355
2356         status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2357         if (!NT_STATUS_IS_OK(status)) {
2358                 goto fail;
2359         }
2360
2361         result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2362         talloc_free(auth_generic_ctx);
2363         *presult = result;
2364         return NT_STATUS_OK;
2365
2366  fail:
2367         TALLOC_FREE(result);
2368         return status;
2369 }
2370
2371 static NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx,
2372                                 const char *domain,
2373                                 enum dcerpc_AuthLevel auth_level,
2374                                 struct netlogon_creds_CredentialState *creds,
2375                                 struct pipe_auth_data **presult)
2376 {
2377         struct schannel_state *schannel_auth;
2378         struct pipe_auth_data *result;
2379
2380         result = talloc(mem_ctx, struct pipe_auth_data);
2381         if (result == NULL) {
2382                 return NT_STATUS_NO_MEMORY;
2383         }
2384
2385         result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2386         result->auth_level = auth_level;
2387
2388         result->user_name = talloc_strdup(result, "");
2389         result->domain = talloc_strdup(result, domain);
2390         if ((result->user_name == NULL) || (result->domain == NULL)) {
2391                 goto fail;
2392         }
2393
2394         schannel_auth = talloc_zero(result, struct schannel_state);
2395         if (schannel_auth == NULL) {
2396                 goto fail;
2397         }
2398
2399         schannel_auth->state = SCHANNEL_STATE_START;
2400         schannel_auth->initiator = true;
2401         schannel_auth->creds = netlogon_creds_copy(schannel_auth, creds);
2402         if (schannel_auth->creds == NULL) {
2403                 goto fail;
2404         }
2405
2406         result->auth_ctx = schannel_auth;
2407         *presult = result;
2408         return NT_STATUS_OK;
2409
2410  fail:
2411         TALLOC_FREE(result);
2412         return NT_STATUS_NO_MEMORY;
2413 }
2414
2415 /**
2416  * Create an rpc pipe client struct, connecting to a tcp port.
2417  */
2418 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2419                                        const struct sockaddr_storage *ss_addr,
2420                                        uint16_t port,
2421                                        const struct ndr_interface_table *table,
2422                                        struct rpc_pipe_client **presult)
2423 {
2424         struct rpc_pipe_client *result;
2425         struct sockaddr_storage addr;
2426         NTSTATUS status;
2427         int fd;
2428
2429         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2430         if (result == NULL) {
2431                 return NT_STATUS_NO_MEMORY;
2432         }
2433
2434         result->abstract_syntax = table->syntax_id;
2435         result->transfer_syntax = ndr_transfer_syntax_ndr;
2436
2437         result->desthost = talloc_strdup(result, host);
2438         result->srv_name_slash = talloc_asprintf_strupper_m(
2439                 result, "\\\\%s", result->desthost);
2440         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2441                 status = NT_STATUS_NO_MEMORY;
2442                 goto fail;
2443         }
2444
2445         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2446         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2447
2448         if (ss_addr == NULL) {
2449                 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2450                         status = NT_STATUS_NOT_FOUND;
2451                         goto fail;
2452                 }
2453         } else {
2454                 addr = *ss_addr;
2455         }
2456
2457         status = open_socket_out(&addr, port, 60*1000, &fd);
2458         if (!NT_STATUS_IS_OK(status)) {
2459                 goto fail;
2460         }
2461         set_socket_options(fd, lp_socket_options());
2462
2463         status = rpc_transport_sock_init(result, fd, &result->transport);
2464         if (!NT_STATUS_IS_OK(status)) {
2465                 close(fd);
2466                 goto fail;
2467         }
2468
2469         result->transport->transport = NCACN_IP_TCP;
2470
2471         result->binding_handle = rpccli_bh_create(result);
2472         if (result->binding_handle == NULL) {
2473                 TALLOC_FREE(result);
2474                 return NT_STATUS_NO_MEMORY;
2475         }
2476
2477         *presult = result;
2478         return NT_STATUS_OK;
2479
2480  fail:
2481         TALLOC_FREE(result);
2482         return status;
2483 }
2484
2485 /**
2486  * Determine the tcp port on which a dcerpc interface is listening
2487  * for the ncacn_ip_tcp transport via the endpoint mapper of the
2488  * target host.
2489  */
2490 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2491                                       const struct sockaddr_storage *addr,
2492                                       const struct ndr_interface_table *table,
2493                                       uint16_t *pport)
2494 {
2495         NTSTATUS status;
2496         struct rpc_pipe_client *epm_pipe = NULL;
2497         struct dcerpc_binding_handle *epm_handle = NULL;
2498         struct pipe_auth_data *auth = NULL;
2499         struct dcerpc_binding *map_binding = NULL;
2500         struct dcerpc_binding *res_binding = NULL;
2501         struct epm_twr_t *map_tower = NULL;
2502         struct epm_twr_t *res_towers = NULL;
2503         struct policy_handle *entry_handle = NULL;
2504         uint32_t num_towers = 0;
2505         uint32_t max_towers = 1;
2506         struct epm_twr_p_t towers;
2507         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2508         uint32_t result = 0;
2509
2510         if (pport == NULL) {
2511                 status = NT_STATUS_INVALID_PARAMETER;
2512                 goto done;
2513         }
2514
2515         if (ndr_syntax_id_equal(&table->syntax_id,
2516                                 &ndr_table_epmapper.syntax_id)) {
2517                 *pport = 135;
2518                 return NT_STATUS_OK;
2519         }
2520
2521         /* open the connection to the endpoint mapper */
2522         status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2523                                         &ndr_table_epmapper,
2524                                         &epm_pipe);
2525
2526         if (!NT_STATUS_IS_OK(status)) {
2527                 goto done;
2528         }
2529         epm_handle = epm_pipe->binding_handle;
2530
2531         status = rpccli_anon_bind_data(tmp_ctx, &auth);
2532         if (!NT_STATUS_IS_OK(status)) {
2533                 goto done;
2534         }
2535
2536         status = rpc_pipe_bind(epm_pipe, auth);
2537         if (!NT_STATUS_IS_OK(status)) {
2538                 goto done;
2539         }
2540
2541         /* create tower for asking the epmapper */
2542
2543         map_binding = talloc_zero(tmp_ctx, struct dcerpc_binding);
2544         if (map_binding == NULL) {
2545                 status = NT_STATUS_NO_MEMORY;
2546                 goto done;
2547         }
2548
2549         map_binding->transport = NCACN_IP_TCP;
2550         map_binding->object = table->syntax_id;
2551         map_binding->host = host; /* needed? */
2552         map_binding->endpoint = "0"; /* correct? needed? */
2553
2554         map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2555         if (map_tower == NULL) {
2556                 status = NT_STATUS_NO_MEMORY;
2557                 goto done;
2558         }
2559
2560         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2561                                             &(map_tower->tower));
2562         if (!NT_STATUS_IS_OK(status)) {
2563                 goto done;
2564         }
2565
2566         /* allocate further parameters for the epm_Map call */
2567
2568         res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2569         if (res_towers == NULL) {
2570                 status = NT_STATUS_NO_MEMORY;
2571                 goto done;
2572         }
2573         towers.twr = res_towers;
2574
2575         entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2576         if (entry_handle == NULL) {
2577                 status = NT_STATUS_NO_MEMORY;
2578                 goto done;
2579         }
2580
2581         /* ask the endpoint mapper for the port */
2582
2583         status = dcerpc_epm_Map(epm_handle,
2584                                 tmp_ctx,
2585                                 discard_const_p(struct GUID,
2586                                               &(table->syntax_id.uuid)),
2587                                 map_tower,
2588                                 entry_handle,
2589                                 max_towers,
2590                                 &num_towers,
2591                                 &towers,
2592                                 &result);
2593
2594         if (!NT_STATUS_IS_OK(status)) {
2595                 goto done;
2596         }
2597
2598         if (result != EPMAPPER_STATUS_OK) {
2599                 status = NT_STATUS_UNSUCCESSFUL;
2600                 goto done;
2601         }
2602
2603         if (num_towers != 1) {
2604                 status = NT_STATUS_UNSUCCESSFUL;
2605                 goto done;
2606         }
2607
2608         /* extract the port from the answer */
2609
2610         status = dcerpc_binding_from_tower(tmp_ctx,
2611                                            &(towers.twr->tower),
2612                                            &res_binding);
2613         if (!NT_STATUS_IS_OK(status)) {
2614                 goto done;
2615         }
2616
2617         /* are further checks here necessary? */
2618         if (res_binding->transport != NCACN_IP_TCP) {
2619                 status = NT_STATUS_UNSUCCESSFUL;
2620                 goto done;
2621         }
2622
2623         *pport = (uint16_t)atoi(res_binding->endpoint);
2624
2625 done:
2626         TALLOC_FREE(tmp_ctx);
2627         return status;
2628 }
2629
2630 /**
2631  * Create a rpc pipe client struct, connecting to a host via tcp.
2632  * The port is determined by asking the endpoint mapper on the given
2633  * host.
2634  */
2635 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2636                            const struct sockaddr_storage *addr,
2637                            const struct ndr_interface_table *table,
2638                            struct rpc_pipe_client **presult)
2639 {
2640         NTSTATUS status;
2641         uint16_t port = 0;
2642
2643         status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2644         if (!NT_STATUS_IS_OK(status)) {
2645                 return status;
2646         }
2647
2648         return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2649                                       table, presult);
2650 }
2651
2652 /********************************************************************
2653  Create a rpc pipe client struct, connecting to a unix domain socket
2654  ********************************************************************/
2655 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2656                                const struct ndr_interface_table *table,
2657                                struct rpc_pipe_client **presult)
2658 {
2659         struct rpc_pipe_client *result;
2660         struct sockaddr_un addr;
2661         NTSTATUS status;
2662         int fd;
2663         socklen_t salen;
2664
2665         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2666         if (result == NULL) {
2667                 return NT_STATUS_NO_MEMORY;
2668         }
2669
2670         result->abstract_syntax = table->syntax_id;
2671         result->transfer_syntax = ndr_transfer_syntax_ndr;
2672
2673         result->desthost = get_myname(result);
2674         result->srv_name_slash = talloc_asprintf_strupper_m(
2675                 result, "\\\\%s", result->desthost);
2676         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2677                 status = NT_STATUS_NO_MEMORY;
2678                 goto fail;
2679         }
2680
2681         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2682         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2683
2684         fd = socket(AF_UNIX, SOCK_STREAM, 0);
2685         if (fd == -1) {
2686                 status = map_nt_error_from_unix(errno);
2687                 goto fail;
2688         }
2689
2690         ZERO_STRUCT(addr);
2691         addr.sun_family = AF_UNIX;
2692         strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2693         salen = sizeof(struct sockaddr_un);
2694
2695         if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
2696                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2697                           strerror(errno)));
2698                 close(fd);
2699                 return map_nt_error_from_unix(errno);
2700         }
2701
2702         status = rpc_transport_sock_init(result, fd, &result->transport);
2703         if (!NT_STATUS_IS_OK(status)) {
2704                 close(fd);
2705                 goto fail;
2706         }
2707
2708         result->transport->transport = NCALRPC;
2709
2710         result->binding_handle = rpccli_bh_create(result);
2711         if (result->binding_handle == NULL) {
2712                 TALLOC_FREE(result);
2713                 return NT_STATUS_NO_MEMORY;
2714         }
2715
2716         *presult = result;
2717         return NT_STATUS_OK;
2718
2719  fail:
2720         TALLOC_FREE(result);
2721         return status;
2722 }
2723
2724 struct rpc_pipe_client_np_ref {
2725         struct cli_state *cli;
2726         struct rpc_pipe_client *pipe;
2727 };
2728
2729 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2730 {
2731         DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2732         return 0;
2733 }
2734
2735 /****************************************************************************
2736  Open a named pipe over SMB to a remote server.
2737  *
2738  * CAVEAT CALLER OF THIS FUNCTION:
2739  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2740  *    so be sure that this function is called AFTER any structure (vs pointer)
2741  *    assignment of the cli.  In particular, libsmbclient does structure
2742  *    assignments of cli, which invalidates the data in the returned
2743  *    rpc_pipe_client if this function is called before the structure assignment
2744  *    of cli.
2745  * 
2746  ****************************************************************************/
2747
2748 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2749                                  const struct ndr_interface_table *table,
2750                                  struct rpc_pipe_client **presult)
2751 {
2752         struct rpc_pipe_client *result;
2753         NTSTATUS status;
2754         struct rpc_pipe_client_np_ref *np_ref;
2755
2756         /* sanity check to protect against crashes */
2757
2758         if ( !cli ) {
2759                 return NT_STATUS_INVALID_HANDLE;
2760         }
2761
2762         result = talloc_zero(NULL, struct rpc_pipe_client);
2763         if (result == NULL) {
2764                 return NT_STATUS_NO_MEMORY;
2765         }
2766
2767         result->abstract_syntax = table->syntax_id;
2768         result->transfer_syntax = ndr_transfer_syntax_ndr;
2769         result->desthost = talloc_strdup(result, smbXcli_conn_remote_name(cli->conn));
2770         result->srv_name_slash = talloc_asprintf_strupper_m(
2771                 result, "\\\\%s", result->desthost);
2772
2773         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2774         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2775
2776         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2777                 TALLOC_FREE(result);
2778                 return NT_STATUS_NO_MEMORY;
2779         }
2780
2781         status = rpc_transport_np_init(result, cli, table,
2782                                        &result->transport);
2783         if (!NT_STATUS_IS_OK(status)) {
2784                 TALLOC_FREE(result);
2785                 return status;
2786         }
2787
2788         result->transport->transport = NCACN_NP;
2789
2790         np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2791         if (np_ref == NULL) {
2792                 TALLOC_FREE(result);
2793                 return NT_STATUS_NO_MEMORY;
2794         }
2795         np_ref->cli = cli;
2796         np_ref->pipe = result;
2797
2798         DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2799         talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2800
2801         result->binding_handle = rpccli_bh_create(result);
2802         if (result->binding_handle == NULL) {
2803                 TALLOC_FREE(result);
2804                 return NT_STATUS_NO_MEMORY;
2805         }
2806
2807         *presult = result;
2808         return NT_STATUS_OK;
2809 }
2810
2811 /****************************************************************************
2812  Open a pipe to a remote server.
2813  ****************************************************************************/
2814
2815 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2816                                   enum dcerpc_transport_t transport,
2817                                   const struct ndr_interface_table *table,
2818                                   struct rpc_pipe_client **presult)
2819 {
2820         switch (transport) {
2821         case NCACN_IP_TCP:
2822                 return rpc_pipe_open_tcp(NULL,
2823                                          smbXcli_conn_remote_name(cli->conn),
2824                                          smbXcli_conn_remote_sockaddr(cli->conn),
2825                                          table, presult);
2826         case NCACN_NP:
2827                 return rpc_pipe_open_np(cli, table, presult);
2828         default:
2829                 return NT_STATUS_NOT_IMPLEMENTED;
2830         }
2831 }
2832
2833 /****************************************************************************
2834  Open a named pipe to an SMB server and bind anonymously.
2835  ****************************************************************************/
2836
2837 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2838                                             enum dcerpc_transport_t transport,
2839                                             const struct ndr_interface_table *table,
2840                                             struct rpc_pipe_client **presult)
2841 {
2842         struct rpc_pipe_client *result;
2843         struct pipe_auth_data *auth;
2844         NTSTATUS status;
2845
2846         status = cli_rpc_pipe_open(cli, transport, table, &result);
2847         if (!NT_STATUS_IS_OK(status)) {
2848                 return status;
2849         }
2850
2851         status = rpccli_anon_bind_data(result, &auth);
2852         if (!NT_STATUS_IS_OK(status)) {
2853                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2854                           nt_errstr(status)));
2855                 TALLOC_FREE(result);
2856                 return status;
2857         }
2858
2859         /*
2860          * This is a bit of an abstraction violation due to the fact that an
2861          * anonymous bind on an authenticated SMB inherits the user/domain
2862          * from the enclosing SMB creds
2863          */
2864
2865         TALLOC_FREE(auth->user_name);
2866         TALLOC_FREE(auth->domain);
2867
2868         auth->user_name = talloc_strdup(auth, cli->user_name);
2869         auth->domain = talloc_strdup(auth, cli->domain);
2870
2871         if (transport == NCACN_NP) {
2872                 struct smbXcli_session *session;
2873
2874                 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2875                         session = cli->smb2.session;
2876                 } else {
2877                         session = cli->smb1.session;
2878                 }
2879
2880                 status = smbXcli_session_application_key(session, auth,
2881                                                 &auth->transport_session_key);
2882                 if (!NT_STATUS_IS_OK(status)) {
2883                         auth->transport_session_key = data_blob_null;
2884                 }
2885         }
2886
2887         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2888                 TALLOC_FREE(result);
2889                 return NT_STATUS_NO_MEMORY;
2890         }
2891
2892         status = rpc_pipe_bind(result, auth);
2893         if (!NT_STATUS_IS_OK(status)) {
2894                 int lvl = 0;
2895                 if (ndr_syntax_id_equal(&table->syntax_id,
2896                                         &ndr_table_dssetup.syntax_id)) {
2897                         /* non AD domains just don't have this pipe, avoid
2898                          * level 0 statement in that case - gd */
2899                         lvl = 3;
2900                 }
2901                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2902                             "%s failed with error %s\n",
2903                             get_pipe_name_from_syntax(talloc_tos(),
2904                                                       &table->syntax_id),
2905                             nt_errstr(status) ));
2906                 TALLOC_FREE(result);
2907                 return status;
2908         }
2909
2910         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2911                   "%s and bound anonymously.\n",
2912                   get_pipe_name_from_syntax(talloc_tos(), &table->syntax_id),
2913                   result->desthost));
2914
2915         *presult = result;
2916         return NT_STATUS_OK;
2917 }
2918
2919 /****************************************************************************
2920  ****************************************************************************/
2921
2922 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2923                                   const struct ndr_interface_table *table,
2924                                   struct rpc_pipe_client **presult)
2925 {
2926         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2927                                                   table, presult);
2928 }
2929
2930 /****************************************************************************
2931  Open a named pipe to an SMB server and bind using the mech specified
2932  ****************************************************************************/
2933
2934 NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
2935                                         const struct ndr_interface_table *table,
2936                                         enum dcerpc_transport_t transport,
2937                                         enum dcerpc_AuthType auth_type,
2938                                         enum dcerpc_AuthLevel auth_level,
2939                                         const char *server,
2940                                         const char *domain,
2941                                         const char *username,
2942                                         const char *password,
2943                                         struct rpc_pipe_client **presult)
2944 {
2945         struct rpc_pipe_client *result;
2946         struct pipe_auth_data *auth = NULL;
2947         const char *target_service = table->authservices->names[0];
2948         
2949         NTSTATUS status;
2950
2951         status = cli_rpc_pipe_open(cli, transport, table, &result);
2952         if (!NT_STATUS_IS_OK(status)) {
2953                 return status;
2954         }
2955
2956         status = rpccli_generic_bind_data(result,
2957                                           auth_type, auth_level,
2958                                           server, target_service,
2959                                           domain, username, password, 
2960                                           CRED_AUTO_USE_KERBEROS,
2961                                           &auth);
2962         if (!NT_STATUS_IS_OK(status)) {
2963                 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
2964                           nt_errstr(status)));
2965                 goto err;
2966         }
2967
2968         status = rpc_pipe_bind(result, auth);
2969         if (!NT_STATUS_IS_OK(status)) {
2970                 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
2971                         nt_errstr(status) ));
2972                 goto err;
2973         }
2974
2975         DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
2976                 "machine %s and bound as user %s\\%s.\n", table->name,
2977                   result->desthost, domain, username));
2978
2979         *presult = result;
2980         return NT_STATUS_OK;
2981
2982   err:
2983
2984         TALLOC_FREE(result);
2985         return status;
2986 }
2987
2988 /****************************************************************************
2989  External interface.
2990  Open a named pipe to an SMB server and bind using schannel (bind type 68)
2991  using session_key. sign and seal.
2992
2993  The *pdc will be stolen onto this new pipe
2994  ****************************************************************************/
2995
2996 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2997                                              const struct ndr_interface_table *table,
2998                                              enum dcerpc_transport_t transport,
2999                                              enum dcerpc_AuthLevel auth_level,
3000                                              const char *domain,
3001                                              struct netlogon_creds_CredentialState **pdc,
3002                                              struct rpc_pipe_client **_rpccli)
3003 {
3004         struct rpc_pipe_client *rpccli;
3005         struct pipe_auth_data *rpcauth;
3006         NTSTATUS status;
3007
3008         status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
3009         if (!NT_STATUS_IS_OK(status)) {
3010                 return status;
3011         }
3012
3013         status = rpccli_schannel_bind_data(rpccli, domain, auth_level,
3014                                            *pdc, &rpcauth);
3015         if (!NT_STATUS_IS_OK(status)) {
3016                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3017                           nt_errstr(status)));
3018                 TALLOC_FREE(rpccli);
3019                 return status;
3020         }
3021
3022         /*
3023          * The credentials on a new netlogon pipe are the ones we are passed
3024          * in - copy them over
3025          *
3026          * This may get overwritten... in rpc_pipe_bind()...
3027          */
3028         rpccli->dc = netlogon_creds_copy(rpccli, *pdc);
3029         if (rpccli->dc == NULL) {
3030                 TALLOC_FREE(rpccli);
3031                 return NT_STATUS_NO_MEMORY;
3032         }
3033
3034         status = rpc_pipe_bind(rpccli, rpcauth);
3035         if (!NT_STATUS_IS_OK(status)) {
3036                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3037                           "cli_rpc_pipe_bind failed with error %s\n",
3038                           nt_errstr(status) ));
3039                 TALLOC_FREE(rpccli);
3040                 return status;
3041         }
3042
3043         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3044                   "for domain %s and bound using schannel.\n",
3045                   get_pipe_name_from_syntax(talloc_tos(), &table->syntax_id),
3046                   rpccli->desthost, domain));
3047
3048         *_rpccli = rpccli;
3049         return NT_STATUS_OK;
3050 }
3051
3052 NTSTATUS cli_rpc_pipe_open_spnego(struct cli_state *cli,
3053                                   const struct ndr_interface_table *table,
3054                                   enum dcerpc_transport_t transport,
3055                                   const char *oid,
3056                                   enum dcerpc_AuthLevel auth_level,
3057                                   const char *server,
3058                                   const char *domain,
3059                                   const char *username,
3060                                   const char *password,
3061                                   struct rpc_pipe_client **presult)
3062 {
3063         struct rpc_pipe_client *result;
3064         struct pipe_auth_data *auth = NULL;
3065         const char *target_service = table->authservices->names[0];
3066         
3067         NTSTATUS status;
3068         enum credentials_use_kerberos use_kerberos;
3069
3070         if (strcmp(oid, GENSEC_OID_KERBEROS5) == 0) {
3071                 use_kerberos = CRED_MUST_USE_KERBEROS;
3072         } else if (strcmp(oid, GENSEC_OID_NTLMSSP) == 0) {
3073                 use_kerberos = CRED_DONT_USE_KERBEROS;
3074         } else {
3075                 return NT_STATUS_INVALID_PARAMETER;
3076         }
3077
3078         status = cli_rpc_pipe_open(cli, transport, table, &result);
3079         if (!NT_STATUS_IS_OK(status)) {
3080                 return status;
3081         }
3082
3083         status = rpccli_generic_bind_data(result,
3084                                           DCERPC_AUTH_TYPE_SPNEGO, auth_level,
3085                                           server, target_service,
3086                                           domain, username, password, 
3087                                           use_kerberos,
3088                                           &auth);
3089         if (!NT_STATUS_IS_OK(status)) {
3090                 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3091                           nt_errstr(status)));
3092                 goto err;
3093         }
3094
3095         status = rpc_pipe_bind(result, auth);
3096         if (!NT_STATUS_IS_OK(status)) {
3097                 DEBUG(0, ("cli_rpc_pipe_open_spnego: cli_rpc_pipe_bind failed with error %s\n",
3098                         nt_errstr(status) ));
3099                 goto err;
3100         }
3101
3102         DEBUG(10,("cli_rpc_pipe_open_spnego: opened pipe %s to "
3103                   "machine %s.\n", table->name,
3104                   result->desthost));
3105
3106         *presult = result;
3107         return NT_STATUS_OK;
3108
3109   err:
3110
3111         TALLOC_FREE(result);
3112         return status;
3113 }
3114
3115 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3116                              struct rpc_pipe_client *cli,
3117                              DATA_BLOB *session_key)
3118 {
3119         NTSTATUS status;
3120         struct pipe_auth_data *a;
3121         struct schannel_state *schannel_auth;
3122         struct gensec_security *gensec_security;
3123         DATA_BLOB sk = data_blob_null;
3124         bool make_dup = false;
3125
3126         if (!session_key || !cli) {
3127                 return NT_STATUS_INVALID_PARAMETER;
3128         }
3129
3130         a = cli->auth;
3131
3132         if (a == NULL) {
3133                 return NT_STATUS_INVALID_PARAMETER;
3134         }
3135
3136         switch (cli->auth->auth_type) {
3137         case DCERPC_AUTH_TYPE_SCHANNEL:
3138                 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3139                                                       struct schannel_state);
3140                 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3141                 make_dup = true;
3142                 break;
3143         case DCERPC_AUTH_TYPE_SPNEGO:
3144         case DCERPC_AUTH_TYPE_NTLMSSP:
3145         case DCERPC_AUTH_TYPE_KRB5:
3146                 gensec_security = talloc_get_type_abort(a->auth_ctx,
3147                                                 struct gensec_security);
3148                 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3149                 if (!NT_STATUS_IS_OK(status)) {
3150                         return status;
3151                 }
3152                 make_dup = false;
3153                 break;
3154         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3155         case DCERPC_AUTH_TYPE_NONE:
3156                 sk = data_blob_const(a->transport_session_key.data,
3157                                      a->transport_session_key.length);
3158                 make_dup = true;
3159                 break;
3160         default:
3161                 break;
3162         }
3163
3164         if (!sk.data) {
3165                 return NT_STATUS_NO_USER_SESSION_KEY;
3166         }
3167
3168         if (make_dup) {
3169                 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3170         } else {
3171                 *session_key = sk;
3172         }
3173
3174         return NT_STATUS_OK;
3175 }