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