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