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