s3:rpc_client: fix/add AES downgrade detection to rpc_pipe_bind_step_two_done()
[metze/samba/wip.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->incoming_frag = data_blob_null;
729         state->reply_pdu = data_blob_null;
730         state->reply_pdu_offset = 0;
731         state->endianess = DCERPC_DREP_LE;
732
733         /*
734          * Ensure we're not sending too much.
735          */
736         if (data->length > cli->max_xmit_frag) {
737                 status = NT_STATUS_INVALID_PARAMETER;
738                 goto post_status;
739         }
740
741         DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
742
743         if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
744                 subreq = rpc_write_send(state, ev, cli->transport,
745                                         data->data, data->length);
746                 if (subreq == NULL) {
747                         goto fail;
748                 }
749                 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
750                 return req;
751         }
752
753         /* get the header first, then fetch the rest once we have
754          * the frag_length available */
755         max_recv_frag = RPC_HEADER_LEN;
756
757         subreq = cli_api_pipe_send(state, ev, cli->transport,
758                                    data->data, data->length, max_recv_frag);
759         if (subreq == NULL) {
760                 goto fail;
761         }
762         tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
763         return req;
764
765  post_status:
766         tevent_req_nterror(req, status);
767         return tevent_req_post(req, ev);
768  fail:
769         TALLOC_FREE(req);
770         return NULL;
771 }
772
773 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
774 {
775         struct tevent_req *req =
776                 tevent_req_callback_data(subreq,
777                 struct tevent_req);
778         NTSTATUS status;
779
780         status = rpc_write_recv(subreq);
781         TALLOC_FREE(subreq);
782         if (!NT_STATUS_IS_OK(status)) {
783                 tevent_req_nterror(req, status);
784                 return;
785         }
786
787         tevent_req_done(req);
788 }
789
790 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
791 {
792         struct tevent_req *req = tevent_req_callback_data(
793                 subreq, struct tevent_req);
794         struct rpc_api_pipe_state *state = tevent_req_data(
795                 req, struct rpc_api_pipe_state);
796         NTSTATUS status;
797         uint8_t *rdata = NULL;
798         uint32_t rdata_len = 0;
799
800         status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
801         TALLOC_FREE(subreq);
802         if (!NT_STATUS_IS_OK(status)) {
803                 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
804                 tevent_req_nterror(req, status);
805                 return;
806         }
807
808         if (rdata == NULL) {
809                 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
810                          rpccli_pipe_txt(talloc_tos(), state->cli)));
811                 tevent_req_done(req);
812                 return;
813         }
814
815         /*
816          * Move data on state->incoming_frag.
817          */
818         state->incoming_frag.data = talloc_move(state, &rdata);
819         state->incoming_frag.length = rdata_len;
820         if (!state->incoming_frag.data) {
821                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
822                 return;
823         }
824
825         /* Ensure we have enough data for a pdu. */
826         subreq = get_complete_frag_send(state, state->ev, state->cli,
827                                         &state->incoming_frag);
828         if (tevent_req_nomem(subreq, req)) {
829                 return;
830         }
831         tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
832 }
833
834 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
835 {
836         struct tevent_req *req = tevent_req_callback_data(
837                 subreq, struct tevent_req);
838         struct rpc_api_pipe_state *state = tevent_req_data(
839                 req, struct rpc_api_pipe_state);
840         NTSTATUS status;
841         DATA_BLOB rdata = data_blob_null;
842
843         status = get_complete_frag_recv(subreq);
844         TALLOC_FREE(subreq);
845         if (!NT_STATUS_IS_OK(status)) {
846                 DEBUG(5, ("get_complete_frag failed: %s\n",
847                           nt_errstr(status)));
848                 tevent_req_nterror(req, status);
849                 return;
850         }
851
852         state->pkt = talloc(state, struct ncacn_packet);
853         if (!state->pkt) {
854                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
855                 return;
856         }
857
858         status = dcerpc_pull_ncacn_packet(state->pkt,
859                                           &state->incoming_frag,
860                                           state->pkt,
861                                           !state->endianess);
862         if (!NT_STATUS_IS_OK(status)) {
863                 tevent_req_nterror(req, status);
864                 return;
865         }
866
867         if (state->incoming_frag.length != state->pkt->frag_length) {
868                 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
869                           (unsigned int)state->incoming_frag.length,
870                           (unsigned int)state->pkt->frag_length));
871                 tevent_req_nterror(req,  NT_STATUS_INVALID_PARAMETER);
872                 return;
873         }
874
875         status = cli_pipe_validate_current_pdu(state,
876                                                 state->cli, state->pkt,
877                                                 &state->incoming_frag,
878                                                 state->expected_pkt_type,
879                                                 &rdata,
880                                                 &state->reply_pdu);
881
882         DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
883                   (unsigned)state->incoming_frag.length,
884                   (unsigned)state->reply_pdu_offset,
885                   nt_errstr(status)));
886
887         if (!NT_STATUS_IS_OK(status)) {
888                 tevent_req_nterror(req, status);
889                 return;
890         }
891
892         if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
893             && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
894                 /*
895                  * Set the data type correctly for big-endian data on the
896                  * first packet.
897                  */
898                 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
899                           "big-endian.\n",
900                           rpccli_pipe_txt(talloc_tos(), state->cli)));
901                 state->endianess = 0x00; /* BIG ENDIAN */
902         }
903         /*
904          * Check endianness on subsequent packets.
905          */
906         if (state->endianess != state->pkt->drep[0]) {
907                 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
908                          "%s\n",
909                          state->endianess?"little":"big",
910                          state->pkt->drep[0]?"little":"big"));
911                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
912                 return;
913         }
914
915         /* Now copy the data portion out of the pdu into rbuf. */
916         if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
917                 if (!data_blob_realloc(NULL, &state->reply_pdu,
918                                 state->reply_pdu_offset + rdata.length)) {
919                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
920                         return;
921                 }
922         }
923
924         memcpy(state->reply_pdu.data + state->reply_pdu_offset,
925                 rdata.data, rdata.length);
926         state->reply_pdu_offset += rdata.length;
927
928         /* reset state->incoming_frag, there is no need to free it,
929          * it will be reallocated to the right size the next time
930          * it is used */
931         state->incoming_frag.length = 0;
932
933         if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
934                 /* make sure the pdu length is right now that we
935                  * have all the data available (alloc hint may
936                  * have allocated more than was actually used) */
937                 state->reply_pdu.length = state->reply_pdu_offset;
938                 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
939                           rpccli_pipe_txt(talloc_tos(), state->cli),
940                           (unsigned)state->reply_pdu.length));
941                 tevent_req_done(req);
942                 return;
943         }
944
945         subreq = get_complete_frag_send(state, state->ev, state->cli,
946                                         &state->incoming_frag);
947         if (tevent_req_nomem(subreq, req)) {
948                 return;
949         }
950         tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
951 }
952
953 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
954                                   struct ncacn_packet **pkt,
955                                   DATA_BLOB *reply_pdu)
956 {
957         struct rpc_api_pipe_state *state = tevent_req_data(
958                 req, struct rpc_api_pipe_state);
959         NTSTATUS status;
960
961         if (tevent_req_is_nterror(req, &status)) {
962                 return status;
963         }
964
965         /* return data to caller and assign it ownership of memory */
966         if (reply_pdu) {
967                 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
968                 reply_pdu->length = state->reply_pdu.length;
969                 state->reply_pdu.length = 0;
970         } else {
971                 data_blob_free(&state->reply_pdu);
972         }
973
974         if (pkt) {
975                 *pkt = talloc_steal(mem_ctx, state->pkt);
976         }
977
978         return NT_STATUS_OK;
979 }
980
981 /*******************************************************************
982  Creates NTLMSSP auth bind.
983  ********************************************************************/
984
985 static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
986                                                  TALLOC_CTX *mem_ctx,
987                                                  DATA_BLOB *auth_token)
988 {
989         struct gensec_security *gensec_security;
990         DATA_BLOB null_blob = data_blob_null;
991
992         gensec_security = talloc_get_type_abort(cli->auth->auth_ctx,
993                                         struct gensec_security);
994
995         DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
996         return gensec_update(gensec_security, mem_ctx, NULL, null_blob, auth_token);
997 }
998
999 /*******************************************************************
1000  Creates schannel auth bind.
1001  ********************************************************************/
1002
1003 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1004                                                   DATA_BLOB *auth_token)
1005 {
1006         NTSTATUS status;
1007         struct NL_AUTH_MESSAGE r;
1008
1009         /* Use lp_workgroup() if domain not specified */
1010
1011         if (!cli->auth->domain || !cli->auth->domain[0]) {
1012                 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1013                 if (cli->auth->domain == NULL) {
1014                         return NT_STATUS_NO_MEMORY;
1015                 }
1016         }
1017
1018         /*
1019          * Now marshall the data into the auth parse_struct.
1020          */
1021
1022         r.MessageType                   = NL_NEGOTIATE_REQUEST;
1023         r.Flags                         = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1024                                           NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1025         r.oem_netbios_domain.a          = cli->auth->domain;
1026         r.oem_netbios_computer.a        = lp_netbios_name();
1027
1028         status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1029         if (!NT_STATUS_IS_OK(status)) {
1030                 return status;
1031         }
1032
1033         return NT_STATUS_OK;
1034 }
1035
1036 /*******************************************************************
1037  Creates the internals of a DCE/RPC bind request or alter context PDU.
1038  ********************************************************************/
1039
1040 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1041                                                 enum dcerpc_pkt_type ptype,
1042                                                 uint32 rpc_call_id,
1043                                                 const struct ndr_syntax_id *abstract,
1044                                                 const struct ndr_syntax_id *transfer,
1045                                                 const DATA_BLOB *auth_info,
1046                                                 DATA_BLOB *blob)
1047 {
1048         uint16 auth_len = auth_info->length;
1049         NTSTATUS status;
1050         union dcerpc_payload u;
1051         struct dcerpc_ctx_list ctx_list;
1052
1053         if (auth_len) {
1054                 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1055         }
1056
1057         ctx_list.context_id = 0;
1058         ctx_list.num_transfer_syntaxes = 1;
1059         ctx_list.abstract_syntax = *abstract;
1060         ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1061
1062         u.bind.max_xmit_frag    = RPC_MAX_PDU_FRAG_LEN;
1063         u.bind.max_recv_frag    = RPC_MAX_PDU_FRAG_LEN;
1064         u.bind.assoc_group_id   = 0x0;
1065         u.bind.num_contexts     = 1;
1066         u.bind.ctx_list         = &ctx_list;
1067         u.bind.auth_info        = *auth_info;
1068
1069         status = dcerpc_push_ncacn_packet(mem_ctx,
1070                                           ptype,
1071                                           DCERPC_PFC_FLAG_FIRST |
1072                                           DCERPC_PFC_FLAG_LAST,
1073                                           auth_len,
1074                                           rpc_call_id,
1075                                           &u,
1076                                           blob);
1077         if (!NT_STATUS_IS_OK(status)) {
1078                 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1079                 return status;
1080         }
1081
1082         return NT_STATUS_OK;
1083 }
1084
1085 /*******************************************************************
1086  Creates a DCE/RPC bind request.
1087  ********************************************************************/
1088
1089 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1090                                     struct rpc_pipe_client *cli,
1091                                     struct pipe_auth_data *auth,
1092                                     uint32 rpc_call_id,
1093                                     const struct ndr_syntax_id *abstract,
1094                                     const struct ndr_syntax_id *transfer,
1095                                     DATA_BLOB *rpc_out)
1096 {
1097         DATA_BLOB auth_token = data_blob_null;
1098         DATA_BLOB auth_info = data_blob_null;
1099         NTSTATUS ret = NT_STATUS_OK;
1100
1101         switch (auth->auth_type) {
1102         case DCERPC_AUTH_TYPE_SCHANNEL:
1103                 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1104                 if (!NT_STATUS_IS_OK(ret)) {
1105                         return ret;
1106                 }
1107                 break;
1108
1109         case DCERPC_AUTH_TYPE_NTLMSSP:
1110         case DCERPC_AUTH_TYPE_KRB5:
1111         case DCERPC_AUTH_TYPE_SPNEGO:
1112                 ret = create_generic_auth_rpc_bind_req(cli, mem_ctx, &auth_token);
1113
1114                 if (!NT_STATUS_IS_OK(ret) &&
1115                     !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1116                         return ret;
1117                 }
1118                 break;
1119
1120         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1121                 auth_token = data_blob_talloc(mem_ctx,
1122                                               "NCALRPC_AUTH_TOKEN",
1123                                               18);
1124                 break;
1125
1126         case DCERPC_AUTH_TYPE_NONE:
1127                 break;
1128
1129         default:
1130                 /* "Can't" happen. */
1131                 return NT_STATUS_INVALID_INFO_CLASS;
1132         }
1133
1134         if (auth_token.length != 0) {
1135                 ret = dcerpc_push_dcerpc_auth(cli,
1136                                                 auth->auth_type,
1137                                                 auth->auth_level,
1138                                                 0, /* auth_pad_length */
1139                                                 1, /* auth_context_id */
1140                                                 &auth_token,
1141                                                 &auth_info);
1142                 if (!NT_STATUS_IS_OK(ret)) {
1143                         return ret;
1144                 }
1145                 data_blob_free(&auth_token);
1146         }
1147
1148         ret = create_bind_or_alt_ctx_internal(mem_ctx,
1149                                               DCERPC_PKT_BIND,
1150                                               rpc_call_id,
1151                                               abstract,
1152                                               transfer,
1153                                               &auth_info,
1154                                               rpc_out);
1155         return ret;
1156 }
1157
1158 /*******************************************************************
1159  External interface.
1160  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1161  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1162  and deals with signing/sealing details.
1163  ********************************************************************/
1164
1165 struct rpc_api_pipe_req_state {
1166         struct tevent_context *ev;
1167         struct rpc_pipe_client *cli;
1168         uint8_t op_num;
1169         uint32_t call_id;
1170         DATA_BLOB *req_data;
1171         uint32_t req_data_sent;
1172         DATA_BLOB rpc_out;
1173         DATA_BLOB reply_pdu;
1174 };
1175
1176 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1177 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1178 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1179                                   bool *is_last_frag);
1180
1181 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1182                                          struct tevent_context *ev,
1183                                          struct rpc_pipe_client *cli,
1184                                          uint8_t op_num,
1185                                          DATA_BLOB *req_data)
1186 {
1187         struct tevent_req *req, *subreq;
1188         struct rpc_api_pipe_req_state *state;
1189         NTSTATUS status;
1190         bool is_last_frag;
1191
1192         req = tevent_req_create(mem_ctx, &state,
1193                                 struct rpc_api_pipe_req_state);
1194         if (req == NULL) {
1195                 return NULL;
1196         }
1197         state->ev = ev;
1198         state->cli = cli;
1199         state->op_num = op_num;
1200         state->req_data = req_data;
1201         state->req_data_sent = 0;
1202         state->call_id = get_rpc_call_id();
1203         state->reply_pdu = data_blob_null;
1204         state->rpc_out = data_blob_null;
1205
1206         if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1207                                         + RPC_MAX_SIGN_SIZE) {
1208                 /* Server is screwed up ! */
1209                 status = NT_STATUS_INVALID_PARAMETER;
1210                 goto post_status;
1211         }
1212
1213         status = prepare_next_frag(state, &is_last_frag);
1214         if (!NT_STATUS_IS_OK(status)) {
1215                 goto post_status;
1216         }
1217
1218         if (is_last_frag) {
1219                 subreq = rpc_api_pipe_send(state, ev, state->cli,
1220                                            &state->rpc_out,
1221                                            DCERPC_PKT_RESPONSE);
1222                 if (subreq == NULL) {
1223                         goto fail;
1224                 }
1225                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1226         } else {
1227                 subreq = rpc_write_send(state, ev, cli->transport,
1228                                         state->rpc_out.data,
1229                                         state->rpc_out.length);
1230                 if (subreq == NULL) {
1231                         goto fail;
1232                 }
1233                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1234                                         req);
1235         }
1236         return req;
1237
1238  post_status:
1239         tevent_req_nterror(req, status);
1240         return tevent_req_post(req, ev);
1241  fail:
1242         TALLOC_FREE(req);
1243         return NULL;
1244 }
1245
1246 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1247                                   bool *is_last_frag)
1248 {
1249         size_t data_sent_thistime;
1250         size_t auth_len;
1251         size_t frag_len;
1252         uint8_t flags = 0;
1253         size_t pad_len;
1254         size_t data_left;
1255         NTSTATUS status;
1256         union dcerpc_payload u;
1257
1258         data_left = state->req_data->length - state->req_data_sent;
1259
1260         status = dcerpc_guess_sizes(state->cli->auth,
1261                                     DCERPC_REQUEST_LENGTH, data_left,
1262                                     state->cli->max_xmit_frag,
1263                                     CLIENT_NDR_PADDING_SIZE,
1264                                     &data_sent_thistime,
1265                                     &frag_len, &auth_len, &pad_len);
1266         if (!NT_STATUS_IS_OK(status)) {
1267                 return status;
1268         }
1269
1270         if (state->req_data_sent == 0) {
1271                 flags = DCERPC_PFC_FLAG_FIRST;
1272         }
1273
1274         if (data_sent_thistime == data_left) {
1275                 flags |= DCERPC_PFC_FLAG_LAST;
1276         }
1277
1278         data_blob_free(&state->rpc_out);
1279
1280         ZERO_STRUCT(u.request);
1281
1282         u.request.alloc_hint    = state->req_data->length;
1283         u.request.context_id    = 0;
1284         u.request.opnum         = state->op_num;
1285
1286         status = dcerpc_push_ncacn_packet(state,
1287                                           DCERPC_PKT_REQUEST,
1288                                           flags,
1289                                           auth_len,
1290                                           state->call_id,
1291                                           &u,
1292                                           &state->rpc_out);
1293         if (!NT_STATUS_IS_OK(status)) {
1294                 return status;
1295         }
1296
1297         /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1298          * compute it right for requests because the auth trailer is missing
1299          * at this stage */
1300         dcerpc_set_frag_length(&state->rpc_out, frag_len);
1301
1302         /* Copy in the data. */
1303         if (!data_blob_append(NULL, &state->rpc_out,
1304                                 state->req_data->data + state->req_data_sent,
1305                                 data_sent_thistime)) {
1306                 return NT_STATUS_NO_MEMORY;
1307         }
1308
1309         switch (state->cli->auth->auth_level) {
1310         case DCERPC_AUTH_LEVEL_NONE:
1311         case DCERPC_AUTH_LEVEL_CONNECT:
1312         case DCERPC_AUTH_LEVEL_PACKET:
1313                 break;
1314         case DCERPC_AUTH_LEVEL_INTEGRITY:
1315         case DCERPC_AUTH_LEVEL_PRIVACY:
1316                 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1317                                                 &state->rpc_out);
1318                 if (!NT_STATUS_IS_OK(status)) {
1319                         return status;
1320                 }
1321                 break;
1322         default:
1323                 return NT_STATUS_INVALID_PARAMETER;
1324         }
1325
1326         state->req_data_sent += data_sent_thistime;
1327         *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1328
1329         return status;
1330 }
1331
1332 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1333 {
1334         struct tevent_req *req = tevent_req_callback_data(
1335                 subreq, struct tevent_req);
1336         struct rpc_api_pipe_req_state *state = tevent_req_data(
1337                 req, struct rpc_api_pipe_req_state);
1338         NTSTATUS status;
1339         bool is_last_frag;
1340
1341         status = rpc_write_recv(subreq);
1342         TALLOC_FREE(subreq);
1343         if (!NT_STATUS_IS_OK(status)) {
1344                 tevent_req_nterror(req, status);
1345                 return;
1346         }
1347
1348         status = prepare_next_frag(state, &is_last_frag);
1349         if (!NT_STATUS_IS_OK(status)) {
1350                 tevent_req_nterror(req, status);
1351                 return;
1352         }
1353
1354         if (is_last_frag) {
1355                 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1356                                            &state->rpc_out,
1357                                            DCERPC_PKT_RESPONSE);
1358                 if (tevent_req_nomem(subreq, req)) {
1359                         return;
1360                 }
1361                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1362         } else {
1363                 subreq = rpc_write_send(state, state->ev,
1364                                         state->cli->transport,
1365                                         state->rpc_out.data,
1366                                         state->rpc_out.length);
1367                 if (tevent_req_nomem(subreq, req)) {
1368                         return;
1369                 }
1370                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1371                                         req);
1372         }
1373 }
1374
1375 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1376 {
1377         struct tevent_req *req = tevent_req_callback_data(
1378                 subreq, struct tevent_req);
1379         struct rpc_api_pipe_req_state *state = tevent_req_data(
1380                 req, struct rpc_api_pipe_req_state);
1381         NTSTATUS status;
1382
1383         status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1384         TALLOC_FREE(subreq);
1385         if (!NT_STATUS_IS_OK(status)) {
1386                 tevent_req_nterror(req, status);
1387                 return;
1388         }
1389         tevent_req_done(req);
1390 }
1391
1392 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1393                                DATA_BLOB *reply_pdu)
1394 {
1395         struct rpc_api_pipe_req_state *state = tevent_req_data(
1396                 req, struct rpc_api_pipe_req_state);
1397         NTSTATUS status;
1398
1399         if (tevent_req_is_nterror(req, &status)) {
1400                 /*
1401                  * We always have to initialize to reply pdu, even if there is
1402                  * none. The rpccli_* caller routines expect this.
1403                  */
1404                 *reply_pdu = data_blob_null;
1405                 return status;
1406         }
1407
1408         /* return data to caller and assign it ownership of memory */
1409         reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1410         reply_pdu->length = state->reply_pdu.length;
1411         state->reply_pdu.length = 0;
1412
1413         return NT_STATUS_OK;
1414 }
1415
1416 /****************************************************************************
1417  Check the rpc bind acknowledge response.
1418 ****************************************************************************/
1419
1420 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1421                                 const struct ndr_syntax_id *transfer)
1422 {
1423         struct dcerpc_ack_ctx ctx;
1424
1425         if (r->secondary_address_size == 0) {
1426                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1427         }
1428
1429         if (r->num_results < 1 || !r->ctx_list) {
1430                 return false;
1431         }
1432
1433         ctx = r->ctx_list[0];
1434
1435         /* check the transfer syntax */
1436         if ((ctx.syntax.if_version != transfer->if_version) ||
1437              (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1438                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1439                 return False;
1440         }
1441
1442         if (r->num_results != 0x1 || ctx.result != 0) {
1443                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1444                           r->num_results, ctx.reason));
1445         }
1446
1447         DEBUG(5,("check_bind_response: accepted!\n"));
1448         return True;
1449 }
1450
1451 /*******************************************************************
1452  Creates a DCE/RPC bind authentication response.
1453  This is the packet that is sent back to the server once we
1454  have received a BIND-ACK, to finish the third leg of
1455  the authentication handshake.
1456  ********************************************************************/
1457
1458 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1459                                 struct rpc_pipe_client *cli,
1460                                 uint32 rpc_call_id,
1461                                 enum dcerpc_AuthType auth_type,
1462                                 enum dcerpc_AuthLevel auth_level,
1463                                 DATA_BLOB *pauth_blob,
1464                                 DATA_BLOB *rpc_out)
1465 {
1466         NTSTATUS status;
1467         union dcerpc_payload u;
1468
1469         u.auth3._pad = 0;
1470
1471         status = dcerpc_push_dcerpc_auth(mem_ctx,
1472                                          auth_type,
1473                                          auth_level,
1474                                          0, /* auth_pad_length */
1475                                          1, /* auth_context_id */
1476                                          pauth_blob,
1477                                          &u.auth3.auth_info);
1478         if (!NT_STATUS_IS_OK(status)) {
1479                 return status;
1480         }
1481
1482         status = dcerpc_push_ncacn_packet(mem_ctx,
1483                                           DCERPC_PKT_AUTH3,
1484                                           DCERPC_PFC_FLAG_FIRST |
1485                                           DCERPC_PFC_FLAG_LAST,
1486                                           pauth_blob->length,
1487                                           rpc_call_id,
1488                                           &u,
1489                                           rpc_out);
1490         data_blob_free(&u.auth3.auth_info);
1491         if (!NT_STATUS_IS_OK(status)) {
1492                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1493                 return status;
1494         }
1495
1496         return NT_STATUS_OK;
1497 }
1498
1499 /*******************************************************************
1500  Creates a DCE/RPC bind alter context authentication request which
1501  may contain a spnego auth blobl
1502  ********************************************************************/
1503
1504 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1505                                         enum dcerpc_AuthType auth_type,
1506                                         enum dcerpc_AuthLevel auth_level,
1507                                         uint32 rpc_call_id,
1508                                         const struct ndr_syntax_id *abstract,
1509                                         const struct ndr_syntax_id *transfer,
1510                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1511                                         DATA_BLOB *rpc_out)
1512 {
1513         DATA_BLOB auth_info;
1514         NTSTATUS status;
1515
1516         status = dcerpc_push_dcerpc_auth(mem_ctx,
1517                                          auth_type,
1518                                          auth_level,
1519                                          0, /* auth_pad_length */
1520                                          1, /* auth_context_id */
1521                                          pauth_blob,
1522                                          &auth_info);
1523         if (!NT_STATUS_IS_OK(status)) {
1524                 return status;
1525         }
1526
1527         status = create_bind_or_alt_ctx_internal(mem_ctx,
1528                                                  DCERPC_PKT_ALTER,
1529                                                  rpc_call_id,
1530                                                  abstract,
1531                                                  transfer,
1532                                                  &auth_info,
1533                                                  rpc_out);
1534         data_blob_free(&auth_info);
1535         return status;
1536 }
1537
1538 /****************************************************************************
1539  Do an rpc bind.
1540 ****************************************************************************/
1541
1542 struct rpc_pipe_bind_state {
1543         struct tevent_context *ev;
1544         struct rpc_pipe_client *cli;
1545         DATA_BLOB rpc_out;
1546         bool auth3;
1547         uint32_t rpc_call_id;
1548         struct netr_Authenticator auth;
1549         struct netr_Authenticator return_auth;
1550         struct netlogon_creds_CredentialState *creds;
1551         union netr_Capabilities capabilities;
1552         struct netr_LogonGetCapabilities r;
1553 };
1554
1555 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1556 static void rpc_pipe_bind_step_two_trigger(struct tevent_req *req);
1557 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1558                                    struct rpc_pipe_bind_state *state,
1559                                    DATA_BLOB *credentials);
1560 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1561                                      struct rpc_pipe_bind_state *state,
1562                                      DATA_BLOB *credentials);
1563
1564 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1565                                       struct tevent_context *ev,
1566                                       struct rpc_pipe_client *cli,
1567                                       struct pipe_auth_data *auth)
1568 {
1569         struct tevent_req *req, *subreq;
1570         struct rpc_pipe_bind_state *state;
1571         NTSTATUS status;
1572
1573         req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1574         if (req == NULL) {
1575                 return NULL;
1576         }
1577
1578         DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1579                 rpccli_pipe_txt(talloc_tos(), cli),
1580                 (unsigned int)auth->auth_type,
1581                 (unsigned int)auth->auth_level ));
1582
1583         state->ev = ev;
1584         state->cli = cli;
1585         state->rpc_call_id = get_rpc_call_id();
1586
1587         cli->auth = talloc_move(cli, &auth);
1588
1589         /* Marshall the outgoing data. */
1590         status = create_rpc_bind_req(state, cli,
1591                                      cli->auth,
1592                                      state->rpc_call_id,
1593                                      &cli->abstract_syntax,
1594                                      &cli->transfer_syntax,
1595                                      &state->rpc_out);
1596
1597         if (!NT_STATUS_IS_OK(status) &&
1598             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1599                 goto post_status;
1600         }
1601
1602         subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1603                                    DCERPC_PKT_BIND_ACK);
1604         if (subreq == NULL) {
1605                 goto fail;
1606         }
1607         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1608         return req;
1609
1610  post_status:
1611         tevent_req_nterror(req, status);
1612         return tevent_req_post(req, ev);
1613  fail:
1614         TALLOC_FREE(req);
1615         return NULL;
1616 }
1617
1618 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1619 {
1620         struct tevent_req *req = tevent_req_callback_data(
1621                 subreq, struct tevent_req);
1622         struct rpc_pipe_bind_state *state = tevent_req_data(
1623                 req, struct rpc_pipe_bind_state);
1624         struct pipe_auth_data *pauth = state->cli->auth;
1625         struct gensec_security *gensec_security;
1626         struct ncacn_packet *pkt = NULL;
1627         struct dcerpc_auth auth;
1628         DATA_BLOB auth_token = data_blob_null;
1629         NTSTATUS status;
1630
1631         status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1632         TALLOC_FREE(subreq);
1633         if (!NT_STATUS_IS_OK(status)) {
1634                 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1635                           rpccli_pipe_txt(talloc_tos(), state->cli),
1636                           nt_errstr(status)));
1637                 tevent_req_nterror(req, status);
1638                 return;
1639         }
1640
1641         if (state->auth3) {
1642                 tevent_req_done(req);
1643                 return;
1644         }
1645
1646         if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1647                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1648                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1649                 return;
1650         }
1651
1652         state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1653         state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1654
1655         switch(pauth->auth_type) {
1656
1657         case DCERPC_AUTH_TYPE_NONE:
1658         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1659                 /* Bind complete. */
1660                 tevent_req_done(req);
1661                 return;
1662
1663         case DCERPC_AUTH_TYPE_SCHANNEL:
1664                 rpc_pipe_bind_step_two_trigger(req);
1665                 return;
1666
1667         case DCERPC_AUTH_TYPE_NTLMSSP:
1668         case DCERPC_AUTH_TYPE_SPNEGO:
1669         case DCERPC_AUTH_TYPE_KRB5:
1670                 /* Paranoid lenght checks */
1671                 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1672                                                 + pkt->auth_length) {
1673                         tevent_req_nterror(req,
1674                                         NT_STATUS_INFO_LENGTH_MISMATCH);
1675                         return;
1676                 }
1677                 /* get auth credentials */
1678                 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1679                                                  &pkt->u.bind_ack.auth_info,
1680                                                  &auth, false);
1681                 if (!NT_STATUS_IS_OK(status)) {
1682                         DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1683                                   nt_errstr(status)));
1684                         tevent_req_nterror(req, status);
1685                         return;
1686                 }
1687                 break;
1688
1689         default:
1690                 goto err_out;
1691         }
1692
1693         /*
1694          * For authenticated binds we may need to do 3 or 4 leg binds.
1695          */
1696
1697         switch(pauth->auth_type) {
1698
1699         case DCERPC_AUTH_TYPE_NONE:
1700         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1701         case DCERPC_AUTH_TYPE_SCHANNEL:
1702                 /* Bind complete. */
1703                 tevent_req_done(req);
1704                 return;
1705
1706         case DCERPC_AUTH_TYPE_NTLMSSP:
1707         case DCERPC_AUTH_TYPE_KRB5:
1708         case DCERPC_AUTH_TYPE_SPNEGO:
1709                 gensec_security = talloc_get_type_abort(pauth->auth_ctx,
1710                                                 struct gensec_security);
1711                 status = gensec_update(gensec_security, state, NULL,
1712                                        auth.credentials, &auth_token);
1713                 if (NT_STATUS_EQUAL(status,
1714                                     NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1715                         status = rpc_bind_next_send(req, state,
1716                                                         &auth_token);
1717                 } else if (NT_STATUS_IS_OK(status)) {
1718                         if (auth_token.length == 0) {
1719                                 /* Bind complete. */
1720                                 tevent_req_done(req);
1721                                 return;
1722                         }
1723                         status = rpc_bind_finish_send(req, state,
1724                                                         &auth_token);
1725                 }
1726                 break;
1727
1728         default:
1729                 goto err_out;
1730         }
1731
1732         if (!NT_STATUS_IS_OK(status)) {
1733                 tevent_req_nterror(req, status);
1734         }
1735         return;
1736
1737 err_out:
1738         DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1739                  (unsigned int)state->cli->auth->auth_type));
1740         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1741 }
1742
1743 static void rpc_pipe_bind_step_two_done(struct tevent_req *subreq);
1744
1745 static void rpc_pipe_bind_step_two_trigger(struct tevent_req *req)
1746 {
1747         struct rpc_pipe_bind_state *state =
1748                 tevent_req_data(req,
1749                                 struct rpc_pipe_bind_state);
1750         struct dcerpc_binding_handle *b = state->cli->binding_handle;
1751         struct schannel_state *schannel_auth =
1752                 talloc_get_type_abort(state->cli->auth->auth_ctx,
1753                                       struct schannel_state);
1754         struct tevent_req *subreq;
1755
1756         if (schannel_auth == NULL ||
1757             !ndr_syntax_id_equal(&state->cli->abstract_syntax,
1758                                  &ndr_table_netlogon.syntax_id)) {
1759                 tevent_req_done(req);
1760                 return;
1761         }
1762
1763         ZERO_STRUCT(state->return_auth);
1764
1765         state->creds = netlogon_creds_copy(state, schannel_auth->creds);
1766         if (state->creds == NULL) {
1767                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1768                 return;
1769         }
1770
1771         netlogon_creds_client_authenticator(state->creds, &state->auth);
1772
1773         state->r.in.server_name = state->cli->srv_name_slash;
1774         state->r.in.computer_name = state->creds->computer_name;
1775         state->r.in.credential = &state->auth;
1776         state->r.in.query_level = 1;
1777         state->r.in.return_authenticator = &state->return_auth;
1778
1779         state->r.out.capabilities = &state->capabilities;
1780         state->r.out.return_authenticator = &state->return_auth;
1781
1782         subreq = dcerpc_netr_LogonGetCapabilities_r_send(talloc_tos(),
1783                                                          state->ev,
1784                                                          b,
1785                                                          &state->r);
1786         if (subreq == NULL) {
1787                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1788                 return;
1789         }
1790
1791         tevent_req_set_callback(subreq, rpc_pipe_bind_step_two_done, req);
1792         return;
1793 }
1794
1795 static void rpc_pipe_bind_step_two_done(struct tevent_req *subreq)
1796 {
1797         struct tevent_req *req =
1798                 tevent_req_callback_data(subreq,
1799                                          struct tevent_req);
1800         struct rpc_pipe_bind_state *state =
1801                 tevent_req_data(req,
1802                                 struct rpc_pipe_bind_state);
1803         NTSTATUS status;
1804
1805         status = dcerpc_netr_LogonGetCapabilities_r_recv(subreq, talloc_tos());
1806         TALLOC_FREE(subreq);
1807         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
1808                 if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1809                         DEBUG(5, ("AES is not supported and the error was %s\n",
1810                                   nt_errstr(status)));
1811                         tevent_req_nterror(req,
1812                                            NT_STATUS_INVALID_NETWORK_RESPONSE);
1813                         return;
1814                 }
1815
1816                 /* This is probably NT */
1817                 DEBUG(5, ("We are checking against an NT - %s\n",
1818                           nt_errstr(status)));
1819                 tevent_req_done(req);
1820                 return;
1821         } else if (!NT_STATUS_IS_OK(status)) {
1822                 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
1823                           nt_errstr(status)));
1824                 tevent_req_nterror(req, status);
1825                 return;
1826         }
1827
1828         if (NT_STATUS_EQUAL(state->r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1829                 if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1830                         /* This means AES isn't supported. */
1831                         DEBUG(5, ("AES is not supported and the error was %s\n",
1832                                   nt_errstr(state->r.out.result)));
1833                         tevent_req_nterror(req,
1834                                            NT_STATUS_INVALID_NETWORK_RESPONSE);
1835                         return;
1836                 }
1837
1838                 /* This is probably an old Samba version */
1839                 DEBUG(5, ("We are checking against an old Samba version - %s\n",
1840                           nt_errstr(state->r.out.result)));
1841                 tevent_req_done(req);
1842                 return;
1843         }
1844
1845         /* We need to check the credential state here, cause win2k3 and earlier
1846          * returns NT_STATUS_NOT_IMPLEMENTED */
1847         if (!netlogon_creds_client_check(state->creds,
1848                                          &state->r.out.return_authenticator->cred)) {
1849                 /*
1850                  * Server replied with bad credential. Fail.
1851                  */
1852                 DEBUG(0,("rpc_pipe_bind_step_two_done: server %s "
1853                          "replied with bad credential\n",
1854                          state->cli->desthost));
1855                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1856                 return;
1857         }
1858
1859         if (!NT_STATUS_IS_OK(state->r.out.result)) {
1860                 DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
1861                           nt_errstr(state->r.out.result)));
1862                 tevent_req_nterror(req, state->r.out.result);
1863                 return;
1864         }
1865
1866         if (!(state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1867                 DEBUG(0, ("netr_LogonGetCapabilities is supported by %s, "
1868                           "but AES was not negotiated - downgrade detected",
1869                          state->cli->desthost));
1870                 tevent_req_nterror(req,
1871                                    NT_STATUS_INVALID_NETWORK_RESPONSE);
1872                 return;
1873         }
1874
1875         TALLOC_FREE(state->cli->dc);
1876         state->cli->dc = talloc_move(state->cli, &state->creds);
1877
1878         tevent_req_done(req);
1879         return;
1880 }
1881
1882 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1883                                    struct rpc_pipe_bind_state *state,
1884                                    DATA_BLOB *auth_token)
1885 {
1886         struct pipe_auth_data *auth = state->cli->auth;
1887         struct tevent_req *subreq;
1888         NTSTATUS status;
1889
1890         /* Now prepare the alter context pdu. */
1891         data_blob_free(&state->rpc_out);
1892
1893         status = create_rpc_alter_context(state,
1894                                           auth->auth_type,
1895                                           auth->auth_level,
1896                                           state->rpc_call_id,
1897                                           &state->cli->abstract_syntax,
1898                                           &state->cli->transfer_syntax,
1899                                           auth_token,
1900                                           &state->rpc_out);
1901         if (!NT_STATUS_IS_OK(status)) {
1902                 return status;
1903         }
1904
1905         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1906                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1907         if (subreq == NULL) {
1908                 return NT_STATUS_NO_MEMORY;
1909         }
1910         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1911         return NT_STATUS_OK;
1912 }
1913
1914 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1915                                      struct rpc_pipe_bind_state *state,
1916                                      DATA_BLOB *auth_token)
1917 {
1918         struct pipe_auth_data *auth = state->cli->auth;
1919         struct tevent_req *subreq;
1920         NTSTATUS status;
1921
1922         state->auth3 = true;
1923
1924         /* Now prepare the auth3 context pdu. */
1925         data_blob_free(&state->rpc_out);
1926
1927         status = create_rpc_bind_auth3(state, state->cli,
1928                                         state->rpc_call_id,
1929                                         auth->auth_type,
1930                                         auth->auth_level,
1931                                         auth_token,
1932                                         &state->rpc_out);
1933         if (!NT_STATUS_IS_OK(status)) {
1934                 return status;
1935         }
1936
1937         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1938                                    &state->rpc_out, DCERPC_PKT_AUTH3);
1939         if (subreq == NULL) {
1940                 return NT_STATUS_NO_MEMORY;
1941         }
1942         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1943         return NT_STATUS_OK;
1944 }
1945
1946 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1947 {
1948         return tevent_req_simple_recv_ntstatus(req);
1949 }
1950
1951 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1952                        struct pipe_auth_data *auth)
1953 {
1954         TALLOC_CTX *frame = talloc_stackframe();
1955         struct tevent_context *ev;
1956         struct tevent_req *req;
1957         NTSTATUS status = NT_STATUS_OK;
1958
1959         ev = samba_tevent_context_init(frame);
1960         if (ev == NULL) {
1961                 status = NT_STATUS_NO_MEMORY;
1962                 goto fail;
1963         }
1964
1965         req = rpc_pipe_bind_send(frame, ev, cli, auth);
1966         if (req == NULL) {
1967                 status = NT_STATUS_NO_MEMORY;
1968                 goto fail;
1969         }
1970
1971         if (!tevent_req_poll(req, ev)) {
1972                 status = map_nt_error_from_unix(errno);
1973                 goto fail;
1974         }
1975
1976         status = rpc_pipe_bind_recv(req);
1977  fail:
1978         TALLOC_FREE(frame);
1979         return status;
1980 }
1981
1982 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1983
1984 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1985                                 unsigned int timeout)
1986 {
1987         unsigned int old;
1988
1989         if (rpc_cli->transport == NULL) {
1990                 return RPCCLI_DEFAULT_TIMEOUT;
1991         }
1992
1993         if (rpc_cli->transport->set_timeout == NULL) {
1994                 return RPCCLI_DEFAULT_TIMEOUT;
1995         }
1996
1997         old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1998         if (old == 0) {
1999                 return RPCCLI_DEFAULT_TIMEOUT;
2000         }
2001
2002         return old;
2003 }
2004
2005 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2006 {
2007         if (rpc_cli == NULL) {
2008                 return false;
2009         }
2010
2011         if (rpc_cli->transport == NULL) {
2012                 return false;
2013         }
2014
2015         return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2016 }
2017
2018 struct rpccli_bh_state {
2019         struct rpc_pipe_client *rpc_cli;
2020 };
2021
2022 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2023 {
2024         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2025                                      struct rpccli_bh_state);
2026
2027         return rpccli_is_connected(hs->rpc_cli);
2028 }
2029
2030 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2031                                       uint32_t timeout)
2032 {
2033         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2034                                      struct rpccli_bh_state);
2035
2036         return rpccli_set_timeout(hs->rpc_cli, timeout);
2037 }
2038
2039 struct rpccli_bh_raw_call_state {
2040         DATA_BLOB in_data;
2041         DATA_BLOB out_data;
2042         uint32_t out_flags;
2043 };
2044
2045 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2046
2047 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2048                                                   struct tevent_context *ev,
2049                                                   struct dcerpc_binding_handle *h,
2050                                                   const struct GUID *object,
2051                                                   uint32_t opnum,
2052                                                   uint32_t in_flags,
2053                                                   const uint8_t *in_data,
2054                                                   size_t in_length)
2055 {
2056         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2057                                      struct rpccli_bh_state);
2058         struct tevent_req *req;
2059         struct rpccli_bh_raw_call_state *state;
2060         bool ok;
2061         struct tevent_req *subreq;
2062
2063         req = tevent_req_create(mem_ctx, &state,
2064                                 struct rpccli_bh_raw_call_state);
2065         if (req == NULL) {
2066                 return NULL;
2067         }
2068         state->in_data.data = discard_const_p(uint8_t, in_data);
2069         state->in_data.length = in_length;
2070
2071         ok = rpccli_bh_is_connected(h);
2072         if (!ok) {
2073                 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2074                 return tevent_req_post(req, ev);
2075         }
2076
2077         subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2078                                        opnum, &state->in_data);
2079         if (tevent_req_nomem(subreq, req)) {
2080                 return tevent_req_post(req, ev);
2081         }
2082         tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2083
2084         return req;
2085 }
2086
2087 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2088 {
2089         struct tevent_req *req =
2090                 tevent_req_callback_data(subreq,
2091                 struct tevent_req);
2092         struct rpccli_bh_raw_call_state *state =
2093                 tevent_req_data(req,
2094                 struct rpccli_bh_raw_call_state);
2095         NTSTATUS status;
2096
2097         state->out_flags = 0;
2098
2099         /* TODO: support bigendian responses */
2100
2101         status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2102         TALLOC_FREE(subreq);
2103         if (!NT_STATUS_IS_OK(status)) {
2104                 tevent_req_nterror(req, status);
2105                 return;
2106         }
2107
2108         tevent_req_done(req);
2109 }
2110
2111 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2112                                         TALLOC_CTX *mem_ctx,
2113                                         uint8_t **out_data,
2114                                         size_t *out_length,
2115                                         uint32_t *out_flags)
2116 {
2117         struct rpccli_bh_raw_call_state *state =
2118                 tevent_req_data(req,
2119                 struct rpccli_bh_raw_call_state);
2120         NTSTATUS status;
2121
2122         if (tevent_req_is_nterror(req, &status)) {
2123                 tevent_req_received(req);
2124                 return status;
2125         }
2126
2127         *out_data = talloc_move(mem_ctx, &state->out_data.data);
2128         *out_length = state->out_data.length;
2129         *out_flags = state->out_flags;
2130         tevent_req_received(req);
2131         return NT_STATUS_OK;
2132 }
2133
2134 struct rpccli_bh_disconnect_state {
2135         uint8_t _dummy;
2136 };
2137
2138 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2139                                                 struct tevent_context *ev,
2140                                                 struct dcerpc_binding_handle *h)
2141 {
2142         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2143                                      struct rpccli_bh_state);
2144         struct tevent_req *req;
2145         struct rpccli_bh_disconnect_state *state;
2146         bool ok;
2147
2148         req = tevent_req_create(mem_ctx, &state,
2149                                 struct rpccli_bh_disconnect_state);
2150         if (req == NULL) {
2151                 return NULL;
2152         }
2153
2154         ok = rpccli_bh_is_connected(h);
2155         if (!ok) {
2156                 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2157                 return tevent_req_post(req, ev);
2158         }
2159
2160         /*
2161          * TODO: do a real async disconnect ...
2162          *
2163          * For now the caller needs to free rpc_cli
2164          */
2165         hs->rpc_cli = NULL;
2166
2167         tevent_req_done(req);
2168         return tevent_req_post(req, ev);
2169 }
2170
2171 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2172 {
2173         NTSTATUS status;
2174
2175         if (tevent_req_is_nterror(req, &status)) {
2176                 tevent_req_received(req);
2177                 return status;
2178         }
2179
2180         tevent_req_received(req);
2181         return NT_STATUS_OK;
2182 }
2183
2184 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2185 {
2186         return true;
2187 }
2188
2189 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2190                                    int ndr_flags,
2191                                    const void *_struct_ptr,
2192                                    const struct ndr_interface_call *call)
2193 {
2194         void *struct_ptr = discard_const(_struct_ptr);
2195
2196         if (DEBUGLEVEL < 10) {
2197                 return;
2198         }
2199
2200         if (ndr_flags & NDR_IN) {
2201                 ndr_print_function_debug(call->ndr_print,
2202                                          call->name,
2203                                          ndr_flags,
2204                                          struct_ptr);
2205         }
2206         if (ndr_flags & NDR_OUT) {
2207                 ndr_print_function_debug(call->ndr_print,
2208                                          call->name,
2209                                          ndr_flags,
2210                                          struct_ptr);
2211         }
2212 }
2213
2214 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2215         .name                   = "rpccli",
2216         .is_connected           = rpccli_bh_is_connected,
2217         .set_timeout            = rpccli_bh_set_timeout,
2218         .raw_call_send          = rpccli_bh_raw_call_send,
2219         .raw_call_recv          = rpccli_bh_raw_call_recv,
2220         .disconnect_send        = rpccli_bh_disconnect_send,
2221         .disconnect_recv        = rpccli_bh_disconnect_recv,
2222
2223         .ref_alloc              = rpccli_bh_ref_alloc,
2224         .do_ndr_print           = rpccli_bh_do_ndr_print,
2225 };
2226
2227 /* initialise a rpc_pipe_client binding handle */
2228 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2229 {
2230         struct dcerpc_binding_handle *h;
2231         struct rpccli_bh_state *hs;
2232
2233         h = dcerpc_binding_handle_create(c,
2234                                          &rpccli_bh_ops,
2235                                          NULL,
2236                                          NULL, /* TODO */
2237                                          &hs,
2238                                          struct rpccli_bh_state,
2239                                          __location__);
2240         if (h == NULL) {
2241                 return NULL;
2242         }
2243         hs->rpc_cli = c;
2244
2245         return h;
2246 }
2247
2248 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2249                                   struct pipe_auth_data **presult)
2250 {
2251         struct pipe_auth_data *result;
2252
2253         result = talloc(mem_ctx, struct pipe_auth_data);
2254         if (result == NULL) {
2255                 return NT_STATUS_NO_MEMORY;
2256         }
2257
2258         result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2259         result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2260
2261         result->user_name = talloc_strdup(result, "");
2262         result->domain = talloc_strdup(result, "");
2263         if ((result->user_name == NULL) || (result->domain == NULL)) {
2264                 TALLOC_FREE(result);
2265                 return NT_STATUS_NO_MEMORY;
2266         }
2267
2268         *presult = result;
2269         return NT_STATUS_OK;
2270 }
2271
2272 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2273                                struct pipe_auth_data **presult)
2274 {
2275         struct pipe_auth_data *result;
2276
2277         result = talloc(mem_ctx, struct pipe_auth_data);
2278         if (result == NULL) {
2279                 return NT_STATUS_NO_MEMORY;
2280         }
2281
2282         result->auth_type = DCERPC_AUTH_TYPE_NONE;
2283         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2284
2285         result->user_name = talloc_strdup(result, "");
2286         result->domain = talloc_strdup(result, "");
2287         if ((result->user_name == NULL) || (result->domain == NULL)) {
2288                 TALLOC_FREE(result);
2289                 return NT_STATUS_NO_MEMORY;
2290         }
2291
2292         *presult = result;
2293         return NT_STATUS_OK;
2294 }
2295
2296 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2297                                          enum dcerpc_AuthType auth_type,
2298                                          enum dcerpc_AuthLevel auth_level,
2299                                          const char *server,
2300                                          const char *target_service,
2301                                          const char *domain,
2302                                          const char *username,
2303                                          const char *password,
2304                                          enum credentials_use_kerberos use_kerberos,
2305                                          struct pipe_auth_data **presult)
2306 {
2307         struct auth_generic_state *auth_generic_ctx;
2308         struct pipe_auth_data *result;
2309         NTSTATUS status;
2310
2311         result = talloc(mem_ctx, struct pipe_auth_data);
2312         if (result == NULL) {
2313                 return NT_STATUS_NO_MEMORY;
2314         }
2315
2316         result->auth_type = auth_type;
2317         result->auth_level = auth_level;
2318
2319         result->user_name = talloc_strdup(result, username);
2320         result->domain = talloc_strdup(result, domain);
2321         if ((result->user_name == NULL) || (result->domain == NULL)) {
2322                 status = NT_STATUS_NO_MEMORY;
2323                 goto fail;
2324         }
2325
2326         status = auth_generic_client_prepare(result,
2327                                              &auth_generic_ctx);
2328         if (!NT_STATUS_IS_OK(status)) {
2329                 goto fail;
2330         }
2331
2332         status = auth_generic_set_username(auth_generic_ctx, username);
2333         if (!NT_STATUS_IS_OK(status)) {
2334                 goto fail;
2335         }
2336
2337         status = auth_generic_set_domain(auth_generic_ctx, domain);
2338         if (!NT_STATUS_IS_OK(status)) {
2339                 goto fail;
2340         }
2341
2342         status = auth_generic_set_password(auth_generic_ctx, password);
2343         if (!NT_STATUS_IS_OK(status)) {
2344                 goto fail;
2345         }
2346
2347         status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2348         if (!NT_STATUS_IS_OK(status)) {
2349                 goto fail;
2350         }
2351
2352         status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2353         if (!NT_STATUS_IS_OK(status)) {
2354                 goto fail;
2355         }
2356
2357         cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
2358
2359         status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2360         if (!NT_STATUS_IS_OK(status)) {
2361                 goto fail;
2362         }
2363
2364         result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2365         talloc_free(auth_generic_ctx);
2366         *presult = result;
2367         return NT_STATUS_OK;
2368
2369  fail:
2370         TALLOC_FREE(result);
2371         return status;
2372 }
2373
2374 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2375                                    enum dcerpc_AuthLevel auth_level,
2376                                    struct netlogon_creds_CredentialState *creds,
2377                                    struct pipe_auth_data **presult)
2378 {
2379         struct schannel_state *schannel_auth;
2380         struct pipe_auth_data *result;
2381
2382         result = talloc(mem_ctx, struct pipe_auth_data);
2383         if (result == NULL) {
2384                 return NT_STATUS_NO_MEMORY;
2385         }
2386
2387         result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2388         result->auth_level = auth_level;
2389
2390         result->user_name = talloc_strdup(result, "");
2391         result->domain = talloc_strdup(result, domain);
2392         if ((result->user_name == NULL) || (result->domain == NULL)) {
2393                 goto fail;
2394         }
2395
2396         schannel_auth = talloc_zero(result, struct schannel_state);
2397         if (schannel_auth == NULL) {
2398                 goto fail;
2399         }
2400
2401         schannel_auth->state = SCHANNEL_STATE_START;
2402         schannel_auth->initiator = true;
2403         schannel_auth->creds = netlogon_creds_copy(result, creds);
2404
2405         result->auth_ctx = schannel_auth;
2406         *presult = result;
2407         return NT_STATUS_OK;
2408
2409  fail:
2410         TALLOC_FREE(result);
2411         return NT_STATUS_NO_MEMORY;
2412 }
2413
2414 /**
2415  * Create an rpc pipe client struct, connecting to a tcp port.
2416  */
2417 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2418                                        const struct sockaddr_storage *ss_addr,
2419                                        uint16_t port,
2420                                        const struct ndr_syntax_id *abstract_syntax,
2421                                        struct rpc_pipe_client **presult)
2422 {
2423         struct rpc_pipe_client *result;
2424         struct sockaddr_storage addr;
2425         NTSTATUS status;
2426         int fd;
2427
2428         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2429         if (result == NULL) {
2430                 return NT_STATUS_NO_MEMORY;
2431         }
2432
2433         result->abstract_syntax = *abstract_syntax;
2434         result->transfer_syntax = ndr_transfer_syntax_ndr;
2435
2436         result->desthost = talloc_strdup(result, host);
2437         result->srv_name_slash = talloc_asprintf_strupper_m(
2438                 result, "\\\\%s", result->desthost);
2439         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2440                 status = NT_STATUS_NO_MEMORY;
2441                 goto fail;
2442         }
2443
2444         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2445         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2446
2447         if (ss_addr == NULL) {
2448                 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2449                         status = NT_STATUS_NOT_FOUND;
2450                         goto fail;
2451                 }
2452         } else {
2453                 addr = *ss_addr;
2454         }
2455
2456         status = open_socket_out(&addr, port, 60*1000, &fd);
2457         if (!NT_STATUS_IS_OK(status)) {
2458                 goto fail;
2459         }
2460         set_socket_options(fd, lp_socket_options());
2461
2462         status = rpc_transport_sock_init(result, fd, &result->transport);
2463         if (!NT_STATUS_IS_OK(status)) {
2464                 close(fd);
2465                 goto fail;
2466         }
2467
2468         result->transport->transport = NCACN_IP_TCP;
2469
2470         result->binding_handle = rpccli_bh_create(result);
2471         if (result->binding_handle == NULL) {
2472                 TALLOC_FREE(result);
2473                 return NT_STATUS_NO_MEMORY;
2474         }
2475
2476         *presult = result;
2477         return NT_STATUS_OK;
2478
2479  fail:
2480         TALLOC_FREE(result);
2481         return status;
2482 }
2483
2484 /**
2485  * Determine the tcp port on which a dcerpc interface is listening
2486  * for the ncacn_ip_tcp transport via the endpoint mapper of the
2487  * target host.
2488  */
2489 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2490                                       const struct sockaddr_storage *addr,
2491                                       const struct ndr_syntax_id *abstract_syntax,
2492                                       uint16_t *pport)
2493 {
2494         NTSTATUS status;
2495         struct rpc_pipe_client *epm_pipe = NULL;
2496         struct dcerpc_binding_handle *epm_handle = NULL;
2497         struct pipe_auth_data *auth = NULL;
2498         struct dcerpc_binding *map_binding = NULL;
2499         struct dcerpc_binding *res_binding = NULL;
2500         struct epm_twr_t *map_tower = NULL;
2501         struct epm_twr_t *res_towers = NULL;
2502         struct policy_handle *entry_handle = NULL;
2503         uint32_t num_towers = 0;
2504         uint32_t max_towers = 1;
2505         struct epm_twr_p_t towers;
2506         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2507         uint32_t result = 0;
2508
2509         if (pport == NULL) {
2510                 status = NT_STATUS_INVALID_PARAMETER;
2511                 goto done;
2512         }
2513
2514         if (ndr_syntax_id_equal(abstract_syntax,
2515                                 &ndr_table_epmapper.syntax_id)) {
2516                 *pport = 135;
2517                 return NT_STATUS_OK;
2518         }
2519
2520         /* open the connection to the endpoint mapper */
2521         status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2522                                         &ndr_table_epmapper.syntax_id,
2523                                         &epm_pipe);
2524
2525         if (!NT_STATUS_IS_OK(status)) {
2526                 goto done;
2527         }
2528         epm_handle = epm_pipe->binding_handle;
2529
2530         status = rpccli_anon_bind_data(tmp_ctx, &auth);
2531         if (!NT_STATUS_IS_OK(status)) {
2532                 goto done;
2533         }
2534
2535         status = rpc_pipe_bind(epm_pipe, auth);
2536         if (!NT_STATUS_IS_OK(status)) {
2537                 goto done;
2538         }
2539
2540         /* create tower for asking the epmapper */
2541
2542         map_binding = talloc_zero(tmp_ctx, struct dcerpc_binding);
2543         if (map_binding == NULL) {
2544                 status = NT_STATUS_NO_MEMORY;
2545                 goto done;
2546         }
2547
2548         map_binding->transport = NCACN_IP_TCP;
2549         map_binding->object = *abstract_syntax;
2550         map_binding->host = host; /* needed? */
2551         map_binding->endpoint = "0"; /* correct? needed? */
2552
2553         map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2554         if (map_tower == NULL) {
2555                 status = NT_STATUS_NO_MEMORY;
2556                 goto done;
2557         }
2558
2559         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2560                                             &(map_tower->tower));
2561         if (!NT_STATUS_IS_OK(status)) {
2562                 goto done;
2563         }
2564
2565         /* allocate further parameters for the epm_Map call */
2566
2567         res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2568         if (res_towers == NULL) {
2569                 status = NT_STATUS_NO_MEMORY;
2570                 goto done;
2571         }
2572         towers.twr = res_towers;
2573
2574         entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2575         if (entry_handle == NULL) {
2576                 status = NT_STATUS_NO_MEMORY;
2577                 goto done;
2578         }
2579
2580         /* ask the endpoint mapper for the port */
2581
2582         status = dcerpc_epm_Map(epm_handle,
2583                                 tmp_ctx,
2584                                 discard_const_p(struct GUID,
2585                                               &(abstract_syntax->uuid)),
2586                                 map_tower,
2587                                 entry_handle,
2588                                 max_towers,
2589                                 &num_towers,
2590                                 &towers,
2591                                 &result);
2592
2593         if (!NT_STATUS_IS_OK(status)) {
2594                 goto done;
2595         }
2596
2597         if (result != EPMAPPER_STATUS_OK) {
2598                 status = NT_STATUS_UNSUCCESSFUL;
2599                 goto done;
2600         }
2601
2602         if (num_towers != 1) {
2603                 status = NT_STATUS_UNSUCCESSFUL;
2604                 goto done;
2605         }
2606
2607         /* extract the port from the answer */
2608
2609         status = dcerpc_binding_from_tower(tmp_ctx,
2610                                            &(towers.twr->tower),
2611                                            &res_binding);
2612         if (!NT_STATUS_IS_OK(status)) {
2613                 goto done;
2614         }
2615
2616         /* are further checks here necessary? */
2617         if (res_binding->transport != NCACN_IP_TCP) {
2618                 status = NT_STATUS_UNSUCCESSFUL;
2619                 goto done;
2620         }
2621
2622         *pport = (uint16_t)atoi(res_binding->endpoint);
2623
2624 done:
2625         TALLOC_FREE(tmp_ctx);
2626         return status;
2627 }
2628
2629 /**
2630  * Create a rpc pipe client struct, connecting to a host via tcp.
2631  * The port is determined by asking the endpoint mapper on the given
2632  * host.
2633  */
2634 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2635                            const struct sockaddr_storage *addr,
2636                            const struct ndr_syntax_id *abstract_syntax,
2637                            struct rpc_pipe_client **presult)
2638 {
2639         NTSTATUS status;
2640         uint16_t port = 0;
2641
2642         status = rpc_pipe_get_tcp_port(host, addr, abstract_syntax, &port);
2643         if (!NT_STATUS_IS_OK(status)) {
2644                 return status;
2645         }
2646
2647         return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2648                                         abstract_syntax, presult);
2649 }
2650
2651 /********************************************************************
2652  Create a rpc pipe client struct, connecting to a unix domain socket
2653  ********************************************************************/
2654 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2655                                const struct ndr_syntax_id *abstract_syntax,
2656                                struct rpc_pipe_client **presult)
2657 {
2658         struct rpc_pipe_client *result;
2659         struct sockaddr_un addr;
2660         NTSTATUS status;
2661         int fd;
2662         socklen_t salen;
2663
2664         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2665         if (result == NULL) {
2666                 return NT_STATUS_NO_MEMORY;
2667         }
2668
2669         result->abstract_syntax = *abstract_syntax;
2670         result->transfer_syntax = ndr_transfer_syntax_ndr;
2671
2672         result->desthost = get_myname(result);
2673         result->srv_name_slash = talloc_asprintf_strupper_m(
2674                 result, "\\\\%s", result->desthost);
2675         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2676                 status = NT_STATUS_NO_MEMORY;
2677                 goto fail;
2678         }
2679
2680         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2681         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2682
2683         fd = socket(AF_UNIX, SOCK_STREAM, 0);
2684         if (fd == -1) {
2685                 status = map_nt_error_from_unix(errno);
2686                 goto fail;
2687         }
2688
2689         ZERO_STRUCT(addr);
2690         addr.sun_family = AF_UNIX;
2691         strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2692         salen = sizeof(struct sockaddr_un);
2693
2694         if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
2695                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2696                           strerror(errno)));
2697                 close(fd);
2698                 return map_nt_error_from_unix(errno);
2699         }
2700
2701         status = rpc_transport_sock_init(result, fd, &result->transport);
2702         if (!NT_STATUS_IS_OK(status)) {
2703                 close(fd);
2704                 goto fail;
2705         }
2706
2707         result->transport->transport = NCALRPC;
2708
2709         result->binding_handle = rpccli_bh_create(result);
2710         if (result->binding_handle == NULL) {
2711                 TALLOC_FREE(result);
2712                 return NT_STATUS_NO_MEMORY;
2713         }
2714
2715         *presult = result;
2716         return NT_STATUS_OK;
2717
2718  fail:
2719         TALLOC_FREE(result);
2720         return status;
2721 }
2722
2723 struct rpc_pipe_client_np_ref {
2724         struct cli_state *cli;
2725         struct rpc_pipe_client *pipe;
2726 };
2727
2728 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2729 {
2730         DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2731         return 0;
2732 }
2733
2734 /****************************************************************************
2735  Open a named pipe over SMB to a remote server.
2736  *
2737  * CAVEAT CALLER OF THIS FUNCTION:
2738  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2739  *    so be sure that this function is called AFTER any structure (vs pointer)
2740  *    assignment of the cli.  In particular, libsmbclient does structure
2741  *    assignments of cli, which invalidates the data in the returned
2742  *    rpc_pipe_client if this function is called before the structure assignment
2743  *    of cli.
2744  * 
2745  ****************************************************************************/
2746
2747 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2748                                  const struct ndr_syntax_id *abstract_syntax,
2749                                  struct rpc_pipe_client **presult)
2750 {
2751         struct rpc_pipe_client *result;
2752         NTSTATUS status;
2753         struct rpc_pipe_client_np_ref *np_ref;
2754
2755         /* sanity check to protect against crashes */
2756
2757         if ( !cli ) {
2758                 return NT_STATUS_INVALID_HANDLE;
2759         }
2760
2761         result = talloc_zero(NULL, struct rpc_pipe_client);
2762         if (result == NULL) {
2763                 return NT_STATUS_NO_MEMORY;
2764         }
2765
2766         result->abstract_syntax = *abstract_syntax;
2767         result->transfer_syntax = ndr_transfer_syntax_ndr;
2768         result->desthost = talloc_strdup(result, smbXcli_conn_remote_name(cli->conn));
2769         result->srv_name_slash = talloc_asprintf_strupper_m(
2770                 result, "\\\\%s", result->desthost);
2771
2772         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2773         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2774
2775         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2776                 TALLOC_FREE(result);
2777                 return NT_STATUS_NO_MEMORY;
2778         }
2779
2780         status = rpc_transport_np_init(result, cli, abstract_syntax,
2781                                        &result->transport);
2782         if (!NT_STATUS_IS_OK(status)) {
2783                 TALLOC_FREE(result);
2784                 return status;
2785         }
2786
2787         result->transport->transport = NCACN_NP;
2788
2789         np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2790         if (np_ref == NULL) {
2791                 TALLOC_FREE(result);
2792                 return NT_STATUS_NO_MEMORY;
2793         }
2794         np_ref->cli = cli;
2795         np_ref->pipe = result;
2796
2797         DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2798         talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2799
2800         result->binding_handle = rpccli_bh_create(result);
2801         if (result->binding_handle == NULL) {
2802                 TALLOC_FREE(result);
2803                 return NT_STATUS_NO_MEMORY;
2804         }
2805
2806         *presult = result;
2807         return NT_STATUS_OK;
2808 }
2809
2810 /****************************************************************************
2811  Open a pipe to a remote server.
2812  ****************************************************************************/
2813
2814 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2815                                   enum dcerpc_transport_t transport,
2816                                   const struct ndr_syntax_id *interface,
2817                                   struct rpc_pipe_client **presult)
2818 {
2819         switch (transport) {
2820         case NCACN_IP_TCP:
2821                 return rpc_pipe_open_tcp(NULL,
2822                                          smbXcli_conn_remote_name(cli->conn),
2823                                          smbXcli_conn_remote_sockaddr(cli->conn),
2824                                          interface, presult);
2825         case NCACN_NP:
2826                 return rpc_pipe_open_np(cli, interface, presult);
2827         default:
2828                 return NT_STATUS_NOT_IMPLEMENTED;
2829         }
2830 }
2831
2832 /****************************************************************************
2833  Open a named pipe to an SMB server and bind anonymously.
2834  ****************************************************************************/
2835
2836 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2837                                             enum dcerpc_transport_t transport,
2838                                             const struct ndr_syntax_id *interface,
2839                                             struct rpc_pipe_client **presult)
2840 {
2841         struct rpc_pipe_client *result;
2842         struct pipe_auth_data *auth;
2843         NTSTATUS status;
2844
2845         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2846         if (!NT_STATUS_IS_OK(status)) {
2847                 return status;
2848         }
2849
2850         status = rpccli_anon_bind_data(result, &auth);
2851         if (!NT_STATUS_IS_OK(status)) {
2852                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2853                           nt_errstr(status)));
2854                 TALLOC_FREE(result);
2855                 return status;
2856         }
2857
2858         /*
2859          * This is a bit of an abstraction violation due to the fact that an
2860          * anonymous bind on an authenticated SMB inherits the user/domain
2861          * from the enclosing SMB creds
2862          */
2863
2864         TALLOC_FREE(auth->user_name);
2865         TALLOC_FREE(auth->domain);
2866
2867         auth->user_name = talloc_strdup(auth, cli->user_name);
2868         auth->domain = talloc_strdup(auth, cli->domain);
2869
2870         if (transport == NCACN_NP) {
2871                 struct smbXcli_session *session;
2872
2873                 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2874                         session = cli->smb2.session;
2875                 } else {
2876                         session = cli->smb1.session;
2877                 }
2878
2879                 status = smbXcli_session_application_key(session, auth,
2880                                                 &auth->transport_session_key);
2881                 if (!NT_STATUS_IS_OK(status)) {
2882                         auth->transport_session_key = data_blob_null;
2883                 }
2884         }
2885
2886         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2887                 TALLOC_FREE(result);
2888                 return NT_STATUS_NO_MEMORY;
2889         }
2890
2891         status = rpc_pipe_bind(result, auth);
2892         if (!NT_STATUS_IS_OK(status)) {
2893                 int lvl = 0;
2894                 if (ndr_syntax_id_equal(interface,
2895                                         &ndr_table_dssetup.syntax_id)) {
2896                         /* non AD domains just don't have this pipe, avoid
2897                          * level 0 statement in that case - gd */
2898                         lvl = 3;
2899                 }
2900                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2901                             "%s failed with error %s\n",
2902                             get_pipe_name_from_syntax(talloc_tos(), interface),
2903                             nt_errstr(status) ));
2904                 TALLOC_FREE(result);
2905                 return status;
2906         }
2907
2908         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2909                   "%s and bound anonymously.\n",
2910                   get_pipe_name_from_syntax(talloc_tos(), interface),
2911                   result->desthost));
2912
2913         *presult = result;
2914         return NT_STATUS_OK;
2915 }
2916
2917 /****************************************************************************
2918  ****************************************************************************/
2919
2920 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2921                                   const struct ndr_syntax_id *interface,
2922                                   struct rpc_pipe_client **presult)
2923 {
2924         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2925                                                   interface, presult);
2926 }
2927
2928 /****************************************************************************
2929  Open a named pipe to an SMB server and bind using the mech specified
2930  ****************************************************************************/
2931
2932 NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
2933                                         const struct ndr_interface_table *table,
2934                                         enum dcerpc_transport_t transport,
2935                                         enum dcerpc_AuthType auth_type,
2936                                         enum dcerpc_AuthLevel auth_level,
2937                                         const char *server,
2938                                         const char *domain,
2939                                         const char *username,
2940                                         const char *password,
2941                                         struct rpc_pipe_client **presult)
2942 {
2943         struct rpc_pipe_client *result;
2944         struct pipe_auth_data *auth = NULL;
2945         const char *target_service = table->authservices->names[0];
2946         
2947         NTSTATUS status;
2948
2949         status = cli_rpc_pipe_open(cli, transport, &table->syntax_id, &result);
2950         if (!NT_STATUS_IS_OK(status)) {
2951                 return status;
2952         }
2953
2954         status = rpccli_generic_bind_data(result,
2955                                           auth_type, auth_level,
2956                                           server, target_service,
2957                                           domain, username, password, 
2958                                           CRED_AUTO_USE_KERBEROS,
2959                                           &auth);
2960         if (!NT_STATUS_IS_OK(status)) {
2961                 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
2962                           nt_errstr(status)));
2963                 goto err;
2964         }
2965
2966         status = rpc_pipe_bind(result, auth);
2967         if (!NT_STATUS_IS_OK(status)) {
2968                 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
2969                         nt_errstr(status) ));
2970                 goto err;
2971         }
2972
2973         DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
2974                 "machine %s and bound as user %s\\%s.\n", table->name,
2975                   result->desthost, domain, username));
2976
2977         *presult = result;
2978         return NT_STATUS_OK;
2979
2980   err:
2981
2982         TALLOC_FREE(result);
2983         return status;
2984 }
2985
2986 /****************************************************************************
2987  External interface.
2988  Open a named pipe to an SMB server and bind using schannel (bind type 68)
2989  using session_key. sign and seal.
2990
2991  The *pdc will be stolen onto this new pipe
2992  ****************************************************************************/
2993
2994 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2995                                              const struct ndr_syntax_id *interface,
2996                                              enum dcerpc_transport_t transport,
2997                                              enum dcerpc_AuthLevel auth_level,
2998                                              const char *domain,
2999                                              struct netlogon_creds_CredentialState **pdc,
3000                                              struct rpc_pipe_client **presult)
3001 {
3002         struct rpc_pipe_client *result;
3003         struct pipe_auth_data *auth;
3004         NTSTATUS status;
3005
3006         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3007         if (!NT_STATUS_IS_OK(status)) {
3008                 return status;
3009         }
3010
3011         status = rpccli_schannel_bind_data(result, domain, auth_level,
3012                                            *pdc, &auth);
3013         if (!NT_STATUS_IS_OK(status)) {
3014                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3015                           nt_errstr(status)));
3016                 TALLOC_FREE(result);
3017                 return status;
3018         }
3019
3020         status = rpc_pipe_bind(result, auth);
3021         if (!NT_STATUS_IS_OK(status)) {
3022                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3023                           "cli_rpc_pipe_bind failed with error %s\n",
3024                           nt_errstr(status) ));
3025                 TALLOC_FREE(result);
3026                 return status;
3027         }
3028
3029         /*
3030          * The credentials on a new netlogon pipe are the ones we are passed
3031          * in - copy them over
3032          */
3033         if (result->dc == NULL) {
3034                 result->dc = netlogon_creds_copy(result, *pdc);
3035                 if (result->dc == NULL) {
3036                         TALLOC_FREE(result);
3037                         return NT_STATUS_NO_MEMORY;
3038                 }
3039         }
3040
3041         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3042                   "for domain %s and bound using schannel.\n",
3043                   get_pipe_name_from_syntax(talloc_tos(), interface),
3044                   result->desthost, domain));
3045
3046         *presult = result;
3047         return NT_STATUS_OK;
3048 }
3049
3050 NTSTATUS cli_rpc_pipe_open_spnego(struct cli_state *cli,
3051                                   const struct ndr_interface_table *table,
3052                                   enum dcerpc_transport_t transport,
3053                                   const char *oid,
3054                                   enum dcerpc_AuthLevel auth_level,
3055                                   const char *server,
3056                                   const char *domain,
3057                                   const char *username,
3058                                   const char *password,
3059                                   struct rpc_pipe_client **presult)
3060 {
3061         struct rpc_pipe_client *result;
3062         struct pipe_auth_data *auth = NULL;
3063         const char *target_service = table->authservices->names[0];
3064         
3065         NTSTATUS status;
3066         enum credentials_use_kerberos use_kerberos;
3067
3068         if (strcmp(oid, GENSEC_OID_KERBEROS5) == 0) {
3069                 use_kerberos = CRED_MUST_USE_KERBEROS;
3070         } else if (strcmp(oid, GENSEC_OID_NTLMSSP) == 0) {
3071                 use_kerberos = CRED_DONT_USE_KERBEROS;
3072         } else {
3073                 return NT_STATUS_INVALID_PARAMETER;
3074         }
3075
3076         status = cli_rpc_pipe_open(cli, transport, &table->syntax_id, &result);
3077         if (!NT_STATUS_IS_OK(status)) {
3078                 return status;
3079         }
3080
3081         status = rpccli_generic_bind_data(result,
3082                                           DCERPC_AUTH_TYPE_SPNEGO, auth_level,
3083                                           server, target_service,
3084                                           domain, username, password, 
3085                                           use_kerberos,
3086                                           &auth);
3087         if (!NT_STATUS_IS_OK(status)) {
3088                 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3089                           nt_errstr(status)));
3090                 goto err;
3091         }
3092
3093         status = rpc_pipe_bind(result, auth);
3094         if (!NT_STATUS_IS_OK(status)) {
3095                 DEBUG(0, ("cli_rpc_pipe_open_spnego: cli_rpc_pipe_bind failed with error %s\n",
3096                         nt_errstr(status) ));
3097                 goto err;
3098         }
3099
3100         DEBUG(10,("cli_rpc_pipe_open_spnego: opened pipe %s to "
3101                   "machine %s.\n", table->name,
3102                   result->desthost));
3103
3104         *presult = result;
3105         return NT_STATUS_OK;
3106
3107   err:
3108
3109         TALLOC_FREE(result);
3110         return status;
3111 }
3112
3113 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3114                              struct rpc_pipe_client *cli,
3115                              DATA_BLOB *session_key)
3116 {
3117         NTSTATUS status;
3118         struct pipe_auth_data *a;
3119         struct schannel_state *schannel_auth;
3120         struct gensec_security *gensec_security;
3121         DATA_BLOB sk = data_blob_null;
3122         bool make_dup = false;
3123
3124         if (!session_key || !cli) {
3125                 return NT_STATUS_INVALID_PARAMETER;
3126         }
3127
3128         a = cli->auth;
3129
3130         if (a == NULL) {
3131                 return NT_STATUS_INVALID_PARAMETER;
3132         }
3133
3134         switch (cli->auth->auth_type) {
3135         case DCERPC_AUTH_TYPE_SCHANNEL:
3136                 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3137                                                       struct schannel_state);
3138                 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3139                 make_dup = true;
3140                 break;
3141         case DCERPC_AUTH_TYPE_SPNEGO:
3142         case DCERPC_AUTH_TYPE_NTLMSSP:
3143         case DCERPC_AUTH_TYPE_KRB5:
3144                 gensec_security = talloc_get_type_abort(a->auth_ctx,
3145                                                 struct gensec_security);
3146                 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3147                 if (!NT_STATUS_IS_OK(status)) {
3148                         return status;
3149                 }
3150                 make_dup = false;
3151                 break;
3152         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3153         case DCERPC_AUTH_TYPE_NONE:
3154                 sk = data_blob_const(a->transport_session_key.data,
3155                                      a->transport_session_key.length);
3156                 make_dup = true;
3157                 break;
3158         default:
3159                 break;
3160         }
3161
3162         if (!sk.data) {
3163                 return NT_STATUS_NO_USER_SESSION_KEY;
3164         }
3165
3166         if (make_dup) {
3167                 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3168         } else {
3169                 *session_key = sk;
3170         }
3171
3172         return NT_STATUS_OK;
3173 }