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