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