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