s3-dcerpc: finally remove the legaqcy spnego_type variable from pipe_auth_data
[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/crypto/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, auth_level %u\n",
1634                 rpccli_pipe_txt(talloc_tos(), cli),
1635                 (unsigned int)auth->auth_type,
1636                 (unsigned int)auth->auth_level ));
1637
1638         state->ev = ev;
1639         state->cli = cli;
1640         state->rpc_call_id = get_rpc_call_id();
1641
1642         cli->auth = talloc_move(cli, &auth);
1643
1644         /* Marshall the outgoing data. */
1645         status = create_rpc_bind_req(state, cli,
1646                                      cli->auth,
1647                                      state->rpc_call_id,
1648                                      &cli->abstract_syntax,
1649                                      &cli->transfer_syntax,
1650                                      &state->rpc_out);
1651
1652         if (!NT_STATUS_IS_OK(status)) {
1653                 goto post_status;
1654         }
1655
1656         subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1657                                    DCERPC_PKT_BIND_ACK);
1658         if (subreq == NULL) {
1659                 goto fail;
1660         }
1661         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1662         return req;
1663
1664  post_status:
1665         tevent_req_nterror(req, status);
1666         return tevent_req_post(req, ev);
1667  fail:
1668         TALLOC_FREE(req);
1669         return NULL;
1670 }
1671
1672 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1673 {
1674         struct tevent_req *req = tevent_req_callback_data(
1675                 subreq, struct tevent_req);
1676         struct rpc_pipe_bind_state *state = tevent_req_data(
1677                 req, struct rpc_pipe_bind_state);
1678         struct pipe_auth_data *pauth = state->cli->auth;
1679         struct ncacn_packet *pkt;
1680         struct dcerpc_auth auth;
1681         DATA_BLOB auth_token = data_blob_null;
1682         NTSTATUS status;
1683
1684         status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1685         TALLOC_FREE(subreq);
1686         if (!NT_STATUS_IS_OK(status)) {
1687                 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1688                           rpccli_pipe_txt(talloc_tos(), state->cli),
1689                           nt_errstr(status)));
1690                 tevent_req_nterror(req, status);
1691                 return;
1692         }
1693
1694         if (state->auth3) {
1695                 tevent_req_done(req);
1696                 return;
1697         }
1698
1699         if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1700                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1701                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1702                 return;
1703         }
1704
1705         state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1706         state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1707
1708         switch(pauth->auth_type) {
1709
1710         case DCERPC_AUTH_TYPE_NONE:
1711         case DCERPC_AUTH_TYPE_SCHANNEL:
1712                 /* Bind complete. */
1713                 tevent_req_done(req);
1714                 return;
1715
1716         case DCERPC_AUTH_TYPE_NTLMSSP:
1717         case DCERPC_AUTH_TYPE_SPNEGO:
1718         case DCERPC_AUTH_TYPE_KRB5:
1719                 /* Paranoid lenght checks */
1720                 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1721                                                 + pkt->auth_length) {
1722                         tevent_req_nterror(req,
1723                                         NT_STATUS_INFO_LENGTH_MISMATCH);
1724                         return;
1725                 }
1726                 /* get auth credentials */
1727                 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1728                                                  &pkt->u.bind_ack.auth_info,
1729                                                  &auth, false);
1730                 if (!NT_STATUS_IS_OK(status)) {
1731                         DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1732                                   nt_errstr(status)));
1733                         tevent_req_nterror(req, status);
1734                         return;
1735                 }
1736                 break;
1737
1738         default:
1739                 goto err_out;
1740         }
1741
1742         /*
1743          * For authenticated binds we may need to do 3 or 4 leg binds.
1744          */
1745
1746         switch(pauth->auth_type) {
1747
1748         case DCERPC_AUTH_TYPE_NONE:
1749         case DCERPC_AUTH_TYPE_SCHANNEL:
1750                 /* Bind complete. */
1751                 tevent_req_done(req);
1752                 return;
1753
1754         case DCERPC_AUTH_TYPE_NTLMSSP:
1755                 status = auth_ntlmssp_update(pauth->a_u.auth_ntlmssp_state,
1756                                              auth.credentials, &auth_token);
1757                 if (NT_STATUS_EQUAL(status,
1758                                     NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1759                         status = rpc_bind_next_send(req, state,
1760                                                         &auth_token);
1761                 } else if (NT_STATUS_IS_OK(status)) {
1762                         status = rpc_bind_finish_send(req, state,
1763                                                         &auth_token);
1764                 }
1765                 break;
1766
1767         case DCERPC_AUTH_TYPE_SPNEGO:
1768                 status = spnego_get_client_auth_token(state,
1769                                                 pauth->a_u.spnego_state,
1770                                                 &auth.credentials,
1771                                                 &auth_token);
1772                 if (!NT_STATUS_IS_OK(status)) {
1773                         break;
1774                 }
1775                 if (auth_token.length == 0) {
1776                         /* Bind complete. */
1777                         tevent_req_done(req);
1778                         return;
1779                 }
1780                 if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
1781                         status = rpc_bind_next_send(req, state,
1782                                                         &auth_token);
1783                 } else {
1784                         status = rpc_bind_finish_send(req, state,
1785                                                         &auth_token);
1786                 }
1787                 break;
1788
1789         case DCERPC_AUTH_TYPE_KRB5:
1790                 status = gse_get_client_auth_token(state,
1791                                                    pauth->a_u.gssapi_state,
1792                                                    &auth.credentials,
1793                                                    &auth_token);
1794                 if (!NT_STATUS_IS_OK(status)) {
1795                         break;
1796                 }
1797
1798                 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
1799                         status = rpc_bind_next_send(req, state, &auth_token);
1800                 } else {
1801                         status = rpc_bind_finish_send(req, state, &auth_token);
1802                 }
1803                 break;
1804
1805         default:
1806                 goto err_out;
1807         }
1808
1809         if (!NT_STATUS_IS_OK(status)) {
1810                 tevent_req_nterror(req, status);
1811         }
1812         return;
1813
1814 err_out:
1815         DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1816                  (unsigned int)state->cli->auth->auth_type));
1817         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1818 }
1819
1820 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1821                                    struct rpc_pipe_bind_state *state,
1822                                    DATA_BLOB *auth_token)
1823 {
1824         struct pipe_auth_data *auth = state->cli->auth;
1825         struct tevent_req *subreq;
1826         NTSTATUS status;
1827
1828         /* Now prepare the alter context pdu. */
1829         data_blob_free(&state->rpc_out);
1830
1831         status = create_rpc_alter_context(state,
1832                                           auth->auth_type,
1833                                           auth->auth_level,
1834                                           state->rpc_call_id,
1835                                           &state->cli->abstract_syntax,
1836                                           &state->cli->transfer_syntax,
1837                                           auth_token,
1838                                           &state->rpc_out);
1839         if (!NT_STATUS_IS_OK(status)) {
1840                 return status;
1841         }
1842
1843         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1844                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1845         if (subreq == NULL) {
1846                 return NT_STATUS_NO_MEMORY;
1847         }
1848         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1849         return NT_STATUS_OK;
1850 }
1851
1852 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1853                                      struct rpc_pipe_bind_state *state,
1854                                      DATA_BLOB *auth_token)
1855 {
1856         struct pipe_auth_data *auth = state->cli->auth;
1857         struct tevent_req *subreq;
1858         NTSTATUS status;
1859
1860         state->auth3 = true;
1861
1862         /* Now prepare the auth3 context pdu. */
1863         data_blob_free(&state->rpc_out);
1864
1865         status = create_rpc_bind_auth3(state, state->cli,
1866                                         state->rpc_call_id,
1867                                         auth->auth_type,
1868                                         auth->auth_level,
1869                                         auth_token,
1870                                         &state->rpc_out);
1871         if (!NT_STATUS_IS_OK(status)) {
1872                 return status;
1873         }
1874
1875         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1876                                    &state->rpc_out, DCERPC_PKT_AUTH3);
1877         if (subreq == NULL) {
1878                 return NT_STATUS_NO_MEMORY;
1879         }
1880         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1881         return NT_STATUS_OK;
1882 }
1883
1884 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1885 {
1886         return tevent_req_simple_recv_ntstatus(req);
1887 }
1888
1889 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1890                        struct pipe_auth_data *auth)
1891 {
1892         TALLOC_CTX *frame = talloc_stackframe();
1893         struct event_context *ev;
1894         struct tevent_req *req;
1895         NTSTATUS status = NT_STATUS_OK;
1896
1897         ev = event_context_init(frame);
1898         if (ev == NULL) {
1899                 status = NT_STATUS_NO_MEMORY;
1900                 goto fail;
1901         }
1902
1903         req = rpc_pipe_bind_send(frame, ev, cli, auth);
1904         if (req == NULL) {
1905                 status = NT_STATUS_NO_MEMORY;
1906                 goto fail;
1907         }
1908
1909         if (!tevent_req_poll(req, ev)) {
1910                 status = map_nt_error_from_unix(errno);
1911                 goto fail;
1912         }
1913
1914         status = rpc_pipe_bind_recv(req);
1915  fail:
1916         TALLOC_FREE(frame);
1917         return status;
1918 }
1919
1920 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1921
1922 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1923                                 unsigned int timeout)
1924 {
1925         unsigned int old;
1926
1927         if (rpc_cli->transport == NULL) {
1928                 return RPCCLI_DEFAULT_TIMEOUT;
1929         }
1930
1931         if (rpc_cli->transport->set_timeout == NULL) {
1932                 return RPCCLI_DEFAULT_TIMEOUT;
1933         }
1934
1935         old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1936         if (old == 0) {
1937                 return RPCCLI_DEFAULT_TIMEOUT;
1938         }
1939
1940         return old;
1941 }
1942
1943 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1944 {
1945         if (rpc_cli == NULL) {
1946                 return false;
1947         }
1948
1949         if (rpc_cli->transport == NULL) {
1950                 return false;
1951         }
1952
1953         return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1954 }
1955
1956 struct rpccli_bh_state {
1957         struct rpc_pipe_client *rpc_cli;
1958 };
1959
1960 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1961 {
1962         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1963                                      struct rpccli_bh_state);
1964
1965         return rpccli_is_connected(hs->rpc_cli);
1966 }
1967
1968 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1969                                       uint32_t timeout)
1970 {
1971         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1972                                      struct rpccli_bh_state);
1973
1974         return rpccli_set_timeout(hs->rpc_cli, timeout);
1975 }
1976
1977 struct rpccli_bh_raw_call_state {
1978         DATA_BLOB in_data;
1979         DATA_BLOB out_data;
1980         uint32_t out_flags;
1981 };
1982
1983 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
1984
1985 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
1986                                                   struct tevent_context *ev,
1987                                                   struct dcerpc_binding_handle *h,
1988                                                   const struct GUID *object,
1989                                                   uint32_t opnum,
1990                                                   uint32_t in_flags,
1991                                                   const uint8_t *in_data,
1992                                                   size_t in_length)
1993 {
1994         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1995                                      struct rpccli_bh_state);
1996         struct tevent_req *req;
1997         struct rpccli_bh_raw_call_state *state;
1998         bool ok;
1999         struct tevent_req *subreq;
2000
2001         req = tevent_req_create(mem_ctx, &state,
2002                                 struct rpccli_bh_raw_call_state);
2003         if (req == NULL) {
2004                 return NULL;
2005         }
2006         state->in_data.data = discard_const_p(uint8_t, in_data);
2007         state->in_data.length = in_length;
2008
2009         ok = rpccli_bh_is_connected(h);
2010         if (!ok) {
2011                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2012                 return tevent_req_post(req, ev);
2013         }
2014
2015         subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2016                                        opnum, &state->in_data);
2017         if (tevent_req_nomem(subreq, req)) {
2018                 return tevent_req_post(req, ev);
2019         }
2020         tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2021
2022         return req;
2023 }
2024
2025 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2026 {
2027         struct tevent_req *req =
2028                 tevent_req_callback_data(subreq,
2029                 struct tevent_req);
2030         struct rpccli_bh_raw_call_state *state =
2031                 tevent_req_data(req,
2032                 struct rpccli_bh_raw_call_state);
2033         NTSTATUS status;
2034
2035         state->out_flags = 0;
2036
2037         /* TODO: support bigendian responses */
2038
2039         status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2040         TALLOC_FREE(subreq);
2041         if (!NT_STATUS_IS_OK(status)) {
2042                 tevent_req_nterror(req, status);
2043                 return;
2044         }
2045
2046         tevent_req_done(req);
2047 }
2048
2049 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2050                                         TALLOC_CTX *mem_ctx,
2051                                         uint8_t **out_data,
2052                                         size_t *out_length,
2053                                         uint32_t *out_flags)
2054 {
2055         struct rpccli_bh_raw_call_state *state =
2056                 tevent_req_data(req,
2057                 struct rpccli_bh_raw_call_state);
2058         NTSTATUS status;
2059
2060         if (tevent_req_is_nterror(req, &status)) {
2061                 tevent_req_received(req);
2062                 return status;
2063         }
2064
2065         *out_data = talloc_move(mem_ctx, &state->out_data.data);
2066         *out_length = state->out_data.length;
2067         *out_flags = state->out_flags;
2068         tevent_req_received(req);
2069         return NT_STATUS_OK;
2070 }
2071
2072 struct rpccli_bh_disconnect_state {
2073         uint8_t _dummy;
2074 };
2075
2076 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2077                                                 struct tevent_context *ev,
2078                                                 struct dcerpc_binding_handle *h)
2079 {
2080         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2081                                      struct rpccli_bh_state);
2082         struct tevent_req *req;
2083         struct rpccli_bh_disconnect_state *state;
2084         bool ok;
2085
2086         req = tevent_req_create(mem_ctx, &state,
2087                                 struct rpccli_bh_disconnect_state);
2088         if (req == NULL) {
2089                 return NULL;
2090         }
2091
2092         ok = rpccli_bh_is_connected(h);
2093         if (!ok) {
2094                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2095                 return tevent_req_post(req, ev);
2096         }
2097
2098         /*
2099          * TODO: do a real async disconnect ...
2100          *
2101          * For now the caller needs to free rpc_cli
2102          */
2103         hs->rpc_cli = NULL;
2104
2105         tevent_req_done(req);
2106         return tevent_req_post(req, ev);
2107 }
2108
2109 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2110 {
2111         NTSTATUS status;
2112
2113         if (tevent_req_is_nterror(req, &status)) {
2114                 tevent_req_received(req);
2115                 return status;
2116         }
2117
2118         tevent_req_received(req);
2119         return NT_STATUS_OK;
2120 }
2121
2122 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2123 {
2124         return true;
2125 }
2126
2127 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2128                                    int ndr_flags,
2129                                    const void *_struct_ptr,
2130                                    const struct ndr_interface_call *call)
2131 {
2132         void *struct_ptr = discard_const(_struct_ptr);
2133
2134         if (DEBUGLEVEL < 10) {
2135                 return;
2136         }
2137
2138         if (ndr_flags & NDR_IN) {
2139                 ndr_print_function_debug(call->ndr_print,
2140                                          call->name,
2141                                          ndr_flags,
2142                                          struct_ptr);
2143         }
2144         if (ndr_flags & NDR_OUT) {
2145                 ndr_print_function_debug(call->ndr_print,
2146                                          call->name,
2147                                          ndr_flags,
2148                                          struct_ptr);
2149         }
2150 }
2151
2152 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2153         .name                   = "rpccli",
2154         .is_connected           = rpccli_bh_is_connected,
2155         .set_timeout            = rpccli_bh_set_timeout,
2156         .raw_call_send          = rpccli_bh_raw_call_send,
2157         .raw_call_recv          = rpccli_bh_raw_call_recv,
2158         .disconnect_send        = rpccli_bh_disconnect_send,
2159         .disconnect_recv        = rpccli_bh_disconnect_recv,
2160
2161         .ref_alloc              = rpccli_bh_ref_alloc,
2162         .do_ndr_print           = rpccli_bh_do_ndr_print,
2163 };
2164
2165 /* initialise a rpc_pipe_client binding handle */
2166 static struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2167 {
2168         struct dcerpc_binding_handle *h;
2169         struct rpccli_bh_state *hs;
2170
2171         h = dcerpc_binding_handle_create(c,
2172                                          &rpccli_bh_ops,
2173                                          NULL,
2174                                          NULL, /* TODO */
2175                                          &hs,
2176                                          struct rpccli_bh_state,
2177                                          __location__);
2178         if (h == NULL) {
2179                 return NULL;
2180         }
2181         hs->rpc_cli = c;
2182
2183         return h;
2184 }
2185
2186 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2187 {
2188         struct auth_ntlmssp_state *a = NULL;
2189         struct cli_state *cli;
2190
2191         if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2192                 a = rpc_cli->auth->a_u.auth_ntlmssp_state;
2193         } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2194                 enum spnego_mech auth_type;
2195                 void *auth_ctx;
2196                 NTSTATUS status;
2197
2198                 status = spnego_get_negotiated_mech(
2199                                         rpc_cli->auth->a_u.spnego_state,
2200                                         &auth_type, &auth_ctx);
2201                 if (!NT_STATUS_IS_OK(status)) {
2202                         return false;
2203                 }
2204
2205                 if (auth_type == SPNEGO_NTLMSSP) {
2206                         a = talloc_get_type(auth_ctx,
2207                                             struct auth_ntlmssp_state);
2208                 }
2209         }
2210
2211         if (a) {
2212                 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2213                 return true;
2214         }
2215
2216         cli = rpc_pipe_np_smb_conn(rpc_cli);
2217         if (cli == NULL) {
2218                 return false;
2219         }
2220         E_md4hash(cli->password ? cli->password : "", nt_hash);
2221         return true;
2222 }
2223
2224 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2225                                struct pipe_auth_data **presult)
2226 {
2227         struct pipe_auth_data *result;
2228
2229         result = talloc(mem_ctx, struct pipe_auth_data);
2230         if (result == NULL) {
2231                 return NT_STATUS_NO_MEMORY;
2232         }
2233
2234         result->auth_type = DCERPC_AUTH_TYPE_NONE;
2235         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2236
2237         result->user_name = talloc_strdup(result, "");
2238         result->domain = talloc_strdup(result, "");
2239         if ((result->user_name == NULL) || (result->domain == NULL)) {
2240                 TALLOC_FREE(result);
2241                 return NT_STATUS_NO_MEMORY;
2242         }
2243
2244         *presult = result;
2245         return NT_STATUS_OK;
2246 }
2247
2248 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2249 {
2250         TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2251         return 0;
2252 }
2253
2254 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2255                                   enum dcerpc_AuthType auth_type,
2256                                   enum dcerpc_AuthLevel auth_level,
2257                                   const char *domain,
2258                                   const char *username,
2259                                   const char *password,
2260                                   struct pipe_auth_data **presult)
2261 {
2262         struct pipe_auth_data *result;
2263         NTSTATUS status;
2264
2265         result = talloc(mem_ctx, struct pipe_auth_data);
2266         if (result == NULL) {
2267                 return NT_STATUS_NO_MEMORY;
2268         }
2269
2270         result->auth_type = auth_type;
2271         result->auth_level = auth_level;
2272
2273         result->user_name = talloc_strdup(result, username);
2274         result->domain = talloc_strdup(result, domain);
2275         if ((result->user_name == NULL) || (result->domain == NULL)) {
2276                 status = NT_STATUS_NO_MEMORY;
2277                 goto fail;
2278         }
2279
2280         status = auth_ntlmssp_client_start(NULL,
2281                                       global_myname(),
2282                                       lp_workgroup(),
2283                                       lp_client_ntlmv2_auth(),
2284                                       &result->a_u.auth_ntlmssp_state);
2285         if (!NT_STATUS_IS_OK(status)) {
2286                 goto fail;
2287         }
2288
2289         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2290
2291         status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2292                                            username);
2293         if (!NT_STATUS_IS_OK(status)) {
2294                 goto fail;
2295         }
2296
2297         status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2298                                          domain);
2299         if (!NT_STATUS_IS_OK(status)) {
2300                 goto fail;
2301         }
2302
2303         status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2304                                            password);
2305         if (!NT_STATUS_IS_OK(status)) {
2306                 goto fail;
2307         }
2308
2309         /*
2310          * Turn off sign+seal to allow selected auth level to turn it back on.
2311          */
2312         auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2313                                                 ~(NTLMSSP_NEGOTIATE_SIGN |
2314                                                   NTLMSSP_NEGOTIATE_SEAL));
2315
2316         if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2317                 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2318                                                 NTLMSSP_NEGOTIATE_SIGN);
2319         } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2320                 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2321                                                 NTLMSSP_NEGOTIATE_SEAL |
2322                                                 NTLMSSP_NEGOTIATE_SIGN);
2323         }
2324
2325         *presult = result;
2326         return NT_STATUS_OK;
2327
2328  fail:
2329         TALLOC_FREE(result);
2330         return status;
2331 }
2332
2333 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2334                                    enum dcerpc_AuthLevel auth_level,
2335                                    struct netlogon_creds_CredentialState *creds,
2336                                    struct pipe_auth_data **presult)
2337 {
2338         struct pipe_auth_data *result;
2339
2340         result = talloc(mem_ctx, struct pipe_auth_data);
2341         if (result == NULL) {
2342                 return NT_STATUS_NO_MEMORY;
2343         }
2344
2345         result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2346         result->auth_level = auth_level;
2347
2348         result->user_name = talloc_strdup(result, "");
2349         result->domain = talloc_strdup(result, domain);
2350         if ((result->user_name == NULL) || (result->domain == NULL)) {
2351                 goto fail;
2352         }
2353
2354         result->a_u.schannel_auth = talloc(result, struct schannel_state);
2355         if (result->a_u.schannel_auth == NULL) {
2356                 goto fail;
2357         }
2358
2359         result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2360         result->a_u.schannel_auth->seq_num = 0;
2361         result->a_u.schannel_auth->initiator = true;
2362         result->a_u.schannel_auth->creds = netlogon_creds_copy(result, creds);
2363
2364         *presult = result;
2365         return NT_STATUS_OK;
2366
2367  fail:
2368         TALLOC_FREE(result);
2369         return NT_STATUS_NO_MEMORY;
2370 }
2371
2372 /**
2373  * Create an rpc pipe client struct, connecting to a tcp port.
2374  */
2375 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2376                                        uint16_t port,
2377                                        const struct ndr_syntax_id *abstract_syntax,
2378                                        struct rpc_pipe_client **presult)
2379 {
2380         struct rpc_pipe_client *result;
2381         struct sockaddr_storage addr;
2382         NTSTATUS status;
2383         int fd;
2384
2385         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2386         if (result == NULL) {
2387                 return NT_STATUS_NO_MEMORY;
2388         }
2389
2390         result->abstract_syntax = *abstract_syntax;
2391         result->transfer_syntax = ndr_transfer_syntax;
2392
2393         result->desthost = talloc_strdup(result, host);
2394         result->srv_name_slash = talloc_asprintf_strupper_m(
2395                 result, "\\\\%s", result->desthost);
2396         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2397                 status = NT_STATUS_NO_MEMORY;
2398                 goto fail;
2399         }
2400
2401         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2402         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2403
2404         if (!resolve_name(host, &addr, 0, false)) {
2405                 status = NT_STATUS_NOT_FOUND;
2406                 goto fail;
2407         }
2408
2409         status = open_socket_out(&addr, port, 60, &fd);
2410         if (!NT_STATUS_IS_OK(status)) {
2411                 goto fail;
2412         }
2413         set_socket_options(fd, lp_socket_options());
2414
2415         status = rpc_transport_sock_init(result, fd, &result->transport);
2416         if (!NT_STATUS_IS_OK(status)) {
2417                 close(fd);
2418                 goto fail;
2419         }
2420
2421         result->transport->transport = NCACN_IP_TCP;
2422
2423         result->binding_handle = rpccli_bh_create(result);
2424         if (result->binding_handle == NULL) {
2425                 TALLOC_FREE(result);
2426                 return NT_STATUS_NO_MEMORY;
2427         }
2428
2429         *presult = result;
2430         return NT_STATUS_OK;
2431
2432  fail:
2433         TALLOC_FREE(result);
2434         return status;
2435 }
2436
2437 /**
2438  * Determine the tcp port on which a dcerpc interface is listening
2439  * for the ncacn_ip_tcp transport via the endpoint mapper of the
2440  * target host.
2441  */
2442 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2443                                       const struct ndr_syntax_id *abstract_syntax,
2444                                       uint16_t *pport)
2445 {
2446         NTSTATUS status;
2447         struct rpc_pipe_client *epm_pipe = NULL;
2448         struct pipe_auth_data *auth = NULL;
2449         struct dcerpc_binding *map_binding = NULL;
2450         struct dcerpc_binding *res_binding = NULL;
2451         struct epm_twr_t *map_tower = NULL;
2452         struct epm_twr_t *res_towers = NULL;
2453         struct policy_handle *entry_handle = NULL;
2454         uint32_t num_towers = 0;
2455         uint32_t max_towers = 1;
2456         struct epm_twr_p_t towers;
2457         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2458
2459         if (pport == NULL) {
2460                 status = NT_STATUS_INVALID_PARAMETER;
2461                 goto done;
2462         }
2463
2464         /* open the connection to the endpoint mapper */
2465         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2466                                         &ndr_table_epmapper.syntax_id,
2467                                         &epm_pipe);
2468
2469         if (!NT_STATUS_IS_OK(status)) {
2470                 goto done;
2471         }
2472
2473         status = rpccli_anon_bind_data(tmp_ctx, &auth);
2474         if (!NT_STATUS_IS_OK(status)) {
2475                 goto done;
2476         }
2477
2478         status = rpc_pipe_bind(epm_pipe, auth);
2479         if (!NT_STATUS_IS_OK(status)) {
2480                 goto done;
2481         }
2482
2483         /* create tower for asking the epmapper */
2484
2485         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2486         if (map_binding == NULL) {
2487                 status = NT_STATUS_NO_MEMORY;
2488                 goto done;
2489         }
2490
2491         map_binding->transport = NCACN_IP_TCP;
2492         map_binding->object = *abstract_syntax;
2493         map_binding->host = host; /* needed? */
2494         map_binding->endpoint = "0"; /* correct? needed? */
2495
2496         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2497         if (map_tower == NULL) {
2498                 status = NT_STATUS_NO_MEMORY;
2499                 goto done;
2500         }
2501
2502         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2503                                             &(map_tower->tower));
2504         if (!NT_STATUS_IS_OK(status)) {
2505                 goto done;
2506         }
2507
2508         /* allocate further parameters for the epm_Map call */
2509
2510         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2511         if (res_towers == NULL) {
2512                 status = NT_STATUS_NO_MEMORY;
2513                 goto done;
2514         }
2515         towers.twr = res_towers;
2516
2517         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2518         if (entry_handle == NULL) {
2519                 status = NT_STATUS_NO_MEMORY;
2520                 goto done;
2521         }
2522
2523         /* ask the endpoint mapper for the port */
2524
2525         status = rpccli_epm_Map(epm_pipe,
2526                                 tmp_ctx,
2527                                 CONST_DISCARD(struct GUID *,
2528                                               &(abstract_syntax->uuid)),
2529                                 map_tower,
2530                                 entry_handle,
2531                                 max_towers,
2532                                 &num_towers,
2533                                 &towers);
2534
2535         if (!NT_STATUS_IS_OK(status)) {
2536                 goto done;
2537         }
2538
2539         if (num_towers != 1) {
2540                 status = NT_STATUS_UNSUCCESSFUL;
2541                 goto done;
2542         }
2543
2544         /* extract the port from the answer */
2545
2546         status = dcerpc_binding_from_tower(tmp_ctx,
2547                                            &(towers.twr->tower),
2548                                            &res_binding);
2549         if (!NT_STATUS_IS_OK(status)) {
2550                 goto done;
2551         }
2552
2553         /* are further checks here necessary? */
2554         if (res_binding->transport != NCACN_IP_TCP) {
2555                 status = NT_STATUS_UNSUCCESSFUL;
2556                 goto done;
2557         }
2558
2559         *pport = (uint16_t)atoi(res_binding->endpoint);
2560
2561 done:
2562         TALLOC_FREE(tmp_ctx);
2563         return status;
2564 }
2565
2566 /**
2567  * Create a rpc pipe client struct, connecting to a host via tcp.
2568  * The port is determined by asking the endpoint mapper on the given
2569  * host.
2570  */
2571 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2572                            const struct ndr_syntax_id *abstract_syntax,
2573                            struct rpc_pipe_client **presult)
2574 {
2575         NTSTATUS status;
2576         uint16_t port = 0;
2577
2578         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2579         if (!NT_STATUS_IS_OK(status)) {
2580                 return status;
2581         }
2582
2583         return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2584                                         abstract_syntax, presult);
2585 }
2586
2587 /********************************************************************
2588  Create a rpc pipe client struct, connecting to a unix domain socket
2589  ********************************************************************/
2590 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2591                                const struct ndr_syntax_id *abstract_syntax,
2592                                struct rpc_pipe_client **presult)
2593 {
2594         struct rpc_pipe_client *result;
2595         struct sockaddr_un addr;
2596         NTSTATUS status;
2597         int fd;
2598
2599         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2600         if (result == NULL) {
2601                 return NT_STATUS_NO_MEMORY;
2602         }
2603
2604         result->abstract_syntax = *abstract_syntax;
2605         result->transfer_syntax = ndr_transfer_syntax;
2606
2607         result->desthost = get_myname(result);
2608         result->srv_name_slash = talloc_asprintf_strupper_m(
2609                 result, "\\\\%s", result->desthost);
2610         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2611                 status = NT_STATUS_NO_MEMORY;
2612                 goto fail;
2613         }
2614
2615         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2616         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2617
2618         fd = socket(AF_UNIX, SOCK_STREAM, 0);
2619         if (fd == -1) {
2620                 status = map_nt_error_from_unix(errno);
2621                 goto fail;
2622         }
2623
2624         ZERO_STRUCT(addr);
2625         addr.sun_family = AF_UNIX;
2626         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2627
2628         if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2629                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2630                           strerror(errno)));
2631                 close(fd);
2632                 return map_nt_error_from_unix(errno);
2633         }
2634
2635         status = rpc_transport_sock_init(result, fd, &result->transport);
2636         if (!NT_STATUS_IS_OK(status)) {
2637                 close(fd);
2638                 goto fail;
2639         }
2640
2641         result->transport->transport = NCALRPC;
2642
2643         result->binding_handle = rpccli_bh_create(result);
2644         if (result->binding_handle == NULL) {
2645                 TALLOC_FREE(result);
2646                 return NT_STATUS_NO_MEMORY;
2647         }
2648
2649         *presult = result;
2650         return NT_STATUS_OK;
2651
2652  fail:
2653         TALLOC_FREE(result);
2654         return status;
2655 }
2656
2657 struct rpc_pipe_client_np_ref {
2658         struct cli_state *cli;
2659         struct rpc_pipe_client *pipe;
2660 };
2661
2662 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2663 {
2664         DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2665         return 0;
2666 }
2667
2668 /****************************************************************************
2669  Open a named pipe over SMB to a remote server.
2670  *
2671  * CAVEAT CALLER OF THIS FUNCTION:
2672  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2673  *    so be sure that this function is called AFTER any structure (vs pointer)
2674  *    assignment of the cli.  In particular, libsmbclient does structure
2675  *    assignments of cli, which invalidates the data in the returned
2676  *    rpc_pipe_client if this function is called before the structure assignment
2677  *    of cli.
2678  * 
2679  ****************************************************************************/
2680
2681 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2682                                  const struct ndr_syntax_id *abstract_syntax,
2683                                  struct rpc_pipe_client **presult)
2684 {
2685         struct rpc_pipe_client *result;
2686         NTSTATUS status;
2687         struct rpc_pipe_client_np_ref *np_ref;
2688
2689         /* sanity check to protect against crashes */
2690
2691         if ( !cli ) {
2692                 return NT_STATUS_INVALID_HANDLE;
2693         }
2694
2695         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2696         if (result == NULL) {
2697                 return NT_STATUS_NO_MEMORY;
2698         }
2699
2700         result->abstract_syntax = *abstract_syntax;
2701         result->transfer_syntax = ndr_transfer_syntax;
2702         result->desthost = talloc_strdup(result, cli->desthost);
2703         result->srv_name_slash = talloc_asprintf_strupper_m(
2704                 result, "\\\\%s", result->desthost);
2705
2706         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2707         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2708
2709         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2710                 TALLOC_FREE(result);
2711                 return NT_STATUS_NO_MEMORY;
2712         }
2713
2714         status = rpc_transport_np_init(result, cli, abstract_syntax,
2715                                        &result->transport);
2716         if (!NT_STATUS_IS_OK(status)) {
2717                 TALLOC_FREE(result);
2718                 return status;
2719         }
2720
2721         result->transport->transport = NCACN_NP;
2722
2723         np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2724         if (np_ref == NULL) {
2725                 TALLOC_FREE(result);
2726                 return NT_STATUS_NO_MEMORY;
2727         }
2728         np_ref->cli = cli;
2729         np_ref->pipe = result;
2730
2731         DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2732         talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2733
2734         result->binding_handle = rpccli_bh_create(result);
2735         if (result->binding_handle == NULL) {
2736                 TALLOC_FREE(result);
2737                 return NT_STATUS_NO_MEMORY;
2738         }
2739
2740         *presult = result;
2741         return NT_STATUS_OK;
2742 }
2743
2744 /****************************************************************************
2745  Open a pipe to a remote server.
2746  ****************************************************************************/
2747
2748 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2749                                   enum dcerpc_transport_t transport,
2750                                   const struct ndr_syntax_id *interface,
2751                                   struct rpc_pipe_client **presult)
2752 {
2753         switch (transport) {
2754         case NCACN_IP_TCP:
2755                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2756                                          presult);
2757         case NCACN_NP:
2758                 return rpc_pipe_open_np(cli, interface, presult);
2759         default:
2760                 return NT_STATUS_NOT_IMPLEMENTED;
2761         }
2762 }
2763
2764 /****************************************************************************
2765  Open a named pipe to an SMB server and bind anonymously.
2766  ****************************************************************************/
2767
2768 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2769                                             enum dcerpc_transport_t transport,
2770                                             const struct ndr_syntax_id *interface,
2771                                             struct rpc_pipe_client **presult)
2772 {
2773         struct rpc_pipe_client *result;
2774         struct pipe_auth_data *auth;
2775         NTSTATUS status;
2776
2777         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2778         if (!NT_STATUS_IS_OK(status)) {
2779                 return status;
2780         }
2781
2782         status = rpccli_anon_bind_data(result, &auth);
2783         if (!NT_STATUS_IS_OK(status)) {
2784                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2785                           nt_errstr(status)));
2786                 TALLOC_FREE(result);
2787                 return status;
2788         }
2789
2790         /*
2791          * This is a bit of an abstraction violation due to the fact that an
2792          * anonymous bind on an authenticated SMB inherits the user/domain
2793          * from the enclosing SMB creds
2794          */
2795
2796         TALLOC_FREE(auth->user_name);
2797         TALLOC_FREE(auth->domain);
2798
2799         auth->user_name = talloc_strdup(auth, cli->user_name);
2800         auth->domain = talloc_strdup(auth, cli->domain);
2801         auth->user_session_key = data_blob_talloc(auth,
2802                 cli->user_session_key.data,
2803                 cli->user_session_key.length);
2804
2805         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2806                 TALLOC_FREE(result);
2807                 return NT_STATUS_NO_MEMORY;
2808         }
2809
2810         status = rpc_pipe_bind(result, auth);
2811         if (!NT_STATUS_IS_OK(status)) {
2812                 int lvl = 0;
2813                 if (ndr_syntax_id_equal(interface,
2814                                         &ndr_table_dssetup.syntax_id)) {
2815                         /* non AD domains just don't have this pipe, avoid
2816                          * level 0 statement in that case - gd */
2817                         lvl = 3;
2818                 }
2819                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2820                             "%s failed with error %s\n",
2821                             get_pipe_name_from_syntax(talloc_tos(), interface),
2822                             nt_errstr(status) ));
2823                 TALLOC_FREE(result);
2824                 return status;
2825         }
2826
2827         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2828                   "%s and bound anonymously.\n",
2829                   get_pipe_name_from_syntax(talloc_tos(), interface),
2830                   cli->desthost));
2831
2832         *presult = result;
2833         return NT_STATUS_OK;
2834 }
2835
2836 /****************************************************************************
2837  ****************************************************************************/
2838
2839 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2840                                   const struct ndr_syntax_id *interface,
2841                                   struct rpc_pipe_client **presult)
2842 {
2843         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2844                                                   interface, presult);
2845 }
2846
2847 /****************************************************************************
2848  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2849  ****************************************************************************/
2850
2851 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2852                                    const struct ndr_syntax_id *interface,
2853                                    enum dcerpc_transport_t transport,
2854                                    enum dcerpc_AuthLevel auth_level,
2855                                    const char *domain,
2856                                    const char *username,
2857                                    const char *password,
2858                                    struct rpc_pipe_client **presult)
2859 {
2860         struct rpc_pipe_client *result;
2861         struct pipe_auth_data *auth = NULL;
2862         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2863         NTSTATUS status;
2864
2865         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2866         if (!NT_STATUS_IS_OK(status)) {
2867                 return status;
2868         }
2869
2870         status = rpccli_ntlmssp_bind_data(result,
2871                                           auth_type, auth_level,
2872                                           domain, username, password,
2873                                           &auth);
2874         if (!NT_STATUS_IS_OK(status)) {
2875                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2876                           nt_errstr(status)));
2877                 goto err;
2878         }
2879
2880         status = rpc_pipe_bind(result, auth);
2881         if (!NT_STATUS_IS_OK(status)) {
2882                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2883                         nt_errstr(status) ));
2884                 goto err;
2885         }
2886
2887         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2888                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2889                   get_pipe_name_from_syntax(talloc_tos(), interface),
2890                   cli->desthost, domain, username ));
2891
2892         *presult = result;
2893         return NT_STATUS_OK;
2894
2895   err:
2896
2897         TALLOC_FREE(result);
2898         return status;
2899 }
2900
2901 /****************************************************************************
2902  External interface.
2903  Open a named pipe to an SMB server and bind using schannel (bind type 68)
2904  using session_key. sign and seal.
2905
2906  The *pdc will be stolen onto this new pipe
2907  ****************************************************************************/
2908
2909 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2910                                              const struct ndr_syntax_id *interface,
2911                                              enum dcerpc_transport_t transport,
2912                                              enum dcerpc_AuthLevel auth_level,
2913                                              const char *domain,
2914                                              struct netlogon_creds_CredentialState **pdc,
2915                                              struct rpc_pipe_client **presult)
2916 {
2917         struct rpc_pipe_client *result;
2918         struct pipe_auth_data *auth;
2919         NTSTATUS status;
2920
2921         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2922         if (!NT_STATUS_IS_OK(status)) {
2923                 return status;
2924         }
2925
2926         status = rpccli_schannel_bind_data(result, domain, auth_level,
2927                                            *pdc, &auth);
2928         if (!NT_STATUS_IS_OK(status)) {
2929                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2930                           nt_errstr(status)));
2931                 TALLOC_FREE(result);
2932                 return status;
2933         }
2934
2935         status = rpc_pipe_bind(result, auth);
2936         if (!NT_STATUS_IS_OK(status)) {
2937                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
2938                           "cli_rpc_pipe_bind failed with error %s\n",
2939                           nt_errstr(status) ));
2940                 TALLOC_FREE(result);
2941                 return status;
2942         }
2943
2944         /*
2945          * The credentials on a new netlogon pipe are the ones we are passed
2946          * in - copy them over
2947          */
2948         result->dc = netlogon_creds_copy(result, *pdc);
2949         if (result->dc == NULL) {
2950                 TALLOC_FREE(result);
2951                 return NT_STATUS_NO_MEMORY;
2952         }
2953
2954         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2955                   "for domain %s and bound using schannel.\n",
2956                   get_pipe_name_from_syntax(talloc_tos(), interface),
2957                   cli->desthost, domain ));
2958
2959         *presult = result;
2960         return NT_STATUS_OK;
2961 }
2962
2963 /****************************************************************************
2964  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2965  The idea is this can be called with service_princ, username and password all
2966  NULL so long as the caller has a TGT.
2967  ****************************************************************************/
2968
2969 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
2970                                 const struct ndr_syntax_id *interface,
2971                                 enum dcerpc_transport_t transport,
2972                                 enum dcerpc_AuthLevel auth_level,
2973                                 const char *server,
2974                                 const char *username,
2975                                 const char *password,
2976                                 struct rpc_pipe_client **presult)
2977 {
2978         struct rpc_pipe_client *result;
2979         struct pipe_auth_data *auth;
2980         NTSTATUS status;
2981
2982         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2983         if (!NT_STATUS_IS_OK(status)) {
2984                 return status;
2985         }
2986
2987         auth = talloc(result, struct pipe_auth_data);
2988         if (auth == NULL) {
2989                 status = NT_STATUS_NO_MEMORY;
2990                 goto err_out;
2991         }
2992         auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
2993         auth->auth_level = auth_level;
2994
2995         if (!username) {
2996                 username = "";
2997         }
2998         auth->user_name = talloc_strdup(auth, username);
2999         if (!auth->user_name) {
3000                 status = NT_STATUS_NO_MEMORY;
3001                 goto err_out;
3002         }
3003
3004         /* Fixme, should we fetch/set the Realm ? */
3005         auth->domain = talloc_strdup(auth, "");
3006         if (!auth->domain) {
3007                 status = NT_STATUS_NO_MEMORY;
3008                 goto err_out;
3009         }
3010
3011         status = gse_init_client(auth,
3012                                  (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
3013                                  (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
3014                                  NULL, server, "cifs", username, password,
3015                                  GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3016
3017         if (!NT_STATUS_IS_OK(status)) {
3018                 DEBUG(0, ("gse_init_client returned %s\n",
3019                           nt_errstr(status)));
3020                 goto err_out;
3021         }
3022
3023         status = rpc_pipe_bind(result, auth);
3024         if (!NT_STATUS_IS_OK(status)) {
3025                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3026                           nt_errstr(status)));
3027                 goto err_out;
3028         }
3029
3030         *presult = result;
3031         return NT_STATUS_OK;
3032
3033 err_out:
3034         TALLOC_FREE(result);
3035         return status;
3036 }
3037
3038 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3039                                         const struct ndr_syntax_id *interface,
3040                                         enum dcerpc_transport_t transport,
3041                                         enum dcerpc_AuthLevel auth_level,
3042                                         const char *server,
3043                                         const char *username,
3044                                         const char *password,
3045                                         struct rpc_pipe_client **presult)
3046 {
3047         struct rpc_pipe_client *result;
3048         struct pipe_auth_data *auth;
3049         NTSTATUS status;
3050
3051         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3052         if (!NT_STATUS_IS_OK(status)) {
3053                 return status;
3054         }
3055
3056         auth = talloc(result, struct pipe_auth_data);
3057         if (auth == NULL) {
3058                 status = NT_STATUS_NO_MEMORY;
3059                 goto err_out;
3060         }
3061         auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3062         auth->auth_level = auth_level;
3063
3064         if (!username) {
3065                 username = "";
3066         }
3067         auth->user_name = talloc_strdup(auth, username);
3068         if (!auth->user_name) {
3069                 status = NT_STATUS_NO_MEMORY;
3070                 goto err_out;
3071         }
3072
3073         /* Fixme, should we fetch/set the Realm ? */
3074         auth->domain = talloc_strdup(auth, "");
3075         if (!auth->domain) {
3076                 status = NT_STATUS_NO_MEMORY;
3077                 goto err_out;
3078         }
3079
3080         status = spnego_gssapi_init_client(auth,
3081                                            (auth->auth_level ==
3082                                                 DCERPC_AUTH_LEVEL_INTEGRITY),
3083                                            (auth->auth_level ==
3084                                                 DCERPC_AUTH_LEVEL_PRIVACY),
3085                                            true,
3086                                            NULL, server, "cifs",
3087                                            username, password,
3088                                            &auth->a_u.spnego_state);
3089         if (!NT_STATUS_IS_OK(status)) {
3090                 DEBUG(0, ("spnego_init_client returned %s\n",
3091                           nt_errstr(status)));
3092                 goto err_out;
3093         }
3094
3095         status = rpc_pipe_bind(result, auth);
3096         if (!NT_STATUS_IS_OK(status)) {
3097                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3098                           nt_errstr(status)));
3099                 goto err_out;
3100         }
3101
3102         *presult = result;
3103         return NT_STATUS_OK;
3104
3105 err_out:
3106         TALLOC_FREE(result);
3107         return status;
3108 }
3109
3110 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3111                                           const struct ndr_syntax_id *interface,
3112                                           enum dcerpc_transport_t transport,
3113                                           enum dcerpc_AuthLevel auth_level,
3114                                           const char *domain,
3115                                           const char *username,
3116                                           const char *password,
3117                                           struct rpc_pipe_client **presult)
3118 {
3119         struct rpc_pipe_client *result;
3120         struct pipe_auth_data *auth;
3121         NTSTATUS status;
3122
3123         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3124         if (!NT_STATUS_IS_OK(status)) {
3125                 return status;
3126         }
3127
3128         auth = talloc(result, struct pipe_auth_data);
3129         if (auth == NULL) {
3130                 status = NT_STATUS_NO_MEMORY;
3131                 goto err_out;
3132         }
3133         auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3134         auth->auth_level = auth_level;
3135
3136         if (!username) {
3137                 username = "";
3138         }
3139         auth->user_name = talloc_strdup(auth, username);
3140         if (!auth->user_name) {
3141                 status = NT_STATUS_NO_MEMORY;
3142                 goto err_out;
3143         }
3144
3145         if (!domain) {
3146                 domain = "";
3147         }
3148         auth->domain = talloc_strdup(auth, domain);
3149         if (!auth->domain) {
3150                 status = NT_STATUS_NO_MEMORY;
3151                 goto err_out;
3152         }
3153
3154         status = spnego_ntlmssp_init_client(auth,
3155                                             (auth->auth_level ==
3156                                                 DCERPC_AUTH_LEVEL_INTEGRITY),
3157                                             (auth->auth_level ==
3158                                                 DCERPC_AUTH_LEVEL_PRIVACY),
3159                                             true,
3160                                             domain, username, password,
3161                                             &auth->a_u.spnego_state);
3162         if (!NT_STATUS_IS_OK(status)) {
3163                 DEBUG(0, ("spnego_init_client returned %s\n",
3164                           nt_errstr(status)));
3165                 goto err_out;
3166         }
3167
3168         status = rpc_pipe_bind(result, auth);
3169         if (!NT_STATUS_IS_OK(status)) {
3170                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3171                           nt_errstr(status)));
3172                 goto err_out;
3173         }
3174
3175         *presult = result;
3176         return NT_STATUS_OK;
3177
3178 err_out:
3179         TALLOC_FREE(result);
3180         return status;
3181 }
3182
3183 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3184                              struct rpc_pipe_client *cli,
3185                              DATA_BLOB *session_key)
3186 {
3187         struct pipe_auth_data *a = cli->auth;
3188         DATA_BLOB sk = data_blob_null;
3189         bool make_dup = false;
3190
3191         if (!session_key || !cli) {
3192                 return NT_STATUS_INVALID_PARAMETER;
3193         }
3194
3195         if (!cli->auth) {
3196                 return NT_STATUS_INVALID_PARAMETER;
3197         }
3198
3199         switch (cli->auth->auth_type) {
3200         case DCERPC_AUTH_TYPE_SCHANNEL:
3201                 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3202                                      16);
3203                 make_dup = true;
3204                 break;
3205         case DCERPC_AUTH_TYPE_SPNEGO:
3206                 sk = spnego_get_session_key(mem_ctx, a->a_u.spnego_state);
3207                 make_dup = false;
3208                 break;
3209         case DCERPC_AUTH_TYPE_NTLMSSP:
3210                 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3211                 make_dup = true;
3212                 break;
3213         case DCERPC_AUTH_TYPE_KRB5:
3214                 sk = gse_get_session_key(mem_ctx, a->a_u.gssapi_state);
3215                 make_dup = false;
3216                 break;
3217         case DCERPC_AUTH_TYPE_NONE:
3218                 sk = data_blob_const(a->user_session_key.data,
3219                                      a->user_session_key.length);
3220                 make_dup = true;
3221                 break;
3222         default:
3223                 break;
3224         }
3225
3226         if (!sk.data) {
3227                 return NT_STATUS_NO_USER_SESSION_KEY;
3228         }
3229
3230         if (make_dup) {
3231                 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3232         } else {
3233                 *session_key = sk;
3234         }
3235
3236         return NT_STATUS_OK;
3237 }