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