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