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