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