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