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