s3:rpc_client: use rpc_api_pipe_send() for auth3
[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/rpc/dcerpc_gssapi.h"
33 #include "librpc/rpc/dcerpc_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         DATA_BLOB in_token = data_blob_null;
989         NTSTATUS status;
990
991         /* Negotiate the initial auth token */
992         status = spnego_get_client_auth_token(mem_ctx,
993                                               auth->a_u.spnego_state,
994                                               &in_token, auth_token);
995         if (!NT_STATUS_IS_OK(status)) {
996                 return status;
997         }
998
999         DEBUG(5, ("Created GSS Authentication Token:\n"));
1000         dump_data(5, auth_token->data, auth_token->length);
1001
1002         return NT_STATUS_OK;
1003 }
1004
1005 /*******************************************************************
1006  Creates krb5 auth bind.
1007  ********************************************************************/
1008
1009 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
1010                                             struct pipe_auth_data *auth,
1011                                             DATA_BLOB *auth_token)
1012 {
1013         DATA_BLOB in_token = data_blob_null;
1014         NTSTATUS status;
1015
1016         /* Negotiate the initial auth token */
1017         status = gse_get_client_auth_token(mem_ctx,
1018                                            auth->a_u.gssapi_state,
1019                                            &in_token,
1020                                            auth_token);
1021         if (!NT_STATUS_IS_OK(status)) {
1022                 return status;
1023         }
1024
1025         DEBUG(5, ("Created GSS Authentication Token:\n"));
1026         dump_data(5, auth_token->data, auth_token->length);
1027
1028         return NT_STATUS_OK;
1029 }
1030
1031 /*******************************************************************
1032  Creates NTLMSSP auth bind.
1033  ********************************************************************/
1034
1035 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1036                                                  DATA_BLOB *auth_token)
1037 {
1038         NTSTATUS status;
1039         DATA_BLOB null_blob = data_blob_null;
1040
1041         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1042         status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1043                                         null_blob, auth_token);
1044
1045         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1046                 data_blob_free(auth_token);
1047                 return status;
1048         }
1049
1050         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1051         dump_data(5, auth_token->data, auth_token->length);
1052
1053         return NT_STATUS_OK;
1054 }
1055
1056 /*******************************************************************
1057  Creates schannel auth bind.
1058  ********************************************************************/
1059
1060 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1061                                                   DATA_BLOB *auth_token)
1062 {
1063         NTSTATUS status;
1064         struct NL_AUTH_MESSAGE r;
1065
1066         /* Use lp_workgroup() if domain not specified */
1067
1068         if (!cli->auth->domain || !cli->auth->domain[0]) {
1069                 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1070                 if (cli->auth->domain == NULL) {
1071                         return NT_STATUS_NO_MEMORY;
1072                 }
1073         }
1074
1075         /*
1076          * Now marshall the data into the auth parse_struct.
1077          */
1078
1079         r.MessageType                   = NL_NEGOTIATE_REQUEST;
1080         r.Flags                         = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1081                                           NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1082         r.oem_netbios_domain.a          = cli->auth->domain;
1083         r.oem_netbios_computer.a        = global_myname();
1084
1085         status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1086         if (!NT_STATUS_IS_OK(status)) {
1087                 return status;
1088         }
1089
1090         return NT_STATUS_OK;
1091 }
1092
1093 /*******************************************************************
1094  Creates the internals of a DCE/RPC bind request or alter context PDU.
1095  ********************************************************************/
1096
1097 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1098                                                 enum dcerpc_pkt_type ptype,
1099                                                 uint32 rpc_call_id,
1100                                                 const struct ndr_syntax_id *abstract,
1101                                                 const struct ndr_syntax_id *transfer,
1102                                                 const DATA_BLOB *auth_info,
1103                                                 DATA_BLOB *blob)
1104 {
1105         uint16 auth_len = auth_info->length;
1106         NTSTATUS status;
1107         union dcerpc_payload u;
1108         struct dcerpc_ctx_list ctx_list;
1109
1110         if (auth_len) {
1111                 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1112         }
1113
1114         ctx_list.context_id = 0;
1115         ctx_list.num_transfer_syntaxes = 1;
1116         ctx_list.abstract_syntax = *abstract;
1117         ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1118
1119         u.bind.max_xmit_frag    = RPC_MAX_PDU_FRAG_LEN;
1120         u.bind.max_recv_frag    = RPC_MAX_PDU_FRAG_LEN;
1121         u.bind.assoc_group_id   = 0x0;
1122         u.bind.num_contexts     = 1;
1123         u.bind.ctx_list         = &ctx_list;
1124         u.bind.auth_info        = *auth_info;
1125
1126         status = dcerpc_push_ncacn_packet(mem_ctx,
1127                                           ptype,
1128                                           DCERPC_PFC_FLAG_FIRST |
1129                                           DCERPC_PFC_FLAG_LAST,
1130                                           auth_len,
1131                                           rpc_call_id,
1132                                           &u,
1133                                           blob);
1134         if (!NT_STATUS_IS_OK(status)) {
1135                 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1136                 return status;
1137         }
1138
1139         return NT_STATUS_OK;
1140 }
1141
1142 /*******************************************************************
1143  Creates a DCE/RPC bind request.
1144  ********************************************************************/
1145
1146 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1147                                     struct rpc_pipe_client *cli,
1148                                     struct pipe_auth_data *auth,
1149                                     uint32 rpc_call_id,
1150                                     const struct ndr_syntax_id *abstract,
1151                                     const struct ndr_syntax_id *transfer,
1152                                     DATA_BLOB *rpc_out)
1153 {
1154         DATA_BLOB auth_token = data_blob_null;
1155         DATA_BLOB auth_info = data_blob_null;
1156         NTSTATUS ret = NT_STATUS_OK;
1157
1158         switch (auth->auth_type) {
1159         case DCERPC_AUTH_TYPE_SCHANNEL:
1160                 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1161                 if (!NT_STATUS_IS_OK(ret)) {
1162                         return ret;
1163                 }
1164                 break;
1165
1166         case DCERPC_AUTH_TYPE_NTLMSSP:
1167                 ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token);
1168                 if (!NT_STATUS_IS_OK(ret)) {
1169                         return ret;
1170                 }
1171                 break;
1172
1173         case DCERPC_AUTH_TYPE_SPNEGO:
1174                 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1175                 if (!NT_STATUS_IS_OK(ret)) {
1176                         return ret;
1177                 }
1178                 break;
1179
1180         case DCERPC_AUTH_TYPE_KRB5:
1181                 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
1182                 if (!NT_STATUS_IS_OK(ret)) {
1183                         return ret;
1184                 }
1185                 break;
1186
1187         case DCERPC_AUTH_TYPE_NONE:
1188                 break;
1189
1190         default:
1191                 /* "Can't" happen. */
1192                 return NT_STATUS_INVALID_INFO_CLASS;
1193         }
1194
1195         if (auth_token.length != 0) {
1196                 ret = dcerpc_push_dcerpc_auth(cli,
1197                                                 auth->auth_type,
1198                                                 auth->auth_level,
1199                                                 0, /* auth_pad_length */
1200                                                 1, /* auth_context_id */
1201                                                 &auth_token,
1202                                                 &auth_info);
1203                 if (!NT_STATUS_IS_OK(ret)) {
1204                         return ret;
1205                 }
1206                 data_blob_free(&auth_token);
1207         }
1208
1209         ret = create_bind_or_alt_ctx_internal(mem_ctx,
1210                                               DCERPC_PKT_BIND,
1211                                               rpc_call_id,
1212                                               abstract,
1213                                               transfer,
1214                                               &auth_info,
1215                                               rpc_out);
1216         return ret;
1217 }
1218
1219 /*******************************************************************
1220  External interface.
1221  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1222  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1223  and deals with signing/sealing details.
1224  ********************************************************************/
1225
1226 struct rpc_api_pipe_req_state {
1227         struct event_context *ev;
1228         struct rpc_pipe_client *cli;
1229         uint8_t op_num;
1230         uint32_t call_id;
1231         DATA_BLOB *req_data;
1232         uint32_t req_data_sent;
1233         DATA_BLOB rpc_out;
1234         DATA_BLOB reply_pdu;
1235 };
1236
1237 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1238 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1239 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1240                                   bool *is_last_frag);
1241
1242 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1243                                          struct event_context *ev,
1244                                          struct rpc_pipe_client *cli,
1245                                          uint8_t op_num,
1246                                          DATA_BLOB *req_data)
1247 {
1248         struct tevent_req *req, *subreq;
1249         struct rpc_api_pipe_req_state *state;
1250         NTSTATUS status;
1251         bool is_last_frag;
1252
1253         req = tevent_req_create(mem_ctx, &state,
1254                                 struct rpc_api_pipe_req_state);
1255         if (req == NULL) {
1256                 return NULL;
1257         }
1258         state->ev = ev;
1259         state->cli = cli;
1260         state->op_num = op_num;
1261         state->req_data = req_data;
1262         state->req_data_sent = 0;
1263         state->call_id = get_rpc_call_id();
1264         state->reply_pdu = data_blob_null;
1265         state->rpc_out = data_blob_null;
1266
1267         if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1268                                         + RPC_MAX_SIGN_SIZE) {
1269                 /* Server is screwed up ! */
1270                 status = NT_STATUS_INVALID_PARAMETER;
1271                 goto post_status;
1272         }
1273
1274         status = prepare_next_frag(state, &is_last_frag);
1275         if (!NT_STATUS_IS_OK(status)) {
1276                 goto post_status;
1277         }
1278
1279         if (is_last_frag) {
1280                 subreq = rpc_api_pipe_send(state, ev, state->cli,
1281                                            &state->rpc_out,
1282                                            DCERPC_PKT_RESPONSE);
1283                 if (subreq == NULL) {
1284                         goto fail;
1285                 }
1286                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1287         } else {
1288                 subreq = rpc_write_send(state, ev, cli->transport,
1289                                         state->rpc_out.data,
1290                                         state->rpc_out.length);
1291                 if (subreq == NULL) {
1292                         goto fail;
1293                 }
1294                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1295                                         req);
1296         }
1297         return req;
1298
1299  post_status:
1300         tevent_req_nterror(req, status);
1301         return tevent_req_post(req, ev);
1302  fail:
1303         TALLOC_FREE(req);
1304         return NULL;
1305 }
1306
1307 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1308                                   bool *is_last_frag)
1309 {
1310         size_t data_sent_thistime;
1311         size_t auth_len;
1312         size_t frag_len;
1313         uint8_t flags = 0;
1314         size_t pad_len;
1315         size_t data_left;
1316         NTSTATUS status;
1317         union dcerpc_payload u;
1318
1319         data_left = state->req_data->length - state->req_data_sent;
1320
1321         status = dcerpc_guess_sizes(state->cli->auth,
1322                                     DCERPC_REQUEST_LENGTH, data_left,
1323                                     state->cli->max_xmit_frag,
1324                                     CLIENT_NDR_PADDING_SIZE,
1325                                     &data_sent_thistime,
1326                                     &frag_len, &auth_len, &pad_len);
1327         if (!NT_STATUS_IS_OK(status)) {
1328                 return status;
1329         }
1330
1331         if (state->req_data_sent == 0) {
1332                 flags = DCERPC_PFC_FLAG_FIRST;
1333         }
1334
1335         if (data_sent_thistime == data_left) {
1336                 flags |= DCERPC_PFC_FLAG_LAST;
1337         }
1338
1339         data_blob_free(&state->rpc_out);
1340
1341         ZERO_STRUCT(u.request);
1342
1343         u.request.alloc_hint    = state->req_data->length;
1344         u.request.context_id    = 0;
1345         u.request.opnum         = state->op_num;
1346
1347         status = dcerpc_push_ncacn_packet(state,
1348                                           DCERPC_PKT_REQUEST,
1349                                           flags,
1350                                           auth_len,
1351                                           state->call_id,
1352                                           &u,
1353                                           &state->rpc_out);
1354         if (!NT_STATUS_IS_OK(status)) {
1355                 return status;
1356         }
1357
1358         /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1359          * compute it right for requests because the auth trailer is missing
1360          * at this stage */
1361         dcerpc_set_frag_length(&state->rpc_out, frag_len);
1362
1363         /* Copy in the data. */
1364         if (!data_blob_append(NULL, &state->rpc_out,
1365                                 state->req_data->data + state->req_data_sent,
1366                                 data_sent_thistime)) {
1367                 return NT_STATUS_NO_MEMORY;
1368         }
1369
1370         switch (state->cli->auth->auth_level) {
1371         case DCERPC_AUTH_LEVEL_NONE:
1372         case DCERPC_AUTH_LEVEL_CONNECT:
1373         case DCERPC_AUTH_LEVEL_PACKET:
1374                 break;
1375         case DCERPC_AUTH_LEVEL_INTEGRITY:
1376         case DCERPC_AUTH_LEVEL_PRIVACY:
1377                 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1378                                                 &state->rpc_out);
1379                 if (!NT_STATUS_IS_OK(status)) {
1380                         return status;
1381                 }
1382                 break;
1383         default:
1384                 return NT_STATUS_INVALID_PARAMETER;
1385         }
1386
1387         state->req_data_sent += data_sent_thistime;
1388         *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1389
1390         return status;
1391 }
1392
1393 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1394 {
1395         struct tevent_req *req = tevent_req_callback_data(
1396                 subreq, struct tevent_req);
1397         struct rpc_api_pipe_req_state *state = tevent_req_data(
1398                 req, struct rpc_api_pipe_req_state);
1399         NTSTATUS status;
1400         bool is_last_frag;
1401
1402         status = rpc_write_recv(subreq);
1403         TALLOC_FREE(subreq);
1404         if (!NT_STATUS_IS_OK(status)) {
1405                 tevent_req_nterror(req, status);
1406                 return;
1407         }
1408
1409         status = prepare_next_frag(state, &is_last_frag);
1410         if (!NT_STATUS_IS_OK(status)) {
1411                 tevent_req_nterror(req, status);
1412                 return;
1413         }
1414
1415         if (is_last_frag) {
1416                 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1417                                            &state->rpc_out,
1418                                            DCERPC_PKT_RESPONSE);
1419                 if (tevent_req_nomem(subreq, req)) {
1420                         return;
1421                 }
1422                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1423         } else {
1424                 subreq = rpc_write_send(state, state->ev,
1425                                         state->cli->transport,
1426                                         state->rpc_out.data,
1427                                         state->rpc_out.length);
1428                 if (tevent_req_nomem(subreq, req)) {
1429                         return;
1430                 }
1431                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1432                                         req);
1433         }
1434 }
1435
1436 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1437 {
1438         struct tevent_req *req = tevent_req_callback_data(
1439                 subreq, struct tevent_req);
1440         struct rpc_api_pipe_req_state *state = tevent_req_data(
1441                 req, struct rpc_api_pipe_req_state);
1442         NTSTATUS status;
1443
1444         status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1445         TALLOC_FREE(subreq);
1446         if (!NT_STATUS_IS_OK(status)) {
1447                 tevent_req_nterror(req, status);
1448                 return;
1449         }
1450         tevent_req_done(req);
1451 }
1452
1453 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1454                                DATA_BLOB *reply_pdu)
1455 {
1456         struct rpc_api_pipe_req_state *state = tevent_req_data(
1457                 req, struct rpc_api_pipe_req_state);
1458         NTSTATUS status;
1459
1460         if (tevent_req_is_nterror(req, &status)) {
1461                 /*
1462                  * We always have to initialize to reply pdu, even if there is
1463                  * none. The rpccli_* caller routines expect this.
1464                  */
1465                 *reply_pdu = data_blob_null;
1466                 return status;
1467         }
1468
1469         /* return data to caller and assign it ownership of memory */
1470         reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1471         reply_pdu->length = state->reply_pdu.length;
1472         state->reply_pdu.length = 0;
1473
1474         return NT_STATUS_OK;
1475 }
1476
1477 #if 0
1478 /****************************************************************************
1479  Set the handle state.
1480 ****************************************************************************/
1481
1482 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1483                                    const char *pipe_name, uint16 device_state)
1484 {
1485         bool state_set = False;
1486         char param[2];
1487         uint16 setup[2]; /* only need 2 uint16 setup parameters */
1488         char *rparam = NULL;
1489         char *rdata = NULL;
1490         uint32 rparam_len, rdata_len;
1491
1492         if (pipe_name == NULL)
1493                 return False;
1494
1495         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1496                  cli->fnum, pipe_name, device_state));
1497
1498         /* create parameters: device state */
1499         SSVAL(param, 0, device_state);
1500
1501         /* create setup parameters. */
1502         setup[0] = 0x0001; 
1503         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
1504
1505         /* send the data on \PIPE\ */
1506         if (cli_api_pipe(cli->cli, "\\PIPE\\",
1507                     setup, 2, 0,                /* setup, length, max */
1508                     param, 2, 0,                /* param, length, max */
1509                     NULL, 0, 1024,              /* data, length, max */
1510                     &rparam, &rparam_len,        /* return param, length */
1511                     &rdata, &rdata_len))         /* return data, length */
1512         {
1513                 DEBUG(5, ("Set Handle state: return OK\n"));
1514                 state_set = True;
1515         }
1516
1517         SAFE_FREE(rparam);
1518         SAFE_FREE(rdata);
1519
1520         return state_set;
1521 }
1522 #endif
1523
1524 /****************************************************************************
1525  Check the rpc bind acknowledge response.
1526 ****************************************************************************/
1527
1528 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1529                                 const struct ndr_syntax_id *transfer)
1530 {
1531         struct dcerpc_ack_ctx ctx;
1532
1533         if (r->secondary_address_size == 0) {
1534                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1535         }
1536
1537         if (r->num_results < 1 || !r->ctx_list) {
1538                 return false;
1539         }
1540
1541         ctx = r->ctx_list[0];
1542
1543         /* check the transfer syntax */
1544         if ((ctx.syntax.if_version != transfer->if_version) ||
1545              (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1546                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1547                 return False;
1548         }
1549
1550         if (r->num_results != 0x1 || ctx.result != 0) {
1551                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1552                           r->num_results, ctx.reason));
1553         }
1554
1555         DEBUG(5,("check_bind_response: accepted!\n"));
1556         return True;
1557 }
1558
1559 /*******************************************************************
1560  Creates a DCE/RPC bind authentication response.
1561  This is the packet that is sent back to the server once we
1562  have received a BIND-ACK, to finish the third leg of
1563  the authentication handshake.
1564  ********************************************************************/
1565
1566 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1567                                 struct rpc_pipe_client *cli,
1568                                 uint32 rpc_call_id,
1569                                 enum dcerpc_AuthType auth_type,
1570                                 enum dcerpc_AuthLevel auth_level,
1571                                 DATA_BLOB *pauth_blob,
1572                                 DATA_BLOB *rpc_out)
1573 {
1574         NTSTATUS status;
1575         union dcerpc_payload u;
1576
1577         u.auth3._pad = 0;
1578
1579         status = dcerpc_push_dcerpc_auth(mem_ctx,
1580                                          auth_type,
1581                                          auth_level,
1582                                          0, /* auth_pad_length */
1583                                          1, /* auth_context_id */
1584                                          pauth_blob,
1585                                          &u.auth3.auth_info);
1586         if (!NT_STATUS_IS_OK(status)) {
1587                 return status;
1588         }
1589
1590         status = dcerpc_push_ncacn_packet(mem_ctx,
1591                                           DCERPC_PKT_AUTH3,
1592                                           DCERPC_PFC_FLAG_FIRST |
1593                                           DCERPC_PFC_FLAG_LAST,
1594                                           pauth_blob->length,
1595                                           rpc_call_id,
1596                                           &u,
1597                                           rpc_out);
1598         data_blob_free(&u.auth3.auth_info);
1599         if (!NT_STATUS_IS_OK(status)) {
1600                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1601                 return status;
1602         }
1603
1604         return NT_STATUS_OK;
1605 }
1606
1607 /*******************************************************************
1608  Creates a DCE/RPC bind alter context authentication request which
1609  may contain a spnego auth blobl
1610  ********************************************************************/
1611
1612 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1613                                         enum dcerpc_AuthType auth_type,
1614                                         enum dcerpc_AuthLevel auth_level,
1615                                         uint32 rpc_call_id,
1616                                         const struct ndr_syntax_id *abstract,
1617                                         const struct ndr_syntax_id *transfer,
1618                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1619                                         DATA_BLOB *rpc_out)
1620 {
1621         DATA_BLOB auth_info;
1622         NTSTATUS status;
1623
1624         status = dcerpc_push_dcerpc_auth(mem_ctx,
1625                                          auth_type,
1626                                          auth_level,
1627                                          0, /* auth_pad_length */
1628                                          1, /* auth_context_id */
1629                                          pauth_blob,
1630                                          &auth_info);
1631         if (!NT_STATUS_IS_OK(status)) {
1632                 return status;
1633         }
1634
1635         status = create_bind_or_alt_ctx_internal(mem_ctx,
1636                                                  DCERPC_PKT_ALTER,
1637                                                  rpc_call_id,
1638                                                  abstract,
1639                                                  transfer,
1640                                                  &auth_info,
1641                                                  rpc_out);
1642         data_blob_free(&auth_info);
1643         return status;
1644 }
1645
1646 /****************************************************************************
1647  Do an rpc bind.
1648 ****************************************************************************/
1649
1650 struct rpc_pipe_bind_state {
1651         struct event_context *ev;
1652         struct rpc_pipe_client *cli;
1653         DATA_BLOB rpc_out;
1654         bool auth3;
1655         uint32_t rpc_call_id;
1656 };
1657
1658 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1659 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1660                                    struct rpc_pipe_bind_state *state,
1661                                    DATA_BLOB *credentials);
1662 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1663                                      struct rpc_pipe_bind_state *state,
1664                                      DATA_BLOB *credentials);
1665
1666 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1667                                       struct event_context *ev,
1668                                       struct rpc_pipe_client *cli,
1669                                       struct pipe_auth_data *auth)
1670 {
1671         struct tevent_req *req, *subreq;
1672         struct rpc_pipe_bind_state *state;
1673         NTSTATUS status;
1674
1675         req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1676         if (req == NULL) {
1677                 return NULL;
1678         }
1679
1680         DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1681                 rpccli_pipe_txt(talloc_tos(), cli),
1682                 (unsigned int)auth->auth_type,
1683                 (unsigned int)auth->spnego_type,
1684                 (unsigned int)auth->auth_level ));
1685
1686         state->ev = ev;
1687         state->cli = cli;
1688         state->rpc_call_id = get_rpc_call_id();
1689
1690         cli->auth = talloc_move(cli, &auth);
1691
1692         /* Marshall the outgoing data. */
1693         status = create_rpc_bind_req(state, cli,
1694                                      cli->auth,
1695                                      state->rpc_call_id,
1696                                      &cli->abstract_syntax,
1697                                      &cli->transfer_syntax,
1698                                      &state->rpc_out);
1699
1700         if (!NT_STATUS_IS_OK(status)) {
1701                 goto post_status;
1702         }
1703
1704         subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1705                                    DCERPC_PKT_BIND_ACK);
1706         if (subreq == NULL) {
1707                 goto fail;
1708         }
1709         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1710         return req;
1711
1712  post_status:
1713         tevent_req_nterror(req, status);
1714         return tevent_req_post(req, ev);
1715  fail:
1716         TALLOC_FREE(req);
1717         return NULL;
1718 }
1719
1720 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1721 {
1722         struct tevent_req *req = tevent_req_callback_data(
1723                 subreq, struct tevent_req);
1724         struct rpc_pipe_bind_state *state = tevent_req_data(
1725                 req, struct rpc_pipe_bind_state);
1726         struct pipe_auth_data *pauth = state->cli->auth;
1727         struct ncacn_packet *pkt;
1728         struct dcerpc_auth auth;
1729         DATA_BLOB auth_token = data_blob_null;
1730         NTSTATUS status;
1731
1732         status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1733         TALLOC_FREE(subreq);
1734         if (!NT_STATUS_IS_OK(status)) {
1735                 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1736                           rpccli_pipe_txt(talloc_tos(), state->cli),
1737                           nt_errstr(status)));
1738                 tevent_req_nterror(req, status);
1739                 return;
1740         }
1741
1742         if (state->auth3) {
1743                 tevent_req_done(req);
1744                 return;
1745         }
1746
1747         if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1748                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1749                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1750                 return;
1751         }
1752
1753         state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1754         state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1755
1756         switch(pauth->auth_type) {
1757
1758         case DCERPC_AUTH_TYPE_NONE:
1759         case DCERPC_AUTH_TYPE_SCHANNEL:
1760                 /* Bind complete. */
1761                 tevent_req_done(req);
1762                 return;
1763
1764         case DCERPC_AUTH_TYPE_NTLMSSP:
1765         case DCERPC_AUTH_TYPE_SPNEGO:
1766         case DCERPC_AUTH_TYPE_KRB5:
1767                 /* Paranoid lenght checks */
1768                 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1769                                                 + pkt->auth_length) {
1770                         tevent_req_nterror(req,
1771                                         NT_STATUS_INFO_LENGTH_MISMATCH);
1772                         return;
1773                 }
1774                 /* get auth credentials */
1775                 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1776                                                  &pkt->u.bind_ack.auth_info,
1777                                                  &auth, false);
1778                 if (!NT_STATUS_IS_OK(status)) {
1779                         DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1780                                   nt_errstr(status)));
1781                         tevent_req_nterror(req, status);
1782                         return;
1783                 }
1784                 break;
1785
1786         default:
1787                 goto err_out;
1788         }
1789
1790         /*
1791          * For authenticated binds we may need to do 3 or 4 leg binds.
1792          */
1793
1794         switch(pauth->auth_type) {
1795
1796         case DCERPC_AUTH_TYPE_NONE:
1797         case DCERPC_AUTH_TYPE_SCHANNEL:
1798                 /* Bind complete. */
1799                 tevent_req_done(req);
1800                 return;
1801
1802         case DCERPC_AUTH_TYPE_NTLMSSP:
1803                 status = auth_ntlmssp_update(pauth->a_u.auth_ntlmssp_state,
1804                                              auth.credentials, &auth_token);
1805                 if (NT_STATUS_EQUAL(status,
1806                                     NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1807                         status = rpc_bind_next_send(req, state,
1808                                                         &auth_token);
1809                 } else if (NT_STATUS_IS_OK(status)) {
1810                         status = rpc_bind_finish_send(req, state,
1811                                                         &auth_token);
1812                 }
1813                 break;
1814
1815         case DCERPC_AUTH_TYPE_SPNEGO:
1816                 status = spnego_get_client_auth_token(state,
1817                                                 pauth->a_u.spnego_state,
1818                                                 &auth.credentials,
1819                                                 &auth_token);
1820                 if (!NT_STATUS_IS_OK(status)) {
1821                         break;
1822                 }
1823                 if (auth_token.length == 0) {
1824                         /* Bind complete. */
1825                         tevent_req_done(req);
1826                         return;
1827                 }
1828                 if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
1829                         status = rpc_bind_next_send(req, state,
1830                                                         &auth_token);
1831                 } else {
1832                         status = rpc_bind_finish_send(req, state,
1833                                                         &auth_token);
1834                 }
1835                 break;
1836
1837         case DCERPC_AUTH_TYPE_KRB5:
1838                 status = gse_get_client_auth_token(state,
1839                                                    pauth->a_u.gssapi_state,
1840                                                    &auth.credentials,
1841                                                    &auth_token);
1842                 if (!NT_STATUS_IS_OK(status)) {
1843                         break;
1844                 }
1845
1846                 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
1847                         status = rpc_bind_next_send(req, state, &auth_token);
1848                 } else {
1849                         status = rpc_bind_finish_send(req, state, &auth_token);
1850                 }
1851                 break;
1852
1853         default:
1854                 goto err_out;
1855         }
1856
1857         if (!NT_STATUS_IS_OK(status)) {
1858                 tevent_req_nterror(req, status);
1859         }
1860         return;
1861
1862 err_out:
1863         DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
1864                  (unsigned int)state->cli->auth->auth_type,
1865                  (unsigned int)state->cli->auth->spnego_type));
1866         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1867 }
1868
1869 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1870                                    struct rpc_pipe_bind_state *state,
1871                                    DATA_BLOB *auth_token)
1872 {
1873         struct pipe_auth_data *auth = state->cli->auth;
1874         struct tevent_req *subreq;
1875         NTSTATUS status;
1876
1877         /* Now prepare the alter context pdu. */
1878         data_blob_free(&state->rpc_out);
1879
1880         status = create_rpc_alter_context(state,
1881                                           auth->auth_type,
1882                                           auth->auth_level,
1883                                           state->rpc_call_id,
1884                                           &state->cli->abstract_syntax,
1885                                           &state->cli->transfer_syntax,
1886                                           auth_token,
1887                                           &state->rpc_out);
1888         if (!NT_STATUS_IS_OK(status)) {
1889                 return status;
1890         }
1891
1892         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1893                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1894         if (subreq == NULL) {
1895                 return NT_STATUS_NO_MEMORY;
1896         }
1897         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1898         return NT_STATUS_OK;
1899 }
1900
1901 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1902                                      struct rpc_pipe_bind_state *state,
1903                                      DATA_BLOB *auth_token)
1904 {
1905         struct pipe_auth_data *auth = state->cli->auth;
1906         struct tevent_req *subreq;
1907         NTSTATUS status;
1908
1909         state->auth3 = true;
1910
1911         /* Now prepare the auth3 context pdu. */
1912         data_blob_free(&state->rpc_out);
1913
1914         status = create_rpc_bind_auth3(state, state->cli,
1915                                         state->rpc_call_id,
1916                                         auth->auth_type,
1917                                         auth->auth_level,
1918                                         auth_token,
1919                                         &state->rpc_out);
1920         if (!NT_STATUS_IS_OK(status)) {
1921                 return status;
1922         }
1923
1924         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1925                                    &state->rpc_out, DCERPC_PKT_AUTH3);
1926         if (subreq == NULL) {
1927                 return NT_STATUS_NO_MEMORY;
1928         }
1929         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1930         return NT_STATUS_OK;
1931 }
1932
1933 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1934 {
1935         return tevent_req_simple_recv_ntstatus(req);
1936 }
1937
1938 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1939                        struct pipe_auth_data *auth)
1940 {
1941         TALLOC_CTX *frame = talloc_stackframe();
1942         struct event_context *ev;
1943         struct tevent_req *req;
1944         NTSTATUS status = NT_STATUS_OK;
1945
1946         ev = event_context_init(frame);
1947         if (ev == NULL) {
1948                 status = NT_STATUS_NO_MEMORY;
1949                 goto fail;
1950         }
1951
1952         req = rpc_pipe_bind_send(frame, ev, cli, auth);
1953         if (req == NULL) {
1954                 status = NT_STATUS_NO_MEMORY;
1955                 goto fail;
1956         }
1957
1958         if (!tevent_req_poll(req, ev)) {
1959                 status = map_nt_error_from_unix(errno);
1960                 goto fail;
1961         }
1962
1963         status = rpc_pipe_bind_recv(req);
1964  fail:
1965         TALLOC_FREE(frame);
1966         return status;
1967 }
1968
1969 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1970
1971 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1972                                 unsigned int timeout)
1973 {
1974         unsigned int old;
1975
1976         if (rpc_cli->transport == NULL) {
1977                 return RPCCLI_DEFAULT_TIMEOUT;
1978         }
1979
1980         if (rpc_cli->transport->set_timeout == NULL) {
1981                 return RPCCLI_DEFAULT_TIMEOUT;
1982         }
1983
1984         old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1985         if (old == 0) {
1986                 return RPCCLI_DEFAULT_TIMEOUT;
1987         }
1988
1989         return old;
1990 }
1991
1992 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1993 {
1994         if (rpc_cli == NULL) {
1995                 return false;
1996         }
1997
1998         if (rpc_cli->transport == NULL) {
1999                 return false;
2000         }
2001
2002         return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2003 }
2004
2005 struct rpccli_bh_state {
2006         struct rpc_pipe_client *rpc_cli;
2007 };
2008
2009 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2010 {
2011         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2012                                      struct rpccli_bh_state);
2013
2014         return rpccli_is_connected(hs->rpc_cli);
2015 }
2016
2017 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2018                                       uint32_t timeout)
2019 {
2020         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2021                                      struct rpccli_bh_state);
2022
2023         return rpccli_set_timeout(hs->rpc_cli, timeout);
2024 }
2025
2026 struct rpccli_bh_raw_call_state {
2027         DATA_BLOB in_data;
2028         DATA_BLOB out_data;
2029         uint32_t out_flags;
2030 };
2031
2032 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2033
2034 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2035                                                   struct tevent_context *ev,
2036                                                   struct dcerpc_binding_handle *h,
2037                                                   const struct GUID *object,
2038                                                   uint32_t opnum,
2039                                                   uint32_t in_flags,
2040                                                   const uint8_t *in_data,
2041                                                   size_t in_length)
2042 {
2043         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2044                                      struct rpccli_bh_state);
2045         struct tevent_req *req;
2046         struct rpccli_bh_raw_call_state *state;
2047         bool ok;
2048         struct tevent_req *subreq;
2049
2050         req = tevent_req_create(mem_ctx, &state,
2051                                 struct rpccli_bh_raw_call_state);
2052         if (req == NULL) {
2053                 return NULL;
2054         }
2055         state->in_data.data = discard_const_p(uint8_t, in_data);
2056         state->in_data.length = in_length;
2057
2058         ok = rpccli_bh_is_connected(h);
2059         if (!ok) {
2060                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2061                 return tevent_req_post(req, ev);
2062         }
2063
2064         subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2065                                        opnum, &state->in_data);
2066         if (tevent_req_nomem(subreq, req)) {
2067                 return tevent_req_post(req, ev);
2068         }
2069         tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2070
2071         return req;
2072 }
2073
2074 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2075 {
2076         struct tevent_req *req =
2077                 tevent_req_callback_data(subreq,
2078                 struct tevent_req);
2079         struct rpccli_bh_raw_call_state *state =
2080                 tevent_req_data(req,
2081                 struct rpccli_bh_raw_call_state);
2082         NTSTATUS status;
2083
2084         state->out_flags = 0;
2085
2086         /* TODO: support bigendian responses */
2087
2088         status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2089         TALLOC_FREE(subreq);
2090         if (!NT_STATUS_IS_OK(status)) {
2091                 tevent_req_nterror(req, status);
2092                 return;
2093         }
2094
2095         tevent_req_done(req);
2096 }
2097
2098 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2099                                         TALLOC_CTX *mem_ctx,
2100                                         uint8_t **out_data,
2101                                         size_t *out_length,
2102                                         uint32_t *out_flags)
2103 {
2104         struct rpccli_bh_raw_call_state *state =
2105                 tevent_req_data(req,
2106                 struct rpccli_bh_raw_call_state);
2107         NTSTATUS status;
2108
2109         if (tevent_req_is_nterror(req, &status)) {
2110                 tevent_req_received(req);
2111                 return status;
2112         }
2113
2114         *out_data = talloc_move(mem_ctx, &state->out_data.data);
2115         *out_length = state->out_data.length;
2116         *out_flags = state->out_flags;
2117         tevent_req_received(req);
2118         return NT_STATUS_OK;
2119 }
2120
2121 struct rpccli_bh_disconnect_state {
2122         uint8_t _dummy;
2123 };
2124
2125 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2126                                                 struct tevent_context *ev,
2127                                                 struct dcerpc_binding_handle *h)
2128 {
2129         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2130                                      struct rpccli_bh_state);
2131         struct tevent_req *req;
2132         struct rpccli_bh_disconnect_state *state;
2133         bool ok;
2134
2135         req = tevent_req_create(mem_ctx, &state,
2136                                 struct rpccli_bh_disconnect_state);
2137         if (req == NULL) {
2138                 return NULL;
2139         }
2140
2141         ok = rpccli_bh_is_connected(h);
2142         if (!ok) {
2143                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2144                 return tevent_req_post(req, ev);
2145         }
2146
2147         /*
2148          * TODO: do a real async disconnect ...
2149          *
2150          * For now the caller needs to free rpc_cli
2151          */
2152         hs->rpc_cli = NULL;
2153
2154         tevent_req_done(req);
2155         return tevent_req_post(req, ev);
2156 }
2157
2158 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2159 {
2160         NTSTATUS status;
2161
2162         if (tevent_req_is_nterror(req, &status)) {
2163                 tevent_req_received(req);
2164                 return status;
2165         }
2166
2167         tevent_req_received(req);
2168         return NT_STATUS_OK;
2169 }
2170
2171 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2172 {
2173         return true;
2174 }
2175
2176 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2177                                    int ndr_flags,
2178                                    const void *_struct_ptr,
2179                                    const struct ndr_interface_call *call)
2180 {
2181         void *struct_ptr = discard_const(_struct_ptr);
2182
2183         if (DEBUGLEVEL < 10) {
2184                 return;
2185         }
2186
2187         if (ndr_flags & NDR_IN) {
2188                 ndr_print_function_debug(call->ndr_print,
2189                                          call->name,
2190                                          ndr_flags,
2191                                          struct_ptr);
2192         }
2193         if (ndr_flags & NDR_OUT) {
2194                 ndr_print_function_debug(call->ndr_print,
2195                                          call->name,
2196                                          ndr_flags,
2197                                          struct_ptr);
2198         }
2199 }
2200
2201 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2202         .name                   = "rpccli",
2203         .is_connected           = rpccli_bh_is_connected,
2204         .set_timeout            = rpccli_bh_set_timeout,
2205         .raw_call_send          = rpccli_bh_raw_call_send,
2206         .raw_call_recv          = rpccli_bh_raw_call_recv,
2207         .disconnect_send        = rpccli_bh_disconnect_send,
2208         .disconnect_recv        = rpccli_bh_disconnect_recv,
2209
2210         .ref_alloc              = rpccli_bh_ref_alloc,
2211         .do_ndr_print           = rpccli_bh_do_ndr_print,
2212 };
2213
2214 /* initialise a rpc_pipe_client binding handle */
2215 static struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2216 {
2217         struct dcerpc_binding_handle *h;
2218         struct rpccli_bh_state *hs;
2219
2220         h = dcerpc_binding_handle_create(c,
2221                                          &rpccli_bh_ops,
2222                                          NULL,
2223                                          NULL, /* TODO */
2224                                          &hs,
2225                                          struct rpccli_bh_state,
2226                                          __location__);
2227         if (h == NULL) {
2228                 return NULL;
2229         }
2230         hs->rpc_cli = c;
2231
2232         return h;
2233 }
2234
2235 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2236 {
2237         struct auth_ntlmssp_state *a = NULL;
2238         struct cli_state *cli;
2239
2240         if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2241                 a = rpc_cli->auth->a_u.auth_ntlmssp_state;
2242         } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2243                 enum dcerpc_AuthType auth_type;
2244                 void *auth_ctx;
2245                 NTSTATUS status;
2246
2247                 status = spnego_get_negotiated_mech(
2248                                         rpc_cli->auth->a_u.spnego_state,
2249                                         &auth_type, &auth_ctx);
2250                 if (!NT_STATUS_IS_OK(status)) {
2251                         return false;
2252                 }
2253
2254                 if (auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2255                         a = talloc_get_type(auth_ctx,
2256                                             struct auth_ntlmssp_state);
2257                 }
2258         }
2259
2260         if (a) {
2261                 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2262                 return true;
2263         }
2264
2265         cli = rpc_pipe_np_smb_conn(rpc_cli);
2266         if (cli == NULL) {
2267                 return false;
2268         }
2269         E_md4hash(cli->password ? cli->password : "", nt_hash);
2270         return true;
2271 }
2272
2273 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2274                                struct pipe_auth_data **presult)
2275 {
2276         struct pipe_auth_data *result;
2277
2278         result = talloc(mem_ctx, struct pipe_auth_data);
2279         if (result == NULL) {
2280                 return NT_STATUS_NO_MEMORY;
2281         }
2282
2283         result->auth_type = DCERPC_AUTH_TYPE_NONE;
2284         result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2285         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2286
2287         result->user_name = talloc_strdup(result, "");
2288         result->domain = talloc_strdup(result, "");
2289         if ((result->user_name == NULL) || (result->domain == NULL)) {
2290                 TALLOC_FREE(result);
2291                 return NT_STATUS_NO_MEMORY;
2292         }
2293
2294         *presult = result;
2295         return NT_STATUS_OK;
2296 }
2297
2298 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2299 {
2300         TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2301         return 0;
2302 }
2303
2304 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2305                                   enum dcerpc_AuthType auth_type,
2306                                   enum dcerpc_AuthLevel auth_level,
2307                                   const char *domain,
2308                                   const char *username,
2309                                   const char *password,
2310                                   struct pipe_auth_data **presult)
2311 {
2312         struct pipe_auth_data *result;
2313         NTSTATUS status;
2314
2315         result = talloc(mem_ctx, struct pipe_auth_data);
2316         if (result == NULL) {
2317                 return NT_STATUS_NO_MEMORY;
2318         }
2319
2320         result->auth_type = auth_type;
2321         result->auth_level = auth_level;
2322
2323         result->user_name = talloc_strdup(result, username);
2324         result->domain = talloc_strdup(result, domain);
2325         if ((result->user_name == NULL) || (result->domain == NULL)) {
2326                 status = NT_STATUS_NO_MEMORY;
2327                 goto fail;
2328         }
2329
2330         status = auth_ntlmssp_client_start(NULL,
2331                                       global_myname(),
2332                                       lp_workgroup(),
2333                                       lp_client_ntlmv2_auth(),
2334                                       &result->a_u.auth_ntlmssp_state);
2335         if (!NT_STATUS_IS_OK(status)) {
2336                 goto fail;
2337         }
2338
2339         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2340
2341         status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2342                                            username);
2343         if (!NT_STATUS_IS_OK(status)) {
2344                 goto fail;
2345         }
2346
2347         status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2348                                          domain);
2349         if (!NT_STATUS_IS_OK(status)) {
2350                 goto fail;
2351         }
2352
2353         status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2354                                            password);
2355         if (!NT_STATUS_IS_OK(status)) {
2356                 goto fail;
2357         }
2358
2359         /*
2360          * Turn off sign+seal to allow selected auth level to turn it back on.
2361          */
2362         auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2363                                                 ~(NTLMSSP_NEGOTIATE_SIGN |
2364                                                   NTLMSSP_NEGOTIATE_SEAL));
2365
2366         if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2367                 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2368                                                 NTLMSSP_NEGOTIATE_SIGN);
2369         } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2370                 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2371                                                 NTLMSSP_NEGOTIATE_SEAL |
2372                                                 NTLMSSP_NEGOTIATE_SIGN);
2373         }
2374
2375         *presult = result;
2376         return NT_STATUS_OK;
2377
2378  fail:
2379         TALLOC_FREE(result);
2380         return status;
2381 }
2382
2383 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2384                                    enum dcerpc_AuthLevel auth_level,
2385                                    struct netlogon_creds_CredentialState *creds,
2386                                    struct pipe_auth_data **presult)
2387 {
2388         struct pipe_auth_data *result;
2389
2390         result = talloc(mem_ctx, struct pipe_auth_data);
2391         if (result == NULL) {
2392                 return NT_STATUS_NO_MEMORY;
2393         }
2394
2395         result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2396         result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2397         result->auth_level = auth_level;
2398
2399         result->user_name = talloc_strdup(result, "");
2400         result->domain = talloc_strdup(result, domain);
2401         if ((result->user_name == NULL) || (result->domain == NULL)) {
2402                 goto fail;
2403         }
2404
2405         result->a_u.schannel_auth = talloc(result, struct schannel_state);
2406         if (result->a_u.schannel_auth == NULL) {
2407                 goto fail;
2408         }
2409
2410         result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2411         result->a_u.schannel_auth->seq_num = 0;
2412         result->a_u.schannel_auth->initiator = true;
2413         result->a_u.schannel_auth->creds = netlogon_creds_copy(result, creds);
2414
2415         *presult = result;
2416         return NT_STATUS_OK;
2417
2418  fail:
2419         TALLOC_FREE(result);
2420         return NT_STATUS_NO_MEMORY;
2421 }
2422
2423 /**
2424  * Create an rpc pipe client struct, connecting to a tcp port.
2425  */
2426 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2427                                        uint16_t port,
2428                                        const struct ndr_syntax_id *abstract_syntax,
2429                                        struct rpc_pipe_client **presult)
2430 {
2431         struct rpc_pipe_client *result;
2432         struct sockaddr_storage addr;
2433         NTSTATUS status;
2434         int fd;
2435
2436         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2437         if (result == NULL) {
2438                 return NT_STATUS_NO_MEMORY;
2439         }
2440
2441         result->abstract_syntax = *abstract_syntax;
2442         result->transfer_syntax = ndr_transfer_syntax;
2443
2444         result->desthost = talloc_strdup(result, host);
2445         result->srv_name_slash = talloc_asprintf_strupper_m(
2446                 result, "\\\\%s", result->desthost);
2447         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2448                 status = NT_STATUS_NO_MEMORY;
2449                 goto fail;
2450         }
2451
2452         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2453         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2454
2455         if (!resolve_name(host, &addr, 0, false)) {
2456                 status = NT_STATUS_NOT_FOUND;
2457                 goto fail;
2458         }
2459
2460         status = open_socket_out(&addr, port, 60, &fd);
2461         if (!NT_STATUS_IS_OK(status)) {
2462                 goto fail;
2463         }
2464         set_socket_options(fd, lp_socket_options());
2465
2466         status = rpc_transport_sock_init(result, fd, &result->transport);
2467         if (!NT_STATUS_IS_OK(status)) {
2468                 close(fd);
2469                 goto fail;
2470         }
2471
2472         result->transport->transport = NCACN_IP_TCP;
2473
2474         result->binding_handle = rpccli_bh_create(result);
2475         if (result->binding_handle == NULL) {
2476                 TALLOC_FREE(result);
2477                 return NT_STATUS_NO_MEMORY;
2478         }
2479
2480         *presult = result;
2481         return NT_STATUS_OK;
2482
2483  fail:
2484         TALLOC_FREE(result);
2485         return status;
2486 }
2487
2488 /**
2489  * Determine the tcp port on which a dcerpc interface is listening
2490  * for the ncacn_ip_tcp transport via the endpoint mapper of the
2491  * target host.
2492  */
2493 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2494                                       const struct ndr_syntax_id *abstract_syntax,
2495                                       uint16_t *pport)
2496 {
2497         NTSTATUS status;
2498         struct rpc_pipe_client *epm_pipe = NULL;
2499         struct pipe_auth_data *auth = NULL;
2500         struct dcerpc_binding *map_binding = NULL;
2501         struct dcerpc_binding *res_binding = NULL;
2502         struct epm_twr_t *map_tower = NULL;
2503         struct epm_twr_t *res_towers = NULL;
2504         struct policy_handle *entry_handle = NULL;
2505         uint32_t num_towers = 0;
2506         uint32_t max_towers = 1;
2507         struct epm_twr_p_t towers;
2508         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2509
2510         if (pport == NULL) {
2511                 status = NT_STATUS_INVALID_PARAMETER;
2512                 goto done;
2513         }
2514
2515         /* open the connection to the endpoint mapper */
2516         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2517                                         &ndr_table_epmapper.syntax_id,
2518                                         &epm_pipe);
2519
2520         if (!NT_STATUS_IS_OK(status)) {
2521                 goto done;
2522         }
2523
2524         status = rpccli_anon_bind_data(tmp_ctx, &auth);
2525         if (!NT_STATUS_IS_OK(status)) {
2526                 goto done;
2527         }
2528
2529         status = rpc_pipe_bind(epm_pipe, auth);
2530         if (!NT_STATUS_IS_OK(status)) {
2531                 goto done;
2532         }
2533
2534         /* create tower for asking the epmapper */
2535
2536         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2537         if (map_binding == NULL) {
2538                 status = NT_STATUS_NO_MEMORY;
2539                 goto done;
2540         }
2541
2542         map_binding->transport = NCACN_IP_TCP;
2543         map_binding->object = *abstract_syntax;
2544         map_binding->host = host; /* needed? */
2545         map_binding->endpoint = "0"; /* correct? needed? */
2546
2547         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2548         if (map_tower == NULL) {
2549                 status = NT_STATUS_NO_MEMORY;
2550                 goto done;
2551         }
2552
2553         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2554                                             &(map_tower->tower));
2555         if (!NT_STATUS_IS_OK(status)) {
2556                 goto done;
2557         }
2558
2559         /* allocate further parameters for the epm_Map call */
2560
2561         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2562         if (res_towers == NULL) {
2563                 status = NT_STATUS_NO_MEMORY;
2564                 goto done;
2565         }
2566         towers.twr = res_towers;
2567
2568         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2569         if (entry_handle == NULL) {
2570                 status = NT_STATUS_NO_MEMORY;
2571                 goto done;
2572         }
2573
2574         /* ask the endpoint mapper for the port */
2575
2576         status = rpccli_epm_Map(epm_pipe,
2577                                 tmp_ctx,
2578                                 CONST_DISCARD(struct GUID *,
2579                                               &(abstract_syntax->uuid)),
2580                                 map_tower,
2581                                 entry_handle,
2582                                 max_towers,
2583                                 &num_towers,
2584                                 &towers);
2585
2586         if (!NT_STATUS_IS_OK(status)) {
2587                 goto done;
2588         }
2589
2590         if (num_towers != 1) {
2591                 status = NT_STATUS_UNSUCCESSFUL;
2592                 goto done;
2593         }
2594
2595         /* extract the port from the answer */
2596
2597         status = dcerpc_binding_from_tower(tmp_ctx,
2598                                            &(towers.twr->tower),
2599                                            &res_binding);
2600         if (!NT_STATUS_IS_OK(status)) {
2601                 goto done;
2602         }
2603
2604         /* are further checks here necessary? */
2605         if (res_binding->transport != NCACN_IP_TCP) {
2606                 status = NT_STATUS_UNSUCCESSFUL;
2607                 goto done;
2608         }
2609
2610         *pport = (uint16_t)atoi(res_binding->endpoint);
2611
2612 done:
2613         TALLOC_FREE(tmp_ctx);
2614         return status;
2615 }
2616
2617 /**
2618  * Create a rpc pipe client struct, connecting to a host via tcp.
2619  * The port is determined by asking the endpoint mapper on the given
2620  * host.
2621  */
2622 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2623                            const struct ndr_syntax_id *abstract_syntax,
2624                            struct rpc_pipe_client **presult)
2625 {
2626         NTSTATUS status;
2627         uint16_t port = 0;
2628
2629         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2630         if (!NT_STATUS_IS_OK(status)) {
2631                 return status;
2632         }
2633
2634         return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2635                                         abstract_syntax, presult);
2636 }
2637
2638 /********************************************************************
2639  Create a rpc pipe client struct, connecting to a unix domain socket
2640  ********************************************************************/
2641 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2642                                const struct ndr_syntax_id *abstract_syntax,
2643                                struct rpc_pipe_client **presult)
2644 {
2645         struct rpc_pipe_client *result;
2646         struct sockaddr_un addr;
2647         NTSTATUS status;
2648         int fd;
2649
2650         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2651         if (result == NULL) {
2652                 return NT_STATUS_NO_MEMORY;
2653         }
2654
2655         result->abstract_syntax = *abstract_syntax;
2656         result->transfer_syntax = ndr_transfer_syntax;
2657
2658         result->desthost = get_myname(result);
2659         result->srv_name_slash = talloc_asprintf_strupper_m(
2660                 result, "\\\\%s", result->desthost);
2661         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2662                 status = NT_STATUS_NO_MEMORY;
2663                 goto fail;
2664         }
2665
2666         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2667         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2668
2669         fd = socket(AF_UNIX, SOCK_STREAM, 0);
2670         if (fd == -1) {
2671                 status = map_nt_error_from_unix(errno);
2672                 goto fail;
2673         }
2674
2675         ZERO_STRUCT(addr);
2676         addr.sun_family = AF_UNIX;
2677         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2678
2679         if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2680                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2681                           strerror(errno)));
2682                 close(fd);
2683                 return map_nt_error_from_unix(errno);
2684         }
2685
2686         status = rpc_transport_sock_init(result, fd, &result->transport);
2687         if (!NT_STATUS_IS_OK(status)) {
2688                 close(fd);
2689                 goto fail;
2690         }
2691
2692         result->transport->transport = NCALRPC;
2693
2694         result->binding_handle = rpccli_bh_create(result);
2695         if (result->binding_handle == NULL) {
2696                 TALLOC_FREE(result);
2697                 return NT_STATUS_NO_MEMORY;
2698         }
2699
2700         *presult = result;
2701         return NT_STATUS_OK;
2702
2703  fail:
2704         TALLOC_FREE(result);
2705         return status;
2706 }
2707
2708 struct rpc_pipe_client_np_ref {
2709         struct cli_state *cli;
2710         struct rpc_pipe_client *pipe;
2711 };
2712
2713 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2714 {
2715         DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2716         return 0;
2717 }
2718
2719 /****************************************************************************
2720  Open a named pipe over SMB to a remote server.
2721  *
2722  * CAVEAT CALLER OF THIS FUNCTION:
2723  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2724  *    so be sure that this function is called AFTER any structure (vs pointer)
2725  *    assignment of the cli.  In particular, libsmbclient does structure
2726  *    assignments of cli, which invalidates the data in the returned
2727  *    rpc_pipe_client if this function is called before the structure assignment
2728  *    of cli.
2729  * 
2730  ****************************************************************************/
2731
2732 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2733                                  const struct ndr_syntax_id *abstract_syntax,
2734                                  struct rpc_pipe_client **presult)
2735 {
2736         struct rpc_pipe_client *result;
2737         NTSTATUS status;
2738         struct rpc_pipe_client_np_ref *np_ref;
2739
2740         /* sanity check to protect against crashes */
2741
2742         if ( !cli ) {
2743                 return NT_STATUS_INVALID_HANDLE;
2744         }
2745
2746         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2747         if (result == NULL) {
2748                 return NT_STATUS_NO_MEMORY;
2749         }
2750
2751         result->abstract_syntax = *abstract_syntax;
2752         result->transfer_syntax = ndr_transfer_syntax;
2753         result->desthost = talloc_strdup(result, cli->desthost);
2754         result->srv_name_slash = talloc_asprintf_strupper_m(
2755                 result, "\\\\%s", result->desthost);
2756
2757         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2758         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2759
2760         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2761                 TALLOC_FREE(result);
2762                 return NT_STATUS_NO_MEMORY;
2763         }
2764
2765         status = rpc_transport_np_init(result, cli, abstract_syntax,
2766                                        &result->transport);
2767         if (!NT_STATUS_IS_OK(status)) {
2768                 TALLOC_FREE(result);
2769                 return status;
2770         }
2771
2772         result->transport->transport = NCACN_NP;
2773
2774         np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2775         if (np_ref == NULL) {
2776                 TALLOC_FREE(result);
2777                 return NT_STATUS_NO_MEMORY;
2778         }
2779         np_ref->cli = cli;
2780         np_ref->pipe = result;
2781
2782         DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2783         talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2784
2785         result->binding_handle = rpccli_bh_create(result);
2786         if (result->binding_handle == NULL) {
2787                 TALLOC_FREE(result);
2788                 return NT_STATUS_NO_MEMORY;
2789         }
2790
2791         *presult = result;
2792         return NT_STATUS_OK;
2793 }
2794
2795 /****************************************************************************
2796  Open a pipe to a remote server.
2797  ****************************************************************************/
2798
2799 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2800                                   enum dcerpc_transport_t transport,
2801                                   const struct ndr_syntax_id *interface,
2802                                   struct rpc_pipe_client **presult)
2803 {
2804         switch (transport) {
2805         case NCACN_IP_TCP:
2806                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2807                                          presult);
2808         case NCACN_NP:
2809                 return rpc_pipe_open_np(cli, interface, presult);
2810         default:
2811                 return NT_STATUS_NOT_IMPLEMENTED;
2812         }
2813 }
2814
2815 /****************************************************************************
2816  Open a named pipe to an SMB server and bind anonymously.
2817  ****************************************************************************/
2818
2819 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2820                                             enum dcerpc_transport_t transport,
2821                                             const struct ndr_syntax_id *interface,
2822                                             struct rpc_pipe_client **presult)
2823 {
2824         struct rpc_pipe_client *result;
2825         struct pipe_auth_data *auth;
2826         NTSTATUS status;
2827
2828         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2829         if (!NT_STATUS_IS_OK(status)) {
2830                 return status;
2831         }
2832
2833         status = rpccli_anon_bind_data(result, &auth);
2834         if (!NT_STATUS_IS_OK(status)) {
2835                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2836                           nt_errstr(status)));
2837                 TALLOC_FREE(result);
2838                 return status;
2839         }
2840
2841         /*
2842          * This is a bit of an abstraction violation due to the fact that an
2843          * anonymous bind on an authenticated SMB inherits the user/domain
2844          * from the enclosing SMB creds
2845          */
2846
2847         TALLOC_FREE(auth->user_name);
2848         TALLOC_FREE(auth->domain);
2849
2850         auth->user_name = talloc_strdup(auth, cli->user_name);
2851         auth->domain = talloc_strdup(auth, cli->domain);
2852         auth->user_session_key = data_blob_talloc(auth,
2853                 cli->user_session_key.data,
2854                 cli->user_session_key.length);
2855
2856         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2857                 TALLOC_FREE(result);
2858                 return NT_STATUS_NO_MEMORY;
2859         }
2860
2861         status = rpc_pipe_bind(result, auth);
2862         if (!NT_STATUS_IS_OK(status)) {
2863                 int lvl = 0;
2864                 if (ndr_syntax_id_equal(interface,
2865                                         &ndr_table_dssetup.syntax_id)) {
2866                         /* non AD domains just don't have this pipe, avoid
2867                          * level 0 statement in that case - gd */
2868                         lvl = 3;
2869                 }
2870                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2871                             "%s failed with error %s\n",
2872                             get_pipe_name_from_syntax(talloc_tos(), interface),
2873                             nt_errstr(status) ));
2874                 TALLOC_FREE(result);
2875                 return status;
2876         }
2877
2878         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2879                   "%s and bound anonymously.\n",
2880                   get_pipe_name_from_syntax(talloc_tos(), interface),
2881                   cli->desthost));
2882
2883         *presult = result;
2884         return NT_STATUS_OK;
2885 }
2886
2887 /****************************************************************************
2888  ****************************************************************************/
2889
2890 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2891                                   const struct ndr_syntax_id *interface,
2892                                   struct rpc_pipe_client **presult)
2893 {
2894         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2895                                                   interface, presult);
2896 }
2897
2898 /****************************************************************************
2899  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2900  ****************************************************************************/
2901
2902 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2903                                    const struct ndr_syntax_id *interface,
2904                                    enum dcerpc_transport_t transport,
2905                                    enum dcerpc_AuthLevel auth_level,
2906                                    const char *domain,
2907                                    const char *username,
2908                                    const char *password,
2909                                    struct rpc_pipe_client **presult)
2910 {
2911         struct rpc_pipe_client *result;
2912         struct pipe_auth_data *auth = NULL;
2913         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2914         NTSTATUS status;
2915
2916         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2917         if (!NT_STATUS_IS_OK(status)) {
2918                 return status;
2919         }
2920
2921         status = rpccli_ntlmssp_bind_data(result,
2922                                           auth_type, auth_level,
2923                                           domain, username, password,
2924                                           &auth);
2925         if (!NT_STATUS_IS_OK(status)) {
2926                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2927                           nt_errstr(status)));
2928                 goto err;
2929         }
2930
2931         status = rpc_pipe_bind(result, auth);
2932         if (!NT_STATUS_IS_OK(status)) {
2933                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2934                         nt_errstr(status) ));
2935                 goto err;
2936         }
2937
2938         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2939                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2940                   get_pipe_name_from_syntax(talloc_tos(), interface),
2941                   cli->desthost, domain, username ));
2942
2943         *presult = result;
2944         return NT_STATUS_OK;
2945
2946   err:
2947
2948         TALLOC_FREE(result);
2949         return status;
2950 }
2951
2952 /****************************************************************************
2953  External interface.
2954  Open a named pipe to an SMB server and bind using schannel (bind type 68)
2955  using session_key. sign and seal.
2956
2957  The *pdc will be stolen onto this new pipe
2958  ****************************************************************************/
2959
2960 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2961                                              const struct ndr_syntax_id *interface,
2962                                              enum dcerpc_transport_t transport,
2963                                              enum dcerpc_AuthLevel auth_level,
2964                                              const char *domain,
2965                                              struct netlogon_creds_CredentialState **pdc,
2966                                              struct rpc_pipe_client **presult)
2967 {
2968         struct rpc_pipe_client *result;
2969         struct pipe_auth_data *auth;
2970         NTSTATUS status;
2971
2972         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2973         if (!NT_STATUS_IS_OK(status)) {
2974                 return status;
2975         }
2976
2977         status = rpccli_schannel_bind_data(result, domain, auth_level,
2978                                            *pdc, &auth);
2979         if (!NT_STATUS_IS_OK(status)) {
2980                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2981                           nt_errstr(status)));
2982                 TALLOC_FREE(result);
2983                 return status;
2984         }
2985
2986         status = rpc_pipe_bind(result, auth);
2987         if (!NT_STATUS_IS_OK(status)) {
2988                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
2989                           "cli_rpc_pipe_bind failed with error %s\n",
2990                           nt_errstr(status) ));
2991                 TALLOC_FREE(result);
2992                 return status;
2993         }
2994
2995         /*
2996          * The credentials on a new netlogon pipe are the ones we are passed
2997          * in - copy them over
2998          */
2999         result->dc = netlogon_creds_copy(result, *pdc);
3000         if (result->dc == NULL) {
3001                 TALLOC_FREE(result);
3002                 return NT_STATUS_NO_MEMORY;
3003         }
3004
3005         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3006                   "for domain %s and bound using schannel.\n",
3007                   get_pipe_name_from_syntax(talloc_tos(), interface),
3008                   cli->desthost, domain ));
3009
3010         *presult = result;
3011         return NT_STATUS_OK;
3012 }
3013
3014 /****************************************************************************
3015  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3016  The idea is this can be called with service_princ, username and password all
3017  NULL so long as the caller has a TGT.
3018  ****************************************************************************/
3019
3020 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3021                                 const struct ndr_syntax_id *interface,
3022                                 enum dcerpc_transport_t transport,
3023                                 enum dcerpc_AuthLevel auth_level,
3024                                 const char *server,
3025                                 const char *username,
3026                                 const char *password,
3027                                 struct rpc_pipe_client **presult)
3028 {
3029         struct rpc_pipe_client *result;
3030         struct pipe_auth_data *auth;
3031         NTSTATUS status;
3032
3033         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3034         if (!NT_STATUS_IS_OK(status)) {
3035                 return status;
3036         }
3037
3038         auth = talloc(result, struct pipe_auth_data);
3039         if (auth == NULL) {
3040                 status = NT_STATUS_NO_MEMORY;
3041                 goto err_out;
3042         }
3043         auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3044         auth->auth_level = auth_level;
3045
3046         if (!username) {
3047                 username = "";
3048         }
3049         auth->user_name = talloc_strdup(auth, username);
3050         if (!auth->user_name) {
3051                 status = NT_STATUS_NO_MEMORY;
3052                 goto err_out;
3053         }
3054
3055         /* Fixme, should we fetch/set the Realm ? */
3056         auth->domain = talloc_strdup(auth, "");
3057         if (!auth->domain) {
3058                 status = NT_STATUS_NO_MEMORY;
3059                 goto err_out;
3060         }
3061
3062         status = gse_init_client(auth, auth->auth_type, auth->auth_level,
3063                                  NULL, server, "cifs", username, password,
3064                                  GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3065
3066         if (!NT_STATUS_IS_OK(status)) {
3067                 DEBUG(0, ("gse_init_client returned %s\n",
3068                           nt_errstr(status)));
3069                 goto err_out;
3070         }
3071
3072         status = rpc_pipe_bind(result, auth);
3073         if (!NT_STATUS_IS_OK(status)) {
3074                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3075                           nt_errstr(status)));
3076                 goto err_out;
3077         }
3078
3079         *presult = result;
3080         return NT_STATUS_OK;
3081
3082 err_out:
3083         TALLOC_FREE(result);
3084         return status;
3085 }
3086
3087 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3088                                         const struct ndr_syntax_id *interface,
3089                                         enum dcerpc_transport_t transport,
3090                                         enum dcerpc_AuthLevel auth_level,
3091                                         const char *server,
3092                                         const char *username,
3093                                         const char *password,
3094                                         struct rpc_pipe_client **presult)
3095 {
3096         struct rpc_pipe_client *result;
3097         struct pipe_auth_data *auth;
3098         NTSTATUS status;
3099
3100         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3101         if (!NT_STATUS_IS_OK(status)) {
3102                 return status;
3103         }
3104
3105         auth = talloc(result, struct pipe_auth_data);
3106         if (auth == NULL) {
3107                 status = NT_STATUS_NO_MEMORY;
3108                 goto err_out;
3109         }
3110         auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3111         auth->auth_level = auth_level;
3112         /* compat */
3113         auth->spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
3114
3115         if (!username) {
3116                 username = "";
3117         }
3118         auth->user_name = talloc_strdup(auth, username);
3119         if (!auth->user_name) {
3120                 status = NT_STATUS_NO_MEMORY;
3121                 goto err_out;
3122         }
3123
3124         /* Fixme, should we fetch/set the Realm ? */
3125         auth->domain = talloc_strdup(auth, "");
3126         if (!auth->domain) {
3127                 status = NT_STATUS_NO_MEMORY;
3128                 goto err_out;
3129         }
3130
3131         status = spnego_gssapi_init_client(auth, auth->auth_level,
3132                                            NULL, server, "cifs",
3133                                            username, password,
3134                                            GSS_C_DCE_STYLE,
3135                                            &auth->a_u.spnego_state);
3136         if (!NT_STATUS_IS_OK(status)) {
3137                 DEBUG(0, ("spnego_init_client returned %s\n",
3138                           nt_errstr(status)));
3139                 goto err_out;
3140         }
3141
3142         status = rpc_pipe_bind(result, auth);
3143         if (!NT_STATUS_IS_OK(status)) {
3144                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3145                           nt_errstr(status)));
3146                 goto err_out;
3147         }
3148
3149         *presult = result;
3150         return NT_STATUS_OK;
3151
3152 err_out:
3153         TALLOC_FREE(result);
3154         return status;
3155 }
3156
3157 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3158                                           const struct ndr_syntax_id *interface,
3159                                           enum dcerpc_transport_t transport,
3160                                           enum dcerpc_AuthLevel auth_level,
3161                                           const char *domain,
3162                                           const char *username,
3163                                           const char *password,
3164                                           struct rpc_pipe_client **presult)
3165 {
3166         struct rpc_pipe_client *result;
3167         struct pipe_auth_data *auth;
3168         NTSTATUS status;
3169
3170         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3171         if (!NT_STATUS_IS_OK(status)) {
3172                 return status;
3173         }
3174
3175         auth = talloc(result, struct pipe_auth_data);
3176         if (auth == NULL) {
3177                 status = NT_STATUS_NO_MEMORY;
3178                 goto err_out;
3179         }
3180         auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3181         auth->auth_level = auth_level;
3182
3183         if (!username) {
3184                 username = "";
3185         }
3186         auth->user_name = talloc_strdup(auth, username);
3187         if (!auth->user_name) {
3188                 status = NT_STATUS_NO_MEMORY;
3189                 goto err_out;
3190         }
3191
3192         if (!domain) {
3193                 domain = "";
3194         }
3195         auth->domain = talloc_strdup(auth, domain);
3196         if (!auth->domain) {
3197                 status = NT_STATUS_NO_MEMORY;
3198                 goto err_out;
3199         }
3200
3201         status = spnego_ntlmssp_init_client(auth, auth->auth_level,
3202                                             domain, username, password,
3203                                             &auth->a_u.spnego_state);
3204         if (!NT_STATUS_IS_OK(status)) {
3205                 DEBUG(0, ("spnego_init_client returned %s\n",
3206                           nt_errstr(status)));
3207                 goto err_out;
3208         }
3209
3210         status = rpc_pipe_bind(result, auth);
3211         if (!NT_STATUS_IS_OK(status)) {
3212                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3213                           nt_errstr(status)));
3214                 goto err_out;
3215         }
3216
3217         *presult = result;
3218         return NT_STATUS_OK;
3219
3220 err_out:
3221         TALLOC_FREE(result);
3222         return status;
3223 }
3224
3225 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3226                              struct rpc_pipe_client *cli,
3227                              DATA_BLOB *session_key)
3228 {
3229         struct pipe_auth_data *a = cli->auth;
3230         DATA_BLOB sk = data_blob_null;
3231         bool make_dup = false;
3232
3233         if (!session_key || !cli) {
3234                 return NT_STATUS_INVALID_PARAMETER;
3235         }
3236
3237         if (!cli->auth) {
3238                 return NT_STATUS_INVALID_PARAMETER;
3239         }
3240
3241         switch (cli->auth->auth_type) {
3242         case DCERPC_AUTH_TYPE_SCHANNEL:
3243                 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3244                                      16);
3245                 make_dup = true;
3246                 break;
3247         case DCERPC_AUTH_TYPE_SPNEGO:
3248                 sk = spnego_get_session_key(mem_ctx, a->a_u.spnego_state);
3249                 make_dup = false;
3250                 break;
3251         case DCERPC_AUTH_TYPE_NTLMSSP:
3252                 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3253                 make_dup = true;
3254                 break;
3255         case DCERPC_AUTH_TYPE_KRB5:
3256                 sk = gse_get_session_key(mem_ctx, a->a_u.gssapi_state);
3257                 make_dup = false;
3258                 break;
3259         case DCERPC_AUTH_TYPE_NONE:
3260                 sk = data_blob_const(a->user_session_key.data,
3261                                      a->user_session_key.length);
3262                 make_dup = true;
3263                 break;
3264         default:
3265                 break;
3266         }
3267
3268         if (!sk.data) {
3269                 return NT_STATUS_NO_USER_SESSION_KEY;
3270         }
3271
3272         if (make_dup) {
3273                 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3274         } else {
3275                 *session_key = sk;
3276         }
3277
3278         return NT_STATUS_OK;
3279 }