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