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