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