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