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