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