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