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