4666bac6e49a446f8c2ea564fcf24cb8c3d08874
[samba.git] / source3 / rpc_client / cli_pipe.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client routines
4  *  Largely rewritten by Jeremy Allison             2005.
5  *  Heavily modified by Simo Sorce                  2010.
6  *  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 dcerpc_ctx_list ctx_list = {
1134                 .context_id = 0,
1135                 .num_transfer_syntaxes = 1,
1136                 .abstract_syntax = *abstract,
1137                 .transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer),
1138         };
1139         union dcerpc_payload u = {
1140                 .bind.max_xmit_frag     = RPC_MAX_PDU_FRAG_LEN,
1141                 .bind.max_recv_frag     = RPC_MAX_PDU_FRAG_LEN,
1142                 .bind.num_contexts      = 1,
1143                 .bind.ctx_list          = &ctx_list,
1144                 .bind.auth_info         = *auth_info,
1145         };
1146         uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1147
1148         if (auth_len) {
1149                 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1150         }
1151
1152         if (client_hdr_signing) {
1153                 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
1154         }
1155
1156         status = dcerpc_push_ncacn_packet(mem_ctx,
1157                                           ptype, pfc_flags,
1158                                           auth_len,
1159                                           rpc_call_id,
1160                                           &u,
1161                                           blob);
1162         if (!NT_STATUS_IS_OK(status)) {
1163                 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1164                 return status;
1165         }
1166
1167         return NT_STATUS_OK;
1168 }
1169
1170 /*******************************************************************
1171  Creates a DCE/RPC bind request.
1172  ********************************************************************/
1173
1174 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1175                                     struct rpc_pipe_client *cli,
1176                                     struct pipe_auth_data *auth,
1177                                     uint32_t rpc_call_id,
1178                                     const struct ndr_syntax_id *abstract,
1179                                     const struct ndr_syntax_id *transfer,
1180                                     DATA_BLOB *rpc_out)
1181 {
1182         DATA_BLOB auth_token = { .data = NULL };
1183         DATA_BLOB auth_info = { .data = NULL };
1184         NTSTATUS ret;
1185
1186         if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
1187                 ret = create_generic_auth_rpc_bind_req(
1188                         cli, mem_ctx, &auth_token, &auth->client_hdr_signing);
1189
1190                 if (!NT_STATUS_IS_OK(ret) &&
1191                     !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1192                         return ret;
1193                 }
1194         }
1195
1196         if (auth_token.length != 0) {
1197                 ret = dcerpc_push_dcerpc_auth(cli,
1198                                                 auth->auth_type,
1199                                                 auth->auth_level,
1200                                                 0, /* auth_pad_length */
1201                                                 auth->auth_context_id,
1202                                                 &auth_token,
1203                                                 &auth_info);
1204                 if (!NT_STATUS_IS_OK(ret)) {
1205                         return ret;
1206                 }
1207                 data_blob_free(&auth_token);
1208         }
1209
1210         ret = create_bind_or_alt_ctx_internal(mem_ctx,
1211                                               DCERPC_PKT_BIND,
1212                                               rpc_call_id,
1213                                               abstract,
1214                                               transfer,
1215                                               &auth_info,
1216                                               auth->client_hdr_signing,
1217                                               rpc_out);
1218         data_blob_free(&auth_info);
1219
1220         return ret;
1221 }
1222
1223 /*******************************************************************
1224  External interface.
1225  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1226  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1227  and deals with signing/sealing details.
1228  ********************************************************************/
1229
1230 struct rpc_api_pipe_req_state {
1231         struct tevent_context *ev;
1232         struct rpc_pipe_client *cli;
1233         uint8_t op_num;
1234         uint32_t call_id;
1235         const DATA_BLOB *req_data;
1236         const struct GUID *object_uuid;
1237         uint32_t req_data_sent;
1238         DATA_BLOB req_trailer;
1239         uint32_t req_trailer_sent;
1240         bool verify_bitmask1;
1241         bool verify_pcontext;
1242         DATA_BLOB rpc_out;
1243         DATA_BLOB reply_pdu;
1244 };
1245
1246 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1247 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1248 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
1249 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1250                                   bool *is_last_frag);
1251
1252 static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1253                                          struct tevent_context *ev,
1254                                          struct rpc_pipe_client *cli,
1255                                          uint8_t op_num,
1256                                          const struct GUID *object_uuid,
1257                                          const DATA_BLOB *req_data)
1258 {
1259         struct tevent_req *req, *subreq;
1260         struct rpc_api_pipe_req_state *state;
1261         NTSTATUS status;
1262         bool is_last_frag;
1263
1264         req = tevent_req_create(mem_ctx, &state,
1265                                 struct rpc_api_pipe_req_state);
1266         if (req == NULL) {
1267                 return NULL;
1268         }
1269         state->ev = ev;
1270         state->cli = cli;
1271         state->op_num = op_num;
1272         state->object_uuid = object_uuid;
1273         state->req_data = req_data;
1274         state->call_id = get_rpc_call_id();
1275
1276         if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1277                                         + RPC_MAX_SIGN_SIZE) {
1278                 /* Server is screwed up ! */
1279                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1280                 return tevent_req_post(req, ev);
1281         }
1282
1283         status = prepare_verification_trailer(state);
1284         if (tevent_req_nterror(req, status)) {
1285                 return tevent_req_post(req, ev);
1286         }
1287
1288         status = prepare_next_frag(state, &is_last_frag);
1289         if (tevent_req_nterror(req, status)) {
1290                 return tevent_req_post(req, ev);
1291         }
1292
1293         if (is_last_frag) {
1294                 subreq = rpc_api_pipe_send(state, ev, state->cli,
1295                                            &state->rpc_out,
1296                                            DCERPC_PKT_RESPONSE,
1297                                            state->call_id);
1298                 if (tevent_req_nomem(subreq, req)) {
1299                         return tevent_req_post(req, ev);
1300                 }
1301                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1302         } else {
1303                 subreq = rpc_write_send(state, ev, cli->transport,
1304                                         state->rpc_out.data,
1305                                         state->rpc_out.length);
1306                 if (tevent_req_nomem(subreq, req)) {
1307                         return tevent_req_post(req, ev);
1308                 }
1309                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1310                                         req);
1311         }
1312         return req;
1313 }
1314
1315 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
1316 {
1317         struct pipe_auth_data *a = state->cli->auth;
1318         struct dcerpc_sec_verification_trailer *t;
1319         struct ndr_push *ndr = NULL;
1320         enum ndr_err_code ndr_err;
1321         size_t align = 0;
1322         size_t pad = 0;
1323
1324         if (a == NULL) {
1325                 return NT_STATUS_OK;
1326         }
1327
1328         if (a->auth_level < DCERPC_AUTH_LEVEL_PACKET) {
1329                 return NT_STATUS_OK;
1330         }
1331
1332         t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
1333         if (t == NULL) {
1334                 return NT_STATUS_NO_MEMORY;
1335         }
1336
1337         if (!a->verified_bitmask1) {
1338                 t->commands = talloc_realloc(t, t->commands,
1339                                              struct dcerpc_sec_vt,
1340                                              t->count.count + 1);
1341                 if (t->commands == NULL) {
1342                         return NT_STATUS_NO_MEMORY;
1343                 }
1344                 t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1345                         .command = DCERPC_SEC_VT_COMMAND_BITMASK1,
1346                         .u.bitmask1 = (a->client_hdr_signing) ?
1347                                 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING :
1348                                 0,
1349                 };
1350                 state->verify_bitmask1 = true;
1351         }
1352
1353         if (!state->cli->verified_pcontext) {
1354                 t->commands = talloc_realloc(t, t->commands,
1355                                              struct dcerpc_sec_vt,
1356                                              t->count.count + 1);
1357                 if (t->commands == NULL) {
1358                         return NT_STATUS_NO_MEMORY;
1359                 }
1360                 t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1361                         .command = DCERPC_SEC_VT_COMMAND_PCONTEXT,
1362                         .u.pcontext.abstract_syntax =
1363                                 state->cli->abstract_syntax,
1364                         .u.pcontext.transfer_syntax =
1365                                 state->cli->transfer_syntax,
1366                 };
1367                 state->verify_pcontext = true;
1368         }
1369
1370         if (!a->hdr_signing) {
1371                 t->commands = talloc_realloc(t, t->commands,
1372                                              struct dcerpc_sec_vt,
1373                                              t->count.count + 1);
1374                 if (t->commands == NULL) {
1375                         return NT_STATUS_NO_MEMORY;
1376                 }
1377                 t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1378                         .command = DCERPC_SEC_VT_COMMAND_HEADER2,
1379                         .u.header2.ptype = DCERPC_PKT_REQUEST,
1380                         .u.header2.drep[0] = DCERPC_DREP_LE,
1381                         .u.header2.call_id = state->call_id,
1382                         .u.header2.context_id = 0,
1383                         .u.header2.opnum = state->op_num,
1384                 };
1385         }
1386
1387         if (t->count.count == 0) {
1388                 TALLOC_FREE(t);
1389                 return NT_STATUS_OK;
1390         }
1391
1392         t->commands[t->count.count - 1].command |= DCERPC_SEC_VT_COMMAND_END;
1393
1394         if (DEBUGLEVEL >= 10) {
1395                 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
1396         }
1397
1398         ndr = ndr_push_init_ctx(state);
1399         if (ndr == NULL) {
1400                 return NT_STATUS_NO_MEMORY;
1401         }
1402
1403         ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
1404                                                 NDR_SCALARS | NDR_BUFFERS,
1405                                                 t);
1406         TALLOC_FREE(t);
1407         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1408                 return ndr_map_error2ntstatus(ndr_err);
1409         }
1410         state->req_trailer = ndr_push_blob(ndr);
1411
1412         align = state->req_data->length & 0x3;
1413         if (align > 0) {
1414                 pad = 4 - align;
1415         }
1416         if (pad > 0) {
1417                 bool ok;
1418                 uint8_t *p;
1419                 const uint8_t zeros[4] = { 0, };
1420
1421                 ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
1422                 if (!ok) {
1423                         return NT_STATUS_NO_MEMORY;
1424                 }
1425
1426                 /* move the padding to the start */
1427                 p = state->req_trailer.data;
1428                 memmove(p + pad, p, state->req_trailer.length - pad);
1429                 memset(p, 0, pad);
1430         }
1431
1432         return NT_STATUS_OK;
1433 }
1434
1435 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1436                                   bool *is_last_frag)
1437 {
1438         size_t auth_len;
1439         size_t frag_len;
1440         uint8_t flags = 0;
1441         size_t pad_len;
1442         size_t data_left;
1443         size_t data_thistime;
1444         size_t trailer_left;
1445         size_t trailer_thistime = 0;
1446         size_t total_left;
1447         size_t total_thistime;
1448         NTSTATUS status;
1449         bool ok;
1450         union dcerpc_payload u;
1451
1452         data_left = state->req_data->length - state->req_data_sent;
1453         trailer_left = state->req_trailer.length - state->req_trailer_sent;
1454         total_left = data_left + trailer_left;
1455         if ((total_left < data_left) || (total_left < trailer_left)) {
1456                 /*
1457                  * overflow
1458                  */
1459                 return NT_STATUS_INVALID_PARAMETER_MIX;
1460         }
1461
1462         status = dcerpc_guess_sizes(state->cli->auth,
1463                                     DCERPC_REQUEST_LENGTH, total_left,
1464                                     state->cli->max_xmit_frag,
1465                                     &total_thistime,
1466                                     &frag_len, &auth_len, &pad_len);
1467         if (!NT_STATUS_IS_OK(status)) {
1468                 return status;
1469         }
1470
1471         if (state->req_data_sent == 0) {
1472                 flags = DCERPC_PFC_FLAG_FIRST;
1473         }
1474
1475         if (total_thistime == total_left) {
1476                 flags |= DCERPC_PFC_FLAG_LAST;
1477         }
1478
1479         data_thistime = MIN(total_thistime, data_left);
1480         if (data_thistime < total_thistime) {
1481                 trailer_thistime = total_thistime - data_thistime;
1482         }
1483
1484         data_blob_free(&state->rpc_out);
1485
1486         u = (union dcerpc_payload) {
1487                 .request.alloc_hint     = total_left,
1488                 .request.context_id     = 0,
1489                 .request.opnum          = state->op_num,
1490         };
1491
1492         if (state->object_uuid) {
1493                 flags |= DCERPC_PFC_FLAG_OBJECT_UUID;
1494                 u.request.object.object = *state->object_uuid;
1495                 frag_len += ndr_size_GUID(state->object_uuid, 0);
1496         }
1497
1498         status = dcerpc_push_ncacn_packet(state,
1499                                           DCERPC_PKT_REQUEST,
1500                                           flags,
1501                                           auth_len,
1502                                           state->call_id,
1503                                           &u,
1504                                           &state->rpc_out);
1505         if (!NT_STATUS_IS_OK(status)) {
1506                 return status;
1507         }
1508
1509         /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1510          * compute it right for requests because the auth trailer is missing
1511          * at this stage */
1512         dcerpc_set_frag_length(&state->rpc_out, frag_len);
1513
1514         if (data_thistime > 0) {
1515                 /* Copy in the data. */
1516                 ok = data_blob_append(NULL, &state->rpc_out,
1517                                 state->req_data->data + state->req_data_sent,
1518                                 data_thistime);
1519                 if (!ok) {
1520                         return NT_STATUS_NO_MEMORY;
1521                 }
1522                 state->req_data_sent += data_thistime;
1523         }
1524
1525         if (trailer_thistime > 0) {
1526                 /* Copy in the verification trailer. */
1527                 ok = data_blob_append(NULL, &state->rpc_out,
1528                                 state->req_trailer.data + state->req_trailer_sent,
1529                                 trailer_thistime);
1530                 if (!ok) {
1531                         return NT_STATUS_NO_MEMORY;
1532                 }
1533                 state->req_trailer_sent += trailer_thistime;
1534         }
1535
1536         switch (state->cli->auth->auth_level) {
1537         case DCERPC_AUTH_LEVEL_NONE:
1538         case DCERPC_AUTH_LEVEL_CONNECT:
1539                 break;
1540         case DCERPC_AUTH_LEVEL_PACKET:
1541         case DCERPC_AUTH_LEVEL_INTEGRITY:
1542         case DCERPC_AUTH_LEVEL_PRIVACY:
1543                 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1544                                                 &state->rpc_out);
1545                 if (!NT_STATUS_IS_OK(status)) {
1546                         return status;
1547                 }
1548                 break;
1549         default:
1550                 return NT_STATUS_INVALID_PARAMETER;
1551         }
1552
1553         *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1554
1555         return status;
1556 }
1557
1558 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1559 {
1560         struct tevent_req *req = tevent_req_callback_data(
1561                 subreq, struct tevent_req);
1562         struct rpc_api_pipe_req_state *state = tevent_req_data(
1563                 req, struct rpc_api_pipe_req_state);
1564         NTSTATUS status;
1565         bool is_last_frag;
1566
1567         status = rpc_write_recv(subreq);
1568         TALLOC_FREE(subreq);
1569         if (tevent_req_nterror(req, status)) {
1570                 return;
1571         }
1572
1573         status = prepare_next_frag(state, &is_last_frag);
1574         if (tevent_req_nterror(req, status)) {
1575                 return;
1576         }
1577
1578         if (is_last_frag) {
1579                 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1580                                            &state->rpc_out,
1581                                            DCERPC_PKT_RESPONSE,
1582                                            state->call_id);
1583                 if (tevent_req_nomem(subreq, req)) {
1584                         return;
1585                 }
1586                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1587         } else {
1588                 subreq = rpc_write_send(state, state->ev,
1589                                         state->cli->transport,
1590                                         state->rpc_out.data,
1591                                         state->rpc_out.length);
1592                 if (tevent_req_nomem(subreq, req)) {
1593                         return;
1594                 }
1595                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1596                                         req);
1597         }
1598 }
1599
1600 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1601 {
1602         struct tevent_req *req = tevent_req_callback_data(
1603                 subreq, struct tevent_req);
1604         struct rpc_api_pipe_req_state *state = tevent_req_data(
1605                 req, struct rpc_api_pipe_req_state);
1606         NTSTATUS status;
1607
1608         status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1609         TALLOC_FREE(subreq);
1610         if (tevent_req_nterror(req, status)) {
1611                 return;
1612         }
1613
1614         if (state->cli->auth == NULL) {
1615                 tevent_req_done(req);
1616                 return;
1617         }
1618
1619         if (state->verify_bitmask1) {
1620                 state->cli->auth->verified_bitmask1 = true;
1621         }
1622
1623         if (state->verify_pcontext) {
1624                 state->cli->verified_pcontext = true;
1625         }
1626
1627         tevent_req_done(req);
1628 }
1629
1630 static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1631                                DATA_BLOB *reply_pdu)
1632 {
1633         struct rpc_api_pipe_req_state *state = tevent_req_data(
1634                 req, struct rpc_api_pipe_req_state);
1635         NTSTATUS status;
1636
1637         if (tevent_req_is_nterror(req, &status)) {
1638                 /*
1639                  * We always have to initialize to reply pdu, even if there is
1640                  * none. The rpccli_* caller routines expect this.
1641                  */
1642                 *reply_pdu = data_blob_null;
1643                 return status;
1644         }
1645
1646         /* return data to caller and assign it ownership of memory */
1647         reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1648         reply_pdu->length = state->reply_pdu.length;
1649         state->reply_pdu.length = 0;
1650
1651         return NT_STATUS_OK;
1652 }
1653
1654 /****************************************************************************
1655  Check the rpc bind acknowledge response.
1656 ****************************************************************************/
1657
1658 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1659                                 struct rpc_pipe_client *cli)
1660 {
1661         const struct ndr_syntax_id *transfer = &cli->transfer_syntax;
1662         struct dcerpc_ack_ctx ctx;
1663         bool equal;
1664
1665         if (r->secondary_address_size == 0) {
1666                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)\n"));
1667         }
1668
1669         if (r->num_results < 1 || !r->ctx_list) {
1670                 return false;
1671         }
1672
1673         ctx = r->ctx_list[0];
1674
1675         /* check the transfer syntax */
1676         equal = ndr_syntax_id_equal(&ctx.syntax, transfer);
1677         if (!equal) {
1678                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1679                 return False;
1680         }
1681
1682         if (r->num_results != 0x1 || ctx.result != 0) {
1683                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1684                           r->num_results, ctx.reason.value));
1685         }
1686
1687         DEBUG(5,("check_bind_response: accepted!\n"));
1688         return True;
1689 }
1690
1691 /*******************************************************************
1692  Creates a DCE/RPC bind authentication response.
1693  This is the packet that is sent back to the server once we
1694  have received a BIND-ACK, to finish the third leg of
1695  the authentication handshake.
1696  ********************************************************************/
1697
1698 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1699                                 struct rpc_pipe_client *cli,
1700                                 struct pipe_auth_data *auth,
1701                                 uint32_t rpc_call_id,
1702                                 DATA_BLOB *pauth_blob,
1703                                 DATA_BLOB *rpc_out)
1704 {
1705         NTSTATUS status;
1706         union dcerpc_payload u = { .auth3._pad = 0, };
1707
1708         status = dcerpc_push_dcerpc_auth(mem_ctx,
1709                                          auth->auth_type,
1710                                          auth->auth_level,
1711                                          0, /* auth_pad_length */
1712                                          auth->auth_context_id,
1713                                          pauth_blob,
1714                                          &u.auth3.auth_info);
1715         if (!NT_STATUS_IS_OK(status)) {
1716                 return status;
1717         }
1718
1719         status = dcerpc_push_ncacn_packet(mem_ctx,
1720                                           DCERPC_PKT_AUTH3,
1721                                           DCERPC_PFC_FLAG_FIRST |
1722                                           DCERPC_PFC_FLAG_LAST,
1723                                           pauth_blob->length,
1724                                           rpc_call_id,
1725                                           &u,
1726                                           rpc_out);
1727         data_blob_free(&u.auth3.auth_info);
1728         if (!NT_STATUS_IS_OK(status)) {
1729                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1730                 return status;
1731         }
1732
1733         return NT_STATUS_OK;
1734 }
1735
1736 /*******************************************************************
1737  Creates a DCE/RPC bind alter context authentication request which
1738  may contain a spnego auth blob
1739  ********************************************************************/
1740
1741 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1742                                         struct pipe_auth_data *auth,
1743                                         uint32_t rpc_call_id,
1744                                         const struct ndr_syntax_id *abstract,
1745                                         const struct ndr_syntax_id *transfer,
1746                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1747                                         DATA_BLOB *rpc_out)
1748 {
1749         DATA_BLOB auth_info;
1750         NTSTATUS status;
1751
1752         status = dcerpc_push_dcerpc_auth(mem_ctx,
1753                                          auth->auth_type,
1754                                          auth->auth_level,
1755                                          0, /* auth_pad_length */
1756                                          auth->auth_context_id,
1757                                          pauth_blob,
1758                                          &auth_info);
1759         if (!NT_STATUS_IS_OK(status)) {
1760                 return status;
1761         }
1762
1763         status = create_bind_or_alt_ctx_internal(mem_ctx,
1764                                                  DCERPC_PKT_ALTER,
1765                                                  rpc_call_id,
1766                                                  abstract,
1767                                                  transfer,
1768                                                  &auth_info,
1769                                                  false, /* client_hdr_signing */
1770                                                  rpc_out);
1771         data_blob_free(&auth_info);
1772         return status;
1773 }
1774
1775 /****************************************************************************
1776  Do an rpc bind.
1777 ****************************************************************************/
1778
1779 struct rpc_pipe_bind_state {
1780         struct tevent_context *ev;
1781         struct rpc_pipe_client *cli;
1782         DATA_BLOB rpc_out;
1783         bool auth3;
1784         uint32_t rpc_call_id;
1785 };
1786
1787 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1788 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1789                                    struct rpc_pipe_bind_state *state,
1790                                    DATA_BLOB *credentials);
1791 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1792                                      struct rpc_pipe_bind_state *state,
1793                                      DATA_BLOB *credentials);
1794
1795 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1796                                       struct tevent_context *ev,
1797                                       struct rpc_pipe_client *cli,
1798                                       struct pipe_auth_data *auth)
1799 {
1800         struct tevent_req *req, *subreq;
1801         struct rpc_pipe_bind_state *state;
1802         NTSTATUS status;
1803
1804         req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1805         if (req == NULL) {
1806                 return NULL;
1807         }
1808
1809         DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1810                 rpccli_pipe_txt(talloc_tos(), cli),
1811                 (unsigned int)auth->auth_type,
1812                 (unsigned int)auth->auth_level ));
1813
1814         state->ev = ev;
1815         state->cli = cli;
1816         state->rpc_call_id = get_rpc_call_id();
1817
1818         cli->auth = talloc_move(cli, &auth);
1819
1820         /* Marshall the outgoing data. */
1821         status = create_rpc_bind_req(state, cli,
1822                                      cli->auth,
1823                                      state->rpc_call_id,
1824                                      &cli->abstract_syntax,
1825                                      &cli->transfer_syntax,
1826                                      &state->rpc_out);
1827
1828         if (!NT_STATUS_IS_OK(status) &&
1829             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1830                 tevent_req_nterror(req, status);
1831                 return tevent_req_post(req, ev);
1832         }
1833
1834         subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1835                                    DCERPC_PKT_BIND_ACK, state->rpc_call_id);
1836         if (tevent_req_nomem(subreq, req)) {
1837                 return tevent_req_post(req, ev);
1838         }
1839         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1840         return req;
1841 }
1842
1843 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1844 {
1845         struct tevent_req *req = tevent_req_callback_data(
1846                 subreq, struct tevent_req);
1847         struct rpc_pipe_bind_state *state = tevent_req_data(
1848                 req, struct rpc_pipe_bind_state);
1849         struct pipe_auth_data *pauth = state->cli->auth;
1850         struct gensec_security *gensec_security;
1851         struct ncacn_packet *pkt = NULL;
1852         struct dcerpc_auth auth;
1853         DATA_BLOB auth_token = { .data = NULL };
1854         NTSTATUS status;
1855
1856         status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1857         TALLOC_FREE(subreq);
1858         if (tevent_req_nterror(req, status)) {
1859                 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1860                           rpccli_pipe_txt(talloc_tos(), state->cli),
1861                           nt_errstr(status)));
1862                 return;
1863         }
1864
1865         if (state->auth3) {
1866                 tevent_req_done(req);
1867                 return;
1868         }
1869
1870         if (!check_bind_response(&pkt->u.bind_ack, state->cli)) {
1871                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1872                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1873                 return;
1874         }
1875
1876         if (pkt->ptype == DCERPC_PKT_BIND_ACK) {
1877                 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
1878                         if (pauth->client_hdr_signing) {
1879                                 pauth->hdr_signing = true;
1880                         }
1881                 }
1882         }
1883
1884         state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1885
1886         if (pauth->auth_type == DCERPC_AUTH_TYPE_NONE) {
1887                 /* Bind complete. */
1888                 tevent_req_done(req);
1889                 return;
1890         }
1891
1892         if (pkt->auth_length == 0) {
1893                 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1894                 return;
1895         }
1896
1897         /* get auth credentials */
1898         status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
1899                                           &pkt->u.bind_ack.auth_info,
1900                                           &auth, NULL, true);
1901         if (tevent_req_nterror(req, status)) {
1902                 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1903                           nt_errstr(status)));
1904                 return;
1905         }
1906
1907         if (auth.auth_type != pauth->auth_type) {
1908                 DBG_ERR("Auth type %u mismatch expected %u.\n",
1909                         auth.auth_type, pauth->auth_type);
1910                 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1911                 return;
1912         }
1913
1914         if (auth.auth_level != pauth->auth_level) {
1915                 DBG_ERR("Auth level %u mismatch expected %u.\n",
1916                         auth.auth_level, pauth->auth_level);
1917                 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1918                 return;
1919         }
1920
1921         if (auth.auth_context_id != pauth->auth_context_id) {
1922                 DBG_ERR("Auth context id %"PRIu32" mismatch "
1923                         "expected %"PRIu32".\n",
1924                         auth.auth_context_id,
1925                         pauth->auth_context_id);
1926                 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1927                 return;
1928         }
1929
1930         /*
1931          * For authenticated binds we may need to do 3 or 4 leg binds.
1932          */
1933
1934         if (pauth->auth_type == DCERPC_AUTH_TYPE_NONE) {
1935                 /* Bind complete. */
1936                 tevent_req_done(req);
1937                 return;
1938         }
1939
1940         gensec_security = pauth->auth_ctx;
1941
1942         status = gensec_update(gensec_security, state,
1943                                auth.credentials, &auth_token);
1944         if (NT_STATUS_EQUAL(status,
1945                             NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1946                 status = rpc_bind_next_send(req, state,
1947                                             &auth_token);
1948         } else if (NT_STATUS_IS_OK(status)) {
1949                 if (pauth->hdr_signing) {
1950                         gensec_want_feature(gensec_security,
1951                                             GENSEC_FEATURE_SIGN_PKT_HEADER);
1952                 }
1953
1954                 if (auth_token.length == 0) {
1955                         /* Bind complete. */
1956                         tevent_req_done(req);
1957                         return;
1958                 }
1959                 status = rpc_bind_finish_send(req, state,
1960                                               &auth_token);
1961         }
1962
1963         if (!NT_STATUS_IS_OK(status)) {
1964                 tevent_req_nterror(req, status);
1965         }
1966         return;
1967 }
1968
1969 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1970                                    struct rpc_pipe_bind_state *state,
1971                                    DATA_BLOB *auth_token)
1972 {
1973         struct pipe_auth_data *auth = state->cli->auth;
1974         struct tevent_req *subreq;
1975         NTSTATUS status;
1976
1977         /* Now prepare the alter context pdu. */
1978         data_blob_free(&state->rpc_out);
1979
1980         status = create_rpc_alter_context(state, auth,
1981                                           state->rpc_call_id,
1982                                           &state->cli->abstract_syntax,
1983                                           &state->cli->transfer_syntax,
1984                                           auth_token,
1985                                           &state->rpc_out);
1986         if (!NT_STATUS_IS_OK(status)) {
1987                 return status;
1988         }
1989
1990         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1991                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP,
1992                                    state->rpc_call_id);
1993         if (subreq == NULL) {
1994                 return NT_STATUS_NO_MEMORY;
1995         }
1996         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1997         return NT_STATUS_OK;
1998 }
1999
2000 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2001                                      struct rpc_pipe_bind_state *state,
2002                                      DATA_BLOB *auth_token)
2003 {
2004         struct pipe_auth_data *auth = state->cli->auth;
2005         struct tevent_req *subreq;
2006         NTSTATUS status;
2007
2008         state->auth3 = true;
2009
2010         /* Now prepare the auth3 context pdu. */
2011         data_blob_free(&state->rpc_out);
2012
2013         status = create_rpc_bind_auth3(state, state->cli, auth,
2014                                         state->rpc_call_id,
2015                                         auth_token,
2016                                         &state->rpc_out);
2017         if (!NT_STATUS_IS_OK(status)) {
2018                 return status;
2019         }
2020
2021         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2022                                    &state->rpc_out, DCERPC_PKT_AUTH3,
2023                                    state->rpc_call_id);
2024         if (subreq == NULL) {
2025                 return NT_STATUS_NO_MEMORY;
2026         }
2027         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2028         return NT_STATUS_OK;
2029 }
2030
2031 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2032 {
2033         return tevent_req_simple_recv_ntstatus(req);
2034 }
2035
2036 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2037                        struct pipe_auth_data *auth)
2038 {
2039         TALLOC_CTX *frame = talloc_stackframe();
2040         struct tevent_context *ev;
2041         struct tevent_req *req;
2042         NTSTATUS status = NT_STATUS_OK;
2043
2044         ev = samba_tevent_context_init(frame);
2045         if (ev == NULL) {
2046                 status = NT_STATUS_NO_MEMORY;
2047                 goto fail;
2048         }
2049
2050         req = rpc_pipe_bind_send(frame, ev, cli, auth);
2051         if (req == NULL) {
2052                 status = NT_STATUS_NO_MEMORY;
2053                 goto fail;
2054         }
2055
2056         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2057                 goto fail;
2058         }
2059
2060         status = rpc_pipe_bind_recv(req);
2061  fail:
2062         TALLOC_FREE(frame);
2063         return status;
2064 }
2065
2066 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2067
2068 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2069                                 unsigned int timeout)
2070 {
2071         if (rpc_cli == NULL) {
2072                 return RPCCLI_DEFAULT_TIMEOUT;
2073         }
2074
2075         if (rpc_cli->binding_handle == NULL) {
2076                 return RPCCLI_DEFAULT_TIMEOUT;
2077         }
2078
2079         return dcerpc_binding_handle_set_timeout(rpc_cli->binding_handle,
2080                                                  timeout);
2081 }
2082
2083 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2084 {
2085         if (rpc_cli == NULL) {
2086                 return false;
2087         }
2088
2089         if (rpc_cli->binding_handle == NULL) {
2090                 return false;
2091         }
2092
2093         return dcerpc_binding_handle_is_connected(rpc_cli->binding_handle);
2094 }
2095
2096 struct rpccli_bh_state {
2097         struct rpc_pipe_client *rpc_cli;
2098 };
2099
2100 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2101 {
2102         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2103                                      struct rpccli_bh_state);
2104         struct rpc_cli_transport *transport = hs->rpc_cli->transport;
2105
2106         if (transport == NULL) {
2107                 return false;
2108         }
2109
2110         if (transport->is_connected == NULL) {
2111                 return false;
2112         }
2113
2114         return transport->is_connected(transport->priv);
2115 }
2116
2117 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2118                                       uint32_t timeout)
2119 {
2120         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2121                                      struct rpccli_bh_state);
2122         struct rpc_cli_transport *transport = hs->rpc_cli->transport;
2123         unsigned int old;
2124
2125         if (transport == NULL) {
2126                 return RPCCLI_DEFAULT_TIMEOUT;
2127         }
2128
2129         if (transport->set_timeout == NULL) {
2130                 return RPCCLI_DEFAULT_TIMEOUT;
2131         }
2132
2133         old = transport->set_timeout(transport->priv, timeout);
2134         if (old == 0) {
2135                 return RPCCLI_DEFAULT_TIMEOUT;
2136         }
2137
2138         return old;
2139 }
2140
2141 static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
2142                                 enum dcerpc_AuthType *auth_type,
2143                                 enum dcerpc_AuthLevel *auth_level)
2144 {
2145         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2146                                      struct rpccli_bh_state);
2147
2148         if (hs->rpc_cli == NULL) {
2149                 return;
2150         }
2151
2152         if (hs->rpc_cli->auth == NULL) {
2153                 return;
2154         }
2155
2156         *auth_type = hs->rpc_cli->auth->auth_type;
2157         *auth_level = hs->rpc_cli->auth->auth_level;
2158 }
2159
2160 struct rpccli_bh_raw_call_state {
2161         DATA_BLOB in_data;
2162         DATA_BLOB out_data;
2163         uint32_t out_flags;
2164 };
2165
2166 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2167
2168 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2169                                                   struct tevent_context *ev,
2170                                                   struct dcerpc_binding_handle *h,
2171                                                   const struct GUID *object,
2172                                                   uint32_t opnum,
2173                                                   uint32_t in_flags,
2174                                                   const uint8_t *in_data,
2175                                                   size_t in_length)
2176 {
2177         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2178                                      struct rpccli_bh_state);
2179         struct tevent_req *req;
2180         struct rpccli_bh_raw_call_state *state;
2181         bool ok;
2182         struct tevent_req *subreq;
2183
2184         req = tevent_req_create(mem_ctx, &state,
2185                                 struct rpccli_bh_raw_call_state);
2186         if (req == NULL) {
2187                 return NULL;
2188         }
2189         state->in_data.data = discard_const_p(uint8_t, in_data);
2190         state->in_data.length = in_length;
2191
2192         ok = rpccli_bh_is_connected(h);
2193         if (!ok) {
2194                 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2195                 return tevent_req_post(req, ev);
2196         }
2197
2198         subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2199                                        opnum, object, &state->in_data);
2200         if (tevent_req_nomem(subreq, req)) {
2201                 return tevent_req_post(req, ev);
2202         }
2203         tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2204
2205         return req;
2206 }
2207
2208 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2209 {
2210         struct tevent_req *req =
2211                 tevent_req_callback_data(subreq,
2212                 struct tevent_req);
2213         struct rpccli_bh_raw_call_state *state =
2214                 tevent_req_data(req,
2215                 struct rpccli_bh_raw_call_state);
2216         NTSTATUS status;
2217
2218         state->out_flags = 0;
2219
2220         /* TODO: support bigendian responses */
2221
2222         status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2223         TALLOC_FREE(subreq);
2224         if (tevent_req_nterror(req, status)) {
2225                 return;
2226         }
2227
2228         tevent_req_done(req);
2229 }
2230
2231 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2232                                         TALLOC_CTX *mem_ctx,
2233                                         uint8_t **out_data,
2234                                         size_t *out_length,
2235                                         uint32_t *out_flags)
2236 {
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         if (tevent_req_is_nterror(req, &status)) {
2243                 tevent_req_received(req);
2244                 return status;
2245         }
2246
2247         *out_data = talloc_move(mem_ctx, &state->out_data.data);
2248         *out_length = state->out_data.length;
2249         *out_flags = state->out_flags;
2250         tevent_req_received(req);
2251         return NT_STATUS_OK;
2252 }
2253
2254 struct rpccli_bh_disconnect_state {
2255         uint8_t _dummy;
2256 };
2257
2258 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2259                                                 struct tevent_context *ev,
2260                                                 struct dcerpc_binding_handle *h)
2261 {
2262         struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2263                                      struct rpccli_bh_state);
2264         struct tevent_req *req;
2265         struct rpccli_bh_disconnect_state *state;
2266         bool ok;
2267
2268         req = tevent_req_create(mem_ctx, &state,
2269                                 struct rpccli_bh_disconnect_state);
2270         if (req == NULL) {
2271                 return NULL;
2272         }
2273
2274         ok = rpccli_bh_is_connected(h);
2275         if (!ok) {
2276                 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2277                 return tevent_req_post(req, ev);
2278         }
2279
2280         /*
2281          * TODO: do a real async disconnect ...
2282          *
2283          * For now we do it sync...
2284          */
2285         TALLOC_FREE(hs->rpc_cli->transport);
2286         hs->rpc_cli = NULL;
2287
2288         tevent_req_done(req);
2289         return tevent_req_post(req, ev);
2290 }
2291
2292 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2293 {
2294         return tevent_req_simple_recv_ntstatus(req);
2295 }
2296
2297 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2298 {
2299         return true;
2300 }
2301
2302 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2303                                    ndr_flags_type ndr_flags,
2304                                    const void *_struct_ptr,
2305                                    const struct ndr_interface_call *call)
2306 {
2307         void *struct_ptr = discard_const(_struct_ptr);
2308
2309         if (DEBUGLEVEL < 10) {
2310                 return;
2311         }
2312
2313         if (ndr_flags & NDR_IN) {
2314                 ndr_print_function_debug(call->ndr_print,
2315                                          call->name,
2316                                          ndr_flags,
2317                                          struct_ptr);
2318         }
2319         if (ndr_flags & NDR_OUT) {
2320                 ndr_print_function_debug(call->ndr_print,
2321                                          call->name,
2322                                          ndr_flags,
2323                                          struct_ptr);
2324         }
2325 }
2326
2327 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2328         .name                   = "rpccli",
2329         .is_connected           = rpccli_bh_is_connected,
2330         .set_timeout            = rpccli_bh_set_timeout,
2331         .auth_info              = rpccli_bh_auth_info,
2332         .raw_call_send          = rpccli_bh_raw_call_send,
2333         .raw_call_recv          = rpccli_bh_raw_call_recv,
2334         .disconnect_send        = rpccli_bh_disconnect_send,
2335         .disconnect_recv        = rpccli_bh_disconnect_recv,
2336
2337         .ref_alloc              = rpccli_bh_ref_alloc,
2338         .do_ndr_print           = rpccli_bh_do_ndr_print,
2339 };
2340
2341 /* initialise a rpc_pipe_client binding handle */
2342 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
2343                                         const struct GUID *object,
2344                                         const struct ndr_interface_table *table)
2345 {
2346         struct dcerpc_binding_handle *h;
2347         struct rpccli_bh_state *hs;
2348
2349         h = dcerpc_binding_handle_create(c,
2350                                          &rpccli_bh_ops,
2351                                          object,
2352                                          table,
2353                                          &hs,
2354                                          struct rpccli_bh_state,
2355                                          __location__);
2356         if (h == NULL) {
2357                 return NULL;
2358         }
2359         hs->rpc_cli = c;
2360
2361         return h;
2362 }
2363
2364 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2365                                struct pipe_auth_data **presult)
2366 {
2367         struct pipe_auth_data *result;
2368         struct auth_generic_state *auth_generic_ctx;
2369         NTSTATUS status;
2370
2371         result = talloc_zero(mem_ctx, struct pipe_auth_data);
2372         if (result == NULL) {
2373                 return NT_STATUS_NO_MEMORY;
2374         }
2375
2376         result->auth_type = DCERPC_AUTH_TYPE_NONE;
2377         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2378         result->auth_context_id = 0;
2379
2380         status = auth_generic_client_prepare(result,
2381                                              &auth_generic_ctx);
2382         if (!NT_STATUS_IS_OK(status)) {
2383                 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2384                           nt_errstr(status)));
2385         }
2386
2387         status = auth_generic_set_username(auth_generic_ctx, "");
2388         if (!NT_STATUS_IS_OK(status)) {
2389                 DEBUG(1, ("Failed to set username: %s\n",
2390                           nt_errstr(status)));
2391         }
2392
2393         status = auth_generic_set_domain(auth_generic_ctx, "");
2394         if (!NT_STATUS_IS_OK(status)) {
2395                 DEBUG(1, ("Failed to set domain: %s\n",
2396                           nt_errstr(status)));
2397                 return status;
2398         }
2399
2400         status = gensec_set_credentials(auth_generic_ctx->gensec_security,
2401                                         auth_generic_ctx->credentials);
2402         if (!NT_STATUS_IS_OK(status)) {
2403                 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2404                           nt_errstr(status)));
2405                 return status;
2406         }
2407         talloc_unlink(auth_generic_ctx, auth_generic_ctx->credentials);
2408         auth_generic_ctx->credentials = NULL;
2409
2410         result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2411         talloc_free(auth_generic_ctx);
2412         *presult = result;
2413         return NT_STATUS_OK;
2414 }
2415
2416 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2417                                          enum dcerpc_AuthType auth_type,
2418                                          enum dcerpc_AuthLevel auth_level,
2419                                          const char *server,
2420                                          const char *target_service,
2421                                          const char *domain,
2422                                          const char *username,
2423                                          const char *password,
2424                                          enum credentials_use_kerberos use_kerberos,
2425                                          struct netlogon_creds_CredentialState *creds,
2426                                          struct pipe_auth_data **presult)
2427 {
2428         struct auth_generic_state *auth_generic_ctx;
2429         struct pipe_auth_data *result;
2430         NTSTATUS status;
2431
2432         result = talloc_zero(mem_ctx, struct pipe_auth_data);
2433         if (result == NULL) {
2434                 return NT_STATUS_NO_MEMORY;
2435         }
2436
2437         result->auth_type = auth_type;
2438         result->auth_level = auth_level;
2439         result->auth_context_id = 1;
2440
2441         status = auth_generic_client_prepare(result,
2442                                              &auth_generic_ctx);
2443         if (!NT_STATUS_IS_OK(status)) {
2444                 goto fail;
2445         }
2446
2447         status = auth_generic_set_username(auth_generic_ctx, username);
2448         if (!NT_STATUS_IS_OK(status)) {
2449                 goto fail;
2450         }
2451
2452         status = auth_generic_set_domain(auth_generic_ctx, domain);
2453         if (!NT_STATUS_IS_OK(status)) {
2454                 goto fail;
2455         }
2456
2457         status = auth_generic_set_password(auth_generic_ctx, password);
2458         if (!NT_STATUS_IS_OK(status)) {
2459                 goto fail;
2460         }
2461
2462         status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2463         if (!NT_STATUS_IS_OK(status)) {
2464                 goto fail;
2465         }
2466
2467         status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2468         if (!NT_STATUS_IS_OK(status)) {
2469                 goto fail;
2470         }
2471
2472         cli_credentials_set_kerberos_state(auth_generic_ctx->credentials,
2473                                            use_kerberos,
2474                                            CRED_SPECIFIED);
2475         cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2476
2477         status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2478         if (!NT_STATUS_IS_OK(status)) {
2479                 goto fail;
2480         }
2481
2482         result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2483         talloc_free(auth_generic_ctx);
2484         *presult = result;
2485         return NT_STATUS_OK;
2486
2487  fail:
2488         TALLOC_FREE(result);
2489         return status;
2490 }
2491
2492 /* This routine steals the creds pointer that is passed in */
2493 static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx,
2494                                                     enum dcerpc_AuthType auth_type,
2495                                                     enum dcerpc_AuthLevel auth_level,
2496                                                     const char *server,
2497                                                     const char *target_service,
2498                                                     struct cli_credentials *creds,
2499                                                     struct pipe_auth_data **presult)
2500 {
2501         struct auth_generic_state *auth_generic_ctx;
2502         struct pipe_auth_data *result;
2503         NTSTATUS status;
2504
2505         result = talloc_zero(mem_ctx, struct pipe_auth_data);
2506         if (result == NULL) {
2507                 return NT_STATUS_NO_MEMORY;
2508         }
2509
2510         result->auth_type = auth_type;
2511         result->auth_level = auth_level;
2512         result->auth_context_id = 1;
2513
2514         status = auth_generic_client_prepare(result,
2515                                              &auth_generic_ctx);
2516         if (!NT_STATUS_IS_OK(status)) {
2517                 goto fail;
2518         }
2519
2520         status = auth_generic_set_creds(auth_generic_ctx, creds);
2521         if (!NT_STATUS_IS_OK(status)) {
2522                 goto fail;
2523         }
2524
2525         status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2526         if (!NT_STATUS_IS_OK(status)) {
2527                 goto fail;
2528         }
2529
2530         status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2531         if (!NT_STATUS_IS_OK(status)) {
2532                 goto fail;
2533         }
2534
2535         status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2536         if (!NT_STATUS_IS_OK(status)) {
2537                 goto fail;
2538         }
2539
2540         result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2541         talloc_free(auth_generic_ctx);
2542         *presult = result;
2543         return NT_STATUS_OK;
2544
2545  fail:
2546         TALLOC_FREE(result);
2547         return status;
2548 }
2549
2550 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2551                                   struct pipe_auth_data **presult)
2552 {
2553         return rpccli_generic_bind_data(mem_ctx,
2554                                         DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
2555                                         DCERPC_AUTH_LEVEL_CONNECT,
2556                                         NULL, /* server */
2557                                         "host", /* target_service */
2558                                         NAME_NT_AUTHORITY, /* domain */
2559                                         "SYSTEM",
2560                                         NULL, /* password */
2561                                         CRED_USE_KERBEROS_DISABLED,
2562                                         NULL, /* netlogon_creds_CredentialState */
2563                                         presult);
2564 }
2565
2566 /**
2567  * Create an rpc pipe client struct, connecting to a tcp port.
2568  */
2569 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2570                                        const struct sockaddr_storage *ss_addr,
2571                                        uint16_t port,
2572                                        const struct ndr_interface_table *table,
2573                                        struct rpc_pipe_client **presult)
2574 {
2575         struct rpc_pipe_client *result;
2576         struct sockaddr_storage addr;
2577         NTSTATUS status;
2578         int fd;
2579
2580         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2581         if (result == NULL) {
2582                 return NT_STATUS_NO_MEMORY;
2583         }
2584
2585         result->abstract_syntax = table->syntax_id;
2586         result->transfer_syntax = ndr_transfer_syntax_ndr;
2587
2588         result->desthost = talloc_strdup(result, host);
2589         if (result->desthost == NULL) {
2590                 status = NT_STATUS_NO_MEMORY;
2591                 goto fail;
2592         }
2593
2594         result->srv_name_slash = talloc_asprintf_strupper_m(
2595                 result, "\\\\%s", result->desthost);
2596         if (result->srv_name_slash == NULL) {
2597                 status = NT_STATUS_NO_MEMORY;
2598                 goto fail;
2599         }
2600
2601         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2602
2603         if (ss_addr == NULL) {
2604                 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2605                         status = NT_STATUS_NOT_FOUND;
2606                         goto fail;
2607                 }
2608         } else {
2609                 addr = *ss_addr;
2610         }
2611
2612         status = open_socket_out(&addr, port, 60*1000, &fd);
2613         if (!NT_STATUS_IS_OK(status)) {
2614                 goto fail;
2615         }
2616         set_socket_options(fd, lp_socket_options());
2617
2618         status = rpc_transport_sock_init(result, fd, &result->transport);
2619         if (!NT_STATUS_IS_OK(status)) {
2620                 close(fd);
2621                 goto fail;
2622         }
2623
2624         result->transport->transport = NCACN_IP_TCP;
2625
2626         result->binding_handle = rpccli_bh_create(result, NULL, table);
2627         if (result->binding_handle == NULL) {
2628                 TALLOC_FREE(result);
2629                 return NT_STATUS_NO_MEMORY;
2630         }
2631
2632         *presult = result;
2633         return NT_STATUS_OK;
2634
2635  fail:
2636         TALLOC_FREE(result);
2637         return status;
2638 }
2639
2640 static NTSTATUS rpccli_epm_map_binding(
2641         struct dcerpc_binding_handle *epm_connection,
2642         struct dcerpc_binding *binding,
2643         TALLOC_CTX *mem_ctx,
2644         char **pendpoint)
2645 {
2646         TALLOC_CTX *frame = talloc_stackframe();
2647         enum dcerpc_transport_t transport =
2648                 dcerpc_binding_get_transport(binding);
2649         enum dcerpc_transport_t res_transport;
2650         struct dcerpc_binding *res_binding = NULL;
2651         struct epm_twr_t *map_tower = NULL;
2652         struct epm_twr_p_t res_towers = { .twr = NULL };
2653         struct policy_handle *entry_handle = NULL;
2654         uint32_t num_towers = 0;
2655         const uint32_t max_towers = 1;
2656         const char *endpoint = NULL;
2657         char *tmp = NULL;
2658         uint32_t result;
2659         NTSTATUS status;
2660
2661         map_tower = talloc_zero(frame, struct epm_twr_t);
2662         if (map_tower == NULL) {
2663                 goto nomem;
2664         }
2665
2666         status = dcerpc_binding_build_tower(
2667                 frame, binding, &(map_tower->tower));
2668         if (!NT_STATUS_IS_OK(status)) {
2669                 DBG_DEBUG("dcerpc_binding_build_tower failed: %s\n",
2670                           nt_errstr(status));
2671                 goto done;
2672         }
2673
2674         res_towers.twr = talloc_array(frame, struct epm_twr_t, max_towers);
2675         if (res_towers.twr == NULL) {
2676                 goto nomem;
2677         }
2678
2679         entry_handle = talloc_zero(frame, struct policy_handle);
2680         if (entry_handle == NULL) {
2681                 goto nomem;
2682         }
2683
2684         status = dcerpc_epm_Map(
2685                 epm_connection,
2686                 frame,
2687                 NULL,
2688                 map_tower,
2689                 entry_handle,
2690                 max_towers,
2691                 &num_towers,
2692                 &res_towers,
2693                 &result);
2694
2695         if (!NT_STATUS_IS_OK(status)) {
2696                 DBG_DEBUG("dcerpc_epm_Map failed: %s\n", nt_errstr(status));
2697                 goto done;
2698         }
2699
2700         if (result != EPMAPPER_STATUS_OK) {
2701                 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32"\n", result);
2702                 status = NT_STATUS_NOT_FOUND;
2703                 goto done;
2704         }
2705
2706         if (num_towers != 1) {
2707                 DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32" towers\n",
2708                           num_towers);
2709                 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2710                 goto done;
2711         }
2712
2713         status = dcerpc_binding_from_tower(
2714                 frame, &(res_towers.twr->tower), &res_binding);
2715         if (!NT_STATUS_IS_OK(status)) {
2716                 DBG_DEBUG("dcerpc_binding_from_tower failed: %s\n",
2717                           nt_errstr(status));
2718                 goto done;
2719         }
2720
2721         res_transport = dcerpc_binding_get_transport(res_binding);
2722         if (res_transport != transport) {
2723                 DBG_DEBUG("dcerpc_epm_Map returned transport %d, "
2724                           "expected %d\n",
2725                           (int)res_transport,
2726                           (int)transport);
2727                 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2728                 goto done;
2729         }
2730
2731         endpoint = dcerpc_binding_get_string_option(res_binding, "endpoint");
2732         if (endpoint == NULL) {
2733                 DBG_DEBUG("dcerpc_epm_Map returned no endpoint\n");
2734                 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2735                 goto done;
2736         }
2737
2738         tmp = talloc_strdup(mem_ctx, endpoint);
2739         if (tmp == NULL) {
2740                 goto nomem;
2741         }
2742         *pendpoint = tmp;
2743
2744         status = NT_STATUS_OK;
2745         goto done;
2746
2747 nomem:
2748         status = NT_STATUS_NO_MEMORY;
2749 done:
2750         TALLOC_FREE(frame);
2751         return status;
2752 }
2753
2754 static NTSTATUS rpccli_epm_map_interface(
2755         struct dcerpc_binding_handle *epm_connection,
2756         enum dcerpc_transport_t transport,
2757         const struct ndr_syntax_id *iface,
2758         TALLOC_CTX *mem_ctx,
2759         char **pendpoint)
2760 {
2761         struct dcerpc_binding *binding = NULL;
2762         char *endpoint = NULL;
2763         NTSTATUS status;
2764
2765         status = dcerpc_parse_binding(mem_ctx, "", &binding);
2766         if (!NT_STATUS_IS_OK(status)) {
2767                 DBG_DEBUG("dcerpc_parse_binding failed: %s\n",
2768                           nt_errstr(status));
2769                 goto done;
2770         }
2771
2772         status = dcerpc_binding_set_transport(binding, transport);
2773         if (!NT_STATUS_IS_OK(status)) {
2774                 DBG_DEBUG("dcerpc_binding_set_transport failed: %s\n",
2775                           nt_errstr(status));
2776                 goto done;
2777         }
2778
2779         status = dcerpc_binding_set_abstract_syntax(binding, iface);
2780         if (!NT_STATUS_IS_OK(status)) {
2781                 DBG_DEBUG("dcerpc_binding_set_abstract_syntax failed: %s\n",
2782                           nt_errstr(status));
2783                 goto done;
2784         }
2785
2786         status = rpccli_epm_map_binding(
2787                 epm_connection, binding, mem_ctx, &endpoint);
2788         if (!NT_STATUS_IS_OK(status)) {
2789                 DBG_DEBUG("rpccli_epm_map_binding failed: %s\n",
2790                           nt_errstr(status));
2791                 goto done;
2792         }
2793         *pendpoint = endpoint;
2794
2795 done:
2796         TALLOC_FREE(binding);
2797         return status;
2798 }
2799
2800 /**
2801  * Determine the tcp port on which a dcerpc interface is listening
2802  * for the ncacn_ip_tcp transport via the endpoint mapper of the
2803  * target host.
2804  */
2805 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2806                                       const struct sockaddr_storage *addr,
2807                                       const struct ndr_interface_table *table,
2808                                       uint16_t *pport)
2809 {
2810         NTSTATUS status;
2811         struct rpc_pipe_client *epm_pipe = NULL;
2812         struct pipe_auth_data *auth = NULL;
2813         char *endpoint = NULL;
2814         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2815
2816         if (pport == NULL) {
2817                 status = NT_STATUS_INVALID_PARAMETER;
2818                 goto done;
2819         }
2820
2821         if (ndr_syntax_id_equal(&table->syntax_id,
2822                                 &ndr_table_epmapper.syntax_id)) {
2823                 *pport = 135;
2824                 status = NT_STATUS_OK;
2825                 goto done;
2826         }
2827
2828         /* open the connection to the endpoint mapper */
2829         status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2830                                         &ndr_table_epmapper,
2831                                         &epm_pipe);
2832
2833         if (!NT_STATUS_IS_OK(status)) {
2834                 goto done;
2835         }
2836
2837         status = rpccli_anon_bind_data(tmp_ctx, &auth);
2838         if (!NT_STATUS_IS_OK(status)) {
2839                 goto done;
2840         }
2841
2842         status = rpc_pipe_bind(epm_pipe, auth);
2843         if (!NT_STATUS_IS_OK(status)) {
2844                 goto done;
2845         }
2846
2847         status = rpccli_epm_map_interface(
2848                 epm_pipe->binding_handle,
2849                 NCACN_IP_TCP,
2850                 &table->syntax_id,
2851                 tmp_ctx,
2852                 &endpoint);
2853         if (!NT_STATUS_IS_OK(status)) {
2854                 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
2855                           nt_errstr(status));
2856                 goto done;
2857         }
2858
2859         *pport = (uint16_t)atoi(endpoint);
2860
2861 done:
2862         TALLOC_FREE(tmp_ctx);
2863         return status;
2864 }
2865
2866 /**
2867  * Create a rpc pipe client struct, connecting to a host via tcp.
2868  * The port is determined by asking the endpoint mapper on the given
2869  * host.
2870  */
2871 static NTSTATUS rpc_pipe_open_tcp(
2872         TALLOC_CTX *mem_ctx,
2873         const char *host,
2874         const struct sockaddr_storage *addr,
2875         const struct ndr_interface_table *table,
2876         struct rpc_pipe_client **presult)
2877 {
2878         NTSTATUS status;
2879         uint16_t port = 0;
2880
2881         status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2882         if (!NT_STATUS_IS_OK(status)) {
2883                 return status;
2884         }
2885
2886         return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2887                                       table, presult);
2888 }
2889
2890 static NTSTATUS rpc_pipe_get_ncalrpc_name(
2891         const struct ndr_syntax_id *iface,
2892         TALLOC_CTX *mem_ctx,
2893         char **psocket_name)
2894 {
2895         TALLOC_CTX *frame = talloc_stackframe();
2896         struct rpc_pipe_client *epm_pipe = NULL;
2897         struct pipe_auth_data *auth = NULL;
2898         NTSTATUS status = NT_STATUS_OK;
2899         bool is_epm;
2900
2901         is_epm = ndr_syntax_id_equal(iface, &ndr_table_epmapper.syntax_id);
2902         if (is_epm) {
2903                 char *endpoint = talloc_strdup(mem_ctx, "EPMAPPER");
2904                 if (endpoint == NULL) {
2905                         status = NT_STATUS_NO_MEMORY;
2906                         goto done;
2907                 }
2908                 *psocket_name = endpoint;
2909                 goto done;
2910         }
2911
2912         status = rpc_pipe_open_ncalrpc(
2913                 frame, &ndr_table_epmapper, &epm_pipe);
2914         if (!NT_STATUS_IS_OK(status)) {
2915                 DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
2916                           nt_errstr(status));
2917                 goto done;
2918         }
2919
2920         status = rpccli_anon_bind_data(epm_pipe, &auth);
2921         if (!NT_STATUS_IS_OK(status)) {
2922                 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
2923                           nt_errstr(status));
2924                 goto done;
2925         }
2926
2927         status = rpc_pipe_bind(epm_pipe, auth);
2928         if (!NT_STATUS_IS_OK(status)) {
2929                 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
2930                 goto done;
2931         }
2932
2933         status = rpccli_epm_map_interface(
2934                 epm_pipe->binding_handle,
2935                 NCALRPC,
2936                 iface,
2937                 mem_ctx,
2938                 psocket_name);
2939         if (!NT_STATUS_IS_OK(status)) {
2940                 DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
2941                           nt_errstr(status));
2942         }
2943
2944 done:
2945         TALLOC_FREE(frame);
2946         return status;
2947 }
2948
2949 /********************************************************************
2950  Create a rpc pipe client struct, connecting to a unix domain socket
2951  ********************************************************************/
2952 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx,
2953                                const struct ndr_interface_table *table,
2954                                struct rpc_pipe_client **presult)
2955 {
2956         char *socket_name = NULL;
2957         struct rpc_pipe_client *result;
2958         struct sockaddr_un addr = { .sun_family = AF_UNIX };
2959         socklen_t salen = sizeof(addr);
2960         int pathlen;
2961         NTSTATUS status;
2962         int fd = -1;
2963
2964         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2965         if (result == NULL) {
2966                 return NT_STATUS_NO_MEMORY;
2967         }
2968
2969         status = rpc_pipe_get_ncalrpc_name(
2970                 &table->syntax_id, result, &socket_name);
2971         if (!NT_STATUS_IS_OK(status)) {
2972                 DBG_DEBUG("rpc_pipe_get_ncalrpc_name failed: %s\n",
2973                           nt_errstr(status));
2974                 goto fail;
2975         }
2976
2977         pathlen = snprintf(
2978                 addr.sun_path,
2979                 sizeof(addr.sun_path),
2980                 "%s/%s",
2981                 lp_ncalrpc_dir(),
2982                 socket_name);
2983         if ((pathlen < 0) || ((size_t)pathlen >= sizeof(addr.sun_path))) {
2984                 DBG_DEBUG("socket_path for %s too long\n", socket_name);
2985                 status = NT_STATUS_NAME_TOO_LONG;
2986                 goto fail;
2987         }
2988         TALLOC_FREE(socket_name);
2989
2990         result->abstract_syntax = table->syntax_id;
2991         result->transfer_syntax = ndr_transfer_syntax_ndr;
2992
2993         result->desthost = get_myname(result);
2994         if (result->desthost == NULL) {
2995                 status = NT_STATUS_NO_MEMORY;
2996                 goto fail;
2997         }
2998
2999         result->srv_name_slash = talloc_asprintf_strupper_m(
3000                 result, "\\\\%s", result->desthost);
3001         if (result->srv_name_slash == NULL) {
3002                 status = NT_STATUS_NO_MEMORY;
3003                 goto fail;
3004         }
3005
3006         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3007
3008         fd = socket(AF_UNIX, SOCK_STREAM, 0);
3009         if (fd == -1) {
3010                 status = map_nt_error_from_unix(errno);
3011                 goto fail;
3012         }
3013
3014         if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
3015                 DBG_WARNING("connect(%s) failed: %s\n",
3016                             addr.sun_path,
3017                             strerror(errno));
3018                 status = map_nt_error_from_unix(errno);
3019                 goto fail;
3020         }
3021
3022         status = rpc_transport_sock_init(result, fd, &result->transport);
3023         if (!NT_STATUS_IS_OK(status)) {
3024                 goto fail;
3025         }
3026         fd = -1;
3027
3028         result->transport->transport = NCALRPC;
3029
3030         result->binding_handle = rpccli_bh_create(result, NULL, table);
3031         if (result->binding_handle == NULL) {
3032                 status = NT_STATUS_NO_MEMORY;
3033                 goto fail;
3034         }
3035
3036         *presult = result;
3037         return NT_STATUS_OK;
3038
3039  fail:
3040         if (fd != -1) {
3041                 close(fd);
3042         }
3043         TALLOC_FREE(result);
3044         return status;
3045 }
3046
3047 NTSTATUS rpc_pipe_open_local_np(
3048         TALLOC_CTX *mem_ctx,
3049         const struct ndr_interface_table *table,
3050         const char *remote_client_name,
3051         const struct tsocket_address *remote_client_addr,
3052         const char *local_server_name,
3053         const struct tsocket_address *local_server_addr,
3054         const struct auth_session_info *session_info,
3055         struct rpc_pipe_client **presult)
3056 {
3057         struct rpc_pipe_client *result = NULL;
3058         struct pipe_auth_data *auth = NULL;
3059         const char *pipe_name = NULL;
3060         struct tstream_context *npa_stream = NULL;
3061         NTSTATUS status = NT_STATUS_NO_MEMORY;
3062         int ret;
3063
3064         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3065         if (result == NULL) {
3066                 goto fail;
3067         }
3068         result->abstract_syntax = table->syntax_id;
3069         result->transfer_syntax = ndr_transfer_syntax_ndr;
3070         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3071
3072         pipe_name = dcerpc_default_transport_endpoint(
3073                 result, NCACN_NP, table);
3074         if (pipe_name == NULL) {
3075                 DBG_DEBUG("dcerpc_default_transport_endpoint failed\n");
3076                 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3077                 goto fail;
3078         }
3079
3080         if (local_server_name == NULL) {
3081                 result->desthost = get_myname(result);
3082         } else {
3083                 result->desthost = talloc_strdup(result, local_server_name);
3084         }
3085         if (result->desthost == NULL) {
3086                 goto fail;
3087         }
3088         result->srv_name_slash = talloc_asprintf_strupper_m(
3089                 result, "\\\\%s", result->desthost);
3090         if (result->srv_name_slash == NULL) {
3091                 goto fail;
3092         }
3093
3094         ret = local_np_connect(
3095                 pipe_name,
3096                 NCALRPC,
3097                 remote_client_name,
3098                 remote_client_addr,
3099                 local_server_name,
3100                 local_server_addr,
3101                 session_info,
3102                 true,
3103                 result,
3104                 &npa_stream);
3105         if (ret != 0) {
3106                 DBG_DEBUG("local_np_connect for %s and "
3107                           "user %s\\%s failed: %s\n",
3108                           pipe_name,
3109                           session_info->info->domain_name,
3110                           session_info->info->account_name,
3111                           strerror(ret));
3112                 status = map_nt_error_from_unix(ret);
3113                 goto fail;
3114         }
3115
3116         status = rpc_transport_tstream_init(
3117                 result, &npa_stream, &result->transport);
3118         if (!NT_STATUS_IS_OK(status)) {
3119                 DBG_DEBUG("rpc_transport_tstream_init failed: %s\n",
3120                           nt_errstr(status));
3121                 goto fail;
3122         }
3123
3124         result->binding_handle = rpccli_bh_create(result, NULL, table);
3125         if (result->binding_handle == NULL) {
3126                 status = NT_STATUS_NO_MEMORY;
3127                 DBG_DEBUG("Failed to create binding handle.\n");
3128                 goto fail;
3129         }
3130
3131         status = rpccli_anon_bind_data(result, &auth);
3132         if (!NT_STATUS_IS_OK(status)) {
3133                 DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3134                           nt_errstr(status));
3135                 goto fail;
3136         }
3137
3138         status = rpc_pipe_bind(result, auth);
3139         if (!NT_STATUS_IS_OK(status)) {
3140                 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
3141                 goto fail;
3142         }
3143
3144         *presult = result;
3145         return NT_STATUS_OK;
3146
3147 fail:
3148         TALLOC_FREE(result);
3149         return status;
3150 }
3151
3152 struct rpc_pipe_client_np_ref {
3153         struct cli_state *cli;
3154         struct rpc_pipe_client *pipe;
3155 };
3156
3157 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3158 {
3159         DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3160         return 0;
3161 }
3162
3163 /****************************************************************************
3164  Open a named pipe over SMB to a remote server.
3165  *
3166  * CAVEAT CALLER OF THIS FUNCTION:
3167  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3168  *    so be sure that this function is called AFTER any structure (vs pointer)
3169  *    assignment of the cli.  In particular, libsmbclient does structure
3170  *    assignments of cli, which invalidates the data in the returned
3171  *    rpc_pipe_client if this function is called before the structure assignment
3172  *    of cli.
3173  *
3174  ****************************************************************************/
3175
3176 struct rpc_pipe_open_np_state {
3177         struct cli_state *cli;
3178         const struct ndr_interface_table *table;
3179         struct rpc_pipe_client *result;
3180 };
3181
3182 static void rpc_pipe_open_np_done(struct tevent_req *subreq);
3183
3184 struct tevent_req *rpc_pipe_open_np_send(
3185         TALLOC_CTX *mem_ctx,
3186         struct tevent_context *ev,
3187         struct cli_state *cli,
3188         const struct ndr_interface_table *table)
3189 {
3190         struct tevent_req *req = NULL, *subreq = NULL;
3191         struct rpc_pipe_open_np_state *state = NULL;
3192         struct rpc_pipe_client *result = NULL;
3193
3194         req = tevent_req_create(
3195                 mem_ctx, &state, struct rpc_pipe_open_np_state);
3196         if (req == NULL) {
3197                 return NULL;
3198         }
3199         state->cli = cli;
3200         state->table = table;
3201
3202         state->result = talloc_zero(state, struct rpc_pipe_client);
3203         if (tevent_req_nomem(state->result, req)) {
3204                 return tevent_req_post(req, ev);
3205         }
3206         result = state->result;
3207
3208         result->abstract_syntax = table->syntax_id;
3209         result->transfer_syntax = ndr_transfer_syntax_ndr;
3210
3211         result->desthost = talloc_strdup(
3212                 result, smbXcli_conn_remote_name(cli->conn));
3213         if (tevent_req_nomem(result->desthost, req)) {
3214                 return tevent_req_post(req, ev);
3215         }
3216
3217         result->srv_name_slash = talloc_asprintf_strupper_m(
3218                 result, "\\\\%s", result->desthost);
3219         if (tevent_req_nomem(result->srv_name_slash, req)) {
3220                 return tevent_req_post(req, ev);
3221         }
3222
3223         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3224
3225         subreq = rpc_transport_np_init_send(state, ev, cli, table);
3226         if (tevent_req_nomem(subreq, req)) {
3227                 return tevent_req_post(req, ev);
3228         }
3229         tevent_req_set_callback(subreq, rpc_pipe_open_np_done, req);
3230         return req;
3231 }
3232
3233 static void rpc_pipe_open_np_done(struct tevent_req *subreq)
3234 {
3235         struct tevent_req *req = tevent_req_callback_data(
3236                 subreq, struct tevent_req);
3237         struct rpc_pipe_open_np_state *state = tevent_req_data(
3238                 req, struct rpc_pipe_open_np_state);
3239         struct rpc_pipe_client *result = state->result;
3240         struct rpc_pipe_client_np_ref *np_ref = NULL;
3241         NTSTATUS status;
3242
3243         status = rpc_transport_np_init_recv(
3244                 subreq, result, &result->transport);
3245         TALLOC_FREE(subreq);
3246         if (tevent_req_nterror(req, status)) {
3247                 return;
3248         }
3249
3250         result->transport->transport = NCACN_NP;
3251
3252         np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3253         if (tevent_req_nomem(np_ref, req)) {
3254                 return;
3255         }
3256         np_ref->cli = state->cli;
3257         np_ref->pipe = result;
3258
3259         DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3260         talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3261
3262         result->binding_handle = rpccli_bh_create(result, NULL, state->table);
3263         if (tevent_req_nomem(result->binding_handle, req)) {
3264                 return;
3265         }
3266
3267         tevent_req_done(req);
3268 }
3269
3270 NTSTATUS rpc_pipe_open_np_recv(
3271         struct tevent_req *req,
3272         TALLOC_CTX *mem_ctx,
3273         struct rpc_pipe_client **_result)
3274 {
3275         struct rpc_pipe_open_np_state *state = tevent_req_data(
3276                 req, struct rpc_pipe_open_np_state);
3277         NTSTATUS status;
3278
3279         if (tevent_req_is_nterror(req, &status)) {
3280                 return status;
3281         }
3282         *_result = talloc_move(mem_ctx, &state->result);
3283         return NT_STATUS_OK;
3284 }
3285
3286 NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3287                           const struct ndr_interface_table *table,
3288                           struct rpc_pipe_client **presult)
3289 {
3290         struct tevent_context *ev = NULL;
3291         struct tevent_req *req = NULL;
3292         NTSTATUS status = NT_STATUS_NO_MEMORY;
3293
3294         ev = samba_tevent_context_init(cli);
3295         if (ev == NULL) {
3296                 goto fail;
3297         }
3298         req = rpc_pipe_open_np_send(ev, ev, cli, table);
3299         if (req == NULL) {
3300                 goto fail;
3301         }
3302         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3303                 goto fail;
3304         }
3305         status = rpc_pipe_open_np_recv(req, NULL, presult);
3306 fail:
3307         TALLOC_FREE(req);
3308         TALLOC_FREE(ev);
3309         return status;
3310 }
3311
3312 /****************************************************************************
3313  Open a pipe to a remote server.
3314  ****************************************************************************/
3315
3316 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3317                                   enum dcerpc_transport_t transport,
3318                                   const struct ndr_interface_table *table,
3319                                   const char *remote_name,
3320                                   const struct sockaddr_storage *remote_sockaddr,
3321                                   struct rpc_pipe_client **presult)
3322 {
3323         switch (transport) {
3324         case NCACN_IP_TCP:
3325                 return rpc_pipe_open_tcp(NULL,
3326                                          remote_name,
3327                                          remote_sockaddr,
3328                                          table, presult);
3329         case NCACN_NP:
3330                 return rpc_pipe_open_np(cli, table, presult);
3331         default:
3332                 return NT_STATUS_NOT_IMPLEMENTED;
3333         }
3334 }
3335
3336 /****************************************************************************
3337  Open a named pipe to an SMB server and bind anonymously.
3338  ****************************************************************************/
3339
3340 NTSTATUS cli_rpc_pipe_open_noauth_transport(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         struct rpc_pipe_client *result;
3348         struct pipe_auth_data *auth;
3349         NTSTATUS status;
3350
3351         status = cli_rpc_pipe_open(cli,
3352                                    transport,
3353                                    table,
3354                                    remote_name,
3355                                    remote_sockaddr,
3356                                    &result);
3357         if (!NT_STATUS_IS_OK(status)) {
3358                 return status;
3359         }
3360
3361         status = rpccli_anon_bind_data(result, &auth);
3362         if (!NT_STATUS_IS_OK(status)) {
3363                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3364                           nt_errstr(status)));
3365                 TALLOC_FREE(result);
3366                 return status;
3367         }
3368
3369         /*
3370          * This is a bit of an abstraction violation due to the fact that an
3371          * anonymous bind on an authenticated SMB inherits the user/domain
3372          * from the enclosing SMB creds
3373          */
3374
3375         if (transport == NCACN_NP) {
3376                 struct smbXcli_session *session;
3377
3378                 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
3379                         session = cli->smb2.session;
3380                 } else {
3381                         session = cli->smb1.session;
3382                 }
3383
3384                 status = smbXcli_session_application_key(session, auth,
3385                                                 &auth->transport_session_key);
3386                 if (!NT_STATUS_IS_OK(status)) {
3387                         auth->transport_session_key = data_blob_null;
3388                 }
3389         }
3390
3391         status = rpc_pipe_bind(result, auth);
3392         if (!NT_STATUS_IS_OK(status)) {
3393                 int lvl = 0;
3394                 if (ndr_syntax_id_equal(&table->syntax_id,
3395                                         &ndr_table_dssetup.syntax_id)) {
3396                         /* non AD domains just don't have this pipe, avoid
3397                          * level 0 statement in that case - gd */
3398                         lvl = 3;
3399                 }
3400                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3401                             "%s failed with error %s\n",
3402                             table->name,
3403                             nt_errstr(status) ));
3404                 TALLOC_FREE(result);
3405                 return status;
3406         }
3407
3408         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3409                   "%s and bound anonymously.\n",
3410                   table->name,
3411                   result->desthost));
3412
3413         *presult = result;
3414         return NT_STATUS_OK;
3415 }
3416
3417 /****************************************************************************
3418  ****************************************************************************/
3419
3420 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3421                                   const struct ndr_interface_table *table,
3422                                   struct rpc_pipe_client **presult)
3423 {
3424         const char *remote_name = smbXcli_conn_remote_name(cli->conn);
3425         const struct sockaddr_storage *remote_sockaddr =
3426                 smbXcli_conn_remote_sockaddr(cli->conn);
3427
3428         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3429                                                   table,
3430                                                   remote_name,
3431                                                   remote_sockaddr,
3432                                                   presult);
3433 }
3434
3435 /****************************************************************************
3436  Open a named pipe to an SMB server and bind using the mech specified
3437
3438  This routine references the creds pointer that is passed in
3439  ****************************************************************************/
3440
3441 NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
3442                                       const struct ndr_interface_table *table,
3443                                       enum dcerpc_transport_t transport,
3444                                       enum dcerpc_AuthType auth_type,
3445                                       enum dcerpc_AuthLevel auth_level,
3446                                       const char *server,
3447                                       const struct sockaddr_storage *remote_sockaddr,
3448                                       struct cli_credentials *creds,
3449                                       struct rpc_pipe_client **presult)
3450 {
3451         struct rpc_pipe_client *result;
3452         struct pipe_auth_data *auth = NULL;
3453         const char *target_service = table->authservices->names[0];
3454         NTSTATUS status;
3455
3456         status = cli_rpc_pipe_open(cli,
3457                                    transport,
3458                                    table,
3459                                    server,
3460                                    remote_sockaddr,
3461                                    &result);
3462         if (!NT_STATUS_IS_OK(status)) {
3463                 return status;
3464         }
3465
3466         status = rpccli_generic_bind_data_from_creds(result,
3467                                                      auth_type, auth_level,
3468                                                      server, target_service,
3469                                                      creds,
3470                                                      &auth);
3471         if (!NT_STATUS_IS_OK(status)) {
3472                 DBG_ERR("rpccli_generic_bind_data_from_creds returned %s\n",
3473                         nt_errstr(status));
3474                 goto err;
3475         }
3476
3477         status = rpc_pipe_bind(result, auth);
3478         if (!NT_STATUS_IS_OK(status)) {
3479                 DBG_ERR("cli_rpc_pipe_bind failed with error %s\n",
3480                         nt_errstr(status));
3481                 goto err;
3482         }
3483
3484         DBG_DEBUG("opened pipe %s to machine %s and bound as user %s.\n",
3485                   table->name,
3486                   result->desthost,
3487                   cli_credentials_get_unparsed_name(creds, talloc_tos()));
3488
3489         *presult = result;
3490         return NT_STATUS_OK;
3491
3492   err:
3493
3494         TALLOC_FREE(result);
3495         return status;
3496 }
3497
3498 NTSTATUS cli_rpc_pipe_open_bind_schannel(
3499         struct cli_state *cli,
3500         const struct ndr_interface_table *table,
3501         enum dcerpc_transport_t transport,
3502         struct netlogon_creds_cli_context *netlogon_creds,
3503         const char *remote_name,
3504         const struct sockaddr_storage *remote_sockaddr,
3505         struct rpc_pipe_client **_rpccli)
3506 {
3507         struct rpc_pipe_client *rpccli;
3508         struct pipe_auth_data *rpcauth;
3509         const char *target_service = table->authservices->names[0];
3510         struct cli_credentials *cli_creds;
3511         enum dcerpc_AuthLevel auth_level;
3512         NTSTATUS status;
3513
3514         status = cli_rpc_pipe_open(cli,
3515                                    transport,
3516                                    table,
3517                                    remote_name,
3518                                    remote_sockaddr,
3519                                    &rpccli);
3520         if (!NT_STATUS_IS_OK(status)) {
3521                 return status;
3522         }
3523
3524         auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
3525
3526         status = netlogon_creds_bind_cli_credentials(
3527                 netlogon_creds, rpccli, &cli_creds);
3528         if (!NT_STATUS_IS_OK(status)) {
3529                 DBG_DEBUG("netlogon_creds_bind_cli_credentials failed: %s\n",
3530                           nt_errstr(status));
3531                 TALLOC_FREE(rpccli);
3532                 return status;
3533         }
3534
3535         status = rpccli_generic_bind_data_from_creds(rpccli,
3536                                                      DCERPC_AUTH_TYPE_SCHANNEL,
3537                                                      auth_level,
3538                                                      rpccli->desthost,
3539                                                      target_service,
3540                                                      cli_creds,
3541                                                      &rpcauth);
3542         if (!NT_STATUS_IS_OK(status)) {
3543                 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
3544                           nt_errstr(status)));
3545                 TALLOC_FREE(rpccli);
3546                 return status;
3547         }
3548
3549         status = rpc_pipe_bind(rpccli, rpcauth);
3550
3551         /* No TALLOC_FREE, gensec takes references */
3552         talloc_unlink(rpccli, cli_creds);
3553         cli_creds = NULL;
3554
3555         if (!NT_STATUS_IS_OK(status)) {
3556                 DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
3557                           nt_errstr(status));
3558                 TALLOC_FREE(rpccli);
3559                 return status;
3560         }
3561
3562         *_rpccli = rpccli;
3563
3564         return NT_STATUS_OK;
3565 }
3566
3567 NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
3568                                                const struct ndr_interface_table *table,
3569                                                enum dcerpc_transport_t transport,
3570                                                struct netlogon_creds_cli_context *netlogon_creds,
3571                                                const char *remote_name,
3572                                                const struct sockaddr_storage *remote_sockaddr,
3573                                                struct rpc_pipe_client **_rpccli)
3574 {
3575         TALLOC_CTX *frame = talloc_stackframe();
3576         struct rpc_pipe_client *rpccli;
3577         struct netlogon_creds_cli_lck *lck;
3578         NTSTATUS status;
3579
3580         status = netlogon_creds_cli_lck(
3581                 netlogon_creds, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE,
3582                 frame, &lck);
3583         if (!NT_STATUS_IS_OK(status)) {
3584                 DBG_WARNING("netlogon_creds_cli_lck returned %s\n",
3585                             nt_errstr(status));
3586                 TALLOC_FREE(frame);
3587                 return status;
3588         }
3589
3590         status = cli_rpc_pipe_open_bind_schannel(cli,
3591                                                  table,
3592                                                  transport,
3593                                                  netlogon_creds,
3594                                                  remote_name,
3595                                                  remote_sockaddr,
3596                                                  &rpccli);
3597         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3598                 netlogon_creds_cli_delete_lck(netlogon_creds);
3599         }
3600         if (!NT_STATUS_IS_OK(status)) {
3601                 DBG_DEBUG("cli_rpc_pipe_open_bind_schannel failed: %s\n",
3602                           nt_errstr(status));
3603                 TALLOC_FREE(frame);
3604                 return status;
3605         }
3606
3607         if (ndr_syntax_id_equal(&table->syntax_id,
3608                                 &ndr_table_netlogon.syntax_id)) {
3609                 status = netlogon_creds_cli_check(netlogon_creds,
3610                                                   rpccli->binding_handle,
3611                                                   NULL);
3612                 if (!NT_STATUS_IS_OK(status)) {
3613                         DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3614                                   nt_errstr(status)));
3615                         TALLOC_FREE(frame);
3616                         return status;
3617                 }
3618         }
3619
3620         DBG_DEBUG("opened pipe %s to machine %s with key %s "
3621                   "and bound using schannel.\n",
3622                   table->name, rpccli->desthost,
3623                   netlogon_creds_cli_debug_string(netlogon_creds, lck));
3624
3625         TALLOC_FREE(frame);
3626
3627         *_rpccli = rpccli;
3628         return NT_STATUS_OK;
3629 }
3630
3631 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3632                              struct rpc_pipe_client *cli,
3633                              DATA_BLOB *session_key)
3634 {
3635         NTSTATUS status;
3636         struct pipe_auth_data *a;
3637         struct gensec_security *gensec_security;
3638         DATA_BLOB sk = { .data = NULL };
3639         bool make_dup = false;
3640
3641         if (!session_key || !cli) {
3642                 return NT_STATUS_INVALID_PARAMETER;
3643         }
3644
3645         a = cli->auth;
3646
3647         if (a == NULL) {
3648                 return NT_STATUS_INVALID_PARAMETER;
3649         }
3650
3651         switch (cli->auth->auth_type) {
3652         case DCERPC_AUTH_TYPE_NONE:
3653                 sk = data_blob_const(a->transport_session_key.data,
3654                                      a->transport_session_key.length);
3655                 make_dup = true;
3656                 break;
3657         default:
3658                 gensec_security = a->auth_ctx;
3659                 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3660                 if (!NT_STATUS_IS_OK(status)) {
3661                         return status;
3662                 }
3663                 make_dup = false;
3664                 break;
3665         }
3666
3667         if (!sk.data) {
3668                 return NT_STATUS_NO_USER_SESSION_KEY;
3669         }
3670
3671         if (make_dup) {
3672                 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3673         } else {
3674                 *session_key = sk;
3675         }
3676
3677         return NT_STATUS_OK;
3678 }