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