s3-auth rename auth_ntlmssp_state -> auth_generic_state
[mat/samba.git] / source3 / rpc_client / cli_pipe.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client routines
4  *  Largely rewritten by Jeremy Allison             2005.
5  *  Heavily modified by Simo Sorce                  2010.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "includes.h"
22 #include "../lib/util/tevent_ntstatus.h"
23 #include "librpc/gen_ndr/ndr_epmapper_c.h"
24 #include "../librpc/gen_ndr/ndr_schannel.h"
25 #include "../librpc/gen_ndr/ndr_dssetup.h"
26 #include "../libcli/auth/schannel.h"
27 #include "../libcli/auth/spnego.h"
28 #include "../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 gensec_security *gensec_security;
1045         DATA_BLOB null_blob = data_blob_null;
1046         NTSTATUS status;
1047
1048         gensec_security = talloc_get_type_abort(cli->auth->auth_ctx,
1049                                         struct gensec_security);
1050
1051         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1052         status = gensec_update(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 gensec_security *gensec_security;
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                 gensec_security = talloc_get_type_abort(pauth->auth_ctx,
1776                                                 struct gensec_security);
1777                 status = gensec_update(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_generic_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 = talloc_move(result, &ntlmssp_ctx->gensec_security);
2320         talloc_free(ntlmssp_ctx);
2321         *presult = result;
2322         return NT_STATUS_OK;
2323
2324  fail:
2325         TALLOC_FREE(result);
2326         return status;
2327 }
2328
2329 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2330                                    enum dcerpc_AuthLevel auth_level,
2331                                    struct netlogon_creds_CredentialState *creds,
2332                                    struct pipe_auth_data **presult)
2333 {
2334         struct schannel_state *schannel_auth;
2335         struct pipe_auth_data *result;
2336
2337         result = talloc(mem_ctx, struct pipe_auth_data);
2338         if (result == NULL) {
2339                 return NT_STATUS_NO_MEMORY;
2340         }
2341
2342         result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2343         result->auth_level = auth_level;
2344
2345         result->user_name = talloc_strdup(result, "");
2346         result->domain = talloc_strdup(result, domain);
2347         if ((result->user_name == NULL) || (result->domain == NULL)) {
2348                 goto fail;
2349         }
2350
2351         schannel_auth = talloc(result, struct schannel_state);
2352         if (schannel_auth == NULL) {
2353                 goto fail;
2354         }
2355
2356         schannel_auth->state = SCHANNEL_STATE_START;
2357         schannel_auth->seq_num = 0;
2358         schannel_auth->initiator = true;
2359         schannel_auth->creds = netlogon_creds_copy(result, creds);
2360
2361         result->auth_ctx = schannel_auth;
2362         *presult = result;
2363         return NT_STATUS_OK;
2364
2365  fail:
2366         TALLOC_FREE(result);
2367         return NT_STATUS_NO_MEMORY;
2368 }
2369
2370 /**
2371  * Create an rpc pipe client struct, connecting to a tcp port.
2372  */
2373 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2374                                        uint16_t port,
2375                                        const struct ndr_syntax_id *abstract_syntax,
2376                                        struct rpc_pipe_client **presult)
2377 {
2378         struct rpc_pipe_client *result;
2379         struct sockaddr_storage addr;
2380         NTSTATUS status;
2381         int fd;
2382
2383         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2384         if (result == NULL) {
2385                 return NT_STATUS_NO_MEMORY;
2386         }
2387
2388         result->abstract_syntax = *abstract_syntax;
2389         result->transfer_syntax = ndr_transfer_syntax;
2390
2391         result->desthost = talloc_strdup(result, host);
2392         result->srv_name_slash = talloc_asprintf_strupper_m(
2393                 result, "\\\\%s", result->desthost);
2394         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2395                 status = NT_STATUS_NO_MEMORY;
2396                 goto fail;
2397         }
2398
2399         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2400         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2401
2402         if (!resolve_name(host, &addr, 0, false)) {
2403                 status = NT_STATUS_NOT_FOUND;
2404                 goto fail;
2405         }
2406
2407         status = open_socket_out(&addr, port, 60*1000, &fd);
2408         if (!NT_STATUS_IS_OK(status)) {
2409                 goto fail;
2410         }
2411         set_socket_options(fd, lp_socket_options());
2412
2413         status = rpc_transport_sock_init(result, fd, &result->transport);
2414         if (!NT_STATUS_IS_OK(status)) {
2415                 close(fd);
2416                 goto fail;
2417         }
2418
2419         result->transport->transport = NCACN_IP_TCP;
2420
2421         result->binding_handle = rpccli_bh_create(result);
2422         if (result->binding_handle == NULL) {
2423                 TALLOC_FREE(result);
2424                 return NT_STATUS_NO_MEMORY;
2425         }
2426
2427         *presult = result;
2428         return NT_STATUS_OK;
2429
2430  fail:
2431         TALLOC_FREE(result);
2432         return status;
2433 }
2434
2435 /**
2436  * Determine the tcp port on which a dcerpc interface is listening
2437  * for the ncacn_ip_tcp transport via the endpoint mapper of the
2438  * target host.
2439  */
2440 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2441                                       const struct ndr_syntax_id *abstract_syntax,
2442                                       uint16_t *pport)
2443 {
2444         NTSTATUS status;
2445         struct rpc_pipe_client *epm_pipe = NULL;
2446         struct dcerpc_binding_handle *epm_handle = NULL;
2447         struct pipe_auth_data *auth = NULL;
2448         struct dcerpc_binding *map_binding = NULL;
2449         struct dcerpc_binding *res_binding = NULL;
2450         struct epm_twr_t *map_tower = NULL;
2451         struct epm_twr_t *res_towers = NULL;
2452         struct policy_handle *entry_handle = NULL;
2453         uint32_t num_towers = 0;
2454         uint32_t max_towers = 1;
2455         struct epm_twr_p_t towers;
2456         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2457         uint32_t result = 0;
2458
2459         if (pport == NULL) {
2460                 status = NT_STATUS_INVALID_PARAMETER;
2461                 goto done;
2462         }
2463
2464         if (ndr_syntax_id_equal(abstract_syntax,
2465                                 &ndr_table_epmapper.syntax_id)) {
2466                 *pport = 135;
2467                 return NT_STATUS_OK;
2468         }
2469
2470         /* open the connection to the endpoint mapper */
2471         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2472                                         &ndr_table_epmapper.syntax_id,
2473                                         &epm_pipe);
2474
2475         if (!NT_STATUS_IS_OK(status)) {
2476                 goto done;
2477         }
2478         epm_handle = epm_pipe->binding_handle;
2479
2480         status = rpccli_anon_bind_data(tmp_ctx, &auth);
2481         if (!NT_STATUS_IS_OK(status)) {
2482                 goto done;
2483         }
2484
2485         status = rpc_pipe_bind(epm_pipe, auth);
2486         if (!NT_STATUS_IS_OK(status)) {
2487                 goto done;
2488         }
2489
2490         /* create tower for asking the epmapper */
2491
2492         map_binding = talloc_zero(tmp_ctx, struct dcerpc_binding);
2493         if (map_binding == NULL) {
2494                 status = NT_STATUS_NO_MEMORY;
2495                 goto done;
2496         }
2497
2498         map_binding->transport = NCACN_IP_TCP;
2499         map_binding->object = *abstract_syntax;
2500         map_binding->host = host; /* needed? */
2501         map_binding->endpoint = "0"; /* correct? needed? */
2502
2503         map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2504         if (map_tower == NULL) {
2505                 status = NT_STATUS_NO_MEMORY;
2506                 goto done;
2507         }
2508
2509         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2510                                             &(map_tower->tower));
2511         if (!NT_STATUS_IS_OK(status)) {
2512                 goto done;
2513         }
2514
2515         /* allocate further parameters for the epm_Map call */
2516
2517         res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2518         if (res_towers == NULL) {
2519                 status = NT_STATUS_NO_MEMORY;
2520                 goto done;
2521         }
2522         towers.twr = res_towers;
2523
2524         entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2525         if (entry_handle == NULL) {
2526                 status = NT_STATUS_NO_MEMORY;
2527                 goto done;
2528         }
2529
2530         /* ask the endpoint mapper for the port */
2531
2532         status = dcerpc_epm_Map(epm_handle,
2533                                 tmp_ctx,
2534                                 discard_const_p(struct GUID,
2535                                               &(abstract_syntax->uuid)),
2536                                 map_tower,
2537                                 entry_handle,
2538                                 max_towers,
2539                                 &num_towers,
2540                                 &towers,
2541                                 &result);
2542
2543         if (!NT_STATUS_IS_OK(status)) {
2544                 goto done;
2545         }
2546
2547         if (result != EPMAPPER_STATUS_OK) {
2548                 status = NT_STATUS_UNSUCCESSFUL;
2549                 goto done;
2550         }
2551
2552         if (num_towers != 1) {
2553                 status = NT_STATUS_UNSUCCESSFUL;
2554                 goto done;
2555         }
2556
2557         /* extract the port from the answer */
2558
2559         status = dcerpc_binding_from_tower(tmp_ctx,
2560                                            &(towers.twr->tower),
2561                                            &res_binding);
2562         if (!NT_STATUS_IS_OK(status)) {
2563                 goto done;
2564         }
2565
2566         /* are further checks here necessary? */
2567         if (res_binding->transport != NCACN_IP_TCP) {
2568                 status = NT_STATUS_UNSUCCESSFUL;
2569                 goto done;
2570         }
2571
2572         *pport = (uint16_t)atoi(res_binding->endpoint);
2573
2574 done:
2575         TALLOC_FREE(tmp_ctx);
2576         return status;
2577 }
2578
2579 /**
2580  * Create a rpc pipe client struct, connecting to a host via tcp.
2581  * The port is determined by asking the endpoint mapper on the given
2582  * host.
2583  */
2584 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2585                            const struct ndr_syntax_id *abstract_syntax,
2586                            struct rpc_pipe_client **presult)
2587 {
2588         NTSTATUS status;
2589         uint16_t port = 0;
2590
2591         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2592         if (!NT_STATUS_IS_OK(status)) {
2593                 return status;
2594         }
2595
2596         return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2597                                         abstract_syntax, presult);
2598 }
2599
2600 /********************************************************************
2601  Create a rpc pipe client struct, connecting to a unix domain socket
2602  ********************************************************************/
2603 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2604                                const struct ndr_syntax_id *abstract_syntax,
2605                                struct rpc_pipe_client **presult)
2606 {
2607         struct rpc_pipe_client *result;
2608         struct sockaddr_un addr;
2609         NTSTATUS status;
2610         int fd;
2611
2612         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2613         if (result == NULL) {
2614                 return NT_STATUS_NO_MEMORY;
2615         }
2616
2617         result->abstract_syntax = *abstract_syntax;
2618         result->transfer_syntax = ndr_transfer_syntax;
2619
2620         result->desthost = get_myname(result);
2621         result->srv_name_slash = talloc_asprintf_strupper_m(
2622                 result, "\\\\%s", result->desthost);
2623         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2624                 status = NT_STATUS_NO_MEMORY;
2625                 goto fail;
2626         }
2627
2628         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2629         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2630
2631         fd = socket(AF_UNIX, SOCK_STREAM, 0);
2632         if (fd == -1) {
2633                 status = map_nt_error_from_unix(errno);
2634                 goto fail;
2635         }
2636
2637         ZERO_STRUCT(addr);
2638         addr.sun_family = AF_UNIX;
2639         strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2640
2641         if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2642                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2643                           strerror(errno)));
2644                 close(fd);
2645                 return map_nt_error_from_unix(errno);
2646         }
2647
2648         status = rpc_transport_sock_init(result, fd, &result->transport);
2649         if (!NT_STATUS_IS_OK(status)) {
2650                 close(fd);
2651                 goto fail;
2652         }
2653
2654         result->transport->transport = NCALRPC;
2655
2656         result->binding_handle = rpccli_bh_create(result);
2657         if (result->binding_handle == NULL) {
2658                 TALLOC_FREE(result);
2659                 return NT_STATUS_NO_MEMORY;
2660         }
2661
2662         *presult = result;
2663         return NT_STATUS_OK;
2664
2665  fail:
2666         TALLOC_FREE(result);
2667         return status;
2668 }
2669
2670 struct rpc_pipe_client_np_ref {
2671         struct cli_state *cli;
2672         struct rpc_pipe_client *pipe;
2673 };
2674
2675 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2676 {
2677         DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2678         return 0;
2679 }
2680
2681 /****************************************************************************
2682  Open a named pipe over SMB to a remote server.
2683  *
2684  * CAVEAT CALLER OF THIS FUNCTION:
2685  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2686  *    so be sure that this function is called AFTER any structure (vs pointer)
2687  *    assignment of the cli.  In particular, libsmbclient does structure
2688  *    assignments of cli, which invalidates the data in the returned
2689  *    rpc_pipe_client if this function is called before the structure assignment
2690  *    of cli.
2691  * 
2692  ****************************************************************************/
2693
2694 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2695                                  const struct ndr_syntax_id *abstract_syntax,
2696                                  struct rpc_pipe_client **presult)
2697 {
2698         struct rpc_pipe_client *result;
2699         NTSTATUS status;
2700         struct rpc_pipe_client_np_ref *np_ref;
2701
2702         /* sanity check to protect against crashes */
2703
2704         if ( !cli ) {
2705                 return NT_STATUS_INVALID_HANDLE;
2706         }
2707
2708         result = talloc_zero(NULL, struct rpc_pipe_client);
2709         if (result == NULL) {
2710                 return NT_STATUS_NO_MEMORY;
2711         }
2712
2713         result->abstract_syntax = *abstract_syntax;
2714         result->transfer_syntax = ndr_transfer_syntax;
2715         result->desthost = talloc_strdup(result, cli_state_remote_name(cli));
2716         result->srv_name_slash = talloc_asprintf_strupper_m(
2717                 result, "\\\\%s", result->desthost);
2718
2719         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2720         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2721
2722         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2723                 TALLOC_FREE(result);
2724                 return NT_STATUS_NO_MEMORY;
2725         }
2726
2727         status = rpc_transport_np_init(result, cli, abstract_syntax,
2728                                        &result->transport);
2729         if (!NT_STATUS_IS_OK(status)) {
2730                 TALLOC_FREE(result);
2731                 return status;
2732         }
2733
2734         result->transport->transport = NCACN_NP;
2735
2736         np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2737         if (np_ref == NULL) {
2738                 TALLOC_FREE(result);
2739                 return NT_STATUS_NO_MEMORY;
2740         }
2741         np_ref->cli = cli;
2742         np_ref->pipe = result;
2743
2744         DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2745         talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2746
2747         result->binding_handle = rpccli_bh_create(result);
2748         if (result->binding_handle == NULL) {
2749                 TALLOC_FREE(result);
2750                 return NT_STATUS_NO_MEMORY;
2751         }
2752
2753         *presult = result;
2754         return NT_STATUS_OK;
2755 }
2756
2757 /****************************************************************************
2758  Open a pipe to a remote server.
2759  ****************************************************************************/
2760
2761 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2762                                   enum dcerpc_transport_t transport,
2763                                   const struct ndr_syntax_id *interface,
2764                                   struct rpc_pipe_client **presult)
2765 {
2766         switch (transport) {
2767         case NCACN_IP_TCP:
2768                 return rpc_pipe_open_tcp(NULL, cli_state_remote_name(cli),
2769                                          interface, presult);
2770         case NCACN_NP:
2771                 return rpc_pipe_open_np(cli, interface, presult);
2772         default:
2773                 return NT_STATUS_NOT_IMPLEMENTED;
2774         }
2775 }
2776
2777 /****************************************************************************
2778  Open a named pipe to an SMB server and bind anonymously.
2779  ****************************************************************************/
2780
2781 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2782                                             enum dcerpc_transport_t transport,
2783                                             const struct ndr_syntax_id *interface,
2784                                             struct rpc_pipe_client **presult)
2785 {
2786         struct rpc_pipe_client *result;
2787         struct pipe_auth_data *auth;
2788         NTSTATUS status;
2789
2790         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2791         if (!NT_STATUS_IS_OK(status)) {
2792                 return status;
2793         }
2794
2795         status = rpccli_anon_bind_data(result, &auth);
2796         if (!NT_STATUS_IS_OK(status)) {
2797                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2798                           nt_errstr(status)));
2799                 TALLOC_FREE(result);
2800                 return status;
2801         }
2802
2803         /*
2804          * This is a bit of an abstraction violation due to the fact that an
2805          * anonymous bind on an authenticated SMB inherits the user/domain
2806          * from the enclosing SMB creds
2807          */
2808
2809         TALLOC_FREE(auth->user_name);
2810         TALLOC_FREE(auth->domain);
2811
2812         auth->user_name = talloc_strdup(auth, cli->user_name);
2813         auth->domain = talloc_strdup(auth, cli->domain);
2814         auth->user_session_key = data_blob_talloc(auth,
2815                 cli->user_session_key.data,
2816                 cli->user_session_key.length);
2817
2818         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2819                 TALLOC_FREE(result);
2820                 return NT_STATUS_NO_MEMORY;
2821         }
2822
2823         status = rpc_pipe_bind(result, auth);
2824         if (!NT_STATUS_IS_OK(status)) {
2825                 int lvl = 0;
2826                 if (ndr_syntax_id_equal(interface,
2827                                         &ndr_table_dssetup.syntax_id)) {
2828                         /* non AD domains just don't have this pipe, avoid
2829                          * level 0 statement in that case - gd */
2830                         lvl = 3;
2831                 }
2832                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2833                             "%s failed with error %s\n",
2834                             get_pipe_name_from_syntax(talloc_tos(), interface),
2835                             nt_errstr(status) ));
2836                 TALLOC_FREE(result);
2837                 return status;
2838         }
2839
2840         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2841                   "%s and bound anonymously.\n",
2842                   get_pipe_name_from_syntax(talloc_tos(), interface),
2843                   result->desthost));
2844
2845         *presult = result;
2846         return NT_STATUS_OK;
2847 }
2848
2849 /****************************************************************************
2850  ****************************************************************************/
2851
2852 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2853                                   const struct ndr_syntax_id *interface,
2854                                   struct rpc_pipe_client **presult)
2855 {
2856         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2857                                                   interface, presult);
2858 }
2859
2860 /****************************************************************************
2861  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2862  ****************************************************************************/
2863
2864 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2865                                    const struct ndr_syntax_id *interface,
2866                                    enum dcerpc_transport_t transport,
2867                                    enum dcerpc_AuthLevel auth_level,
2868                                    const char *domain,
2869                                    const char *username,
2870                                    const char *password,
2871                                    struct rpc_pipe_client **presult)
2872 {
2873         struct rpc_pipe_client *result;
2874         struct pipe_auth_data *auth = NULL;
2875         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2876         NTSTATUS status;
2877
2878         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2879         if (!NT_STATUS_IS_OK(status)) {
2880                 return status;
2881         }
2882
2883         status = rpccli_ntlmssp_bind_data(result,
2884                                           auth_type, auth_level,
2885                                           domain, username, password,
2886                                           &auth);
2887         if (!NT_STATUS_IS_OK(status)) {
2888                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2889                           nt_errstr(status)));
2890                 goto err;
2891         }
2892
2893         status = rpc_pipe_bind(result, auth);
2894         if (!NT_STATUS_IS_OK(status)) {
2895                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2896                         nt_errstr(status) ));
2897                 goto err;
2898         }
2899
2900         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2901                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2902                   get_pipe_name_from_syntax(talloc_tos(), interface),
2903                   result->desthost, domain, username));
2904
2905         *presult = result;
2906         return NT_STATUS_OK;
2907
2908   err:
2909
2910         TALLOC_FREE(result);
2911         return status;
2912 }
2913
2914 /****************************************************************************
2915  External interface.
2916  Open a named pipe to an SMB server and bind using schannel (bind type 68)
2917  using session_key. sign and seal.
2918
2919  The *pdc will be stolen onto this new pipe
2920  ****************************************************************************/
2921
2922 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2923                                              const struct ndr_syntax_id *interface,
2924                                              enum dcerpc_transport_t transport,
2925                                              enum dcerpc_AuthLevel auth_level,
2926                                              const char *domain,
2927                                              struct netlogon_creds_CredentialState **pdc,
2928                                              struct rpc_pipe_client **presult)
2929 {
2930         struct rpc_pipe_client *result;
2931         struct pipe_auth_data *auth;
2932         NTSTATUS status;
2933
2934         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2935         if (!NT_STATUS_IS_OK(status)) {
2936                 return status;
2937         }
2938
2939         status = rpccli_schannel_bind_data(result, domain, auth_level,
2940                                            *pdc, &auth);
2941         if (!NT_STATUS_IS_OK(status)) {
2942                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2943                           nt_errstr(status)));
2944                 TALLOC_FREE(result);
2945                 return status;
2946         }
2947
2948         status = rpc_pipe_bind(result, auth);
2949         if (!NT_STATUS_IS_OK(status)) {
2950                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
2951                           "cli_rpc_pipe_bind failed with error %s\n",
2952                           nt_errstr(status) ));
2953                 TALLOC_FREE(result);
2954                 return status;
2955         }
2956
2957         /*
2958          * The credentials on a new netlogon pipe are the ones we are passed
2959          * in - copy them over
2960          */
2961         result->dc = netlogon_creds_copy(result, *pdc);
2962         if (result->dc == NULL) {
2963                 TALLOC_FREE(result);
2964                 return NT_STATUS_NO_MEMORY;
2965         }
2966
2967         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2968                   "for domain %s and bound using schannel.\n",
2969                   get_pipe_name_from_syntax(talloc_tos(), interface),
2970                   result->desthost, domain));
2971
2972         *presult = result;
2973         return NT_STATUS_OK;
2974 }
2975
2976 /****************************************************************************
2977  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2978  The idea is this can be called with service_princ, username and password all
2979  NULL so long as the caller has a TGT.
2980  ****************************************************************************/
2981
2982 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
2983                                 const struct ndr_syntax_id *interface,
2984                                 enum dcerpc_transport_t transport,
2985                                 enum dcerpc_AuthLevel auth_level,
2986                                 const char *server,
2987                                 const char *username,
2988                                 const char *password,
2989                                 struct rpc_pipe_client **presult)
2990 {
2991         struct rpc_pipe_client *result;
2992         struct pipe_auth_data *auth;
2993         struct gse_context *gse_ctx;
2994         NTSTATUS status;
2995
2996         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2997         if (!NT_STATUS_IS_OK(status)) {
2998                 return status;
2999         }
3000
3001         auth = talloc(result, struct pipe_auth_data);
3002         if (auth == NULL) {
3003                 status = NT_STATUS_NO_MEMORY;
3004                 goto err_out;
3005         }
3006         auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3007         auth->auth_level = auth_level;
3008
3009         if (!username) {
3010                 username = "";
3011         }
3012         auth->user_name = talloc_strdup(auth, username);
3013         if (!auth->user_name) {
3014                 status = NT_STATUS_NO_MEMORY;
3015                 goto err_out;
3016         }
3017
3018         /* Fixme, should we fetch/set the Realm ? */
3019         auth->domain = talloc_strdup(auth, "");
3020         if (!auth->domain) {
3021                 status = NT_STATUS_NO_MEMORY;
3022                 goto err_out;
3023         }
3024
3025         status = gse_init_client(auth,
3026                                  (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
3027                                  (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
3028                                  NULL, server, "cifs", username, password,
3029                                  GSS_C_DCE_STYLE, &gse_ctx);
3030         if (!NT_STATUS_IS_OK(status)) {
3031                 DEBUG(0, ("gse_init_client returned %s\n",
3032                           nt_errstr(status)));
3033                 goto err_out;
3034         }
3035         auth->auth_ctx = gse_ctx;
3036
3037         status = rpc_pipe_bind(result, auth);
3038         if (!NT_STATUS_IS_OK(status)) {
3039                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3040                           nt_errstr(status)));
3041                 goto err_out;
3042         }
3043
3044         *presult = result;
3045         return NT_STATUS_OK;
3046
3047 err_out:
3048         TALLOC_FREE(result);
3049         return status;
3050 }
3051
3052 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3053                                         const struct ndr_syntax_id *interface,
3054                                         enum dcerpc_transport_t transport,
3055                                         enum dcerpc_AuthLevel auth_level,
3056                                         const char *server,
3057                                         const char *username,
3058                                         const char *password,
3059                                         struct rpc_pipe_client **presult)
3060 {
3061         struct rpc_pipe_client *result;
3062         struct pipe_auth_data *auth;
3063         struct spnego_context *spnego_ctx;
3064         NTSTATUS status;
3065
3066         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3067         if (!NT_STATUS_IS_OK(status)) {
3068                 return status;
3069         }
3070
3071         auth = talloc(result, struct pipe_auth_data);
3072         if (auth == NULL) {
3073                 status = NT_STATUS_NO_MEMORY;
3074                 goto err_out;
3075         }
3076         auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3077         auth->auth_level = auth_level;
3078
3079         if (!username) {
3080                 username = "";
3081         }
3082         auth->user_name = talloc_strdup(auth, username);
3083         if (!auth->user_name) {
3084                 status = NT_STATUS_NO_MEMORY;
3085                 goto err_out;
3086         }
3087
3088         /* Fixme, should we fetch/set the Realm ? */
3089         auth->domain = talloc_strdup(auth, "");
3090         if (!auth->domain) {
3091                 status = NT_STATUS_NO_MEMORY;
3092                 goto err_out;
3093         }
3094
3095         status = spnego_gssapi_init_client(auth,
3096                                            (auth->auth_level ==
3097                                                 DCERPC_AUTH_LEVEL_INTEGRITY),
3098                                            (auth->auth_level ==
3099                                                 DCERPC_AUTH_LEVEL_PRIVACY),
3100                                            true,
3101                                            NULL, server, "cifs",
3102                                            username, password,
3103                                            &spnego_ctx);
3104         if (!NT_STATUS_IS_OK(status)) {
3105                 DEBUG(0, ("spnego_init_client returned %s\n",
3106                           nt_errstr(status)));
3107                 goto err_out;
3108         }
3109         auth->auth_ctx = spnego_ctx;
3110
3111         status = rpc_pipe_bind(result, auth);
3112         if (!NT_STATUS_IS_OK(status)) {
3113                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3114                           nt_errstr(status)));
3115                 goto err_out;
3116         }
3117
3118         *presult = result;
3119         return NT_STATUS_OK;
3120
3121 err_out:
3122         TALLOC_FREE(result);
3123         return status;
3124 }
3125
3126 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3127                                           const struct ndr_syntax_id *interface,
3128                                           enum dcerpc_transport_t transport,
3129                                           enum dcerpc_AuthLevel auth_level,
3130                                           const char *domain,
3131                                           const char *username,
3132                                           const char *password,
3133                                           struct rpc_pipe_client **presult)
3134 {
3135         struct rpc_pipe_client *result;
3136         struct pipe_auth_data *auth;
3137         struct spnego_context *spnego_ctx;
3138         NTSTATUS status;
3139
3140         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3141         if (!NT_STATUS_IS_OK(status)) {
3142                 return status;
3143         }
3144
3145         auth = talloc(result, struct pipe_auth_data);
3146         if (auth == NULL) {
3147                 status = NT_STATUS_NO_MEMORY;
3148                 goto err_out;
3149         }
3150         auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3151         auth->auth_level = auth_level;
3152
3153         if (!username) {
3154                 username = "";
3155         }
3156         auth->user_name = talloc_strdup(auth, username);
3157         if (!auth->user_name) {
3158                 status = NT_STATUS_NO_MEMORY;
3159                 goto err_out;
3160         }
3161
3162         if (!domain) {
3163                 domain = "";
3164         }
3165         auth->domain = talloc_strdup(auth, domain);
3166         if (!auth->domain) {
3167                 status = NT_STATUS_NO_MEMORY;
3168                 goto err_out;
3169         }
3170
3171         status = spnego_ntlmssp_init_client(auth,
3172                                             (auth->auth_level ==
3173                                                 DCERPC_AUTH_LEVEL_INTEGRITY),
3174                                             (auth->auth_level ==
3175                                                 DCERPC_AUTH_LEVEL_PRIVACY),
3176                                             true,
3177                                             domain, username, password,
3178                                             &spnego_ctx);
3179         if (!NT_STATUS_IS_OK(status)) {
3180                 DEBUG(0, ("spnego_init_client returned %s\n",
3181                           nt_errstr(status)));
3182                 goto err_out;
3183         }
3184         auth->auth_ctx = spnego_ctx;
3185
3186         status = rpc_pipe_bind(result, auth);
3187         if (!NT_STATUS_IS_OK(status)) {
3188                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3189                           nt_errstr(status)));
3190                 goto err_out;
3191         }
3192
3193         *presult = result;
3194         return NT_STATUS_OK;
3195
3196 err_out:
3197         TALLOC_FREE(result);
3198         return status;
3199 }
3200
3201 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3202                              struct rpc_pipe_client *cli,
3203                              DATA_BLOB *session_key)
3204 {
3205         NTSTATUS status;
3206         struct pipe_auth_data *a;
3207         struct schannel_state *schannel_auth;
3208         struct gensec_security *gensec_security;
3209         struct spnego_context *spnego_ctx;
3210         struct gse_context *gse_ctx;
3211         DATA_BLOB sk = data_blob_null;
3212         bool make_dup = false;
3213
3214         if (!session_key || !cli) {
3215                 return NT_STATUS_INVALID_PARAMETER;
3216         }
3217
3218         a = cli->auth;
3219
3220         if (a == NULL) {
3221                 return NT_STATUS_INVALID_PARAMETER;
3222         }
3223
3224         switch (cli->auth->auth_type) {
3225         case DCERPC_AUTH_TYPE_SCHANNEL:
3226                 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3227                                                       struct schannel_state);
3228                 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3229                 make_dup = true;
3230                 break;
3231         case DCERPC_AUTH_TYPE_SPNEGO:
3232                 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
3233                                                    struct spnego_context);
3234                 sk = spnego_get_session_key(mem_ctx, spnego_ctx);
3235                 make_dup = false;
3236                 break;
3237         case DCERPC_AUTH_TYPE_NTLMSSP:
3238                 gensec_security = talloc_get_type_abort(a->auth_ctx,
3239                                                 struct gensec_security);
3240                 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3241                 if (!NT_STATUS_IS_OK(status)) {
3242                         return status;
3243                 }
3244                 make_dup = false;
3245                 break;
3246         case DCERPC_AUTH_TYPE_KRB5:
3247                 gse_ctx = talloc_get_type_abort(a->auth_ctx,
3248                                                 struct gse_context);
3249                 sk = gse_get_session_key(mem_ctx, gse_ctx);
3250                 make_dup = false;
3251                 break;
3252         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3253         case DCERPC_AUTH_TYPE_NONE:
3254                 sk = data_blob_const(a->user_session_key.data,
3255                                      a->user_session_key.length);
3256                 make_dup = true;
3257                 break;
3258         default:
3259                 break;
3260         }
3261
3262         if (!sk.data) {
3263                 return NT_STATUS_NO_USER_SESSION_KEY;
3264         }
3265
3266         if (make_dup) {
3267                 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3268         } else {
3269                 *session_key = sk;
3270         }
3271
3272         return NT_STATUS_OK;
3273 }