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