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