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