s3-dcerpc: Add SPNEGO incapsulation for KRB5 auth
[metze/samba/wip.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                 switch (auth->spnego_type) {
1251                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1252                         ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli,
1253                                                         auth->auth_level,
1254                                                         &auth_info);
1255                         break;
1256
1257                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1258                         ret = create_spnego_auth_bind_req(cli, auth,
1259                                                           &auth_info);
1260                         break;
1261                 default:
1262                         return NT_STATUS_INTERNAL_ERROR;
1263                 }
1264                 if (!NT_STATUS_IS_OK(ret)) {
1265                         return ret;
1266                 }
1267                 break;
1268
1269         case DCERPC_AUTH_TYPE_KRB5:
1270                 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_info);
1271                 if (!NT_STATUS_IS_OK(ret)) {
1272                         return ret;
1273                 }
1274                 break;
1275
1276         case DCERPC_AUTH_TYPE_NONE:
1277                 break;
1278
1279         default:
1280                 /* "Can't" happen. */
1281                 return NT_STATUS_INVALID_INFO_CLASS;
1282         }
1283
1284         ret = create_bind_or_alt_ctx_internal(mem_ctx,
1285                                               DCERPC_PKT_BIND,
1286                                               rpc_call_id,
1287                                               abstract,
1288                                               transfer,
1289                                               &auth_info,
1290                                               rpc_out);
1291         return ret;
1292 }
1293
1294 /*******************************************************************
1295  Calculate how much data we're going to send in this packet, also
1296  work out any sign/seal padding length.
1297  ********************************************************************/
1298
1299 static NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli,
1300                                           uint32_t data_left,
1301                                           uint32_t *data_to_send,
1302                                           uint16_t *p_frag_len,
1303                                           uint16_t *p_auth_len,
1304                                           uint32_t *p_ss_padding)
1305 {
1306         uint32_t data_space, data_len;
1307         size_t max_len;
1308
1309         switch (cli->auth->auth_level) {
1310         case DCERPC_AUTH_LEVEL_NONE:
1311         case DCERPC_AUTH_LEVEL_CONNECT:
1312         case DCERPC_AUTH_LEVEL_PACKET:
1313                 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1314                 data_len = MIN(data_space, data_left);
1315                 *p_ss_padding = 0;
1316                 *p_auth_len = 0;
1317                 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1318                 *data_to_send = data_len;
1319                 return NT_STATUS_OK;
1320
1321         case DCERPC_AUTH_LEVEL_INTEGRITY:
1322         case DCERPC_AUTH_LEVEL_PRIVACY:
1323                 max_len = cli->max_xmit_frag
1324                                 - DCERPC_REQUEST_LENGTH
1325                                 - DCERPC_AUTH_TRAILER_LENGTH;
1326
1327                 /* Treat the same for all authenticated rpc requests. */
1328                 switch(cli->auth->auth_type) {
1329                 case DCERPC_AUTH_TYPE_SPNEGO:
1330                         switch (cli->auth->spnego_type) {
1331                         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1332                                 *p_auth_len = NTLMSSP_SIG_SIZE;
1333                                 break;
1334                         case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1335                                 *p_auth_len = 0; /* TODO */
1336                                 break;
1337                         default:
1338                                 return NT_STATUS_INVALID_PARAMETER;
1339                         }
1340                 case DCERPC_AUTH_TYPE_NTLMSSP:
1341                         *p_auth_len = NTLMSSP_SIG_SIZE;
1342                         break;
1343                 case DCERPC_AUTH_TYPE_SCHANNEL:
1344                         *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1345                         break;
1346                 case DCERPC_AUTH_TYPE_KRB5:
1347                         *p_auth_len = gse_get_signature_length(
1348                                         cli->auth->a_u.gssapi_state,
1349                                         (cli->auth->auth_level ==
1350                                                 DCERPC_AUTH_LEVEL_PRIVACY),
1351                                         max_len);
1352                         break;
1353                 default:
1354                         return NT_STATUS_INVALID_PARAMETER;
1355                 }
1356
1357                 data_space = max_len - *p_auth_len;
1358
1359                 data_len = MIN(data_space, data_left);
1360                 *p_ss_padding = 0;
1361                 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1362                         *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1363                 }
1364                 *p_frag_len = DCERPC_REQUEST_LENGTH
1365                                 + data_len + *p_ss_padding
1366                                 + DCERPC_AUTH_TRAILER_LENGTH
1367                                 + *p_auth_len;
1368                 *data_to_send = data_len;
1369                 return NT_STATUS_OK;
1370
1371         default:
1372                 break;
1373         }
1374
1375         return NT_STATUS_INVALID_PARAMETER;
1376 }
1377
1378 /*******************************************************************
1379  External interface.
1380  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1381  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1382  and deals with signing/sealing details.
1383  ********************************************************************/
1384
1385 struct rpc_api_pipe_req_state {
1386         struct event_context *ev;
1387         struct rpc_pipe_client *cli;
1388         uint8_t op_num;
1389         uint32_t call_id;
1390         DATA_BLOB *req_data;
1391         uint32_t req_data_sent;
1392         DATA_BLOB rpc_out;
1393         DATA_BLOB reply_pdu;
1394 };
1395
1396 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1397 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1398 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1399                                   bool *is_last_frag);
1400
1401 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1402                                          struct event_context *ev,
1403                                          struct rpc_pipe_client *cli,
1404                                          uint8_t op_num,
1405                                          DATA_BLOB *req_data)
1406 {
1407         struct tevent_req *req, *subreq;
1408         struct rpc_api_pipe_req_state *state;
1409         NTSTATUS status;
1410         bool is_last_frag;
1411
1412         req = tevent_req_create(mem_ctx, &state,
1413                                 struct rpc_api_pipe_req_state);
1414         if (req == NULL) {
1415                 return NULL;
1416         }
1417         state->ev = ev;
1418         state->cli = cli;
1419         state->op_num = op_num;
1420         state->req_data = req_data;
1421         state->req_data_sent = 0;
1422         state->call_id = get_rpc_call_id();
1423         state->reply_pdu = data_blob_null;
1424         state->rpc_out = data_blob_null;
1425
1426         if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1427                                         + RPC_MAX_SIGN_SIZE) {
1428                 /* Server is screwed up ! */
1429                 status = NT_STATUS_INVALID_PARAMETER;
1430                 goto post_status;
1431         }
1432
1433         status = prepare_next_frag(state, &is_last_frag);
1434         if (!NT_STATUS_IS_OK(status)) {
1435                 goto post_status;
1436         }
1437
1438         if (is_last_frag) {
1439                 subreq = rpc_api_pipe_send(state, ev, state->cli,
1440                                            &state->rpc_out,
1441                                            DCERPC_PKT_RESPONSE);
1442                 if (subreq == NULL) {
1443                         goto fail;
1444                 }
1445                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1446         } else {
1447                 subreq = rpc_write_send(state, ev, cli->transport,
1448                                         state->rpc_out.data,
1449                                         state->rpc_out.length);
1450                 if (subreq == NULL) {
1451                         goto fail;
1452                 }
1453                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1454                                         req);
1455         }
1456         return req;
1457
1458  post_status:
1459         tevent_req_nterror(req, status);
1460         return tevent_req_post(req, ev);
1461  fail:
1462         TALLOC_FREE(req);
1463         return NULL;
1464 }
1465
1466 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1467                                   bool *is_last_frag)
1468 {
1469         uint32_t data_sent_thistime;
1470         uint16_t auth_len;
1471         uint16_t frag_len;
1472         uint8_t flags = 0;
1473         uint32_t pad_len;
1474         uint32_t data_left;
1475         NTSTATUS status;
1476         union dcerpc_payload u;
1477
1478         data_left = state->req_data->length - state->req_data_sent;
1479
1480         status = calculate_data_len_tosend(state->cli, data_left,
1481                                            &data_sent_thistime,
1482                                            &frag_len, &auth_len,
1483                                            &pad_len);
1484         if (!NT_STATUS_IS_OK(status)) {
1485                 return status;
1486         }
1487
1488         if (state->req_data_sent == 0) {
1489                 flags = DCERPC_PFC_FLAG_FIRST;
1490         }
1491
1492         if (data_sent_thistime == data_left) {
1493                 flags |= DCERPC_PFC_FLAG_LAST;
1494         }
1495
1496         data_blob_free(&state->rpc_out);
1497
1498         ZERO_STRUCT(u.request);
1499
1500         u.request.alloc_hint    = state->req_data->length;
1501         u.request.context_id    = 0;
1502         u.request.opnum         = state->op_num;
1503
1504         status = dcerpc_push_ncacn_packet(state,
1505                                           DCERPC_PKT_REQUEST,
1506                                           flags,
1507                                           auth_len,
1508                                           state->call_id,
1509                                           &u,
1510                                           &state->rpc_out);
1511         if (!NT_STATUS_IS_OK(status)) {
1512                 return status;
1513         }
1514
1515         /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1516          * compute it right for requests because the auth trailer is missing
1517          * at this stage */
1518         dcerpc_set_frag_length(&state->rpc_out, frag_len);
1519
1520         /* Copy in the data. */
1521         if (!data_blob_append(NULL, &state->rpc_out,
1522                                 state->req_data->data + state->req_data_sent,
1523                                 data_sent_thistime)) {
1524                 return NT_STATUS_NO_MEMORY;
1525         }
1526
1527         switch (state->cli->auth->auth_level) {
1528         case DCERPC_AUTH_LEVEL_NONE:
1529         case DCERPC_AUTH_LEVEL_CONNECT:
1530         case DCERPC_AUTH_LEVEL_PACKET:
1531                 break;
1532         case DCERPC_AUTH_LEVEL_INTEGRITY:
1533         case DCERPC_AUTH_LEVEL_PRIVACY:
1534                 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1535                                                 &state->rpc_out);
1536                 if (!NT_STATUS_IS_OK(status)) {
1537                         return status;
1538                 }
1539                 break;
1540         default:
1541                 return NT_STATUS_INVALID_PARAMETER;
1542         }
1543
1544         state->req_data_sent += data_sent_thistime;
1545         *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1546
1547         return status;
1548 }
1549
1550 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1551 {
1552         struct tevent_req *req = tevent_req_callback_data(
1553                 subreq, struct tevent_req);
1554         struct rpc_api_pipe_req_state *state = tevent_req_data(
1555                 req, struct rpc_api_pipe_req_state);
1556         NTSTATUS status;
1557         bool is_last_frag;
1558
1559         status = rpc_write_recv(subreq);
1560         TALLOC_FREE(subreq);
1561         if (!NT_STATUS_IS_OK(status)) {
1562                 tevent_req_nterror(req, status);
1563                 return;
1564         }
1565
1566         status = prepare_next_frag(state, &is_last_frag);
1567         if (!NT_STATUS_IS_OK(status)) {
1568                 tevent_req_nterror(req, status);
1569                 return;
1570         }
1571
1572         if (is_last_frag) {
1573                 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1574                                            &state->rpc_out,
1575                                            DCERPC_PKT_RESPONSE);
1576                 if (tevent_req_nomem(subreq, req)) {
1577                         return;
1578                 }
1579                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1580         } else {
1581                 subreq = rpc_write_send(state, state->ev,
1582                                         state->cli->transport,
1583                                         state->rpc_out.data,
1584                                         state->rpc_out.length);
1585                 if (tevent_req_nomem(subreq, req)) {
1586                         return;
1587                 }
1588                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1589                                         req);
1590         }
1591 }
1592
1593 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1594 {
1595         struct tevent_req *req = tevent_req_callback_data(
1596                 subreq, struct tevent_req);
1597         struct rpc_api_pipe_req_state *state = tevent_req_data(
1598                 req, struct rpc_api_pipe_req_state);
1599         NTSTATUS status;
1600
1601         status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1602         TALLOC_FREE(subreq);
1603         if (!NT_STATUS_IS_OK(status)) {
1604                 tevent_req_nterror(req, status);
1605                 return;
1606         }
1607         tevent_req_done(req);
1608 }
1609
1610 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1611                                DATA_BLOB *reply_pdu)
1612 {
1613         struct rpc_api_pipe_req_state *state = tevent_req_data(
1614                 req, struct rpc_api_pipe_req_state);
1615         NTSTATUS status;
1616
1617         if (tevent_req_is_nterror(req, &status)) {
1618                 /*
1619                  * We always have to initialize to reply pdu, even if there is
1620                  * none. The rpccli_* caller routines expect this.
1621                  */
1622                 *reply_pdu = data_blob_null;
1623                 return status;
1624         }
1625
1626         /* return data to caller and assign it ownership of memory */
1627         reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1628         reply_pdu->length = state->reply_pdu.length;
1629         state->reply_pdu.length = 0;
1630
1631         return NT_STATUS_OK;
1632 }
1633
1634 #if 0
1635 /****************************************************************************
1636  Set the handle state.
1637 ****************************************************************************/
1638
1639 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1640                                    const char *pipe_name, uint16 device_state)
1641 {
1642         bool state_set = False;
1643         char param[2];
1644         uint16 setup[2]; /* only need 2 uint16 setup parameters */
1645         char *rparam = NULL;
1646         char *rdata = NULL;
1647         uint32 rparam_len, rdata_len;
1648
1649         if (pipe_name == NULL)
1650                 return False;
1651
1652         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1653                  cli->fnum, pipe_name, device_state));
1654
1655         /* create parameters: device state */
1656         SSVAL(param, 0, device_state);
1657
1658         /* create setup parameters. */
1659         setup[0] = 0x0001; 
1660         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
1661
1662         /* send the data on \PIPE\ */
1663         if (cli_api_pipe(cli->cli, "\\PIPE\\",
1664                     setup, 2, 0,                /* setup, length, max */
1665                     param, 2, 0,                /* param, length, max */
1666                     NULL, 0, 1024,              /* data, length, max */
1667                     &rparam, &rparam_len,        /* return param, length */
1668                     &rdata, &rdata_len))         /* return data, length */
1669         {
1670                 DEBUG(5, ("Set Handle state: return OK\n"));
1671                 state_set = True;
1672         }
1673
1674         SAFE_FREE(rparam);
1675         SAFE_FREE(rdata);
1676
1677         return state_set;
1678 }
1679 #endif
1680
1681 /****************************************************************************
1682  Check the rpc bind acknowledge response.
1683 ****************************************************************************/
1684
1685 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1686                                 const struct ndr_syntax_id *transfer)
1687 {
1688         struct dcerpc_ack_ctx ctx;
1689
1690         if (r->secondary_address_size == 0) {
1691                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1692         }
1693
1694         if (r->num_results < 1 || !r->ctx_list) {
1695                 return false;
1696         }
1697
1698         ctx = r->ctx_list[0];
1699
1700         /* check the transfer syntax */
1701         if ((ctx.syntax.if_version != transfer->if_version) ||
1702              (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1703                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1704                 return False;
1705         }
1706
1707         if (r->num_results != 0x1 || ctx.result != 0) {
1708                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1709                           r->num_results, ctx.reason));
1710         }
1711
1712         DEBUG(5,("check_bind_response: accepted!\n"));
1713         return True;
1714 }
1715
1716 /*******************************************************************
1717  Creates a DCE/RPC bind authentication response.
1718  This is the packet that is sent back to the server once we
1719  have received a BIND-ACK, to finish the third leg of
1720  the authentication handshake.
1721  ********************************************************************/
1722
1723 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1724                                 struct rpc_pipe_client *cli,
1725                                 uint32 rpc_call_id,
1726                                 enum dcerpc_AuthType auth_type,
1727                                 enum dcerpc_AuthLevel auth_level,
1728                                 DATA_BLOB *pauth_blob,
1729                                 DATA_BLOB *rpc_out)
1730 {
1731         NTSTATUS status;
1732         union dcerpc_payload u;
1733
1734         u.auth3._pad = 0;
1735
1736         status = dcerpc_push_dcerpc_auth(mem_ctx,
1737                                          auth_type,
1738                                          auth_level,
1739                                          0, /* auth_pad_length */
1740                                          1, /* auth_context_id */
1741                                          pauth_blob,
1742                                          &u.auth3.auth_info);
1743         if (!NT_STATUS_IS_OK(status)) {
1744                 return status;
1745         }
1746
1747         status = dcerpc_push_ncacn_packet(mem_ctx,
1748                                           DCERPC_PKT_AUTH3,
1749                                           DCERPC_PFC_FLAG_FIRST |
1750                                           DCERPC_PFC_FLAG_LAST,
1751                                           pauth_blob->length,
1752                                           rpc_call_id,
1753                                           &u,
1754                                           rpc_out);
1755         data_blob_free(&u.auth3.auth_info);
1756         if (!NT_STATUS_IS_OK(status)) {
1757                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1758                 return status;
1759         }
1760
1761         return NT_STATUS_OK;
1762 }
1763
1764 /*******************************************************************
1765  Creates a DCE/RPC bind alter context authentication request which
1766  may contain a spnego auth blobl
1767  ********************************************************************/
1768
1769 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1770                                         enum dcerpc_AuthType auth_type,
1771                                         enum dcerpc_AuthLevel auth_level,
1772                                         uint32 rpc_call_id,
1773                                         const struct ndr_syntax_id *abstract,
1774                                         const struct ndr_syntax_id *transfer,
1775                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1776                                         DATA_BLOB *rpc_out)
1777 {
1778         DATA_BLOB auth_info;
1779         NTSTATUS status;
1780
1781         status = dcerpc_push_dcerpc_auth(mem_ctx,
1782                                          auth_type,
1783                                          auth_level,
1784                                          0, /* auth_pad_length */
1785                                          1, /* auth_context_id */
1786                                          pauth_blob,
1787                                          &auth_info);
1788         if (!NT_STATUS_IS_OK(status)) {
1789                 return status;
1790         }
1791
1792         status = create_bind_or_alt_ctx_internal(mem_ctx,
1793                                                  DCERPC_PKT_ALTER,
1794                                                  rpc_call_id,
1795                                                  abstract,
1796                                                  transfer,
1797                                                  &auth_info,
1798                                                  rpc_out);
1799         data_blob_free(&auth_info);
1800         return status;
1801 }
1802
1803 /****************************************************************************
1804  Do an rpc bind.
1805 ****************************************************************************/
1806
1807 struct rpc_pipe_bind_state {
1808         struct event_context *ev;
1809         struct rpc_pipe_client *cli;
1810         DATA_BLOB rpc_out;
1811         uint32_t rpc_call_id;
1812 };
1813
1814 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1815 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1816                                            struct rpc_pipe_bind_state *state,
1817                                            DATA_BLOB *credentials);
1818 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1819 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1820                                         struct rpc_pipe_bind_state *state,
1821                                         DATA_BLOB *credentials);
1822 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1823 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1824                                    struct rpc_pipe_bind_state *state,
1825                                    DATA_BLOB *credentials);
1826 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1827                                      struct rpc_pipe_bind_state *state,
1828                                      DATA_BLOB *credentials);
1829
1830 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1831                                       struct event_context *ev,
1832                                       struct rpc_pipe_client *cli,
1833                                       struct pipe_auth_data *auth)
1834 {
1835         struct tevent_req *req, *subreq;
1836         struct rpc_pipe_bind_state *state;
1837         NTSTATUS status;
1838
1839         req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1840         if (req == NULL) {
1841                 return NULL;
1842         }
1843
1844         DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1845                 rpccli_pipe_txt(talloc_tos(), cli),
1846                 (unsigned int)auth->auth_type,
1847                 (unsigned int)auth->spnego_type,
1848                 (unsigned int)auth->auth_level ));
1849
1850         state->ev = ev;
1851         state->cli = cli;
1852         state->rpc_call_id = get_rpc_call_id();
1853         state->rpc_out = data_blob_null;
1854
1855         cli->auth = talloc_move(cli, &auth);
1856
1857         /* Marshall the outgoing data. */
1858         status = create_rpc_bind_req(state, cli,
1859                                      cli->auth,
1860                                      state->rpc_call_id,
1861                                      &cli->abstract_syntax,
1862                                      &cli->transfer_syntax,
1863                                      &state->rpc_out);
1864
1865         if (!NT_STATUS_IS_OK(status)) {
1866                 goto post_status;
1867         }
1868
1869         subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1870                                    DCERPC_PKT_BIND_ACK);
1871         if (subreq == NULL) {
1872                 goto fail;
1873         }
1874         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1875         return req;
1876
1877  post_status:
1878         tevent_req_nterror(req, status);
1879         return tevent_req_post(req, ev);
1880  fail:
1881         TALLOC_FREE(req);
1882         return NULL;
1883 }
1884
1885 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1886 {
1887         struct tevent_req *req = tevent_req_callback_data(
1888                 subreq, struct tevent_req);
1889         struct rpc_pipe_bind_state *state = tevent_req_data(
1890                 req, struct rpc_pipe_bind_state);
1891         struct pipe_auth_data *pauth = state->cli->auth;
1892         DATA_BLOB reply_pdu;
1893         struct ncacn_packet *pkt;
1894         struct dcerpc_auth auth;
1895         DATA_BLOB auth_token = data_blob_null;
1896         NTSTATUS status;
1897
1898         status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1899         TALLOC_FREE(subreq);
1900         if (!NT_STATUS_IS_OK(status)) {
1901                 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1902                           rpccli_pipe_txt(talloc_tos(), state->cli),
1903                           nt_errstr(status)));
1904                 tevent_req_nterror(req, status);
1905                 return;
1906         }
1907
1908         if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1909                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1910                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1911                 return;
1912         }
1913
1914         state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1915         state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1916
1917         switch(state->cli->auth->auth_type) {
1918
1919         case DCERPC_AUTH_TYPE_NONE:
1920         case DCERPC_AUTH_TYPE_SCHANNEL:
1921                 /* Bind complete. */
1922                 tevent_req_done(req);
1923                 return;
1924
1925         case DCERPC_AUTH_TYPE_NTLMSSP:
1926         case DCERPC_AUTH_TYPE_SPNEGO:
1927         case DCERPC_AUTH_TYPE_KRB5:
1928                 /* Paranoid lenght checks */
1929                 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1930                                                 + pkt->auth_length) {
1931                         tevent_req_nterror(req,
1932                                         NT_STATUS_INFO_LENGTH_MISMATCH);
1933                         return;
1934                 }
1935                 /* get auth credentials */
1936                 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1937                                                  &pkt->u.bind_ack.auth_info,
1938                                                  &auth, false);
1939                 if (!NT_STATUS_IS_OK(status)) {
1940                         DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1941                                   nt_errstr(status)));
1942                         tevent_req_nterror(req, status);
1943                         return;
1944                 }
1945                 break;
1946
1947         default:
1948                 goto err_out;
1949         }
1950
1951         /*
1952          * For authenticated binds we may need to do 3 or 4 leg binds.
1953          */
1954
1955         switch(state->cli->auth->auth_type) {
1956
1957         case DCERPC_AUTH_TYPE_NONE:
1958         case DCERPC_AUTH_TYPE_SCHANNEL:
1959                 /* Bind complete. */
1960                 tevent_req_done(req);
1961                 return;
1962
1963         case DCERPC_AUTH_TYPE_NTLMSSP:
1964                 /* Need to send AUTH3 packet - no reply. */
1965                 status = rpc_finish_auth3_bind_send(req, state,
1966                                                     &auth.credentials);
1967                 break;
1968
1969         case DCERPC_AUTH_TYPE_SPNEGO:
1970                 switch (pauth->spnego_type) {
1971                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1972                         /* Need to send alter context request and reply. */
1973                         status = rpc_finish_spnego_ntlmssp_bind_send(req,
1974                                                 state, &auth.credentials);
1975                         break;
1976
1977                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1978                         status = spnego_get_client_auth_token(state,
1979                                                 pauth->a_u.spnego_state,
1980                                                 &auth.credentials,
1981                                                 &auth_token);
1982                         if (!NT_STATUS_IS_OK(status)) {
1983                                 break;
1984                         }
1985                         if (auth_token.length == 0) {
1986                                 /* Bind complete. */
1987                                 tevent_req_done(req);
1988                                 return;
1989                         }
1990                         if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
1991                                 status = rpc_bind_next_send(req, state,
1992                                                                 &auth_token);
1993                         } else {
1994                                 status = rpc_bind_finish_send(req, state,
1995                                                                 &auth_token);
1996                         }
1997                         break;
1998                 default:
1999                         status = NT_STATUS_INTERNAL_ERROR;
2000                 }
2001                 break;
2002
2003         case DCERPC_AUTH_TYPE_KRB5:
2004                 status = gse_get_client_auth_token(state,
2005                                                    pauth->a_u.gssapi_state,
2006                                                    &auth.credentials,
2007                                                    &auth_token);
2008                 if (!NT_STATUS_IS_OK(status)) {
2009                         break;
2010                 }
2011
2012                 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
2013                         status = rpc_bind_next_send(req, state, &auth_token);
2014                 } else {
2015                         status = rpc_bind_finish_send(req, state, &auth_token);
2016                 }
2017                 break;
2018
2019         default:
2020                 goto err_out;
2021         }
2022
2023         if (!NT_STATUS_IS_OK(status)) {
2024                 tevent_req_nterror(req, status);
2025         }
2026         return;
2027
2028 err_out:
2029         DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
2030                  (unsigned int)state->cli->auth->auth_type,
2031                  (unsigned int)state->cli->auth->spnego_type));
2032         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2033 }
2034
2035 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2036                                            struct rpc_pipe_bind_state *state,
2037                                            DATA_BLOB *credentials)
2038 {
2039         struct pipe_auth_data *auth = state->cli->auth;
2040         DATA_BLOB client_reply = data_blob_null;
2041         struct tevent_req *subreq;
2042         NTSTATUS status;
2043
2044         /* TODO - check auth_type/auth_level match. */
2045
2046         status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2047                                      *credentials, &client_reply);
2048
2049         if (!NT_STATUS_IS_OK(status)) {
2050                 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2051                           "blob failed: %s.\n", nt_errstr(status)));
2052                 return status;
2053         }
2054
2055         data_blob_free(&state->rpc_out);
2056
2057         status = create_rpc_bind_auth3(state, state->cli,
2058                                         state->rpc_call_id,
2059                                         auth->auth_type,
2060                                         auth->auth_level,
2061                                         &client_reply,
2062                                         &state->rpc_out);
2063         data_blob_free(&client_reply);
2064
2065         if (!NT_STATUS_IS_OK(status)) {
2066                 return status;
2067         }
2068
2069         subreq = rpc_write_send(state, state->ev, state->cli->transport,
2070                                 state->rpc_out.data, state->rpc_out.length);
2071         if (subreq == NULL) {
2072                 return NT_STATUS_NO_MEMORY;
2073         }
2074         tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2075         return NT_STATUS_OK;
2076 }
2077
2078 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2079 {
2080         struct tevent_req *req = tevent_req_callback_data(
2081                 subreq, struct tevent_req);
2082         NTSTATUS status;
2083
2084         status = rpc_write_recv(subreq);
2085         TALLOC_FREE(subreq);
2086         if (!NT_STATUS_IS_OK(status)) {
2087                 tevent_req_nterror(req, status);
2088                 return;
2089         }
2090         tevent_req_done(req);
2091 }
2092
2093 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2094                                         struct rpc_pipe_bind_state *state,
2095                                         DATA_BLOB *credentials)
2096 {
2097         struct pipe_auth_data *auth = state->cli->auth;
2098         DATA_BLOB server_ntlm_response = data_blob_null;
2099         DATA_BLOB client_reply = data_blob_null;
2100         DATA_BLOB tmp_blob = data_blob_null;
2101         struct tevent_req *subreq;
2102         NTSTATUS status;
2103
2104         /*
2105          * The server might give us back two challenges - tmp_blob is for the
2106          * second.
2107          */
2108         if (!spnego_parse_challenge(state, *credentials,
2109                                     &server_ntlm_response,
2110                                     &tmp_blob)) {
2111                 data_blob_free(&server_ntlm_response);
2112                 data_blob_free(&tmp_blob);
2113                 return NT_STATUS_INVALID_PARAMETER;
2114         }
2115
2116         /* We're finished with the server spnego response and the tmp_blob. */
2117         data_blob_free(&tmp_blob);
2118
2119         status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2120                                      server_ntlm_response, &client_reply);
2121
2122         /* Finished with the server_ntlm response */
2123         data_blob_free(&server_ntlm_response);
2124
2125         if (!NT_STATUS_IS_OK(status)) {
2126                 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2127                           "using server blob failed.\n"));
2128                 data_blob_free(&client_reply);
2129                 return status;
2130         }
2131
2132         /* SPNEGO wrap the client reply. */
2133         tmp_blob = spnego_gen_auth(state, client_reply);
2134         data_blob_free(&client_reply);
2135         client_reply = tmp_blob;
2136         tmp_blob = data_blob_null;
2137
2138         /* Now prepare the alter context pdu. */
2139         data_blob_free(&state->rpc_out);
2140
2141         status = create_rpc_alter_context(state,
2142                                           auth->auth_type,
2143                                           auth->auth_level,
2144                                           state->rpc_call_id,
2145                                           &state->cli->abstract_syntax,
2146                                           &state->cli->transfer_syntax,
2147                                           &client_reply,
2148                                           &state->rpc_out);
2149         data_blob_free(&client_reply);
2150
2151         if (!NT_STATUS_IS_OK(status)) {
2152                 return status;
2153         }
2154
2155         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2156                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2157         if (subreq == NULL) {
2158                 return NT_STATUS_NO_MEMORY;
2159         }
2160         tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2161         return NT_STATUS_OK;
2162 }
2163
2164 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2165 {
2166         struct tevent_req *req = tevent_req_callback_data(
2167                 subreq, struct tevent_req);
2168         struct rpc_pipe_bind_state *state = tevent_req_data(
2169                 req, struct rpc_pipe_bind_state);
2170         DATA_BLOB tmp_blob = data_blob_null;
2171         struct ncacn_packet *pkt;
2172         struct dcerpc_auth auth;
2173         NTSTATUS status;
2174
2175         status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2176         TALLOC_FREE(subreq);
2177         if (!NT_STATUS_IS_OK(status)) {
2178                 tevent_req_nterror(req, status);
2179                 return;
2180         }
2181
2182         status = dcerpc_pull_dcerpc_auth(pkt,
2183                                          &pkt->u.alter_resp.auth_info,
2184                                          &auth, false);
2185         if (!NT_STATUS_IS_OK(status)) {
2186                 tevent_req_nterror(req, status);
2187                 return;
2188         }
2189
2190         /* Check we got a valid auth response. */
2191         if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2192                                         NT_STATUS_OK,
2193                                         OID_NTLMSSP, &tmp_blob)) {
2194                 data_blob_free(&tmp_blob);
2195                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2196                 return;
2197         }
2198
2199         data_blob_free(&tmp_blob);
2200
2201         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2202                  "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2203         tevent_req_done(req);
2204 }
2205
2206 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2207                                    struct rpc_pipe_bind_state *state,
2208                                    DATA_BLOB *auth_token)
2209 {
2210         struct pipe_auth_data *auth = state->cli->auth;
2211         struct tevent_req *subreq;
2212         NTSTATUS status;
2213
2214         /* Now prepare the alter context pdu. */
2215         data_blob_free(&state->rpc_out);
2216
2217         status = create_rpc_alter_context(state,
2218                                           auth->auth_type,
2219                                           auth->auth_level,
2220                                           state->rpc_call_id,
2221                                           &state->cli->abstract_syntax,
2222                                           &state->cli->transfer_syntax,
2223                                           auth_token,
2224                                           &state->rpc_out);
2225         if (!NT_STATUS_IS_OK(status)) {
2226                 return status;
2227         }
2228
2229         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2230                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2231         if (subreq == NULL) {
2232                 return NT_STATUS_NO_MEMORY;
2233         }
2234         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2235         return NT_STATUS_OK;
2236 }
2237
2238 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2239                                      struct rpc_pipe_bind_state *state,
2240                                      DATA_BLOB *auth_token)
2241 {
2242         struct pipe_auth_data *auth = state->cli->auth;
2243         struct tevent_req *subreq;
2244         NTSTATUS status;
2245
2246         /* Now prepare the auth3 context pdu. */
2247         data_blob_free(&state->rpc_out);
2248
2249         status = create_rpc_bind_auth3(state, state->cli,
2250                                         state->rpc_call_id,
2251                                         auth->auth_type,
2252                                         auth->auth_level,
2253                                         auth_token,
2254                                         &state->rpc_out);
2255         if (!NT_STATUS_IS_OK(status)) {
2256                 return status;
2257         }
2258
2259         subreq = rpc_write_send(state, state->ev, state->cli->transport,
2260                                 state->rpc_out.data, state->rpc_out.length);
2261         if (subreq == NULL) {
2262                 return NT_STATUS_NO_MEMORY;
2263         }
2264         tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2265         return NT_STATUS_OK;
2266 }
2267
2268 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2269 {
2270         return tevent_req_simple_recv_ntstatus(req);
2271 }
2272
2273 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2274                        struct pipe_auth_data *auth)
2275 {
2276         TALLOC_CTX *frame = talloc_stackframe();
2277         struct event_context *ev;
2278         struct tevent_req *req;
2279         NTSTATUS status = NT_STATUS_OK;
2280
2281         ev = event_context_init(frame);
2282         if (ev == NULL) {
2283                 status = NT_STATUS_NO_MEMORY;
2284                 goto fail;
2285         }
2286
2287         req = rpc_pipe_bind_send(frame, ev, cli, auth);
2288         if (req == NULL) {
2289                 status = NT_STATUS_NO_MEMORY;
2290                 goto fail;
2291         }
2292
2293         if (!tevent_req_poll(req, ev)) {
2294                 status = map_nt_error_from_unix(errno);
2295                 goto fail;
2296         }
2297
2298         status = rpc_pipe_bind_recv(req);
2299  fail:
2300         TALLOC_FREE(frame);
2301         return status;
2302 }
2303
2304 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2305
2306 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2307                                 unsigned int timeout)
2308 {
2309         unsigned int old;
2310
2311         if (rpc_cli->transport == NULL) {
2312                 return RPCCLI_DEFAULT_TIMEOUT;
2313         }
2314
2315         if (rpc_cli->transport->set_timeout == NULL) {
2316                 return RPCCLI_DEFAULT_TIMEOUT;
2317         }
2318
2319         old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2320         if (old == 0) {
2321                 return RPCCLI_DEFAULT_TIMEOUT;
2322         }
2323
2324         return old;
2325 }
2326
2327 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2328 {
2329         if (rpc_cli == NULL) {
2330                 return false;
2331         }
2332
2333         if (rpc_cli->transport == NULL) {
2334                 return false;
2335         }
2336
2337         return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2338 }
2339
2340 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2341 {
2342         struct cli_state *cli;
2343
2344         if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP)
2345             || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO
2346                  && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2347                 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2348                 return true;
2349         }
2350
2351         cli = rpc_pipe_np_smb_conn(rpc_cli);
2352         if (cli == NULL) {
2353                 return false;
2354         }
2355         E_md4hash(cli->password ? cli->password : "", nt_hash);
2356         return true;
2357 }
2358
2359 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2360                                struct pipe_auth_data **presult)
2361 {
2362         struct pipe_auth_data *result;
2363
2364         result = talloc(mem_ctx, struct pipe_auth_data);
2365         if (result == NULL) {
2366                 return NT_STATUS_NO_MEMORY;
2367         }
2368
2369         result->auth_type = DCERPC_AUTH_TYPE_NONE;
2370         result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2371         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2372
2373         result->user_name = talloc_strdup(result, "");
2374         result->domain = talloc_strdup(result, "");
2375         if ((result->user_name == NULL) || (result->domain == NULL)) {
2376                 TALLOC_FREE(result);
2377                 return NT_STATUS_NO_MEMORY;
2378         }
2379
2380         *presult = result;
2381         return NT_STATUS_OK;
2382 }
2383
2384 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2385 {
2386         TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2387         return 0;
2388 }
2389
2390 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2391                                   enum dcerpc_AuthType auth_type,
2392                                   enum pipe_auth_type_spnego spnego_type,
2393                                   enum dcerpc_AuthLevel auth_level,
2394                                   const char *domain,
2395                                   const char *username,
2396                                   const char *password,
2397                                   struct pipe_auth_data **presult)
2398 {
2399         struct pipe_auth_data *result;
2400         NTSTATUS status;
2401
2402         result = talloc(mem_ctx, struct pipe_auth_data);
2403         if (result == NULL) {
2404                 return NT_STATUS_NO_MEMORY;
2405         }
2406
2407         result->auth_type = auth_type;
2408         result->spnego_type = spnego_type;
2409         result->auth_level = auth_level;
2410
2411         result->user_name = talloc_strdup(result, username);
2412         result->domain = talloc_strdup(result, domain);
2413         if ((result->user_name == NULL) || (result->domain == NULL)) {
2414                 status = NT_STATUS_NO_MEMORY;
2415                 goto fail;
2416         }
2417
2418         status = auth_ntlmssp_client_start(NULL,
2419                                       global_myname(),
2420                                       lp_workgroup(),
2421                                       lp_client_ntlmv2_auth(),
2422                                       &result->a_u.auth_ntlmssp_state);
2423         if (!NT_STATUS_IS_OK(status)) {
2424                 goto fail;
2425         }
2426
2427         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2428
2429         status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2430                                            username);
2431         if (!NT_STATUS_IS_OK(status)) {
2432                 goto fail;
2433         }
2434
2435         status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2436                                          domain);
2437         if (!NT_STATUS_IS_OK(status)) {
2438                 goto fail;
2439         }
2440
2441         status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2442                                            password);
2443         if (!NT_STATUS_IS_OK(status)) {
2444                 goto fail;
2445         }
2446
2447         /*
2448          * Turn off sign+seal to allow selected auth level to turn it back on.
2449          */
2450         auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2451                                                 ~(NTLMSSP_NEGOTIATE_SIGN |
2452                                                   NTLMSSP_NEGOTIATE_SEAL));
2453
2454         if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2455                 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2456                                                 NTLMSSP_NEGOTIATE_SIGN);
2457         } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2458                 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2459                                                 NTLMSSP_NEGOTIATE_SEAL |
2460                                                 NTLMSSP_NEGOTIATE_SIGN);
2461         }
2462
2463         *presult = result;
2464         return NT_STATUS_OK;
2465
2466  fail:
2467         TALLOC_FREE(result);
2468         return status;
2469 }
2470
2471 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2472                                    enum dcerpc_AuthLevel auth_level,
2473                                    struct netlogon_creds_CredentialState *creds,
2474                                    struct pipe_auth_data **presult)
2475 {
2476         struct pipe_auth_data *result;
2477
2478         result = talloc(mem_ctx, struct pipe_auth_data);
2479         if (result == NULL) {
2480                 return NT_STATUS_NO_MEMORY;
2481         }
2482
2483         result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2484         result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2485         result->auth_level = auth_level;
2486
2487         result->user_name = talloc_strdup(result, "");
2488         result->domain = talloc_strdup(result, domain);
2489         if ((result->user_name == NULL) || (result->domain == NULL)) {
2490                 goto fail;
2491         }
2492
2493         result->a_u.schannel_auth = talloc(result, struct schannel_state);
2494         if (result->a_u.schannel_auth == NULL) {
2495                 goto fail;
2496         }
2497
2498         result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2499         result->a_u.schannel_auth->seq_num = 0;
2500         result->a_u.schannel_auth->initiator = true;
2501         result->a_u.schannel_auth->creds = creds;
2502
2503         *presult = result;
2504         return NT_STATUS_OK;
2505
2506  fail:
2507         TALLOC_FREE(result);
2508         return NT_STATUS_NO_MEMORY;
2509 }
2510
2511 /**
2512  * Create an rpc pipe client struct, connecting to a tcp port.
2513  */
2514 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2515                                        uint16_t port,
2516                                        const struct ndr_syntax_id *abstract_syntax,
2517                                        struct rpc_pipe_client **presult)
2518 {
2519         struct rpc_pipe_client *result;
2520         struct sockaddr_storage addr;
2521         NTSTATUS status;
2522         int fd;
2523
2524         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2525         if (result == NULL) {
2526                 return NT_STATUS_NO_MEMORY;
2527         }
2528
2529         result->abstract_syntax = *abstract_syntax;
2530         result->transfer_syntax = ndr_transfer_syntax;
2531         result->dispatch = cli_do_rpc_ndr;
2532         result->dispatch_send = cli_do_rpc_ndr_send;
2533         result->dispatch_recv = cli_do_rpc_ndr_recv;
2534
2535         result->desthost = talloc_strdup(result, host);
2536         result->srv_name_slash = talloc_asprintf_strupper_m(
2537                 result, "\\\\%s", result->desthost);
2538         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2539                 status = NT_STATUS_NO_MEMORY;
2540                 goto fail;
2541         }
2542
2543         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2544         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2545
2546         if (!resolve_name(host, &addr, 0, false)) {
2547                 status = NT_STATUS_NOT_FOUND;
2548                 goto fail;
2549         }
2550
2551         status = open_socket_out(&addr, port, 60, &fd);
2552         if (!NT_STATUS_IS_OK(status)) {
2553                 goto fail;
2554         }
2555         set_socket_options(fd, lp_socket_options());
2556
2557         status = rpc_transport_sock_init(result, fd, &result->transport);
2558         if (!NT_STATUS_IS_OK(status)) {
2559                 close(fd);
2560                 goto fail;
2561         }
2562
2563         result->transport->transport = NCACN_IP_TCP;
2564
2565         *presult = result;
2566         return NT_STATUS_OK;
2567
2568  fail:
2569         TALLOC_FREE(result);
2570         return status;
2571 }
2572
2573 /**
2574  * Determine the tcp port on which a dcerpc interface is listening
2575  * for the ncacn_ip_tcp transport via the endpoint mapper of the
2576  * target host.
2577  */
2578 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2579                                       const struct ndr_syntax_id *abstract_syntax,
2580                                       uint16_t *pport)
2581 {
2582         NTSTATUS status;
2583         struct rpc_pipe_client *epm_pipe = NULL;
2584         struct pipe_auth_data *auth = NULL;
2585         struct dcerpc_binding *map_binding = NULL;
2586         struct dcerpc_binding *res_binding = NULL;
2587         struct epm_twr_t *map_tower = NULL;
2588         struct epm_twr_t *res_towers = NULL;
2589         struct policy_handle *entry_handle = NULL;
2590         uint32_t num_towers = 0;
2591         uint32_t max_towers = 1;
2592         struct epm_twr_p_t towers;
2593         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2594
2595         if (pport == NULL) {
2596                 status = NT_STATUS_INVALID_PARAMETER;
2597                 goto done;
2598         }
2599
2600         /* open the connection to the endpoint mapper */
2601         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2602                                         &ndr_table_epmapper.syntax_id,
2603                                         &epm_pipe);
2604
2605         if (!NT_STATUS_IS_OK(status)) {
2606                 goto done;
2607         }
2608
2609         status = rpccli_anon_bind_data(tmp_ctx, &auth);
2610         if (!NT_STATUS_IS_OK(status)) {
2611                 goto done;
2612         }
2613
2614         status = rpc_pipe_bind(epm_pipe, auth);
2615         if (!NT_STATUS_IS_OK(status)) {
2616                 goto done;
2617         }
2618
2619         /* create tower for asking the epmapper */
2620
2621         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2622         if (map_binding == NULL) {
2623                 status = NT_STATUS_NO_MEMORY;
2624                 goto done;
2625         }
2626
2627         map_binding->transport = NCACN_IP_TCP;
2628         map_binding->object = *abstract_syntax;
2629         map_binding->host = host; /* needed? */
2630         map_binding->endpoint = "0"; /* correct? needed? */
2631
2632         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2633         if (map_tower == NULL) {
2634                 status = NT_STATUS_NO_MEMORY;
2635                 goto done;
2636         }
2637
2638         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2639                                             &(map_tower->tower));
2640         if (!NT_STATUS_IS_OK(status)) {
2641                 goto done;
2642         }
2643
2644         /* allocate further parameters for the epm_Map call */
2645
2646         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2647         if (res_towers == NULL) {
2648                 status = NT_STATUS_NO_MEMORY;
2649                 goto done;
2650         }
2651         towers.twr = res_towers;
2652
2653         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2654         if (entry_handle == NULL) {
2655                 status = NT_STATUS_NO_MEMORY;
2656                 goto done;
2657         }
2658
2659         /* ask the endpoint mapper for the port */
2660
2661         status = rpccli_epm_Map(epm_pipe,
2662                                 tmp_ctx,
2663                                 CONST_DISCARD(struct GUID *,
2664                                               &(abstract_syntax->uuid)),
2665                                 map_tower,
2666                                 entry_handle,
2667                                 max_towers,
2668                                 &num_towers,
2669                                 &towers);
2670
2671         if (!NT_STATUS_IS_OK(status)) {
2672                 goto done;
2673         }
2674
2675         if (num_towers != 1) {
2676                 status = NT_STATUS_UNSUCCESSFUL;
2677                 goto done;
2678         }
2679
2680         /* extract the port from the answer */
2681
2682         status = dcerpc_binding_from_tower(tmp_ctx,
2683                                            &(towers.twr->tower),
2684                                            &res_binding);
2685         if (!NT_STATUS_IS_OK(status)) {
2686                 goto done;
2687         }
2688
2689         /* are further checks here necessary? */
2690         if (res_binding->transport != NCACN_IP_TCP) {
2691                 status = NT_STATUS_UNSUCCESSFUL;
2692                 goto done;
2693         }
2694
2695         *pport = (uint16_t)atoi(res_binding->endpoint);
2696
2697 done:
2698         TALLOC_FREE(tmp_ctx);
2699         return status;
2700 }
2701
2702 /**
2703  * Create a rpc pipe client struct, connecting to a host via tcp.
2704  * The port is determined by asking the endpoint mapper on the given
2705  * host.
2706  */
2707 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2708                            const struct ndr_syntax_id *abstract_syntax,
2709                            struct rpc_pipe_client **presult)
2710 {
2711         NTSTATUS status;
2712         uint16_t port = 0;
2713
2714         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2715         if (!NT_STATUS_IS_OK(status)) {
2716                 return status;
2717         }
2718
2719         return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2720                                         abstract_syntax, presult);
2721 }
2722
2723 /********************************************************************
2724  Create a rpc pipe client struct, connecting to a unix domain socket
2725  ********************************************************************/
2726 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2727                                const struct ndr_syntax_id *abstract_syntax,
2728                                struct rpc_pipe_client **presult)
2729 {
2730         struct rpc_pipe_client *result;
2731         struct sockaddr_un addr;
2732         NTSTATUS status;
2733         int fd;
2734
2735         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2736         if (result == NULL) {
2737                 return NT_STATUS_NO_MEMORY;
2738         }
2739
2740         result->abstract_syntax = *abstract_syntax;
2741         result->transfer_syntax = ndr_transfer_syntax;
2742         result->dispatch = cli_do_rpc_ndr;
2743         result->dispatch_send = cli_do_rpc_ndr_send;
2744         result->dispatch_recv = cli_do_rpc_ndr_recv;
2745
2746         result->desthost = get_myname(result);
2747         result->srv_name_slash = talloc_asprintf_strupper_m(
2748                 result, "\\\\%s", result->desthost);
2749         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2750                 status = NT_STATUS_NO_MEMORY;
2751                 goto fail;
2752         }
2753
2754         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2755         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2756
2757         fd = socket(AF_UNIX, SOCK_STREAM, 0);
2758         if (fd == -1) {
2759                 status = map_nt_error_from_unix(errno);
2760                 goto fail;
2761         }
2762
2763         ZERO_STRUCT(addr);
2764         addr.sun_family = AF_UNIX;
2765         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2766
2767         if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2768                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2769                           strerror(errno)));
2770                 close(fd);
2771                 return map_nt_error_from_unix(errno);
2772         }
2773
2774         status = rpc_transport_sock_init(result, fd, &result->transport);
2775         if (!NT_STATUS_IS_OK(status)) {
2776                 close(fd);
2777                 goto fail;
2778         }
2779
2780         result->transport->transport = NCALRPC;
2781
2782         *presult = result;
2783         return NT_STATUS_OK;
2784
2785  fail:
2786         TALLOC_FREE(result);
2787         return status;
2788 }
2789
2790 struct rpc_pipe_client_np_ref {
2791         struct cli_state *cli;
2792         struct rpc_pipe_client *pipe;
2793 };
2794
2795 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2796 {
2797         DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2798         return 0;
2799 }
2800
2801 /****************************************************************************
2802  Open a named pipe over SMB to a remote server.
2803  *
2804  * CAVEAT CALLER OF THIS FUNCTION:
2805  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2806  *    so be sure that this function is called AFTER any structure (vs pointer)
2807  *    assignment of the cli.  In particular, libsmbclient does structure
2808  *    assignments of cli, which invalidates the data in the returned
2809  *    rpc_pipe_client if this function is called before the structure assignment
2810  *    of cli.
2811  * 
2812  ****************************************************************************/
2813
2814 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2815                                  const struct ndr_syntax_id *abstract_syntax,
2816                                  struct rpc_pipe_client **presult)
2817 {
2818         struct rpc_pipe_client *result;
2819         NTSTATUS status;
2820         struct rpc_pipe_client_np_ref *np_ref;
2821
2822         /* sanity check to protect against crashes */
2823
2824         if ( !cli ) {
2825                 return NT_STATUS_INVALID_HANDLE;
2826         }
2827
2828         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2829         if (result == NULL) {
2830                 return NT_STATUS_NO_MEMORY;
2831         }
2832
2833         result->abstract_syntax = *abstract_syntax;
2834         result->transfer_syntax = ndr_transfer_syntax;
2835         result->dispatch = cli_do_rpc_ndr;
2836         result->dispatch_send = cli_do_rpc_ndr_send;
2837         result->dispatch_recv = cli_do_rpc_ndr_recv;
2838         result->desthost = talloc_strdup(result, cli->desthost);
2839         result->srv_name_slash = talloc_asprintf_strupper_m(
2840                 result, "\\\\%s", result->desthost);
2841
2842         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2843         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2844
2845         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2846                 TALLOC_FREE(result);
2847                 return NT_STATUS_NO_MEMORY;
2848         }
2849
2850         status = rpc_transport_np_init(result, cli, abstract_syntax,
2851                                        &result->transport);
2852         if (!NT_STATUS_IS_OK(status)) {
2853                 TALLOC_FREE(result);
2854                 return status;
2855         }
2856
2857         result->transport->transport = NCACN_NP;
2858
2859         np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2860         if (np_ref == NULL) {
2861                 TALLOC_FREE(result);
2862                 return NT_STATUS_NO_MEMORY;
2863         }
2864         np_ref->cli = cli;
2865         np_ref->pipe = result;
2866
2867         DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2868         talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2869
2870         *presult = result;
2871         return NT_STATUS_OK;
2872 }
2873
2874 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2875                              struct rpc_cli_smbd_conn *conn,
2876                              const struct ndr_syntax_id *syntax,
2877                              struct rpc_pipe_client **presult)
2878 {
2879         struct rpc_pipe_client *result;
2880         struct pipe_auth_data *auth;
2881         NTSTATUS status;
2882
2883         result = talloc(mem_ctx, struct rpc_pipe_client);
2884         if (result == NULL) {
2885                 return NT_STATUS_NO_MEMORY;
2886         }
2887         result->abstract_syntax = *syntax;
2888         result->transfer_syntax = ndr_transfer_syntax;
2889         result->dispatch = cli_do_rpc_ndr;
2890         result->dispatch_send = cli_do_rpc_ndr_send;
2891         result->dispatch_recv = cli_do_rpc_ndr_recv;
2892         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2893         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2894
2895         result->desthost = talloc_strdup(result, global_myname());
2896         result->srv_name_slash = talloc_asprintf_strupper_m(
2897                 result, "\\\\%s", global_myname());
2898         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2899                 TALLOC_FREE(result);
2900                 return NT_STATUS_NO_MEMORY;
2901         }
2902
2903         status = rpc_transport_smbd_init(result, conn, syntax,
2904                                          &result->transport);
2905         if (!NT_STATUS_IS_OK(status)) {
2906                 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2907                           nt_errstr(status)));
2908                 TALLOC_FREE(result);
2909                 return status;
2910         }
2911
2912         status = rpccli_anon_bind_data(result, &auth);
2913         if (!NT_STATUS_IS_OK(status)) {
2914                 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2915                           nt_errstr(status)));
2916                 TALLOC_FREE(result);
2917                 return status;
2918         }
2919
2920         status = rpc_pipe_bind(result, auth);
2921         if (!NT_STATUS_IS_OK(status)) {
2922                 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2923                 TALLOC_FREE(result);
2924                 return status;
2925         }
2926
2927         result->transport->transport = NCACN_INTERNAL;
2928
2929         *presult = result;
2930         return NT_STATUS_OK;
2931 }
2932
2933 /****************************************************************************
2934  Open a pipe to a remote server.
2935  ****************************************************************************/
2936
2937 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2938                                   enum dcerpc_transport_t transport,
2939                                   const struct ndr_syntax_id *interface,
2940                                   struct rpc_pipe_client **presult)
2941 {
2942         switch (transport) {
2943         case NCACN_IP_TCP:
2944                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2945                                          presult);
2946         case NCACN_NP:
2947                 return rpc_pipe_open_np(cli, interface, presult);
2948         default:
2949                 return NT_STATUS_NOT_IMPLEMENTED;
2950         }
2951 }
2952
2953 /****************************************************************************
2954  Open a named pipe to an SMB server and bind anonymously.
2955  ****************************************************************************/
2956
2957 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2958                                             enum dcerpc_transport_t transport,
2959                                             const struct ndr_syntax_id *interface,
2960                                             struct rpc_pipe_client **presult)
2961 {
2962         struct rpc_pipe_client *result;
2963         struct pipe_auth_data *auth;
2964         NTSTATUS status;
2965
2966         status = cli_rpc_pipe_open(cli, transport, interface, &result);
2967         if (!NT_STATUS_IS_OK(status)) {
2968                 return status;
2969         }
2970
2971         status = rpccli_anon_bind_data(result, &auth);
2972         if (!NT_STATUS_IS_OK(status)) {
2973                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2974                           nt_errstr(status)));
2975                 TALLOC_FREE(result);
2976                 return status;
2977         }
2978
2979         /*
2980          * This is a bit of an abstraction violation due to the fact that an
2981          * anonymous bind on an authenticated SMB inherits the user/domain
2982          * from the enclosing SMB creds
2983          */
2984
2985         TALLOC_FREE(auth->user_name);
2986         TALLOC_FREE(auth->domain);
2987
2988         auth->user_name = talloc_strdup(auth, cli->user_name);
2989         auth->domain = talloc_strdup(auth, cli->domain);
2990         auth->user_session_key = data_blob_talloc(auth,
2991                 cli->user_session_key.data,
2992                 cli->user_session_key.length);
2993
2994         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2995                 TALLOC_FREE(result);
2996                 return NT_STATUS_NO_MEMORY;
2997         }
2998
2999         status = rpc_pipe_bind(result, auth);
3000         if (!NT_STATUS_IS_OK(status)) {
3001                 int lvl = 0;
3002                 if (ndr_syntax_id_equal(interface,
3003                                         &ndr_table_dssetup.syntax_id)) {
3004                         /* non AD domains just don't have this pipe, avoid
3005                          * level 0 statement in that case - gd */
3006                         lvl = 3;
3007                 }
3008                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3009                             "%s failed with error %s\n",
3010                             get_pipe_name_from_syntax(talloc_tos(), interface),
3011                             nt_errstr(status) ));
3012                 TALLOC_FREE(result);
3013                 return status;
3014         }
3015
3016         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3017                   "%s and bound anonymously.\n",
3018                   get_pipe_name_from_syntax(talloc_tos(), interface),
3019                   cli->desthost));
3020
3021         *presult = result;
3022         return NT_STATUS_OK;
3023 }
3024
3025 /****************************************************************************
3026  ****************************************************************************/
3027
3028 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3029                                   const struct ndr_syntax_id *interface,
3030                                   struct rpc_pipe_client **presult)
3031 {
3032         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3033                                                   interface, presult);
3034 }
3035
3036 /****************************************************************************
3037  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3038  ****************************************************************************/
3039
3040 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3041                                                    const struct ndr_syntax_id *interface,
3042                                                    enum dcerpc_transport_t transport,
3043                                                    bool use_spnego,
3044                                                    enum dcerpc_AuthLevel auth_level,
3045                                                    const char *domain,
3046                                                    const char *username,
3047                                                    const char *password,
3048                                                    struct rpc_pipe_client **presult)
3049 {
3050         struct rpc_pipe_client *result;
3051         struct pipe_auth_data *auth;
3052         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
3053         enum pipe_auth_type_spnego spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
3054         NTSTATUS status;
3055
3056         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3057         if (!NT_STATUS_IS_OK(status)) {
3058                 return status;
3059         }
3060
3061         if (use_spnego) {
3062                 auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3063                 spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
3064         }
3065
3066         status = rpccli_ntlmssp_bind_data(result,
3067                                           auth_type, spnego_type, auth_level,
3068                                           domain, username, password,
3069                                           &auth);
3070         if (!NT_STATUS_IS_OK(status)) {
3071                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3072                           nt_errstr(status)));
3073                 goto err;
3074         }
3075
3076         status = rpc_pipe_bind(result, auth);
3077         if (!NT_STATUS_IS_OK(status)) {
3078                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3079                         nt_errstr(status) ));
3080                 goto err;
3081         }
3082
3083         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3084                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3085                   get_pipe_name_from_syntax(talloc_tos(), interface),
3086                   cli->desthost, domain, username ));
3087
3088         *presult = result;
3089         return NT_STATUS_OK;
3090
3091   err:
3092
3093         TALLOC_FREE(result);
3094         return status;
3095 }
3096
3097 /****************************************************************************
3098  External interface.
3099  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3100  ****************************************************************************/
3101
3102 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3103                                    const struct ndr_syntax_id *interface,
3104                                    enum dcerpc_transport_t transport,
3105                                    enum dcerpc_AuthLevel auth_level,
3106                                    const char *domain,
3107                                    const char *username,
3108                                    const char *password,
3109                                    struct rpc_pipe_client **presult)
3110 {
3111         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3112                                                 interface,
3113                                                 transport,
3114                                                 false,
3115                                                 auth_level,
3116                                                 domain,
3117                                                 username,
3118                                                 password,
3119                                                 presult);
3120 }
3121
3122 /****************************************************************************
3123  External interface.
3124  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3125  ****************************************************************************/
3126
3127 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3128                                           const struct ndr_syntax_id *interface,
3129                                           enum dcerpc_transport_t transport,
3130                                           enum dcerpc_AuthLevel auth_level,
3131                                           const char *domain,
3132                                           const char *username,
3133                                           const char *password,
3134                                           struct rpc_pipe_client **presult)
3135 {
3136         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3137                                                 interface,
3138                                                 transport,
3139                                                 true,
3140                                                 auth_level,
3141                                                 domain,
3142                                                 username,
3143                                                 password,
3144                                                 presult);
3145 }
3146
3147 /****************************************************************************
3148   Get a the schannel session key out of an already opened netlogon pipe.
3149  ****************************************************************************/
3150 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3151                                                 struct cli_state *cli,
3152                                                 const char *domain,
3153                                                 uint32 *pneg_flags)
3154 {
3155         enum netr_SchannelType sec_chan_type = 0;
3156         unsigned char machine_pwd[16];
3157         const char *machine_account;
3158         NTSTATUS status;
3159
3160         /* Get the machine account credentials from secrets.tdb. */
3161         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3162                                &sec_chan_type))
3163         {
3164                 DEBUG(0, ("get_schannel_session_key: could not fetch "
3165                         "trust account password for domain '%s'\n",
3166                         domain));
3167                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3168         }
3169
3170         status = rpccli_netlogon_setup_creds(netlogon_pipe,
3171                                         cli->desthost, /* server name */
3172                                         domain,        /* domain */
3173                                         global_myname(), /* client name */
3174                                         machine_account, /* machine account name */
3175                                         machine_pwd,
3176                                         sec_chan_type,
3177                                         pneg_flags);
3178
3179         if (!NT_STATUS_IS_OK(status)) {
3180                 DEBUG(3, ("get_schannel_session_key_common: "
3181                           "rpccli_netlogon_setup_creds failed with result %s "
3182                           "to server %s, domain %s, machine account %s.\n",
3183                           nt_errstr(status), cli->desthost, domain,
3184                           machine_account ));
3185                 return status;
3186         }
3187
3188         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3189                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3190                         cli->desthost));
3191                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3192         }
3193
3194         return NT_STATUS_OK;;
3195 }
3196
3197 /****************************************************************************
3198  Open a netlogon pipe and get the schannel session key.
3199  Now exposed to external callers.
3200  ****************************************************************************/
3201
3202
3203 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3204                                   const char *domain,
3205                                   uint32 *pneg_flags,
3206                                   struct rpc_pipe_client **presult)
3207 {
3208         struct rpc_pipe_client *netlogon_pipe = NULL;
3209         NTSTATUS status;
3210
3211         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3212                                           &netlogon_pipe);
3213         if (!NT_STATUS_IS_OK(status)) {
3214                 return status;
3215         }
3216
3217         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3218                                                  pneg_flags);
3219         if (!NT_STATUS_IS_OK(status)) {
3220                 TALLOC_FREE(netlogon_pipe);
3221                 return status;
3222         }
3223
3224         *presult = netlogon_pipe;
3225         return NT_STATUS_OK;
3226 }
3227
3228 /****************************************************************************
3229  External interface.
3230  Open a named pipe to an SMB server and bind using schannel (bind type 68)
3231  using session_key. sign and seal.
3232
3233  The *pdc will be stolen onto this new pipe
3234  ****************************************************************************/
3235
3236 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3237                                              const struct ndr_syntax_id *interface,
3238                                              enum dcerpc_transport_t transport,
3239                                              enum dcerpc_AuthLevel auth_level,
3240                                              const char *domain,
3241                                              struct netlogon_creds_CredentialState **pdc,
3242                                              struct rpc_pipe_client **presult)
3243 {
3244         struct rpc_pipe_client *result;
3245         struct pipe_auth_data *auth;
3246         NTSTATUS status;
3247
3248         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3249         if (!NT_STATUS_IS_OK(status)) {
3250                 return status;
3251         }
3252
3253         status = rpccli_schannel_bind_data(result, domain, auth_level,
3254                                            *pdc, &auth);
3255         if (!NT_STATUS_IS_OK(status)) {
3256                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3257                           nt_errstr(status)));
3258                 TALLOC_FREE(result);
3259                 return status;
3260         }
3261
3262         status = rpc_pipe_bind(result, auth);
3263         if (!NT_STATUS_IS_OK(status)) {
3264                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3265                           "cli_rpc_pipe_bind failed with error %s\n",
3266                           nt_errstr(status) ));
3267                 TALLOC_FREE(result);
3268                 return status;
3269         }
3270
3271         /*
3272          * The credentials on a new netlogon pipe are the ones we are passed
3273          * in - reference them in
3274          */
3275         result->dc = talloc_move(result, pdc);
3276
3277         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3278                   "for domain %s and bound using schannel.\n",
3279                   get_pipe_name_from_syntax(talloc_tos(), interface),
3280                   cli->desthost, domain ));
3281
3282         *presult = result;
3283         return NT_STATUS_OK;
3284 }
3285
3286 /****************************************************************************
3287  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3288  Fetch the session key ourselves using a temporary netlogon pipe. This
3289  version uses an ntlmssp auth bound netlogon pipe to get the key.
3290  ****************************************************************************/
3291
3292 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3293                                                       const char *domain,
3294                                                       const char *username,
3295                                                       const char *password,
3296                                                       uint32 *pneg_flags,
3297                                                       struct rpc_pipe_client **presult)
3298 {
3299         struct rpc_pipe_client *netlogon_pipe = NULL;
3300         NTSTATUS status;
3301
3302         status = cli_rpc_pipe_open_spnego_ntlmssp(
3303                 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3304                 DCERPC_AUTH_LEVEL_PRIVACY,
3305                 domain, username, password, &netlogon_pipe);
3306         if (!NT_STATUS_IS_OK(status)) {
3307                 return status;
3308         }
3309
3310         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3311                                                  pneg_flags);
3312         if (!NT_STATUS_IS_OK(status)) {
3313                 TALLOC_FREE(netlogon_pipe);
3314                 return status;
3315         }
3316
3317         *presult = netlogon_pipe;
3318         return NT_STATUS_OK;
3319 }
3320
3321 /****************************************************************************
3322  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3323  Fetch the session key ourselves using a temporary netlogon pipe. This version
3324  uses an ntlmssp bind to get the session key.
3325  ****************************************************************************/
3326
3327 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3328                                                  const struct ndr_syntax_id *interface,
3329                                                  enum dcerpc_transport_t transport,
3330                                                  enum dcerpc_AuthLevel auth_level,
3331                                                  const char *domain,
3332                                                  const char *username,
3333                                                  const char *password,
3334                                                  struct rpc_pipe_client **presult)
3335 {
3336         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3337         struct rpc_pipe_client *netlogon_pipe = NULL;
3338         struct rpc_pipe_client *result = NULL;
3339         NTSTATUS status;
3340
3341         status = get_schannel_session_key_auth_ntlmssp(
3342                 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3343         if (!NT_STATUS_IS_OK(status)) {
3344                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3345                         "key from server %s for domain %s.\n",
3346                         cli->desthost, domain ));
3347                 return status;
3348         }
3349
3350         status = cli_rpc_pipe_open_schannel_with_key(
3351                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3352                 &result);
3353
3354         /* Now we've bound using the session key we can close the netlog pipe. */
3355         TALLOC_FREE(netlogon_pipe);
3356
3357         if (NT_STATUS_IS_OK(status)) {
3358                 *presult = result;
3359         }
3360         return status;
3361 }
3362
3363 /****************************************************************************
3364  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3365  Fetch the session key ourselves using a temporary netlogon pipe.
3366  ****************************************************************************/
3367
3368 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3369                                     const struct ndr_syntax_id *interface,
3370                                     enum dcerpc_transport_t transport,
3371                                     enum dcerpc_AuthLevel auth_level,
3372                                     const char *domain,
3373                                     struct rpc_pipe_client **presult)
3374 {
3375         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3376         struct rpc_pipe_client *netlogon_pipe = NULL;
3377         struct rpc_pipe_client *result = NULL;
3378         NTSTATUS status;
3379
3380         status = get_schannel_session_key(cli, domain, &neg_flags,
3381                                           &netlogon_pipe);
3382         if (!NT_STATUS_IS_OK(status)) {
3383                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3384                         "key from server %s for domain %s.\n",
3385                         cli->desthost, domain ));
3386                 return status;
3387         }
3388
3389         status = cli_rpc_pipe_open_schannel_with_key(
3390                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3391                 &result);
3392
3393         /* Now we've bound using the session key we can close the netlog pipe. */
3394         TALLOC_FREE(netlogon_pipe);
3395
3396         if (NT_STATUS_IS_OK(status)) {
3397                 *presult = result;
3398         }
3399
3400         return status;
3401 }
3402
3403 /****************************************************************************
3404  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3405  The idea is this can be called with service_princ, username and password all
3406  NULL so long as the caller has a TGT.
3407  ****************************************************************************/
3408
3409 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3410                                 const struct ndr_syntax_id *interface,
3411                                 enum dcerpc_transport_t transport,
3412                                 enum dcerpc_AuthLevel auth_level,
3413                                 const char *server,
3414                                 const char *username,
3415                                 const char *password,
3416                                 struct rpc_pipe_client **presult)
3417 {
3418         struct rpc_pipe_client *result;
3419         struct pipe_auth_data *auth;
3420         NTSTATUS status;
3421
3422         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3423         if (!NT_STATUS_IS_OK(status)) {
3424                 return status;
3425         }
3426
3427         auth = talloc(result, struct pipe_auth_data);
3428         if (auth == NULL) {
3429                 status = NT_STATUS_NO_MEMORY;
3430                 goto err_out;
3431         }
3432         auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3433         auth->auth_level = auth_level;
3434
3435         if (!username) {
3436                 username = "";
3437         }
3438         auth->user_name = talloc_strdup(auth, username);
3439         if (!auth->user_name) {
3440                 status = NT_STATUS_NO_MEMORY;
3441                 goto err_out;
3442         }
3443
3444         /* Fixme, should we fetch/set the Realm ? */
3445         auth->domain = talloc_strdup(auth, "");
3446         if (!auth->domain) {
3447                 status = NT_STATUS_NO_MEMORY;
3448                 goto err_out;
3449         }
3450
3451         status = gse_init_client(auth, auth->auth_type, auth->auth_level,
3452                                  NULL, server, "cifs", username, password,
3453                                  GSS_C_DCE_STYLE, &auth->a_u.gssapi_state);
3454
3455         if (!NT_STATUS_IS_OK(status)) {
3456                 DEBUG(0, ("gse_init_client returned %s\n",
3457                           nt_errstr(status)));
3458                 goto err_out;
3459         }
3460
3461         status = rpc_pipe_bind(result, auth);
3462         if (!NT_STATUS_IS_OK(status)) {
3463                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3464                           nt_errstr(status)));
3465                 goto err_out;
3466         }
3467
3468         *presult = result;
3469         return NT_STATUS_OK;
3470
3471 err_out:
3472         TALLOC_FREE(result);
3473         return status;
3474 }
3475
3476 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3477                                         const struct ndr_syntax_id *interface,
3478                                         enum dcerpc_transport_t transport,
3479                                         enum dcerpc_AuthLevel auth_level,
3480                                         const char *server,
3481                                         const char *username,
3482                                         const char *password,
3483                                         struct rpc_pipe_client **presult)
3484 {
3485         struct rpc_pipe_client *result;
3486         struct pipe_auth_data *auth;
3487         NTSTATUS status;
3488
3489         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3490         if (!NT_STATUS_IS_OK(status)) {
3491                 return status;
3492         }
3493
3494         auth = talloc(result, struct pipe_auth_data);
3495         if (auth == NULL) {
3496                 status = NT_STATUS_NO_MEMORY;
3497                 goto err_out;
3498         }
3499         auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3500         auth->auth_level = auth_level;
3501         /* compat */
3502         auth->spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
3503
3504         if (!username) {
3505                 username = "";
3506         }
3507         auth->user_name = talloc_strdup(auth, username);
3508         if (!auth->user_name) {
3509                 status = NT_STATUS_NO_MEMORY;
3510                 goto err_out;
3511         }
3512
3513         /* Fixme, should we fetch/set the Realm ? */
3514         auth->domain = talloc_strdup(auth, "");
3515         if (!auth->domain) {
3516                 status = NT_STATUS_NO_MEMORY;
3517                 goto err_out;
3518         }
3519
3520         status = spnego_gssapi_init_client(auth, auth->auth_level,
3521                                            NULL, server, "cifs",
3522                                            username, password,
3523                                            GSS_C_DCE_STYLE,
3524                                            &auth->a_u.spnego_state);
3525         if (!NT_STATUS_IS_OK(status)) {
3526                 DEBUG(0, ("spnego_init_client returned %s\n",
3527                           nt_errstr(status)));
3528                 goto err_out;
3529         }
3530
3531         status = rpc_pipe_bind(result, auth);
3532         if (!NT_STATUS_IS_OK(status)) {
3533                 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3534                           nt_errstr(status)));
3535                 goto err_out;
3536         }
3537
3538         *presult = result;
3539         return NT_STATUS_OK;
3540
3541 err_out:
3542         TALLOC_FREE(result);
3543         return status;
3544 }
3545
3546 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3547                              struct rpc_pipe_client *cli,
3548                              DATA_BLOB *session_key)
3549 {
3550         struct pipe_auth_data *a = cli->auth;
3551         DATA_BLOB sk;
3552
3553         if (!session_key || !cli) {
3554                 return NT_STATUS_INVALID_PARAMETER;
3555         }
3556
3557         if (!cli->auth) {
3558                 return NT_STATUS_INVALID_PARAMETER;
3559         }
3560
3561         switch (cli->auth->auth_type) {
3562         case DCERPC_AUTH_TYPE_SCHANNEL:
3563                 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3564                                      16);
3565                 break;
3566         case DCERPC_AUTH_TYPE_SPNEGO:
3567                 switch (cli->auth->spnego_type) {
3568                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3569                         sk = auth_ntlmssp_get_session_key(
3570                                                 a->a_u.auth_ntlmssp_state);
3571                         break;
3572                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3573                         sk = gse_get_session_key(a->a_u.gssapi_state);
3574                         break;
3575                 default:
3576                         return NT_STATUS_NO_USER_SESSION_KEY;
3577                 }
3578                 break;
3579         case DCERPC_AUTH_TYPE_NTLMSSP:
3580                 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3581                 break;
3582         case DCERPC_AUTH_TYPE_KRB5:
3583                 sk = gse_get_session_key(a->a_u.gssapi_state);
3584                 break;
3585         case DCERPC_AUTH_TYPE_NONE:
3586                 sk = data_blob_const(a->user_session_key.data,
3587                                      a->user_session_key.length);
3588                 break;
3589         default:
3590                 return NT_STATUS_NO_USER_SESSION_KEY;
3591         }
3592
3593         *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3594         return NT_STATUS_OK;
3595 }