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