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